home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c070 / 4.ddi / TOOLS.4 / TCTSRC1.EXE / MOHANDLR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-31  |  6.9 KB  |  230 lines

  1. /**
  2. *
  3. * Name        mohandlr -- Install or remove mouse interrupt handler.
  4. *
  5. * Synopsis    ercode = mohandlr(pfunc,call_mask,pstack,stksize,option);
  6. *
  7. *        int ercode      Error return code:
  8. *                    MO_OK if successful;
  9. *                    MO_ABSENT if mouse not found;
  10. *                    MO_ALREADY if already installed
  11. *                      and MO_INSTALL is specified;
  12. *                    MO_NOT_INSTALLED if not installed
  13. *                      and MO_REMOVE is specified;
  14. *                    MO_BAD_OPT if option code
  15. *                      not recognized.
  16. *
  17. *        PMOHANDLER pfunc  Address of mouse interrupt handler
  18. *                    function to install.
  19. *        unsigned call_mask
  20. *                  Bit mask indicating classes of
  21. *                    events that should call the
  22. *                    handler:
  23. *
  24. *                 MO_MOVE         Mouse moved.
  25. *                 MO_L_PRESS      Left   button depressed.
  26. *                 MO_L_RELEASE    Left   button released.
  27. *                 MO_R_PRESS      Right  button depressed.
  28. *                 MO_R_RELEASE    Right  button released.
  29. *                 MO_M_PRESS      Middle button depressed.
  30. *                 MO_M_RELEASE    Middle button released.
  31. *
  32. *        char *pstack      Address of beginning of memory block
  33. *                    to be used for this handler's stack.
  34. *        int stksize      Size (in bytes) of handler's stack.
  35. *        int option      MO_INSTALL or MO_REMOVE.  If MO_REMOVE
  36. *                  is specified, all the other arguments
  37. *                  are ignored.
  38. *
  39. * Description    This function installs a user function ("pfunc") to
  40. *        receive control when certain mouse events occur:  mouse
  41. *        movements or presses or releases of mouse buttons.
  42. *
  43. *        Only one mouse handler can be active at a time.  To
  44. *        change the handler or the call mask, first remove the
  45. *        previous handler by specifying MO_REMOVE, then install
  46. *        the new handler with the new call mask.
  47. *
  48. *        The handler function must be designed carefully:
  49. *
  50. *            1) It must not call DOS.
  51. *            2) If it uses any non-reentrant library functions,
  52. *               the functions must not be in use by any other
  53. *               part of the program.
  54. *            3) If data is arriving at an asynchronous
  55. *               communication port, the handler must exit
  56. *               quickly.
  57. *
  58. *        If DOS services are required, it may be easiest for the
  59. *        handler to set a global variable to indicate a service
  60. *        request, then let the request be fulfilled by an
  61. *        intervention function.
  62. *
  63. * Method    The mouse driver does not call the user function
  64. *        directly.  Instead, the internal function
  65. *        mo_dispatcher() is set up as an interrupt service
  66. *        routine (ISR) that exits via a FAR return.  The mouse
  67. *        driver calls mo_dispatcher() via the usual ISR
  68. *        dispatcher ISDISPAT, and mo_dispatcher() calls the user
  69. *        function in turn, passing a copy of the original
  70. *        register contents.
  71. *
  72. *        This function automatically adjusts to the presence of
  73. *        MOCATCH.  When MOCATCH is installed and a handler is
  74. *        installed by this function, MOCATCH is always called
  75. *        first; then MOCATCH passes control to the user handler
  76. *        if appropriate.
  77. *
  78. *        b_mohanmask contains the user's call mask; MOCATCH uses
  79. *        it to determine whether the user's routine should be
  80. *        called.  b_modispat contains the address of the
  81. *        dispatcher's ISR control block; MOCATCH calls this
  82. *        address and thus enters the dispatcher.
  83. *
  84. * Returns    ercode          Error return code:
  85. *                    MO_OK if successful;
  86. *                    MO_ABSENT if mouse not found;
  87. *                    MO_ALREADY if already installed
  88. *                      and MO_INSTALL is specified;
  89. *                    MO_NOT_INSTALLED if not installed
  90. *                      and MO_REMOVE is specified;
  91. *                    MO_BAD_OPT if option not
  92. *                      recognized.
  93. *        b_mouse       Number of mouse buttons (0 if no driver).
  94. *        b_modispat      If installed, this is the address of
  95. *                    the ISR control block of the
  96. *                    internal dispatcher;
  97. *                  if removed, this is zero.
  98. *        b_mohanmask      If installed, this is the user's call
  99. *                    mask;
  100. *                  if removed, this is zero.
  101. *
  102. * Version    6.00 (C)Copyright Blaise Computing Inc.  1989
  103. *
  104. **/
  105.  
  106. #include <bmouse.h>
  107.  
  108.     /* Local static variables.                          */
  109.  
  110. static ISRCTRL dispat_block = {0};    /* ISR control block.          */
  111. static PMOHANDLER p_user_handler = 0; /* Pointer to user function.    */
  112.  
  113.     /* Internal functions.                          */
  114.  
  115. static void cdecl mo_dispatcher(ALLREG *,ISRCTRL *,ISRMSG *);
  116.  
  117. int mohandlr(pfunc,call_mask,pstack,stksize,option)
  118. PMOHANDLER pfunc;
  119. unsigned   call_mask;
  120. char      *pstack;
  121. int       stksize,option;
  122. {
  123.     int      result;
  124.     unsigned new_mask;
  125.  
  126.     if (moequip() <= 0)           /* Test mouse presence.          */
  127.     return MO_ABSENT;
  128.  
  129.     switch (option)
  130.     {
  131.     case MO_INSTALL:
  132.         if (p_user_handler)
  133.         result = MO_ALREADY;
  134.         else
  135.         {
  136.                       /* Set up dispatcher.          */
  137.         p_user_handler = pfunc;
  138.         isprep(mo_dispatcher,"MOUSEDISPATCHER",&dispat_block,
  139.                pstack,stksize,1);
  140.  
  141.                       /* Install interrupt handler    */
  142.                       /* if necessary.              */
  143.         if (b_mocatch)
  144.         {
  145.                       /* MOCATCH installed; need not  */
  146.                       /* install new handler, but     */
  147.                       /* perhaps augment call mask.   */
  148.             new_mask = (call_mask | b_momask);
  149.             if (new_mask == b_momask)
  150.             result = MO_OK;   /* No change in call mask.  */
  151.             else
  152.                       /* Install new call mask.       */
  153.             result = moinst(b_mocatch,new_mask);
  154.         }
  155.         else
  156.                       /* Install dispatcher directly. */
  157.             result = moinst((void (far *) ()) &dispat_block,
  158.                     call_mask);
  159.  
  160.         if (result == MO_OK)
  161.         {
  162.                       /* Set up pointer & call mask   */
  163.                       /* so MOCATCH can call          */
  164.                       /* dispatcher.              */
  165.             b_modispat       = &dispat_block;
  166.             b_mohanmask    = call_mask;
  167.         }
  168.         else
  169.             p_user_handler = 0;
  170.         }
  171.  
  172.         break;
  173.  
  174.     case MO_REMOVE:
  175.         if (!p_user_handler)
  176.         result = MO_NOT_INSTALLED;
  177.         else
  178.         {
  179.         b_mohanmask    = 0;
  180.         b_modispat     = NIL;
  181.         p_user_handler = 0;
  182.         result           = moinst(b_mocatch,b_momask);
  183.         }
  184.  
  185.         break;
  186.  
  187.     default:
  188.         result = MO_BAD_OPT;
  189.         break;
  190.     }
  191.  
  192.     return result;
  193. }
  194.  
  195. /**
  196. *
  197. * Name        mo_dispatcher -- Invoke user mouse interrupt handler.
  198. *
  199. * Description    This function calls the user mouse interrupt handler.
  200. *
  201. *        This function is built as an interrupt service routine
  202. *        (ISR) to be called from the mouse driver via the ISR
  203. *        dispatcher.  If MOCATCH is installed, the mouse driver
  204. *        calls MOCATCH directly, then MOCATCH calls this function
  205. *        (via the ISR dispatcher) if the event is among those
  206. *        specified in the call mask.
  207. *
  208. **/
  209.  
  210. static void cdecl mo_dispatcher(pregs,pisrctrl,pmsg)
  211. ALLREG    *pregs;
  212. ISRCTRL *pisrctrl;
  213. ISRMSG    *pmsg;
  214. {
  215.     ALLREG regs;          /* Declare local copy of registers      */
  216.                   /*  so user handler can't affect *pregs.*/
  217.     const char *p;
  218.  
  219.     p = (const char *) pisrctrl;      /* Suppress compiler warning    */
  220.     p++;                  /*  that pisrctrl isn't used.   */
  221.  
  222.     if (p_user_handler)
  223.     {
  224.     regs = *pregs;
  225.     p_user_handler(®s);          /* Call user handler.          */
  226.     }
  227.  
  228.     pmsg->exit_style = IEXIT_RETF;
  229. }
  230.