home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d9xx / d968 / justlook.lha / JustLook / Source / JustLook.c < prev    next >
C/C++ Source or Header  |  1993-12-04  |  24KB  |  890 lines

  1.  
  2. /*  JustLook!
  3.     © Kamran Karimi
  4. */
  5.  
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <exec/types.h>
  9. #include <exec/memory.h>
  10. #include <devices/input.h>
  11. #include <intuition/intuitionbase.h>
  12. #include <intuition/intuition.h>
  13. #include <workbench/workbench.h>
  14. #include <clib/intuition_protos.h>
  15. #include <clib/exec_protos.h>
  16. #include <clib/dos_protos.h>
  17. #include <clib/icon_protos.h>
  18. #include <clib/alib_protos.h>
  19.  
  20. #include "JustLook.h"
  21.  
  22. extern struct IntuitionBase *IntuitionBase;
  23. extern struct Library *IconBase;
  24.  
  25. extern VOID DisableIE(),WaitIE();
  26.  
  27. UBYTE HandlerName[] = "JustLook's NoIE Handler";
  28. UBYTE WaitName[] = "JustLook's WaitIE Handler";
  29.  
  30. struct MsgPort *NoMouse_Port = NULL,*NoKey_Port = NULL,*Global_IEPort = NULL;
  31. struct Interrupt *Global_IEHandler = NULL;
  32. struct IOStdReq *Global_IEReq = NULL;
  33.  
  34. struct Task *Me;
  35. ULONG LeftMask,MidMask,RightMask;
  36.  
  37.     
  38.  
  39. ErrorCode GetRatio(struct ScrMap *SM,struct Screen *Scr)
  40. {
  41.  ULONG IBaseLock;
  42.  SHORT DeltaX = 8,DeltaY = 8,CurrX,CurrY;
  43.  ErrorCode ErrCode = NO_ERROR;
  44.  struct MsgPort *IEPort = NULL;
  45.  struct IOStdReq *IEReq = NULL;
  46.  struct InputEvent *FakeEvent = NULL;
  47.  
  48.  if(IEPort = CreatePort(NULL,0)) 
  49.  {
  50.   if(FakeEvent = AllocMem(sizeof(struct InputEvent),MEMF_PUBLIC))
  51.   {
  52.    if(IEReq = (struct IOStdReq *)CreateExtIO(IEPort,sizeof(struct IOStdReq)))
  53.    {
  54.     if(!OpenDevice("input.device",0,(struct IORequest *)IEReq,0))
  55.     { 
  56.      FakeEvent->ie_NextEvent = NULL;
  57.      FakeEvent->ie_Class = IECLASS_RAWMOUSE;
  58.      FakeEvent->ie_Code = IECODE_NOBUTTON;
  59.      FakeEvent->ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
  60.      FakeEvent->ie_X = DeltaX;
  61.      FakeEvent->ie_Y = DeltaY; 
  62.      FakeEvent->ie_SubClass = 0xFF; /* shows that we are generating this */
  63.      IEReq->io_Command = IND_WRITEEVENT;
  64.      IEReq->io_Data = (APTR)FakeEvent;
  65.      IEReq->io_Flags = 0;
  66.      IEReq->io_Length = sizeof(struct InputEvent);
  67.      IBaseLock = LockIBase(0); 
  68.       CurrX = Scr->MouseX;
  69.       CurrY = Scr->MouseY;
  70.       if(CurrX > Scr->LeftEdge + Scr->Width - 32) DeltaX = -8;
  71.       if(CurrY > Scr->TopEdge + Scr->Height - 32) DeltaY = -8;
  72.      UnlockIBase(IBaseLock); 
  73.      FakeEvent->ie_X = DeltaX;
  74.      FakeEvent->ie_Y = DeltaY;
  75.      DoIO((struct IORequest *)IEReq);
  76.      IBaseLock = LockIBase(0); 
  77.       CurrX = Scr->MouseX - CurrX;
  78.       CurrY = Scr->MouseY - CurrY;
  79.       if(!CurrX) ErrCode |= NO_RATIO;
  80.       else if(abs(CurrX) <= abs(DeltaX)) SM->XRatio = (DeltaX / CurrX);
  81.       else SM->XRatio = -(CurrX / DeltaX);      
  82.       if(!CurrY) ErrCode |= NO_RATIO;
  83.       else if(abs(CurrY) <= abs(DeltaY)) SM->YRatio = (DeltaY / CurrY);
  84.       else SM->YRatio = -(CurrY / DeltaY);
  85.      UnlockIBase(IBaseLock);  
  86.      CloseDevice((struct IORequest *)IEReq);
  87.     }
  88.     else ErrCode |= NO_DEVICE; 
  89.     DeleteExtIO((struct IORequest *)IEReq);
  90.    }
  91.    else ErrCode |= NO_EXTIO;
  92.    FreeMem(FakeEvent,sizeof(struct InputEvent));
  93.   }
  94.   else ErrCode |= NO_MEM;
  95.   DeletePort(IEPort);
  96.  }
  97.  else ErrCode |= NO_PORT;
  98.  return(ErrCode);
  99. }
  100.  
  101.  
  102. struct Screen *FindScreen(char *TitleToSearch)
  103. {
  104.  ULONG IBaseLock;
  105.  struct Screen *CurrScreen,*ScreenToReturn = NULL;
  106.  BOOLEAN ScrFound = FALSE;
  107.  
  108.  if(TitleToSearch == NULL) return(NULL);
  109.  IBaseLock = LockIBase(0);
  110.  CurrScreen = IntuitionBase->FirstScreen;
  111.  while(CurrScreen)
  112.  {
  113.   if(!strcmp(CurrScreen->Title,TitleToSearch)) 
  114.   {
  115.    if(ScrFound) ScreenToReturn = SCR_REPEATED;
  116.    else
  117.    {
  118.     ScrFound = TRUE;
  119.     ScreenToReturn = CurrScreen;
  120.    }
  121.   }
  122.   CurrScreen = CurrScreen->NextScreen;
  123.  }
  124.  UnlockIBase(IBaseLock);
  125.  return(ScreenToReturn);
  126. }
  127.  
  128.  
  129. struct Window *FindWindow(char *TitleToSearch,struct Screen *ScreenToSearch)
  130. {
  131.  BOOLEAN ShouldLoop;
  132.  ULONG IBaseLock;
  133.  struct Screen *CurrScreen;
  134.  struct Window *CurrWindow,*WindowToReturn = NULL;
  135.  BOOLEAN WinFound = FALSE;
  136.  
  137.  ShouldLoop = (ScreenToSearch) ? FALSE : TRUE;
  138.  CurrScreen = (ScreenToSearch) ? ScreenToSearch : IntuitionBase->FirstScreen; 
  139.  IBaseLock = LockIBase(0);
  140.  while(CurrScreen)
  141.  {
  142.   CurrWindow = CurrScreen->FirstWindow;
  143.   while(CurrWindow)
  144.   {
  145.    if(!strcmp(CurrWindow->Title,TitleToSearch)) 
  146.    {
  147.     if(WinFound) WindowToReturn = WIN_REPEATED;
  148.     else
  149.     {
  150.      WinFound = TRUE;
  151.      WindowToReturn = CurrWindow;
  152.     }
  153.    }
  154.    CurrWindow = CurrWindow->NextWindow;
  155.   }
  156.   CurrScreen = (ShouldLoop) ?  CurrScreen->NextScreen : NULL;
  157.  }
  158.  UnlockIBase(IBaseLock);
  159.  return(WindowToReturn);
  160. }
  161.  
  162. struct Gadget *FindGad(struct Window *Win,char *GadName,USHORT GadID)
  163. {
  164.  ULONG IBaseLock;
  165.  struct Gadget *CurrGad;
  166.  
  167.  IBaseLock = LockIBase(0);
  168.  CurrGad = Win->FirstGadget;
  169.  while(CurrGad)
  170.  {
  171.   if(GadName) { if(!strcmp(CurrGad->GadgetText->IText,GadName)) break; }
  172.   else if(CurrGad->GadgetID == GadID) break;
  173.   CurrGad = CurrGad->NextGadget;
  174.  }
  175.  UnlockIBase(IBaseLock);
  176.  return(CurrGad);
  177. }
  178.  
  179.  
  180. VOID Rel2Abs(struct ScrMap *SM,SHORT *x, SHORT *y)
  181. {
  182.  *x += SM->CurrX;
  183.  *y += SM->CurrY;
  184. }
  185.  
  186.  
  187. VOID SetDest(struct ScrMap *SM,SHORT X,SHORT Y)
  188. {
  189.  SM->DestX = X;
  190.  SM->DestY = Y;
  191. }
  192.  
  193.  
  194. ErrorCode InitSM(struct ScrMap *SM,struct Screen *Scr)
  195. {
  196.  ULONG IBaseLock;
  197.  
  198.  if(!SM) return(NO_SM);
  199.  if(!Scr) return(NO_SCR);
  200.  IBaseLock = LockIBase(0);
  201.  SM->CurrX = Scr->MouseX;
  202.  SM->CurrY = Scr->MouseY;
  203.  SM->Scr = Scr;
  204.  UnlockIBase(IBaseLock);
  205.  return(GetRatio(SM,Scr));
  206. }
  207.  
  208.  
  209. ErrorCode IEWait(LONG Flag)
  210. {
  211.  BYTE LeftSig,MidSig,RightSig;
  212.  ULONG Mask;
  213.  struct MsgPort *WPort;
  214.  struct Interrupt *WHandler = NULL;
  215.  struct IOStdReq *WReq = NULL;
  216.  
  217.  ErrorCode ErrCode = NO_ERROR;
  218.  
  219.  if(!(Flag & MOUSE)) return(NO_ACT);
  220.  
  221.  Me = FindTask(NULL);
  222.  
  223.  if(WPort = CreatePort(NULL,0)) 
  224.  {
  225.   if(WHandler = AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC|MEMF_CLEAR))
  226.   {
  227.    if(WReq = (struct IOStdReq *)CreateExtIO(WPort,sizeof(struct IOStdReq)))
  228.    {
  229.     if(!OpenDevice("input.device",NULL,(struct IORequest *)WReq,NULL))
  230.     {
  231.      LeftSig = AllocSignal(-1);
  232.      MidSig = AllocSignal(-1);
  233.      RightSig = AllocSignal(-1);
  234.      if(LeftSig & MidSig & RightSig)
  235.      {
  236.       LeftMask = 1L << LeftSig;
  237.       RightMask = 1L << RightSig;
  238.       MidMask = 1L << MidSig;
  239.       
  240.       WHandler->is_Code = WaitIE;
  241.       WHandler->is_Data = NULL;
  242.       WHandler->is_Node.ln_Pri = 127;
  243.       WHandler->is_Node.ln_Name = WaitName;
  244.       WReq->io_Data = (APTR) WHandler;
  245.       WReq->io_Command = IND_ADDHANDLER;
  246.       DoIO((struct IORequest *)WReq);
  247.       CloseDevice((struct IORequest *)WReq);
  248.      }
  249.      else ErrCode = NO_SIG; 
  250.     }
  251.     else ErrCode |= NO_DEVICE;
  252.     if(ErrCode) DeleteExtIO((struct IORequest *)WReq);
  253.    }
  254.    else ErrCode |= NO_EXTIO;
  255.    if(ErrCode) FreeMem(WHandler,sizeof(struct Interrupt));
  256.   }
  257.   else ErrCode |= NO_MEM;
  258.  }
  259.  else ErrCode |= NO_PORT;
  260.  if(ErrCode) return(ErrCode);
  261.  
  262.  Mask = Wait(LeftMask | MidMask | RightMask);
  263.  if(Mask & LeftMask) ErrCode = LBMASK;
  264.  if(Mask & MidMask) ErrCode |= MBMASK;
  265.  if(Mask & RightMask) ErrCode |= RBMASK;
  266.  if(!OpenDevice("input.device",NULL,(struct IORequest *)WReq,NULL))
  267.  {
  268.   WReq->io_Data = (APTR) WHandler;
  269.   WReq->io_Command = IND_REMHANDLER;
  270.   DoIO((struct IORequest *)WReq);
  271.   CloseDevice((struct IORequest *)WReq);
  272.  }
  273.  if(WReq) DeleteExtIO((struct IORequest *)WReq);
  274.  if(WHandler) FreeMem(WHandler,sizeof(struct Interrupt));
  275.  if(WPort) DeletePort(WPort);
  276.  FreeSignal(LeftSig);
  277.  FreeSignal(MidSig);
  278.  FreeSignal(RightSig);
  279.  return(ErrCode);
  280. }
  281.  
  282. ErrorCode IEEnable(LONG  Flag)
  283. {
  284.  ErrorCode ErrCode = NO_ERROR;
  285.  
  286.  if(!(Flag & MOUSE) && !(Flag & KBD)) return(NO_ACT);
  287.  if(!Global_IEHandler || !Global_IEReq || !Global_IEPort) return(NO_STRUCT);
  288.  if(Flag & MOUSE)
  289.   if(NoMouse_Port)
  290.   {
  291.    DeletePort(NoMouse_Port);
  292.    NoMouse_Port = NULL;
  293.   }
  294.  if(Flag & KBD)
  295.   if(NoKey_Port)
  296.   {
  297.    DeletePort(NoKey_Port);
  298.    NoKey_Port = NULL;
  299.   }
  300.  if(!NoMouse_Port && !NoKey_Port)
  301.  {
  302.   if(!OpenDevice("input.device",NULL,(struct IORequest *)Global_IEReq,NULL))
  303.   {
  304.    Global_IEReq->io_Data = (APTR) Global_IEHandler;
  305.    Global_IEReq->io_Command = IND_REMHANDLER;
  306.    DoIO((struct IORequest *)Global_IEReq);
  307.    CloseDevice((struct IORequest *)Global_IEReq);
  308.   }
  309.   else ErrCode |= NO_DEVICE;
  310.   DeleteExtIO((struct IORequest *)Global_IEReq); Global_IEReq = NULL;
  311.   FreeMem(Global_IEHandler,sizeof(struct Interrupt));
  312.   Global_IEHandler = NULL;
  313.   DeletePort(Global_IEPort);
  314.   Global_IEPort = NULL;
  315.  }
  316.  return(ErrCode);
  317. }
  318.  
  319. ErrorCode IEDisable(LONG Flag)
  320. {
  321.  ErrorCode ErrCode = NO_ERROR;
  322.  BOOLEAN ShouldInstallHandler = FALSE;
  323.  
  324.  if(!(Flag & MOUSE) && !(Flag & KBD)) return(NO_ACT);
  325.  if(!NoMouse_Port && !NoKey_Port) ShouldInstallHandler = TRUE; 
  326.  if(Flag & MOUSE)
  327.  {
  328.   Forbid();
  329.   if(!(NoMouse_Port = FindPort("JustLook's NoMouse Port!")))
  330.   {
  331.    if(!(NoMouse_Port = CreatePort("JustLook's NoMouse Port!",0)))
  332.     ErrCode = NO_PORT;
  333.   }
  334.   else ErrCode = PORT_FOUND;
  335.   Permit();
  336.  }
  337.  if(ErrCode) return(ErrCode);
  338.  if(Flag & KBD)
  339.  {
  340.   Forbid();
  341.   if(!(NoKey_Port = FindPort("JustLook's NoKey Port!")))
  342.   {
  343.    if(!(NoKey_Port = CreatePort("JustLook's NoKey Port!",0)))
  344.     ErrCode = NO_PORT;
  345.   }
  346.   else ErrCode = PORT_FOUND;
  347.   Permit();
  348.  }
  349.  if(ErrCode)
  350.  {
  351.   if(Flag & MOUSE)
  352.   {
  353.    DeletePort(NoMouse_Port);
  354.    NoMouse_Port = NULL;
  355.   }
  356.   return(ErrCode);
  357.  }
  358.  if(ShouldInstallHandler)
  359.  {
  360.   if(Global_IEPort = CreatePort(NULL,0)) 
  361.   {
  362.    if(Global_IEHandler = AllocMem(sizeof(struct Interrupt),
  363.                                                      MEMF_PUBLIC|MEMF_CLEAR))
  364.    {
  365.     if(Global_IEReq = (struct IOStdReq *)CreateExtIO(Global_IEPort,
  366.                                                     sizeof(struct IOStdReq)))
  367.     {
  368.      if(!OpenDevice("input.device",NULL,
  369.                                       (struct IORequest *)Global_IEReq,NULL))
  370.      {
  371.       Global_IEHandler->is_Code = DisableIE;
  372.       Global_IEHandler->is_Data = NULL;
  373.       Global_IEHandler->is_Node.ln_Pri = 126;
  374.       Global_IEHandler->is_Node.ln_Name = HandlerName;
  375.       Global_IEReq->io_Data = (APTR) Global_IEHandler;
  376.       Global_IEReq->io_Command = IND_ADDHANDLER;
  377.       DoIO((struct IORequest *)Global_IEReq);
  378.       CloseDevice((struct IORequest *)Global_IEReq);
  379.      }
  380.      else ErrCode |= NO_DEVICE;
  381.      if(ErrCode) 
  382.      { 
  383.       DeleteExtIO((struct IORequest *)Global_IEReq); 
  384.       Global_IEReq = NULL;
  385.      }
  386.     }
  387.     else ErrCode |= NO_EXTIO;
  388.     if(ErrCode) 
  389.     {
  390.      FreeMem(Global_IEHandler,sizeof(struct Interrupt));
  391.      Global_IEHandler = NULL;
  392.     }
  393.    }
  394.    else ErrCode |= NO_MEM;
  395.    if(ErrCode)
  396.    {
  397.     DeletePort(Global_IEPort);
  398.     Global_IEPort = NULL;
  399.    }
  400.   }
  401.   else ErrCode |= NO_PORT;
  402.  }
  403.  if(ErrCode)
  404.  {
  405.   if(Flag & MOUSE)
  406.   {
  407.    DeletePort(NoMouse_Port);
  408.    NoMouse_Port = NULL;
  409.   }
  410.   if(Flag & KBD)
  411.   {
  412.    DeletePort(NoKey_Port);
  413.    NoKey_Port = NULL;
  414.   }
  415.  }
  416.  return(ErrCode);
  417. }
  418.  
  419.  
  420. ErrorCode RawType(struct RawInfo *RawKeys,ULONG Length,ULONG delay)
  421. {
  422.  ErrorCode ErrCode = NO_ERROR;
  423.  struct MsgPort *IEPort = NULL;
  424.  struct IOStdReq *IEReq = NULL;
  425.  struct InputEvent *FakeEvent = NULL;
  426.  ULONG count,count2;
  427.  
  428.  if(!RawKeys) return(NO_KEY);
  429.  if(IEPort = CreatePort(NULL,0)) 
  430.  {
  431.   if(FakeEvent = AllocMem(sizeof(struct InputEvent),MEMF_PUBLIC))
  432.   {
  433.    if(IEReq = (struct IOStdReq *)CreateExtIO(IEPort,sizeof(struct IOStdReq)))
  434.    {
  435.     if(!OpenDevice("input.device",0,(struct IORequest *)IEReq,0))
  436.     { 
  437.      for(count = 0; count < Length; count++)
  438.      {
  439.       for(count2 = 0; count2 < 2; count2++)
  440.       {
  441.        FakeEvent->ie_NextEvent = NULL;
  442.        FakeEvent->ie_Class = IECLASS_RAWKEY;
  443.        FakeEvent->ie_Code = RawKeys[count].RawKey;
  444.        if(count2 == 1) FakeEvent->ie_Class |= IECODE_UP_PREFIX;
  445.        FakeEvent->ie_Qualifier = RawKeys[count].Qualifier;
  446.        FakeEvent->ie_SubClass = 0xFF; /* shows that we are generating this */
  447.        IEReq->io_Command = IND_WRITEEVENT;
  448.        IEReq->io_Data = (APTR)FakeEvent;
  449.        IEReq->io_Flags = 0;
  450.        IEReq->io_Length = sizeof(struct InputEvent);
  451.  
  452.        DoIO((struct IORequest *)IEReq);
  453.        Delay(delay / 3);
  454.       }
  455.       Delay(delay);
  456.      }
  457.      CloseDevice((struct IORequest *)IEReq);
  458.     }
  459.     else ErrCode |= NO_DEVICE; 
  460.     DeleteExtIO((struct IORequest *)IEReq);
  461.    }
  462.    else ErrCode |= NO_EXTIO;
  463.    FreeMem(FakeEvent,sizeof(struct InputEvent));
  464.   }
  465.   else ErrCode |= NO_MEM;
  466.   DeletePort(IEPort);
  467.  }
  468.  else ErrCode |= NO_PORT;
  469.  return(ErrCode);
  470. }
  471.  
  472.  
  473. ErrorCode ChooseMenu(struct ScrMap *SM,struct Window *Win,SHORT Menu, 
  474.                                                     SHORT MItem,SHORT SItem)
  475. {
  476.  ULONG IBaseLock;
  477.  ErrorCode ErrCode;
  478.  struct Screen *Scr;
  479.  struct Menu *CurrMenu;
  480.  struct MenuItem *CurrItem,*CurrSub;
  481.  SHORT XPos,YPos,TempYPos,count;
  482.  
  483.  if(!SM) return(NO_SM);
  484.  if(Menu < 0) return(BAD_ITEM);
  485.  ErrCode = Click(SM,RBUTTON,0,DOWN);
  486.  if(ErrCode) return(ErrCode);
  487.  IBaseLock = LockIBase(0);
  488.  Scr = Win->WScreen;
  489.  CurrMenu = Win->MenuStrip;
  490.  count = 0; 
  491.  while(CurrMenu && (count < Menu)) 
  492.  {
  493.   CurrMenu = CurrMenu->NextMenu;
  494.   count++;
  495.  }
  496.  if(!CurrMenu) ErrCode = NO_MENU;
  497.  else
  498.  {
  499.   XPos = CurrMenu->LeftEdge + Scr->WBorLeft + (CurrMenu->Width >> 1);
  500.   YPos = Scr->WBorTop + (Scr->BarHeight >> 1); 
  501.  }
  502.  UnlockIBase(IBaseLock);
  503.  if(ErrCode) return(ErrCode | Click(SM,RBUTTON,0,UP));
  504.  Delay(15);
  505.  SetDest(SM,XPos,YPos);
  506.  ErrCode = MoveMouse(SM,ABSOLUTE,1);
  507.  if(ErrCode) return(ErrCode | Click(SM,RBUTTON,0,UP));
  508.  if(MItem != -1)
  509.  {
  510.   IBaseLock = LockIBase(0);
  511.   CurrItem = CurrMenu->FirstItem;
  512.   count = 0; 
  513.   while(CurrItem && (count < MItem)) 
  514.   { 
  515.    CurrItem = CurrItem->NextItem;
  516.    count++;
  517.   }
  518.   if(!CurrItem) ErrCode = NO_ITEM;
  519.   else
  520.   { 
  521.    XPos = CurrMenu->LeftEdge + CurrItem->LeftEdge + (CurrItem->Width >> 1);
  522.    YPos = Scr->BarHeight + CurrItem->TopEdge + (CurrItem->Height >> 1);
  523.   }
  524.   UnlockIBase(IBaseLock);
  525.   if(ErrCode) return(Click(SM,RBUTTON,0,UP) | ErrCode);
  526.   Delay(15);
  527.   SetDest(SM,XPos,YPos);
  528.   ErrCode = MoveMouse(SM,ABSOLUTE,1);
  529.   if(ErrCode) return(ErrCode  | Click(SM,RBUTTON,0,UP));
  530.  }
  531.  
  532.  if(SItem != -1)
  533.  {
  534.   IBaseLock = LockIBase(0);
  535.   CurrSub = CurrItem->SubItem;
  536.   count = 0; 
  537.   while(CurrSub && (count < SItem)) 
  538.   {
  539.    CurrSub = CurrSub->NextItem;
  540.    count++;
  541.   }
  542.   if(!CurrSub) ErrCode = NO_SUB;
  543.   else
  544.   { 
  545.    XPos = CurrMenu->LeftEdge + CurrItem->LeftEdge + 
  546.                                    CurrSub->LeftEdge + (CurrSub->Width >> 1);
  547.    TempYPos = Scr->BarHeight + 
  548.                 CurrItem->TopEdge + CurrSub->TopEdge + (CurrSub->Height >> 1);
  549.   }
  550.   UnlockIBase(IBaseLock);
  551.   if(ErrCode) return(ErrCode | Click(SM,RBUTTON,0,UP));
  552.   Delay(15);
  553.   SetDest(SM,XPos,YPos); /* just go in x direction */
  554.   ErrCode = MoveMouse(SM,ABSOLUTE,1);
  555.   if(ErrCode) return(ErrCode | Click(SM,RBUTTON,0,UP));
  556.   Delay(15);
  557.   SetDest(SM,XPos,TempYPos);
  558.   ErrCode = MoveMouse(SM,ABSOLUTE,1);
  559.   if(ErrCode) return(ErrCode | Click(SM,RBUTTON,0,UP));
  560.  }
  561.  Delay(25);
  562.  return(Click(SM,RBUTTON,0,UP));
  563. }
  564.  
  565.  
  566. ErrorCode WinResize(struct ScrMap *SM,struct Window *Win,BOOLEAN IsRelative,
  567.                                                              SHORT X,SHORT Y)
  568. {
  569.  ULONG IBaseLock,Flags;
  570.  ErrorCode ErrCode;
  571.  SHORT XPos,YPos;
  572.  
  573.  if(!SM) return(NO_SM);
  574.  if(!Win) return(NO_WIN);
  575.  IBaseLock = LockIBase(0);
  576.  Flags = Win->Flags;
  577.  XPos = Win->WScreen->LeftEdge + Win->LeftEdge + Win->Width - 3;
  578.  YPos = Win->WScreen->TopEdge + Win->TopEdge + Win->Height - 3;
  579.  UnlockIBase(IBaseLock);
  580.  if(!(Flags & WFLG_SIZEGADGET)) return(NO_ACT);
  581.  SetDest(SM,XPos,YPos);
  582.  ErrCode = MoveMouse(SM,ABSOLUTE,1);
  583.  if(ErrCode) return(ErrCode);
  584.  ErrCode = Click(SM,LBUTTON,0,DOWN);
  585.  if(ErrCode) return(ErrCode);
  586.  Delay(15);
  587.  SetDest(SM,X,Y);
  588.  ErrCode = MoveMouse(SM,IsRelative,1);
  589.  return(ErrCode | Click(SM,LBUTTON,0,UP));
  590. }
  591.  
  592.  
  593. ErrorCode WinAct(struct ScrMap *SM,struct Window *Win,LONG Act)
  594. {
  595.  ULONG IBaseLock,Flags;
  596.  ErrorCode ErrCode = NO_ERROR; 
  597.  SHORT XPos,YPos,Width; 
  598.  
  599.  if(!SM) return(NO_SM);
  600.  if(!Win) return(NO_WIN);
  601.  IBaseLock = LockIBase(0);
  602.  Flags = Win->Flags;
  603.  XPos = Win->WScreen->LeftEdge + Win->LeftEdge;
  604.  YPos = Win->WScreen->TopEdge + Win->TopEdge + 2;
  605.  Width = Win->Width;
  606.  UnlockIBase(IBaseLock);
  607.  switch(Act)
  608.  {
  609.   case CLOSEWIN:
  610.                 if(!(Flags & WFLG_CLOSEGADGET)) ErrCode =  NO_ACT;
  611.                 break;
  612.   case DEPTHWIN:
  613.                 if(!(Flags & WFLG_DEPTHGADGET)) ErrCode =  NO_ACT;
  614.                 break;
  615.   default: ErrCode = NO_ACT; 
  616.  }
  617.  if(ErrCode) return(ErrCode);
  618.  if(Act == CLOSEWIN) XPos += 2;
  619.  else if(Act == DEPTHWIN) XPos += (Width - 2);
  620.  SetDest(SM,XPos,YPos);
  621.  ErrCode = MoveMouse(SM,ABSOLUTE,1);
  622.  if(ErrCode) return(ErrCode);
  623.  return(Click(SM,LBUTTON,0,DOWN_UP));
  624. }
  625.  
  626. ErrorCode WinDrag(struct ScrMap *SM,struct Window *Win,BOOLEAN IsRelative,
  627.                                                            SHORT X, SHORT Y)
  628. {
  629.  ULONG IBaseLock,Flags;
  630.  ErrorCode ErrCode = NO_ERROR;
  631.  SHORT XPos,YPos;
  632.  
  633.  if(!SM) return(NO_SM);
  634.  if(!Win) return(NO_WIN);
  635.  IBaseLock = LockIBase(0);
  636.  Flags = Win->Flags;
  637.  XPos = Win->WScreen->LeftEdge + Win->LeftEdge + (Win->Width >> 1);
  638.  YPos = Win->WScreen->TopEdge +Win->TopEdge + 2;
  639.  UnlockIBase(IBaseLock);
  640.  if(!(Flags & WFLG_DRAGBAR)) return(NO_ACT);
  641.  SetDest(SM,XPos,YPos);
  642.  ErrCode = MoveMouse(SM,ABSOLUTE,1);
  643.  if(ErrCode) return(ErrCode);
  644.  Delay(15);
  645.  ErrCode = Click(SM,LBUTTON,0,DOWN);
  646.  if(ErrCode) return(ErrCode);
  647.  Delay(15);
  648.  SetDest(SM,X,Y);
  649.  ErrCode = MoveMouse(SM,IsRelative,1);
  650.  return(ErrCode | Click(SM,LBUTTON,0,UP));
  651. }
  652.   
  653.  
  654. ErrorCode MoveMouse(struct ScrMap *SM,BOOLEAN IsRelative,SHORT Speed)
  655. {   
  656.  ULONG IBaseLock;
  657.  SHORT AbsX,AbsY,CurrX,CurrY,PrevX,PrevY,CurrXStop,CurrYStop;
  658.  SHORT Reps = 1;
  659.  BOOL XDone = FALSE,YDone = FALSE;
  660.  
  661.  ErrorCode ErrCode = NO_ERROR;
  662.  
  663.  struct Screen *CurrScreen;
  664.  struct MsgPort    *IEPort = NULL;
  665.  struct IOStdReq *IEReq = NULL;
  666.  struct InputEvent *FakeEvent = NULL;
  667.  
  668.  
  669.  if(!SM) return(NO_SM);
  670.  AbsX = SM->DestX; AbsY = SM->DestY;
  671.  
  672.  IBaseLock = LockIBase(0);
  673.  CurrScreen = SM->Scr;
  674.  CurrX = CurrScreen->MouseX;
  675.  CurrY = CurrScreen->MouseY;
  676.  UnlockIBase(IBaseLock); 
  677.  if(IsRelative) Rel2Abs(SM,&AbsX,&AbsY);
  678.  Speed = (Speed % SPEEDLEVELS);
  679.  if(!Speed) Speed = 1;
  680.  CurrXStop = PrevX = CurrX + 1;
  681.  CurrYStop = PrevY = CurrY + 1; 
  682.  
  683.  if(IEPort = CreatePort(NULL,0)) 
  684.  {
  685.   if(FakeEvent = AllocMem(sizeof(struct InputEvent),MEMF_PUBLIC))
  686.   {
  687.    if(IEReq = (struct IOStdReq *)CreateExtIO(IEPort,sizeof(struct IOStdReq)))
  688.    {
  689.     if(!OpenDevice("input.device",0,(struct IORequest *)IEReq,0))
  690.     { 
  691.      for(;;)
  692.      {
  693.       FakeEvent->ie_NextEvent = NULL;
  694.       FakeEvent->ie_Class = IECLASS_RAWMOUSE;
  695.       FakeEvent->ie_Code = IECODE_NOBUTTON;
  696.       FakeEvent->ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
  697.       FakeEvent->ie_SubClass = 0xFF; /* shows that we are generating this */  
  698.       IEReq->io_Command = IND_WRITEEVENT;
  699.       IEReq->io_Data = (APTR)FakeEvent;
  700.       IEReq->io_Flags = 0;
  701.       IEReq->io_Length = sizeof(struct InputEvent);
  702.       
  703.       if(CurrX < AbsX - (Speed >> 1)) FakeEvent->ie_X = Speed;
  704.       else if(CurrX > AbsX + (Speed >> 1)) FakeEvent->ie_X = -Speed;
  705.       else { XDone = TRUE; FakeEvent->ie_X = 0; }  
  706.    
  707.       if(CurrY < AbsY - (Speed >> 1)) FakeEvent->ie_Y = Speed;
  708.       else if(CurrY > AbsY + (Speed >> 1)) FakeEvent->ie_Y = -Speed;
  709.       else { YDone = TRUE; FakeEvent->ie_Y = 0; }        
  710.  
  711.       if(XDone && YDone) break;
  712.     
  713.       if((CurrX == PrevX) && (CurrY == PrevY))
  714.       {
  715.        if((CurrX == CurrXStop) && (CurrY == CurrYStop))  
  716.         { if(Reps++ == 10) { ErrCode |= NO_MOVE; break; } }
  717.        else { Reps = 1; CurrXStop = CurrX; CurrYStop = CurrY; }
  718.       }
  719.       PrevX = CurrX; PrevY = CurrY;
  720.       DoIO((struct IORequest *)IEReq);
  721.  
  722.       IBaseLock = LockIBase(0);
  723.       CurrX = CurrScreen->MouseX; 
  724.       CurrY = CurrScreen->MouseY;
  725.       UnlockIBase(IBaseLock);
  726.      }
  727.      SM->CurrX = AbsX;
  728.      SM->CurrY = AbsY;
  729.      CloseDevice((struct IORequest *)IEReq);
  730.     }
  731.     else ErrCode |= NO_DEVICE; 
  732.     DeleteExtIO((struct IORequest *)IEReq);
  733.    }
  734.    else ErrCode |= NO_EXTIO;
  735.    FreeMem(FakeEvent,sizeof(struct InputEvent));
  736.   }
  737.   else ErrCode |= NO_MEM;
  738.   DeletePort(IEPort);
  739.  }
  740.  else ErrCode |= NO_PORT;
  741.  return(ErrCode);
  742. }    
  743.  
  744.  
  745. ErrorCode GoOverIcon(struct ScrMap *SM,struct Window *Win,UBYTE *Name)
  746. {
  747.  ULONG IBaseLock;
  748.  struct DiskObject *DiskObj;
  749.  struct Gadget *CurrGad;
  750.  SHORT XPos,YPos;
  751.  
  752.  if(!SM) return(NO_SM);
  753.  if(!Win) return(NO_WIN);
  754.  DiskObj = GetDiskObject(Name);
  755.  if(!DiskObj) return(NO_OBJ);
  756.  CurrGad = &(DiskObj->do_Gadget);
  757.  if(!CurrGad) return(NO_OBJ);
  758.  IBaseLock = LockIBase(0);
  759.  XPos =  Win->LeftEdge + DiskObj->do_CurrentX + (CurrGad->Width >> 1);
  760.  YPos = Win->TopEdge + Win->WScreen->BarHeight + DiskObj->do_CurrentY + 
  761.                                                       (CurrGad->Height >> 1);
  762.  UnlockIBase(IBaseLock);
  763.  FreeDiskObject(DiskObj);
  764.  SetDest(SM,XPos,YPos);
  765.  return(MoveMouse(SM,ABSOLUTE,1));
  766. }
  767.  
  768.  
  769. ErrorCode ClickGad(struct ScrMap *SM,struct Window *Win,char *GadName,
  770.                                                     USHORT GadID,SHORT Speed)
  771. {
  772.  ErrorCode ErrCode;
  773.  
  774.  ErrCode = GoOverGad(SM,Win,GadName,GadID,Speed);
  775.  if(ErrCode) return(ErrCode);
  776.  Delay(25);
  777.  return(Click(SM,LBUTTON,0,DOWN_UP));
  778. }
  779.  
  780.  
  781. ErrorCode GoOverGad(struct ScrMap *SM,struct Window *Win,char *GadName,
  782.                                                    USHORT GadID,SHORT Speed)
  783. {
  784.  struct Gadget *CurrGad; 
  785.  ULONG IBaseLock;
  786.  SHORT XPos,YPos,Width,Height;
  787.  
  788.  if(!SM) return(NO_SM);
  789.  if(!Win) return(NO_WIN);
  790.  if(!(CurrGad = FindGad(Win,GadName,GadID))) return(NO_GAD);
  791.  
  792.  IBaseLock = LockIBase(0);
  793.  Width = CurrGad->Width;
  794.  if(CurrGad->Flags & GFLG_RELWIDTH) Width += Win->Width;
  795.  
  796.  Height = CurrGad->Height;
  797.  if(CurrGad->Flags & GFLG_RELHEIGHT) Height += Win->Height;
  798.  
  799.  XPos = Win->LeftEdge + CurrGad->LeftEdge + (Width >> 1);
  800.  if(CurrGad->Flags & GFLG_RELRIGHT) XPos += Win->Width;
  801.     
  802.  YPos = Win->TopEdge + CurrGad->TopEdge + (Height >> 1);
  803.  if(CurrGad->Flags & GFLG_RELBOTTOM) YPos += Win->Height;
  804.  
  805.  UnlockIBase(IBaseLock);
  806.  SetDest(SM,XPos,YPos);
  807.  return(MoveMouse(SM,ABSOLUTE,Speed));
  808. }
  809.  
  810. ErrorCode Click(struct ScrMap *SM,WORD MouseButton,UWORD Qualifier,
  811.                                                                  WORD UpDown)
  812. {
  813.  ULONG IBaseLock;
  814.  SHORT XPos,YPos;
  815.  
  816.  ErrorCode ErrCode = NO_ERROR;
  817.  
  818.  struct MsgPort *IEPort = NULL;
  819.  struct IOStdReq *IEReq = NULL;
  820.  struct InputEvent *FakeEvent = NULL;
  821.  
  822.  if(MouseButton < 0 || MouseButton > 2) return(NO_BUTTON);
  823.  if(UpDown < 0 || UpDown > 2) return(NO_ACT);
  824.  if(!SM) return(NO_SM);
  825.  if(IEPort = CreatePort(NULL,0)) 
  826.  {
  827.   if(FakeEvent = AllocMem(sizeof(struct InputEvent),MEMF_PUBLIC|MEMF_CLEAR))
  828.   {
  829.    if(IEReq = (struct IOStdReq *)CreateExtIO(IEPort,sizeof(struct IOStdReq)))
  830.    {
  831.     if(!OpenDevice("input.device",0,(struct IORequest *)IEReq,0))
  832.     {
  833.      FakeEvent->ie_Class = IECLASS_RAWMOUSE;
  834.      FakeEvent->ie_NextEvent = NULL;
  835.      FakeEvent->ie_Code = IECODE_LBUTTON + MouseButton;
  836.      if(UpDown == UP) FakeEvent->ie_Code |= IECODE_UP_PREFIX; 
  837.      FakeEvent->ie_Qualifier = Qualifier;  
  838.      FakeEvent->ie_SubClass = 0xFF; /* shows that we are generating this */    
  839.      IEReq->io_Command = IND_WRITEEVENT;
  840.      IEReq->io_Data = (APTR)FakeEvent;
  841.      IEReq->io_Flags = 0;
  842.      IEReq->io_Length = sizeof(struct InputEvent);
  843.      IBaseLock = LockIBase(0);
  844.      XPos = SM->CurrX - (SM->Scr)->MouseX;
  845.      YPos = SM->CurrY - (SM->Scr)->MouseY;
  846.      XPos = (SM->XRatio >= 0) ? XPos * SM->XRatio : XPos / -(SM->XRatio);
  847.      YPos = (SM->YRatio >= 0) ? YPos * SM->YRatio : YPos / -(SM->YRatio);
  848.      FakeEvent->ie_X = XPos;
  849.      FakeEvent->ie_Y = YPos;
  850.      UnlockIBase(IBaseLock);
  851.      DoIO((struct IORequest *)IEReq);  
  852.  
  853.      if(UpDown == DOWN_UP)  
  854.      {
  855.       Delay(10);
  856.       FakeEvent->ie_Class = IECLASS_RAWMOUSE;
  857.       FakeEvent->ie_NextEvent = NULL;
  858.       FakeEvent->ie_Code = (IECODE_LBUTTON + MouseButton) | IECODE_UP_PREFIX;
  859.       FakeEvent->ie_Qualifier = Qualifier;
  860.       FakeEvent->ie_SubClass = 0xFF; /* shows that we are generating this */
  861.       IEReq->io_Command = IND_WRITEEVENT;
  862.       IEReq->io_Data = (APTR)FakeEvent;
  863.       IEReq->io_Flags = 0;
  864.       IEReq->io_Length = sizeof(struct InputEvent);
  865.       IBaseLock = LockIBase(0);
  866.       XPos = SM->CurrX - (SM->Scr)->MouseX;
  867.       YPos = SM->CurrY - (SM->Scr)->MouseY;
  868.       XPos = (SM->XRatio >= 0) ? XPos * SM->XRatio : XPos / -(SM->XRatio);
  869.       YPos = (SM->YRatio >= 0) ? YPos * SM->YRatio : YPos / -(SM->YRatio);
  870.       FakeEvent->ie_X = XPos;
  871.       FakeEvent->ie_Y = YPos;
  872.       UnlockIBase(IBaseLock);
  873.       DoIO((struct IORequest *)IEReq); 
  874.      }
  875.      CloseDevice((struct IORequest *)IEReq);
  876.     }
  877.     else ErrCode |= NO_DEVICE; 
  878.     DeleteExtIO((struct IORequest *)IEReq);
  879.    }
  880.    else ErrCode |= NO_EXTIO;
  881.    FreeMem(FakeEvent,sizeof(struct InputEvent));
  882.   }
  883.   else ErrCode |= NO_MEM;
  884.   DeletePort(IEPort);
  885.  }
  886.  else ErrCode |= NO_PORT;
  887.  
  888.  return(ErrCode);
  889. }
  890.