home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 138.lha / DMouse_1.06 / dmouse-handler.c < prev    next >
C/C++ Source or Header  |  1986-11-20  |  12KB  |  318 lines

  1. /*
  2.  *  DMOUSE-HANDLER.C            compile 32 bit integers (+L)
  3.  *                              AZTEC COMPILATION
  4.  *  18 May 1988
  5.  */
  6. #include "dmouse.h"
  7. #define IBASE IntuitionBase
  8. DMS     *Dms;
  9. struct IntuitionBase *IntuitionBase;
  10. struct GfxBase       *GfxBase;
  11. long                 *LayersBase;
  12. NS      Ns = {  0, 0, 64, -1, 1, -1, -1, 0, CUSTOMSCREEN|SCREENQUIET };
  13. IE *handler();
  14. _main()
  15. {
  16.     register DMS *dms;
  17.     IOR  *ior;
  18.     INT addhand;
  19.     {
  20.         register PROC *proc = (PROC *)FindTask(NULL);
  21.         proc->pr_ConsoleTask = NULL;
  22.     }
  23.     dms = Dms = FindPort(PORTNAME);
  24.     if (!dms)
  25.         _exit(0);
  26.     dms->Port.mp_Flags = PA_SIGNAL;
  27.     dms->Port.mp_SigBit = AllocSignal(-1);
  28.     dms->Port.mp_SigTask = FindTask(NULL);
  29.     dms->HandTask = dms->Port.mp_SigTask;
  30.     ior = CreateStdIO(&dms->Port);
  31.     IntuitionBase = OpenLibrary("intuition.library", 0);
  32.     GfxBase = OpenLibrary("graphics.library", 0);
  33.     LayersBase = OpenLibrary("layers.library", 0);
  34.     if (!IntuitionBase || !GfxBase || !LayersBase)
  35.         goto startupfail;
  36.     addhand.is_Node.ln_Pri = 51;
  37.     addhand.is_Code = (FPTR)handler;
  38.     addhand.is_Data = NULL;
  39.     if (OpenDevice("input.device", 0, ior, 0)) {
  40.         goto startupfail;
  41.     } else {
  42.         SCR *scr = NULL;
  43.         uword *SprSavePtr = NULL;
  44.         Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  45.         ior->io_Command = IND_ADDHANDLER;
  46.         ior->io_Data = (APTR)&addhand;
  47.         DoIO(ior);
  48.         for (;;) {
  49.             register long sigs = Wait(SBF_C|(1<<dms->Port.mp_SigBit));
  50.             if (sigs & (1 << dms->Port.mp_SigBit)) {
  51.                 register MSG *msg;
  52.                 while (msg = GetMsg(&dms->Port)) {
  53.                     switch((long)msg->mn_Node.ln_Name) {
  54.                     case REQ_SCREENON:
  55.                         if (scr)
  56.                             CloseScreen(scr);
  57.                         scr = NULL;
  58.                         break;
  59.                     case REQ_SCREENOFF:
  60.                         if (scr) {
  61.                             ScreenToFront(scr);
  62.                         } else {
  63.                             if (scr = OpenScreen(&Ns))
  64.                                 SetRGB4(&scr->ViewPort, 0, 0, 0, 0);
  65.                         }
  66.                         break;
  67.                     case REQ_MOUSEON:
  68.                         if (SprSavePtr) {
  69.                             register COPINIT *ci = GfxBase->copinit;
  70.                             ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
  71.                             ci->sprstrtup[3] = (uword)(long)SprSavePtr;
  72.                             SprSavePtr = NULL;
  73.                         }
  74.                         break;
  75.                     case REQ_MOUSEOFF:
  76.                         {
  77.                             register COPINIT *ci = GfxBase->copinit;
  78.                             if (!SprSavePtr)
  79.                                 SprSavePtr = (uword *)((ci->sprstrtup[1] << 16) | ci->sprstrtup[3]);
  80.                             ci->sprstrtup[1] = (ulong)dms->NoSprData >> 16;
  81.                             ci->sprstrtup[3] = (uword)(long)dms->NoSprData;
  82.                         }
  83.                         break;
  84.                     case REQ_DOCMD:
  85.                         {
  86.                             long fh = Open("nil:", 1006);
  87.                             Execute(dms->Cmd, NULL, fh);
  88.                             if (fh)
  89.                                 Close(fh);
  90.                         }
  91.                         break;
  92.                     }
  93.                     FreeMem(msg, msg->mn_Length);
  94.                 }
  95.             }
  96.             if (sigs & SBF_C)
  97.                 break;
  98.         }
  99.         Forbid();
  100.         ior->io_Command = IND_REMHANDLER;
  101.         ior->io_Data = (APTR)&addhand;
  102.         DoIO(ior);
  103.         Permit();
  104.         CloseDevice(ior);
  105.         {
  106.             register MSG *msg;
  107.             while (msg = GetMsg(&dms->Port))
  108.                 FreeMem(msg, msg->mn_Length);
  109.         }
  110.         if (scr)
  111.             CloseScreen(scr);
  112.         if (SprSavePtr) {
  113.             register COPINIT *ci = GfxBase->copinit;
  114.             ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
  115.             ci->sprstrtup[3] = (uword)(long)SprSavePtr;
  116.             SprSavePtr = NULL;
  117.         }
  118.     }
  119.     goto closedown;
  120. startupfail:
  121.     dms->StartupError = 1;
  122.     Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  123.     Wait(SBF_C);
  124. closedown:
  125.     DeleteStdIO(ior);
  126. fail:
  127.     if (IntuitionBase)
  128.         CloseLibrary(IntuitionBase);
  129.     if (GfxBase)
  130.         CloseLibrary(GfxBase);
  131.     if (LayersBase)
  132.         CloseLibrary(LayersBase);
  133.     Forbid();
  134.     Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  135. }
  136. #asm
  137.             ;   A0 = pointer to event linked list
  138.             ;   A1 = pointer to my data segment
  139.             ;   return new event linked list in D0
  140.             public  _CHandler
  141. _handler:
  142.             movem.l D2/D3/A0/A1/A4/A6,-(sp)
  143.             jsr     _CHandler
  144.             movem.l (sp)+,D2/D3/A0/A1/A4/A6
  145.             rts
  146. #endasm
  147. /*
  148.  *  (1) Accellerate mouse movements.
  149.  *  (2) Auto-Select window
  150.  */
  151. IE *
  152. CHandler(scr0, scr1, Ev)
  153. IE *Ev;
  154. {
  155.     register IE *ev;
  156.     register DMS *dms;
  157.     static char STimedout;
  158.     static char MTimedout;
  159.     static long STime, MTime;
  160.     geta4();
  161.     dms = Dms;
  162.     for (ev = Ev; ev; ev = Ev->ie_NextEvent) {
  163.         switch(ev->ie_Class) {
  164.         case IECLASS_RAWMOUSE:
  165.             /*
  166.              *  Mouse events restore both the screen and mouse pointer.
  167.              */
  168.             STime = ev->ie_TimeStamp.tv_secs + dms->STo;
  169.             MTime = ev->ie_TimeStamp.tv_secs + dms->MTo;
  170.             if (STimedout)
  171.                 sendrequest(REQ_SCREENON);
  172.             if (MTimedout)
  173.                 sendrequest(REQ_MOUSEON);
  174.             STimedout = MTimedout = 0;
  175.             /*
  176.              *  Mouse Acceleration
  177.              */
  178.             {
  179.                 register short n;
  180.                 register short s;
  181.                 if (dms->Acc != 1) {
  182.                     n = ev->ie_X;
  183.                     s = 1;
  184.                     if (n < 0) {
  185.                         n = -n;
  186.                         s = -1;
  187.                     }
  188.                     if (n > dms->AThresh)
  189.                         ev->ie_X = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
  190.                     n = ev->ie_Y;
  191.                     s = 1;
  192.                     if (n < 0) {
  193.                         n = -n;
  194.                         s = -1;
  195.                     }
  196.                     if (n > dms->AThresh)
  197.                         ev->ie_Y = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
  198.                 }
  199.             }
  200.             /*
  201.              *  Auto Activate and LMB (win/scrn front/bak)
  202.              */
  203.             if (dms->AAEnable | dms->LMBEnable) {
  204.                 register LAYER *layer;
  205.                 Forbid();
  206.                 layer = WhichMouseLayer();
  207.                 if (dms->LMBEnable && ev->ie_Code == IECODE_RBUTTON && (ev->ie_Qualifier & dms->RQual)) {
  208.                     register WIN *win;
  209.                     if (layer && (win = (WIN *)layer->Window) && !(win->Flags & BACKDROP) && (win->NextWindow || win->WScreen->FirstWindow != win))
  210.                         WindowToBack(layer->Window);
  211.                     else if (IBASE->FirstScreen)
  212.                         ScreenToBack(IBASE->FirstScreen);
  213.                     ev->ie_Class = IECLASS_NULL;    /*  remove event    */
  214.                 }
  215.                 if (layer && layer->Window) {
  216.                     if (dms->LMBEnable && ev->ie_Code == IECODE_LBUTTON && layer->ClipRect && layer->ClipRect->Next) {
  217.                         /*
  218.                          *  Note: Case where it is the 'first' click in a series, where dms->CTime is
  219.                          *        garbage, works properly no matter what DoubleClick returns.
  220.                          */
  221.                         if ((APTR)dms->CWin == layer->Window && DoubleClick(dms->CTime.tv_secs, dms->CTime.tv_micro, ev->ie_TimeStamp.tv_secs, ev->ie_TimeStamp.tv_micro))
  222.                             --dms->CLeft;
  223.                         else
  224.                             dms->CLeft = dms->Clicks - 1;
  225.                         dms->CTime = ev->ie_TimeStamp;
  226.                         dms->CWin = (WIN *)layer->Window;
  227.                         if (dms->CLeft == 0) {
  228.                             dms->CLeft = dms->Clicks;
  229.                             WindowToFront(layer->Window);
  230.                         }
  231.                     }
  232.                     if (dms->AAEnable && ev->ie_Code == IECODE_NOBUTTON && !(ev->ie_Qualifier & 0x7000) && layer->Window != IBASE->ActiveWindow)
  233.                         ActivateWindow(layer->Window);
  234.                 }
  235.                 Permit();
  236.             }
  237.             break;
  238.         case IECLASS_RAWKEY:
  239.             /*
  240.              *  Keyboard events will kill the screen timeout but not
  241.              *  the mouse timeout.
  242.              */
  243.             {
  244.                 register LAYER *layer;
  245.                 Forbid();
  246.                 layer = WhichMouseLayer();
  247.                 if (layer && layer->Window) {
  248.                     if (dms->AAEnable && layer->Window != IBASE->ActiveWindow)
  249.                         ActivateWindow(layer->Window);
  250.                 }
  251.                 Permit();
  252.             }
  253.             STime = ev->ie_TimeStamp.tv_secs + dms->STo;
  254.             if (STimedout)
  255.                 sendrequest(REQ_SCREENON);
  256.             STimedout = 0;
  257.             if (ev->ie_Code == dms->Code && ev->ie_Qualifier == dms->Qual) {
  258.                 sendrequest(REQ_DOCMD);
  259.                 ev->ie_Class = IECLASS_NULL;    /*  remove event    */
  260.             }
  261.             break;
  262.         case IECLASS_TIMER:
  263.             /*
  264.              *  On a timer event, if timeout has occured execute the operation
  265.              *  and reset the timeout.  Note that this will cause continuous
  266.              *  timeouts every STo and MTo seconds... required because at any
  267.              *  time Intuition might turn the mouse back on or open a screen or
  268.              *  something and I want the blanker's to work in the long run.
  269.              */
  270.             {
  271.                 register long old;
  272.                 if (dms->STo && (old = STime - ev->ie_TimeStamp.tv_secs) < 0) {
  273.                     STime = ev->ie_TimeStamp.tv_secs + dms->STo + 10;
  274.                     STimedout = 1;
  275.                     if (old > -10)
  276.                         sendrequest(REQ_SCREENOFF);
  277.                 }
  278.                 if (dms->MTo && (old = MTime - ev->ie_TimeStamp.tv_secs) < 0) {
  279.                     MTime = ev->ie_TimeStamp.tv_secs + dms->MTo + 1;
  280.                     MTimedout = 1;
  281.                     if (old > -10)
  282.                         sendrequest(REQ_MOUSEOFF);
  283.                 }
  284.             }
  285.             break;
  286.         }
  287.     }
  288.     return(Ev);
  289. }
  290. sendrequest(req)
  291. long req;
  292. {
  293.     register MSG *msg = AllocMem(sizeof(MSG), MEMF_PUBLIC);
  294.     if (msg) {
  295.         msg->mn_Node.ln_Name = (char *)req;
  296.         msg->mn_ReplyPort = NULL;
  297.         msg->mn_Length = sizeof(MSG);
  298.         PutMsg(&Dms->Port, msg);
  299.     }
  300. }
  301. LAYER *
  302. WhichMouseLayer()
  303. {
  304.     register struct IntuitionBase *ib = IBASE;
  305.     register LAYER *layer = NULL;
  306.     register SCR *scr = ib->FirstScreen;
  307.     for (scr = ib->FirstScreen; scr; scr = scr->NextScreen) {
  308.         register short mousey = ib->MouseY;
  309.         if (!(scr->ViewPort.Modes & LACE))
  310.             mousey >>= 1;
  311.         if (layer = WhichLayer(&scr->LayerInfo, ib->MouseX, mousey - scr->ViewPort.DyOffset))
  312.             break;
  313.         if (mousey >= scr->ViewPort.DyOffset)
  314.             break;
  315.     }
  316.     return(layer);
  317. }
  318.