home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 632.lha / ParM_v3.6 / ParM_Src.lzh / ParM_Src / Handler.c next >
Encoding:
C/C++ Source or Header  |  1992-03-23  |  17.2 KB  |  697 lines

  1. /*
  2.  *    Handler.c - Copyright © 1991 by S.R. & P.C.
  3.  *
  4.  *    Created:    30 Jun 1991  19:44:45
  5.  *    Modified:    18 Feb 1992  19:51:36
  6.  *
  7.  *    Make>> make
  8.  */
  9.  
  10. #include "ParMBase.h"
  11.  
  12. void geta4(void);
  13.  
  14. /*#define DEBUG */
  15. /*#define DMOUSE_PTR */
  16.  
  17. #define MIN(x,y)    ((x) < (y) ? (x) : (y))
  18. #define ABS(x)        ((x) < 0 ? (-x) : (x))
  19.  
  20. #define HANDLER_TASK_PRI    5
  21. #define HANDLER_TASK_STACK    2048
  22. #define HANDLER_TASK_NAME    "ParMHandlerTask"
  23. #define HANDLER_NAME        "ParM Handler"
  24.  
  25. extern struct IntuitionBase *IntuitionBase;
  26. extern struct GfxBase *GfxBase;
  27. extern struct ExecBase *SysBase;
  28. extern struct MouseOpt MouseOpt;
  29. extern char ParMLibName[];
  30.  
  31. struct ParMEvent {
  32.     struct ParMEvent *pe_Next;
  33.     struct Window *pe_Owner;
  34.     USHORT pe_Code;
  35.     USHORT pe_Qual;
  36.     USHORT pe_Flags;
  37. };
  38.  
  39. struct HandlerMsg {
  40.     struct Message hm_Message;
  41.     short hm_Action;
  42.     union {
  43.         struct {
  44.             ULONG Class;        /* Allways RAWMOUSE actually */
  45.             USHORT Code;
  46.             USHORT Qual;
  47.             struct timeval TimeStamp;
  48.         } ev;
  49.         struct Screen *Screen;
  50.         struct Window *Win;
  51.     } hm_Data;
  52. };
  53.  
  54. /* Actions for Handler Task (Passed by HandlerMessages) */
  55. #define HMA_START_TASK                0        /* StartUp Message */
  56. #define HMA_FINISH_TASK                1
  57. #define HMA_HANDLE_EV                2
  58. #define HMA_SCREENTOBACK            3
  59. #define HMA_SCREENTOFRONT_ACTIVATE    4        /* ScreenToFront() and ActivateWindow() */
  60. #define HMA_ACTIVATEWINDOW            5
  61.  
  62. void DummySegment(void);    /* for CreateProc() */
  63.  
  64. static struct MsgPort *InputDevPort;
  65. static struct IOStdReq *InputRequestBlock;
  66. static struct Interrupt HandlerStuff;
  67. static struct ParMEvent *ParMEventList;
  68. static struct MsgPort *Process, *StartupMsgReplyPort;
  69. static struct Task *Task;
  70. static struct HandlerMsg StartupMsg;
  71. static BOOL PointerOFF, ScreenOFF;
  72. static long MouseTimeOut, ScreenTimeOut;
  73. static short OSVersion;
  74.  
  75. #ifdef DMOUSE_PTR
  76. static UWORD *NoSprData, *SprSavePtr;
  77. #endif
  78.  
  79. #ifdef DEBUG
  80.  
  81. static char output_buffer[128];
  82.  
  83. static struct IntuiText IText1 = {
  84.     3, 0, JAM2,        /* front and back text pens, drawmode and fill byte */
  85.     7, 13,            /* XY origin relative to container TopLeft */
  86.     NULL,            /* font pointer or NULL for default */
  87.     (UBYTE *)output_buffer,/* pointer to text */
  88.     NULL            /* next IntuiText structure */
  89. };
  90.  
  91. static struct NewWindow NWS = {
  92.     40, 30,            /* window XY origin relative to TopLeft of screen */
  93.     200, 30,        /* window width and height */
  94.     0, 1,            /* detail and block pens */
  95.     NULL,            /* IDCMP flags */
  96.     WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|SIMPLE_REFRESH|NOCAREREFRESH,    /* other window flags */
  97.     NULL,            /* first gadget in gadget list */
  98.     NULL,            /* custom CHECKMARK imagery */
  99.     (UBYTE *)"Handler Window",    /* window title */
  100.     NULL,            /* custom screen pointer */
  101.     NULL,            /* custom bitmap */
  102.     5, 5,            /* minimum width and height */
  103.     -1, -1,            /* maximum width and height */
  104.     WBENCHSCREEN    /* destination screen type */
  105. };
  106.  
  107. static struct Window *DebugW;
  108.  
  109. #endif
  110.  
  111.  
  112. static struct ParMEvent *FindParMEvent(USHORT Code, USHORT Qual, USHORT ExcludeFlags)
  113. {
  114.     struct ParMEvent *ParMEvent;
  115.  
  116.     ParMEvent = ParMEventList;
  117.     while (ParMEvent) {
  118.         if (ParMEvent->pe_Code == Code && ParMEvent->pe_Qual == Qual && !(ParMEvent->pe_Flags & ExcludeFlags))
  119.             return ParMEvent;
  120.         ParMEvent = ParMEvent->pe_Next;
  121.     }
  122.     return NULL;
  123. }
  124.  
  125.  
  126. BOOL AddParMEvent(struct Window *Win, USHORT Code, USHORT Qual, USHORT Flags)
  127. {
  128.     struct ParMEvent *ParMEvent, *LastPE;
  129.     BOOL Ok = TRUE;
  130.  
  131.     Qual |= IEQUALIFIER_RELATIVEMOUSE;    /* All events have this flag set */
  132.     if (!(Flags & PEF_NOCHECK) && FindParMEvent(Code, Qual, PEF_NOCHECK))
  133.         Ok = FALSE;
  134.     if (ParMEvent = AllocMem(sizeof(struct ParMEvent), MEMF_PUBLIC | MEMF_CLEAR)) {
  135.         ParMEvent->pe_Code = Code;
  136.         ParMEvent->pe_Qual = Qual;
  137.         ParMEvent->pe_Owner = Win;
  138.         ParMEvent->pe_Flags = Flags;
  139.         /*
  140.          *    Insert event in first position if NOCHECK (highest priority)
  141.          *    else, insert event in last position (will become active when sooner
  142.          *    inserted events with same hot-key will be gone).
  143.          */
  144.         Forbid();
  145.         if (!ParMEventList || (Flags & PEF_NOCHECK)) {
  146.             ParMEvent->pe_Next = ParMEventList;
  147.             ParMEventList = ParMEvent;
  148.         }
  149.         else {
  150.             LastPE = ParMEventList;
  151.             while (LastPE->pe_Next)
  152.                 LastPE = LastPE->pe_Next;
  153.             LastPE->pe_Next = ParMEvent;
  154.         }
  155.         Permit();
  156.     }
  157.     return Ok;
  158. }
  159.  
  160.  
  161. void RemParMEvents(struct Window *Win)
  162. {
  163.     struct ParMEvent *ParMEvent = ParMEventList, *LastEv;
  164.  
  165.     Forbid();
  166.     LastEv = (struct ParMEvent *)&ParMEventList;
  167.     while (ParMEvent) {
  168.         if (ParMEvent->pe_Owner == Win) {
  169.             LastEv->pe_Next = ParMEvent->pe_Next;
  170.             FreeMem(ParMEvent, sizeof(struct ParMEvent));
  171.         }
  172.         else
  173.             LastEv = ParMEvent;
  174.         ParMEvent = LastEv->pe_Next;
  175.     }
  176.     Permit();
  177. }
  178.  
  179.  
  180. void UpdateParMEventsWindow(struct Window *OldWindow, struct Window *NewWindow)
  181. {
  182.     struct ParMEvent *ParMEvent;
  183.  
  184.     ParMEvent = ParMEventList;
  185.     while (ParMEvent) {
  186.         if (ParMEvent->pe_Owner == OldWindow) {
  187.             if (NewWindow) {
  188.                 ParMEvent->pe_Owner = NewWindow;
  189.                 ParMEvent->pe_Flags &= ~PEF_OUT_OF_ORDER;
  190.             }
  191.             else
  192.                 ParMEvent->pe_Flags |= PEF_OUT_OF_ORDER;
  193.         }
  194.         ParMEvent = ParMEvent->pe_Next;
  195.     }
  196. }
  197.  
  198.  
  199. void HandlerInterface(void);
  200. static void HandlerTask(void);
  201. static void ResetTimeOuts(void);
  202.  
  203. void InstallHandler(void)
  204. {
  205.     BPTR Segment;
  206.  
  207. #ifdef DEBUG
  208.     DebugW = OpenWindow(&NWS);
  209. #endif
  210.  
  211. #ifdef DMOUSE_PTR
  212.     NoSprData = AllocMem(12, MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR);
  213.     NoSprData[0] = 0xFE00;
  214.     NoSprData[1] = 0xFF00;
  215. #endif
  216.  
  217.     OSVersion = IntuitionBase->LibNode.lib_Version;
  218.     StartupMsgReplyPort = CreatePort(0, 0);
  219.     StartupMsg.hm_Message.mn_Length = sizeof(struct HandlerMsg);
  220.     StartupMsg.hm_Message.mn_ReplyPort = StartupMsgReplyPort;
  221.     Segment = (long)DummySegment >> 2;
  222.     if (Process = CreateProc(HANDLER_TASK_NAME, HANDLER_TASK_PRI, Segment, HANDLER_TASK_STACK))
  223.         PutMsg(Process, (struct Message *)&StartupMsg);
  224.     else {
  225.         SimpleRequest(ParMLibName, "Couldn't create %s", HANDLER_TASK_NAME);
  226.         return;
  227.     }
  228.     ResetTimeOuts();    /* init blank stuff */
  229.     InputDevPort = CreatePort(0, 0);
  230.     InputRequestBlock = (struct IOStdReq *) CreateExtIO(InputDevPort, sizeof(struct IOStdReq));
  231.     OpenDevice("input.device", 0, (struct IORequest *)InputRequestBlock, 0);
  232.     HandlerStuff.is_Code = HandlerInterface;
  233.     HandlerStuff.is_Data = (APTR)&MouseOpt;
  234.     HandlerStuff.is_Node.ln_Name = HANDLER_NAME;
  235.     HandlerStuff.is_Node.ln_Pri = MouseOpt.HandlerPri;
  236.     InputRequestBlock->io_Command = IND_ADDHANDLER;
  237.     InputRequestBlock->io_Data = (APTR) & HandlerStuff;
  238.     DoIO((struct IORequest *)InputRequestBlock);
  239. }
  240.  
  241.  
  242. static void SendRequest(short Action, void *APtr);
  243.  
  244. void RemoveHandler(void)
  245. {
  246.     if (!Process)
  247.         return;
  248.     InputRequestBlock->io_Command = IND_REMHANDLER;
  249.     InputRequestBlock->io_Data = (APTR)&HandlerStuff;
  250.     DoIO((struct IORequest *)InputRequestBlock);
  251.     CloseDevice((struct IORequest *)InputRequestBlock);
  252.     FreeMem(InputRequestBlock, sizeof(struct IOStdReq));
  253.     DeletePort(InputDevPort);
  254.  
  255.     SendRequest(HMA_FINISH_TASK, NULL);
  256.     WaitPort(StartupMsgReplyPort);
  257.     GetMsg(StartupMsgReplyPort);
  258.     DeletePort(StartupMsgReplyPort);
  259.  
  260. #ifdef DMOUSE_PTR
  261.     FreeMem(NoSprData, 12);
  262. #endif
  263.  
  264. #ifdef DEBUG
  265.     Forbid();
  266.     CloseWindow(DebugW);
  267.     DebugW = NULL;
  268.     Permit();
  269. #endif
  270. }
  271.  
  272.  
  273. void UpdateMouseOpt(struct MouseOpt *UsrMouseOpt)
  274. {
  275.     MouseOpt = *UsrMouseOpt;
  276.     ResetTimeOuts();
  277. }
  278.  
  279.  
  280. void ScreenOff(void);
  281. void ScreenOn(void);
  282. void PointerOff(void);
  283. void PointerOn(void);
  284.  
  285.  
  286. /**************** Warning: UPDATE for new 2.0 screen modes *************/
  287. /*
  288.  *    On exit, if Screen is not NULL, Screen LayerInfo is locked
  289.  */
  290.  
  291. static struct Layer *WhichMouseLayer(struct Screen **Scr)
  292. {
  293.     struct IntuitionBase *IBase = IntuitionBase;
  294.     struct Screen *Screen;
  295.     struct Layer *Layer = NULL;
  296.     short MouseX;
  297.     short MouseY;
  298.  
  299.     for(Screen = IBase->FirstScreen ; Screen ; Screen = Screen->NextScreen) {
  300.         if (OSVersion < 36)
  301.             LockLayerInfo(&Screen->LayerInfo);
  302.         MouseX = IBase->MouseX;
  303.         MouseY = IBase->MouseY;
  304.         if (!(Screen->ViewPort.Modes & HIRES))
  305.             MouseX >>= 1;
  306.         if (!(Screen->ViewPort.Modes & LACE))
  307.             MouseY >>= 1;
  308.         if (Layer = WhichLayer(&Screen->LayerInfo, MouseX - Screen->ViewPort.DxOffset, MouseY - Screen->ViewPort.DyOffset))
  309.             break;
  310.         if (MouseY >= Screen->ViewPort.DyOffset)
  311.             break;
  312.         if (OSVersion < 36)
  313.             UnlockLayerInfo(&Screen->LayerInfo);
  314.     }
  315.     *Scr = Screen;
  316.     return Layer;
  317. }
  318.  
  319.  
  320. static void HandlerTask(void)
  321. {
  322.     struct IntuitionBase *IBase;
  323.     struct HandlerMsg *Msg;
  324.     struct Screen *Screen;
  325.     struct Layer *Layer;
  326.     struct Window *Win, *ActiveWin, *LastClickWin = NULL;
  327.     ULONG OldSec=0, OldMic=0, Sec, Mic;
  328.     BOOL End = FALSE;
  329.     long ILock;
  330.  
  331.     geta4();
  332.     Task = SysBase->ThisTask;
  333.     WaitPort(Process);
  334.     GetMsg(Process);
  335.     IBase = IntuitionBase;
  336.     if (OSVersion < 36)
  337.         Forbid();
  338.     while(!End) {
  339.         WaitPort(Process);
  340.         if (OSVersion >= 36)
  341.             ILock = LockIBase(0);
  342.         while(Msg = (struct HandlerMsg *)GetMsg(Process)) {
  343.             switch(Msg->hm_Action) {
  344.             case HMA_HANDLE_EV:
  345.                 Sec = Msg->hm_Data.ev.TimeStamp.tv_secs;
  346.                 Mic = Msg->hm_Data.ev.TimeStamp.tv_micro;
  347.                 Layer = WhichMouseLayer(&Screen);
  348.                 Win = (Layer) ? (struct Window *)Layer->Window : NULL;
  349.                 if (Msg->hm_Data.ev.Class == IECLASS_TIMER) {
  350.                     ActiveWin = IBase->ActiveWindow;
  351.                     if (Win && Win != ActiveWin && (!ActiveWin || !ActiveWin->FirstRequest))
  352.                         ActivateWindow(Win);
  353.                 }
  354.                 else if (Msg->hm_Data.ev.Class == IECLASS_RAWMOUSE) {
  355.                     if (Msg->hm_Data.ev.Code == IECODE_LBUTTON) {
  356.                         if (MouseOpt.NClick && Msg->hm_Data.ev.Qual == MouseOpt.WTFQual && Win && !(Win->Flags & BACKDROP) && Layer->ClipRect && Layer->ClipRect->Next) {
  357.                             if (Win == LastClickWin && DoubleClick(OldSec, OldMic, Sec, Mic)) {
  358.                                 /* Do a window to front only if ActiveWindow is still the DoubleClicked */
  359.                                 if (Win == IBase->ActiveWindow)
  360.                                     WindowToFront(Win);
  361.                             }
  362.                             else {
  363.                                 /* Record date and Window Clicked */
  364.                                 OldSec = Sec;
  365.                                 OldMic = Mic;
  366.                                 LastClickWin = Win;
  367.                             }
  368.                         }
  369.                     }
  370.                     else if (Msg->hm_Data.ev.Code == IECODE_RBUTTON && Msg->hm_Data.ev.Qual == (IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_RBUTTON|IEQUALIFIER_RELATIVEMOUSE)) {
  371.                         if ((MouseOpt.Flags & MO_WINDOWTOBACK) && Win && !(Win->Flags & BACKDROP) && (Win->NextWindow || Win->WScreen->FirstWindow != Win)) {
  372.                             WindowToBack(Win);
  373.                         }
  374.                         else if ((MouseOpt.Flags & MO_SCREENTOBACK) && Screen) {
  375.                             if (OSVersion >= 36)
  376.                                 UnlockIBase(ILock);
  377.                             ScreenToBack(Screen);
  378.                             if (OSVersion >= 36)
  379.                                 ILock = LockIBase(0);
  380.                         }
  381.                     }
  382.                 }
  383.                 if (OSVersion < 36 && Screen)
  384.                     UnlockLayerInfo(&Screen->LayerInfo);
  385.                 break;
  386.             case HMA_SCREENTOBACK:
  387.                 ScreenToBack(Msg->hm_Data.Screen);
  388.                 break;
  389.             case HMA_SCREENTOFRONT_ACTIVATE:
  390.                 ScreenToFront(Msg->hm_Data.Win->WScreen);
  391.             case HMA_ACTIVATEWINDOW:
  392.                 ActivateWindow(Msg->hm_Data.Win);
  393.                 break;
  394.             case HMA_FINISH_TASK:
  395.                 End = TRUE;
  396.                 break;
  397.             }
  398.             /* Free message now, don't reply */
  399.             FreeMem(Msg, sizeof(struct HandlerMsg));
  400.         }
  401.         if (OSVersion >= 36)
  402.             UnlockIBase(ILock);
  403.     }
  404.     Forbid();
  405.     ScreenOn();
  406.     PointerOn();
  407.     /* Get rid of pending messages */
  408.     while(Msg = (struct HandlerMsg *)GetMsg(Process))
  409.         FreeMem(Msg, sizeof(struct HandlerMsg));
  410.     /* die now */
  411.     ReplyMsg((struct Message *)&StartupMsg);
  412.     Exit(0);
  413. }
  414.  
  415.  
  416. /*
  417.  *    APtr: generic pointer, may be an InputEvent, Screen, Window or NULL
  418.  *    Action make the difference.
  419.  */
  420.  
  421. #define EV ((struct InputEvent *)APtr)
  422.  
  423. static void SendRequest(short Action, void *APtr)
  424. {
  425.     struct HandlerMsg *Msg = AllocMem(sizeof(struct HandlerMsg), MEMF_PUBLIC|MEMF_CLEAR);
  426.  
  427.     if (Msg) {
  428.         Msg->hm_Message.mn_Length = sizeof(struct HandlerMsg);
  429.         Msg->hm_Action = Action;
  430.         if (Action == HMA_HANDLE_EV) {
  431.             Msg->hm_Data.ev.Class = EV->ie_Class;
  432.             Msg->hm_Data.ev.Code = EV->ie_Code;
  433.             Msg->hm_Data.ev.Qual = EV->ie_Qualifier & ~(IEQUALIFIER_NUMERICPAD|IEQUALIFIER_CAPSLOCK);
  434.             Msg->hm_Data.ev.TimeStamp = EV->ie_TimeStamp;
  435.         }
  436.         else
  437.             Msg->hm_Data.Screen = APtr;        /* Something else than an InputEvent */
  438.         PutMsg(Process, (struct Message *)Msg);
  439.     }
  440. }
  441.  
  442.  
  443. static void ResetTimeOuts(void)
  444. {
  445.     MouseTimeOut = MouseOpt.MouseBlank * 10;        /* 10 timer events per sec */
  446.     ScreenTimeOut = MouseOpt.ScreenBlank * 10;
  447. }
  448.  
  449.  
  450. static short Accel(short d)
  451. {
  452.     short d0 = d, Threshold;
  453.     BOOL Sgn = 1;
  454.  
  455.     if (d < 0) {
  456.         d = -d;
  457.         Sgn = -1;
  458.     }
  459.     if (d > (Threshold = MouseOpt.Threshold))
  460.         return Sgn * ((d - Threshold) * MouseOpt.Acc + Threshold);
  461.     return d0;
  462. }
  463.  
  464.  
  465. static void CheckParMEvent(struct InputEvent *ev)
  466. {
  467.     struct Window *Win;
  468.     struct ParMEvent *ParMEvent;
  469.     long OldPri;
  470.  
  471.     if (ParMEvent = FindParMEvent(ev->ie_Code, ev->ie_Qualifier & ~(IEQUALIFIER_CAPSLOCK|IEQUALIFIER_NUMERICPAD), PEF_OUT_OF_ORDER)) {
  472.         Win = ParMEvent->pe_Owner;
  473.         OldPri = SetTaskPri(Task, 21);
  474.         if (ParMEvent->pe_Flags & PEF_SCREENTOFRONT)
  475.             SendRequest(HMA_SCREENTOFRONT_ACTIVATE, Win);
  476.         else
  477.             SendRequest(HMA_ACTIVATEWINDOW, Win);
  478.         SetTaskPri(Task, OldPri);
  479.         if (!(ParMEvent->pe_Flags & PEF_PASSTHROUGH))
  480.             ev->ie_Class = IECLASS_NULL;    /* Skip Event */
  481.     }
  482. }
  483.  
  484.  
  485. static struct InputEvent *InputHandler(struct InputEvent *EventList, struct MouseOpt *MouseOpt)
  486. {
  487.     struct InputEvent *ev = EventList;
  488.     struct Window *W;
  489.     static USHORT LastMouseMoveQual, MinMove;
  490.     static BOOL NoMouseMove;
  491.     UWORD Code, Qual, X, Y;
  492.  
  493.     while (ev) {
  494.  
  495. #ifdef DEBUG
  496. static short tim;
  497.  
  498.         if (DebugW && (ev->ie_Class != IECLASS_TIMER || ++tim > 5)) {
  499.             tim = 0;
  500.             SPrintf(output_buffer, "%lx    %lx    %lx    %04lx ",
  501.                 (long) ev->ie_Class,
  502.                 (long) ev->ie_SubClass,
  503.                 (long) ev->ie_Code,
  504.                 (long) ev->ie_Qualifier);
  505.             PrintIText(DebugW->RPort, &IText1, 0, 0);
  506.         }
  507.  
  508. #endif
  509.  
  510.         Code = ev->ie_Code;
  511.         /* ignore remanent qualifiers which can disable some handler features */
  512.         Qual = ev->ie_Qualifier & ~(IEQUALIFIER_NUMERICPAD|IEQUALIFIER_CAPSLOCK);
  513.         switch (ev->ie_Class) {
  514.         case IECLASS_RAWMOUSE:
  515.             ResetTimeOuts();
  516.             if (ScreenOFF) {
  517.                 ScreenOn();
  518.                 ScreenOFF = FALSE;
  519.             }
  520.             if (Code == IECODE_NOBUTTON) {
  521.                 if (PointerOFF) {
  522.                     if (W = IntuitionBase->ActiveWindow)
  523.                         WaitBOVP(&W->WScreen->ViewPort);    /* Make pointer appear smoothly */
  524.                     PointerOn();
  525.                     PointerOFF = FALSE;
  526.                 }
  527.                 NoMouseMove = FALSE;
  528.                 LastMouseMoveQual = Qual;
  529.                 if (MouseOpt->Acc) {
  530.                     ev->ie_X = Accel(ev->ie_X);
  531.                     ev->ie_Y = Accel(ev->ie_Y);
  532.                 }
  533.                 X = ABS(ev->ie_X);
  534.                 Y = ABS(ev->ie_Y);
  535.                 if (X + Y > 0)
  536.                     MinMove = MIN(MinMove, X + Y);
  537.             }
  538.             else {
  539.                 CheckParMEvent(ev);
  540.                 if (Code == IECODE_LBUTTON || Code == IECODE_RBUTTON) {
  541.                     SendRequest(HMA_HANDLE_EV, ev);
  542.                     if (Code == IECODE_RBUTTON && (MouseOpt->Flags & (MO_WINDOWTOBACK|MO_SCREENTOBACK)) && Qual == (IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_RBUTTON|IEQUALIFIER_RELATIVEMOUSE))
  543.                         ev->ie_Class = IECLASS_NULL;    /* Remove event */
  544.                 }
  545.             }
  546.             break;
  547.         case IECLASS_RAWKEY:
  548.             ResetTimeOuts();
  549.             if (Code & IECODE_UP_PREFIX)        /* don't handle key up */
  550.                 break;
  551.             if (ScreenOFF) {
  552.                 ScreenOn();
  553.                 ScreenOFF = FALSE;
  554.             }
  555.             if (!PointerOFF && MouseOpt->MouseBlank) {
  556.                 PointerOff();
  557.                 PointerOFF = TRUE;
  558.             }
  559.             CheckParMEvent(ev);
  560.  
  561.             /********** REMOVE IN 2.0 (System handled & Qual parametrable) ************/
  562.             /* LAmiga-M stuff (rawkey 'm' = $37) */
  563.             if (OSVersion < 36 && Code == 0x37 && Qual == (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RELATIVEMOUSE)) {
  564.                 SendRequest(HMA_SCREENTOBACK, IntuitionBase->FirstScreen);
  565.                 ev->ie_Class = IECLASS_NULL;    /* Skip Event */
  566.             }
  567.             break;
  568.         case IECLASS_TIMER:
  569.             MouseTimeOut--;
  570.             ScreenTimeOut--;
  571.             if (LastMouseMoveQual == IEQUALIFIER_RELATIVEMOUSE
  572.                 && (MouseOpt->SunMouse > 0 && MinMove <= MouseOpt->SunMouse        /* Smallest MOUSEMOVE between two TIMER events smaller than SunMouse */
  573.                 || MouseOpt->SunMouse >= 0 && NoMouseMove))        /* No MOUSEMOVE between two TIMER events */
  574.             {
  575.                 SendRequest(HMA_HANDLE_EV, ev);
  576.                 LastMouseMoveQual = 0;
  577.                 MinMove = MouseOpt->SunMouse + 1;
  578.             }
  579.             NoMouseMove = TRUE;
  580.             /* look if something must be blanked */
  581.             if (!PointerOFF && MouseOpt->MouseBlank && MouseTimeOut <= 0) {
  582.                 PointerOff();
  583.                 PointerOFF = TRUE;
  584.             }
  585.             if (!ScreenOFF && MouseOpt->ScreenBlank && ScreenTimeOut <= 0) {
  586.                 ScreenOff();
  587.                 ScreenOFF = TRUE;
  588.             }
  589.             break;
  590.         }
  591.         ev = ev->ie_NextEvent;
  592.     }
  593.     return EventList;
  594. }
  595.  
  596.  
  597. #ifdef DMOUSE_PTR
  598.  
  599. void PointerOff(void)
  600. {
  601.     struct copinit *ci = GfxBase->copinit;
  602.  
  603.     if (!SprSavePtr)
  604.         SprSavePtr = (UWORD *)((ci->sprstrtup[1] << 16) | ci->sprstrtup[3]);
  605.     ci->sprstrtup[1] = (ULONG)NoSprData >> 16;
  606.     ci->sprstrtup[3] = (UWORD)(LONG)NoSprData;
  607. }
  608.  
  609.  
  610. void PointerOn(void)
  611. {
  612.     struct copinit *ci = GfxBase->copinit;
  613.  
  614.     if (SprSavePtr) {
  615.         ci->sprstrtup[1] = (ULONG)SprSavePtr >> 16;
  616.         ci->sprstrtup[3] = (UWORD)(LONG)SprSavePtr;
  617.         SprSavePtr = NULL;
  618.     }
  619. }
  620.  
  621. #endif
  622.  
  623.  
  624. #asm
  625.  
  626.     public _DummySegment
  627.     public _HandlerTask
  628.  
  629.     cseg
  630.  
  631. _DummySegment:
  632.     dc.l    0
  633.     nop
  634.     nop
  635.     jmp        _HandlerTask
  636.  
  637.  
  638. _HandlerInterface:
  639.     move.l    a4,-(sp)        ; save a4
  640.     movem.l    a0/a1,-(sp)        ; push args
  641.     jsr     _geta4            ; get our private a4 to access global data
  642.     jsr     _InputHandler    ; call handler stuff
  643.     addq.l    #8,sp            ; pop args
  644.     move.l    (sp)+,a4        ; restore a4
  645.     rts
  646.  
  647.  
  648. ; blank routines
  649. ; hardware.defs
  650. custom         EQU $dff000
  651. dmacon         EQU $096
  652. spr         EQU $140
  653. sd_dataa    EQU $04
  654. color         EQU $180
  655.  
  656. ;include "hardware/dmabits.i"
  657. DMAF_RASTER EQU $0100
  658. DMAF_COPPER EQU $0080
  659.  
  660. _ScreenOff:
  661.     lea     custom+dmacon,a0
  662.     move.w    #0+DMAF_RASTER+DMAF_COPPER,(a0)
  663.     clr.w    color-dmacon(a0)            ; SET BLACK SCREEN
  664.     clr.l    spr+sd_dataa-dmacon(a0)        ; MAKE SURE SPRITE GOES
  665.     rts
  666.  
  667. _ScreenOn:
  668.     lea        custom+dmacon,a0
  669.     move.w    #$8000+DMAF_RASTER+DMAF_COPPER,(a0)        ; screen on
  670.     rts
  671.  
  672.  
  673. #endasm
  674.  
  675.  
  676. #ifndef DMOUSE_PTR
  677.  
  678. #asm
  679.  
  680.     public    _GfxBase
  681.  
  682. _PointerOff:
  683.     lea        custom+dmacon,a0
  684.     move.w    #0+$20,(a0)                        ; turn sprites off.
  685.     clr.l    spr+sd_dataa-dmacon(a0)
  686.     rts
  687.  
  688. _PointerOn:
  689.     lea     custom+dmacon,a0
  690.     move.w    #$8000+$20,(a0)            ; turn sprites on
  691.     rts
  692.  
  693. #endasm
  694.  
  695. #endif
  696.  
  697.