home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Exec 3 / CD_Magazyn_EXEC_nr_3.iso / Recent / util / mouse / FreeWheel.lha / FreeWheel / CxCustom.c < prev    next >
C/C++ Source or Header  |  2000-05-26  |  10KB  |  373 lines

  1.  
  2. #include <exec/types.h>
  3. #include <devices/inputevent.h>
  4. #include <libraries/commodities.h>
  5. #include <intuition/newmouse.h>
  6. #include <intuition/intuitionbase.h>
  7. #include <intuition/screens.h>
  8. #include <graphics/clip.h>
  9. #include <graphics/layers.h>
  10.  
  11. #include <clib/exec_protos.h>
  12. #include <clib/commodities_protos.h>
  13. #include <clib/intuition_protos.h>
  14. #include <clib/alib_protos.h>
  15.  
  16. #include "WheelMouse.h"
  17. #include "Scroll.h"
  18. #include "Cx.h"
  19. #include "RawKey.h"
  20.  
  21. #include "CxCustom.h"
  22.  
  23. extern struct IntuitionBase *IntuitionBase;
  24. extern struct WheelMouseContext *MyWM;
  25. extern struct CxContext *Cx;
  26.  
  27. int AddIntAtomic(int *a,int v);
  28.  
  29. void HandleDoubleClick(struct ButtonData *bd,struct InputEvent *ie);
  30. void HandleClickToFront(struct InputEvent *ie);
  31. BOOL InWindowBorder(struct Window *win);
  32.  
  33.  
  34. void CxDepthArrange(int dy)
  35. {
  36.   struct Window *win;
  37.   if(win=WindowUnderPointer())
  38.   {
  39.     if(win->Flags&WFLG_DEPTHGADGET)
  40.     {
  41.       if(dy<0)
  42.         WindowToBack(win);
  43.       else
  44.         WindowToFront(win);
  45.     }
  46.   }
  47. }
  48.  
  49.  
  50. void CxCustomRoutine(CxMsg *msg,CxObj *obj)
  51. {
  52.   static int xrem=0,yrem=0;
  53.   static int scrxrem=0,scryrem=0;
  54.   int x,y,dx,dy,msx,msy,fdx,fdy;
  55.   BOOL send=FALSE;
  56.   struct InputEvent *e=CxMsgData(msg);
  57.  
  58.   msx=MyWM->MouseSpeedX;
  59.   msy=MyWM->MouseSpeedY;
  60.  
  61.   dx=dy=fdx=fdy=0;
  62.  
  63.   if(((MyWM->MidButton.State)&&(MyWM->MidButton.ClickMode==ClickShiftClick))
  64.    ||((MyWM->FourthButton.State)&&(MyWM->FourthButton.ClickMode==ClickShiftClick)))
  65.   {
  66.     e->ie_Qualifier&=~IEQUALIFIER_MIDBUTTON;
  67.     e->ie_Qualifier|=IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT;
  68.   }
  69.  
  70.   switch(e->ie_Class)
  71.   {
  72.     case IECLASS_RAWMOUSE:
  73.       x=e->ie_X; y=e->ie_Y;
  74.       if(msx>100)
  75.         if(x<3 && x>-3)
  76.           msx=100;
  77.       if(msy>100)
  78.         if(y<3 && y>-3)
  79.           msy=100;
  80.       x=e->ie_X*msx+xrem; xrem=x; x/=100; xrem-=x*100; e->ie_X=x;
  81.       y=e->ie_Y*msy+yrem; yrem=y; y/=100; yrem-=y*100; e->ie_Y=y;
  82.  
  83.       switch(e->ie_Code)
  84.       {
  85.         case IECODE_MBUTTON:
  86.           HandleDoubleClick(&MyWM->MidButton,e);
  87.  
  88.           MyWM->MidButton.State=TRUE;
  89.           switch(MyWM->MidButton.ClickMode)
  90.           {
  91.             case ClickShift:
  92.               e->ie_Code=RK_LShift;
  93.               e->ie_Class=IECLASS_RAWKEY;
  94.               break;
  95.             case ClickShiftClick:
  96.               e->ie_Code=IECODE_LBUTTON;
  97.               e->ie_Qualifier=IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT;
  98.               break;
  99.             case ClickCycleScreens:
  100.               ScreenToBack(IntuitionBase->FirstScreen);
  101.               break;
  102.             case ClickMoveScrollToggle:
  103.               MyWM->MidButton.ScrollToggle^=1;
  104.               break;
  105.             case ClickMoveToScroll:
  106.               MyWM->MidButton.ScrollToggle=1;
  107.               break;
  108.             case ClickToggleLMB:
  109.               if(MyWM->MidButton.LMBToggle)
  110.               {
  111.                 e->ie_Code=IECODE_LBUTTON|IECODE_UP_PREFIX;
  112.                 MyWM->MidButton.LMBToggle=0;
  113.               }
  114.               else
  115.               {
  116.                 e->ie_Code=IECODE_LBUTTON;
  117.                 MyWM->MidButton.LMBToggle=1;
  118.               }
  119.               break;
  120.           }
  121.           break; /* IECODE_MBUTTON */
  122.  
  123.         case IECODE_MBUTTON|IECODE_UP_PREFIX:
  124.  
  125.           MyWM->MidButton.State=FALSE;
  126.           switch(MyWM->MidButton.ClickMode)
  127.           {
  128.             case ClickShift:
  129.               e->ie_Class=IECLASS_RAWKEY;
  130.               e->ie_Code=RK_LShift|IECODE_UP_PREFIX;
  131.               break;
  132.             case ClickShiftClick:
  133.               e->ie_Code=IECODE_UP_PREFIX|IECODE_LBUTTON;
  134.               e->ie_Qualifier=IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT;
  135.               break;
  136.             case ClickMoveToScroll:
  137.               MyWM->MidButton.ScrollToggle=0;
  138.               break;
  139.           }
  140.           break; /* IECODE_MBUTTON|IECODE_UP_PREFIX */
  141.  
  142.         case IECODE_LBUTTON:
  143.           if(MyWM->ClickToFront||MyWM->ClickToBack)
  144.             HandleClickToFront(e);
  145.           break;
  146.  
  147.         case IECODE_LBUTTON|IECODE_UP_PREFIX:
  148.             MyWM->MidButton.LMBToggle=0;
  149.             MyWM->FourthButton.LMBToggle=0;
  150.           break;
  151.       }
  152.  
  153.  
  154.       /* Generate scrolling movement from mouse movement:
  155.          A remainder is maintained, so small movements will accumulate. */
  156.  
  157.       if((MyWM->MidButton.ScrollToggle)||(MyWM->FourthButton.ScrollToggle))
  158.       {
  159.         fdx=e->ie_X*MyWM->FakeScrollSpeed+scrxrem;
  160.         scrxrem=fdx; fdx/=256; scrxrem-=fdx*256; e->ie_X=0;
  161.         fdy=e->ie_Y*MyWM->FakeScrollSpeed+scryrem;
  162.         scryrem=fdy; fdy/=256; scryrem-=fdy*256; e->ie_Y=0;
  163.         AddIntAtomic(&MyWM->FakeY,fdy);
  164.         AddIntAtomic(&MyWM->FakeX,fdx);
  165.         Signal(MyWM->MainTask,MyWM->Signals);
  166.       }
  167.  
  168.       break; /* IECLASS_RAWMOUSE */
  169.  
  170.     case IECLASS_RAWKEY:
  171.       switch(e->ie_Code)
  172.       {
  173.         case NM_BUTTON_FOURTH:
  174.           HandleDoubleClick(&MyWM->FourthButton,e);
  175.  
  176.           MyWM->FourthButton.State=TRUE;
  177.           switch(MyWM->FourthButton.ClickMode)
  178.           {
  179.             case ClickShift:
  180.               e->ie_Code=RK_LShift;
  181.               e->ie_Class=IECLASS_RAWKEY;
  182.               break;
  183.             case ClickShiftClick:
  184.               e->ie_Class=IECLASS_RAWMOUSE;
  185.               e->ie_Code=IECODE_LBUTTON;
  186.               e->ie_Qualifier=IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT;
  187.               break;
  188.             case ClickCycleScreens:
  189.               ScreenToBack(IntuitionBase->FirstScreen);
  190.               break;
  191.             case ClickMoveScrollToggle:
  192.               MyWM->FourthButton.ScrollToggle^=1;
  193.               break;
  194.             case ClickMoveToScroll:
  195.               MyWM->FourthButton.ScrollToggle=1;
  196.               break;
  197.             case ClickToggleLMB:
  198.               if(MyWM->FourthButton.LMBToggle)
  199.               {
  200.                 e->ie_Class=IECLASS_RAWMOUSE;
  201.                 e->ie_Code=IECODE_LBUTTON|IECODE_UP_PREFIX;
  202.                 e->ie_X=e->ie_Y=0;
  203.                 MyWM->FourthButton.LMBToggle=0;
  204.               }
  205.               else
  206.               {
  207.                 e->ie_Class=IECLASS_RAWMOUSE;
  208.                 e->ie_Code=IECODE_LBUTTON;
  209.                 e->ie_X=e->ie_Y=0;
  210.                 MyWM->FourthButton.LMBToggle=1;
  211.               }
  212.               break;
  213.           }
  214.           break;
  215.         case NM_BUTTON_FOURTH|IECODE_UP_PREFIX:
  216.           MyWM->FourthButton.State=FALSE;
  217.           switch(MyWM->FourthButton.ClickMode)
  218.           {
  219.             case ClickShift:
  220.               e->ie_Class=IECLASS_RAWKEY;
  221.               e->ie_Code=RK_LShift|IECODE_UP_PREFIX;
  222.               break;
  223.             case ClickShiftClick:
  224.               e->ie_Class=IECLASS_RAWMOUSE;
  225.               e->ie_Code=IECODE_UP_PREFIX|IECODE_LBUTTON;
  226.               e->ie_Qualifier=IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT;
  227.               break;
  228.             case ClickMoveToScroll:
  229.               MyWM->FourthButton.ScrollToggle=0;
  230.               break;
  231.           }
  232.           break;
  233.         case NM_WHEEL_UP:
  234.           dy=-1;
  235.           break;
  236.         case NM_WHEEL_DOWN:
  237.           dy=1;
  238.           break;
  239.         case NM_WHEEL_LEFT:
  240.           dx=-1;
  241.           break;
  242.         case NM_WHEEL_RIGHT:
  243.           dx=1;
  244.           break;
  245.       }
  246.       break; /* IECLASS_RAWKEY */
  247.   }
  248.  
  249.   if(dx||dy)
  250.   {
  251.     if(dy&&(MyWM->MidButton.State)&&(MyWM->MidButton.ClickRollMode==ClickRollDepthArrange))
  252.     {
  253.       CxDepthArrange(dy);
  254.       MyWM->MidButton.State=FALSE;
  255.     }
  256.     else if(dy&&(MyWM->FourthButton.State)&&(MyWM->FourthButton.ClickRollMode==ClickRollDepthArrange))
  257.     {
  258.       CxDepthArrange(dy);
  259.       MyWM->FourthButton.State=FALSE;
  260.     }
  261.     else
  262.     {
  263.       if(dy&&(MyWM->MidButton.State)&&(MyWM->MidButton.ClickRollMode==ClickRollHorizontalScroll))
  264.       {
  265.         dx=dy; dy=0;
  266.       }
  267.       else if(dy&&(MyWM->FourthButton.State)&&(MyWM->FourthButton.ClickRollMode==ClickRollHorizontalScroll))
  268.       {
  269.         dx=dy; dy=0;
  270.       }
  271.       if((MyWM->MidButton.AxisToggle)||(MyWM->FourthButton.AxisToggle))
  272.       {
  273.         dx=dy; dy=0;
  274.       }
  275.       /* As long as this addition is atomic, it is safe for the main
  276.          task to read the variables and this task to write them,
  277.          without semaphore protection.  The main task will read the
  278.          value, and then subtract the value it has just read (again
  279.          with an atomic operation). */
  280. /*      dx+=fdx; dy+=fdy;*/
  281.       AddIntAtomic(&MyWM->ScrollY,dy);
  282.       AddIntAtomic(&MyWM->ScrollX,dx);
  283.       Signal(MyWM->MainTask,MyWM->Signals);
  284.     }
  285.   }
  286.  
  287.   if((MyWM->MidButton.ClickMode==ClickShift)&&(MyWM->MidButton.State))
  288.   {
  289.     e->ie_Qualifier|=IEQUALIFIER_LSHIFT;
  290.     e->ie_Qualifier&=~IEQUALIFIER_MIDBUTTON;
  291.   }
  292.  
  293.   if((MyWM->FourthButton.ClickMode==ClickShift)&&(MyWM->FourthButton.State))
  294.     e->ie_Qualifier|=IEQUALIFIER_LSHIFT;
  295. }
  296.  
  297.  
  298. void HandleDoubleClick(struct ButtonData *bd,struct InputEvent *ie)
  299. {
  300.   if((bd->Count==1) && (DoubleClick(bd->Secs,bd->Microsecs,ie->ie_TimeStamp.tv_secs,ie->ie_TimeStamp.tv_micro)))
  301.   {
  302.     switch(bd->DoubleClickMode)
  303.     {
  304.       case DClickCycleScreens:
  305.         ScreenToBack(IntuitionBase->FirstScreen);
  306.         break;
  307.       case DClickSwapAxis:
  308.         bd->AxisToggle^=1;
  309.         break;
  310.     }
  311.     bd->Count=0;
  312.   }
  313.   else
  314.   {
  315.     bd->Count=1;
  316.     bd->Secs=ie->ie_TimeStamp.tv_secs;
  317.     bd->Microsecs=ie->ie_TimeStamp.tv_micro;
  318.   }
  319. }
  320.  
  321.  
  322. void HandleClickToFront(struct InputEvent *ie)
  323. {
  324.   static struct Window *win=0,*lastwin=0;
  325.   static long secs=0,microsecs=0,count=0;
  326.  
  327.   win=WindowUnderPointer();
  328.   if(InWindowBorder(win))
  329.   {
  330.     if((count==1) && (win==lastwin) && (DoubleClick(secs,microsecs,ie->ie_TimeStamp.tv_secs,ie->ie_TimeStamp.tv_micro)))
  331.     {
  332.       struct Window *topwin=NULL;
  333.       if(win->WScreen->LayerInfo.top_layer)
  334.         topwin=win->WScreen->LayerInfo.top_layer->Window;
  335.       if((win==topwin)&&(MyWM->ClickToBack))
  336.         WindowToBack(win);
  337.       else
  338.         WindowToFront(win);
  339.       count=0;
  340.     }
  341.     else
  342.     {
  343.       count=1; lastwin=win;
  344.       secs=ie->ie_TimeStamp.tv_secs;
  345.       microsecs=ie->ie_TimeStamp.tv_micro;
  346.     }
  347.   }
  348. }
  349.  
  350.  
  351. BOOL InWindowBorder(struct Window *win)
  352. {
  353.   int x,y;
  354.   if(!win)
  355.     return(FALSE);
  356.   x=win->MouseX; y=win->MouseY;
  357.   if((win->Flags&WFLG_BORDERLESS)&&!(win->Flags&WFLG_BACKDROP))
  358.   {
  359.     if((x>0)&&(y>0)&&(x<win->Width)&&(y<win->Height))
  360.       return(TRUE);
  361.   }
  362.   if(x<win->BorderLeft)
  363.     return(TRUE);
  364.   if(y<win->BorderTop)
  365.     return(TRUE);
  366.   if(x>(win->Width-win->BorderRight-1))
  367.     return(TRUE);
  368.   if(y>(win->Height-win->BorderBottom-1))
  369.     return(TRUE);
  370.   return(FALSE);
  371. }
  372.  
  373.