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

  1. #include <stdio.h>
  2.  
  3. #include <exec/types.h>
  4.  
  5. #include <intuition/intuitionbase.h>
  6. #include <intuition/intuition.h>
  7. #include <intuition/screens.h>
  8. #include <graphics/clip.h>
  9. #include <devices/inputevent.h>
  10.  
  11. #include <clib/exec_protos.h>
  12. #include <clib/intuition_protos.h>
  13. #include <clib/layers_protos.h>
  14.  
  15. #include "WheelMouse.h"
  16.  
  17. #include "Scroll.h"
  18. #include "RawKey.h"
  19.  
  20. extern struct IntuitionBase *IntuitionBase;
  21.  
  22. struct Window *WindowUnderPointer();
  23.  
  24. #define MUIWHEEL_IS_MUI_WINDOW 0x20000929
  25.  
  26. /* Fixes reported CyberGuard hits with MUI programs. */
  27. struct
  28. {
  29.   char a,b,c,d;
  30. } DeadKeyData;
  31.  
  32.  
  33. void SendIDCMP(struct WheelMouseContext *wmc,int class,int code,int qualifier,struct IntuiMessage *im)
  34. {
  35.   struct Window *win=wmc->Window;
  36.   struct Gadget *gg=wmc->Gadget;
  37.   im->IDCMPWindow=win;
  38.   if(class==IDCMP_RAWKEY)
  39.     im->IAddress=&DeadKeyData;
  40.   else
  41.     im->IAddress=gg;
  42.   im->Class=class;
  43.   im->Code=code;
  44.   im->Qualifier=qualifier;
  45.   im->MouseX=win->MouseX;
  46.   im->MouseY=win->MouseY;
  47.   im->ExecMessage.mn_ReplyPort=wmc->ReplyPort;
  48.   im->Seconds=IntuitionBase->Seconds; im->Micros=IntuitionBase->Micros;
  49.   im->SpecialLink=NULL;
  50.   PutMsg(win->UserPort,(struct Message *)im);
  51. }
  52.  
  53.  
  54. void NudgePropGadget(struct WheelMouseContext *wmc,int axis,int direction)
  55. {
  56.   struct Window *win=wmc->Window;
  57.   struct Gadget *gg=wmc->Gadget;
  58.   struct PropInfo *pi=(struct PropInfo *)gg->SpecialInfo;
  59.  
  60.   long current,offset;
  61.  
  62.   if(axis&FREEVERT)
  63.   {
  64.     current=pi->VertPot;
  65.     offset=(direction*pi->VPotRes*wmc->ScrollSpeedY)/32;
  66.     if(wmc->VertSwap)
  67.       offset=-offset;
  68.     current+=offset;
  69.     if(current<0) current=0;
  70.     if(current>0xffff) current=0xffff;
  71.     pi->VertPot=current;
  72.   }
  73.  
  74.   if(axis&FREEHORIZ)
  75.   {
  76.     current=pi->HorizPot;
  77.     offset=(direction*pi->HPotRes*wmc->ScrollSpeedX)/32;
  78.     if(wmc->HorizSwap)
  79.       offset=-offset;
  80.     current+=offset;
  81.     if(current<0) current=0;
  82.     if(current>0xffff) current=0xffff;
  83.     pi->HorizPot=current;
  84.   }
  85.  
  86. }
  87.  
  88.  
  89. struct Gadget *FindPropGadget(struct Window *win,long type)
  90. {
  91.   struct Gadget *gg=win->FirstGadget,*bestgadget=NULL;
  92.   int gx,gy,gt,gl,gw,gh,dd,distance=32767;
  93.   while(gg)
  94.   {
  95.     if(((gg->GadgetType>YP_GTYPEMASK)==GTYP_PROPGADGET)&&(gg->Flags&GFLG_DISABLED)==0)
  96.     {
  97.       struct PropInfo *pi=(struct PropInfo *)gg->SpecialInfo;
  98.       if(pi)
  99.       {
  100.         if(pi->Flags&type)
  101.         {
  102.           dd=32767;
  103.  
  104.           gl=gg->LeftEdge; gt=gg->TopEdge;
  105.           gw=gg->Width; gh=gg->Height;
  106.           if(gg->Flags&GFLG_RELRIGHT)
  107.             gl+=win->Width;
  108.           if(gg->Flags&GFLG_RELBOTTOM)
  109.             gt+=win->Height;
  110.           if(gg->Flags&GFLG_RELWIDTH)
  111.             gw+=win->Width;
  112.           if(gg->Flags&GFLG_RELHEIGHT)
  113.             gh+=win->Height;
  114.  
  115.           if(pi->Flags&FREEVERT)
  116.           {
  117.             gx=gl+gw;
  118.  
  119.             dd=gx-win->MouseX;
  120.             if(dd<0)
  121.               dd=-dd+win->Width; /* bias to left of scrollbar */
  122.             gy=(gt+gh)-win->MouseY;
  123.             if((gt-win->MouseY)*(gt-win->MouseY)<(gy*gy))
  124.               gy=gt-win->MouseY;
  125.             if(gy<0)
  126.               gy=-gy;
  127.             dd+=gy;
  128.           }
  129.           if(pi->Flags&FREEHORIZ)
  130.           {
  131.             if(type==(FREEHORIZ|FREEVERT))
  132.             {
  133.               gx=win->MouseX-gl;
  134.               gy=win->MouseY-gt;
  135.               if((gx>=-2)&&(gy>=-2)&&(gx<=(gw+2))&&(gy<=(gh+2)))
  136.                 dd=1;
  137.             }
  138.             else
  139.             {
  140.               gy=gt+gh;
  141.  
  142.               dd=gy-win->MouseY;
  143.               if(dd<0)
  144.                 dd=-dd+win->Height; /* bias to top of scrollbar */
  145.               gy=(gl+gw)-win->MouseX;
  146.               if((gt-win->MouseX)*(gt-win->MouseX)<(gy*gy))
  147.                 gy=gt-win->MouseX;
  148.               if(gy<0)
  149.                 gy=-gy;
  150.               dd+=gy;
  151.             }
  152.           }
  153.           if(dd<0) dd=-dd;
  154.           if(dd<distance)
  155.           {
  156.             distance=dd;
  157.             bestgadget=gg;
  158.           }
  159.         }
  160.       }
  161.     }
  162.     gg=gg->NextGadget;
  163.   }
  164.   return(bestgadget);
  165. }
  166.  
  167.  
  168. int DoScroll(struct WheelMouseContext *wmc,int axis,int direction)
  169. {
  170.   struct Window *win;
  171.   unsigned long userdata;
  172.  
  173.   Forbid();
  174.   if(wmc->WindowMode==OverWindow)
  175.     win=wmc->Window=WindowUnderPointer();
  176.   else
  177.     win=wmc->Window=IntuitionBase->ActiveWindow;
  178.   if(!(win))
  179.     return(direction);
  180.   wmc->Gadget=FindPropGadget(win,axis);
  181.   if((!(wmc->Gadget))&&(wmc->WindowMode==OverWindow)&&((win->IDCMPFlags&IDCMP_RAWKEY)==0))
  182.   {
  183.     if(!(win=wmc->Window=IntuitionBase->ActiveWindow))
  184.     {
  185.       Permit();
  186.       return(direction);
  187.     }
  188.     wmc->Gadget=FindPropGadget(win,axis);
  189.   }
  190.  
  191.   /* Ignore MUI windows if MUIWheel is active... */
  192.   userdata=(unsigned long)win->UserData;
  193.   if((userdata==MUIWHEEL_IS_MUI_WINDOW)&&(wmc->IgnoreMUI))
  194.   {
  195.     Permit();
  196.     return(direction);
  197.   }
  198.  
  199.   if((wmc->Gadget)&&(wmc->NudgeProp))
  200.   {
  201.     if(win->UserPort->mp_SigTask!=wmc->MainTask)
  202.     {
  203.       NudgePropGadget(wmc,axis,direction);
  204.       SendIDCMP(wmc,IDCMP_GADGETDOWN,0,0,&wmc->Msg1.eim_IntuiMessage);
  205.       SendIDCMP(wmc,IDCMP_GADGETUP,0,0,&wmc->Msg2.eim_IntuiMessage);
  206.       RefreshGList(wmc->Gadget,wmc->Window,NULL,1);
  207.       Permit();
  208.       WaitPort(wmc->ReplyPort);
  209.       GetMsg(wmc->ReplyPort);
  210.       WaitPort(wmc->ReplyPort);
  211.       GetMsg(wmc->ReplyPort);
  212.     }
  213.     else
  214.       Permit();
  215.     return(direction);
  216.   }
  217.   else if((win->IDCMPFlags&IDCMP_RAWKEY)&&(wmc->ForgeRawKey))
  218.   {
  219.     int code,d,q=0;
  220.     d=direction;
  221.     if((axis==FREEHORIZ)&&(wmc->HorizSwap))
  222.       d=-d;
  223.     if((axis&FREEVERT)&&(wmc->VertSwap))
  224.       d=-d;
  225.     if(d>0)
  226.     {
  227.       if(axis&FREEVERT)
  228.         code=RK_Down;
  229.       else
  230.         code=RK_Right;
  231.     }
  232.     else
  233.     {
  234.       if(axis&FREEVERT)
  235.         code=RK_Up;
  236.       else
  237.         code=RK_Left;
  238.       d=-d;
  239.     }
  240.     if((d>wmc->PageThreshold)&&(wmc->RawKeyPage))
  241.       q=IEQUALIFIER_LSHIFT;
  242.     else
  243.       direction/=d; /* either 1 or -1 */
  244.  
  245.     if(win->UserPort->mp_SigTask!=wmc->MainTask)
  246.     {
  247.       SendIDCMP(wmc,IDCMP_RAWKEY,code,q,&wmc->Msg1.eim_IntuiMessage);
  248.       SendIDCMP(wmc,IDCMP_RAWKEY,code|IECODE_UP_PREFIX,q,&wmc->Msg2.eim_IntuiMessage);
  249.       Permit();
  250.       WaitPort(wmc->ReplyPort);
  251.       GetMsg(wmc->ReplyPort);
  252.       WaitPort(wmc->ReplyPort);
  253.       GetMsg(wmc->ReplyPort);
  254.     }
  255.     else
  256.       Permit();
  257.     return(direction);
  258.   }
  259.   Permit();
  260.   return(direction);
  261. }
  262.  
  263.  
  264. struct Window *WindowUnderPointer()
  265. {
  266.   int x,y;
  267.   struct Window *win=NULL;
  268.   struct Screen *scr;
  269.   struct Layer *layer;
  270.  
  271.   scr=IntuitionBase->FirstScreen;
  272.   do
  273.   {
  274.     x=scr->MouseX; y=scr->MouseY;
  275.     if((x<0) || (y<0))
  276.       scr=scr->NextScreen;
  277.   } while((scr!=NULL) && ((x<0)||(y<0)));
  278.  
  279.   if(!scr)
  280.     return(NULL);
  281.  
  282.   layer=WhichLayer(&scr->LayerInfo,x,y);
  283.   if(layer)
  284.     win=layer->Window;
  285.   return(win);
  286. }
  287.  
  288.