home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name mohandlr -- Install or remove mouse interrupt handler.
- *
- * Synopsis ercode = mohandlr(pfunc,call_mask,pstack,stksize,option);
- *
- * int ercode Error return code:
- * MO_OK if successful;
- * MO_ABSENT if mouse not found;
- * MO_ALREADY if already installed
- * and MO_INSTALL is specified;
- * MO_NOT_INSTALLED if not installed
- * and MO_REMOVE is specified;
- * MO_BAD_OPT if option code
- * not recognized.
- *
- * PMOHANDLER pfunc Address of mouse interrupt handler
- * function to install.
- * unsigned call_mask
- * Bit mask indicating classes of
- * events that should call the
- * handler:
- *
- * MO_MOVE Mouse moved.
- * MO_L_PRESS Left button depressed.
- * MO_L_RELEASE Left button released.
- * MO_R_PRESS Right button depressed.
- * MO_R_RELEASE Right button released.
- * MO_M_PRESS Middle button depressed.
- * MO_M_RELEASE Middle button released.
- *
- * char *pstack Address of beginning of memory block
- * to be used for this handler's stack.
- * int stksize Size (in bytes) of handler's stack.
- * int option MO_INSTALL or MO_REMOVE. If MO_REMOVE
- * is specified, all the other arguments
- * are ignored.
- *
- * Description This function installs a user function ("pfunc") to
- * receive control when certain mouse events occur: mouse
- * movements or presses or releases of mouse buttons.
- *
- * Only one mouse handler can be active at a time. To
- * change the handler or the call mask, first remove the
- * previous handler by specifying MO_REMOVE, then install
- * the new handler with the new call mask.
- *
- * The handler function must be designed carefully:
- *
- * 1) It must not call DOS.
- * 2) If it uses any non-reentrant library functions,
- * the functions must not be in use by any other
- * part of the program.
- * 3) If data is arriving at an asynchronous
- * communication port, the handler must exit
- * quickly.
- *
- * If DOS services are required, it may be easiest for the
- * handler to set a global variable to indicate a service
- * request, then let the request be fulfilled by an
- * intervention function.
- *
- * Method The mouse driver does not call the user function
- * directly. Instead, the internal function
- * mo_dispatcher() is set up as an interrupt service
- * routine (ISR) that exits via a FAR return. The mouse
- * driver calls mo_dispatcher() via the usual ISR
- * dispatcher ISDISPAT, and mo_dispatcher() calls the user
- * function in turn, passing a copy of the original
- * register contents.
- *
- * This function automatically adjusts to the presence of
- * MOCATCH. When MOCATCH is installed and a handler is
- * installed by this function, MOCATCH is always called
- * first; then MOCATCH passes control to the user handler
- * if appropriate.
- *
- * b_mohanmask contains the user's call mask; MOCATCH uses
- * it to determine whether the user's routine should be
- * called. b_modispat contains the address of the
- * dispatcher's ISR control block; MOCATCH calls this
- * address and thus enters the dispatcher.
- *
- * Returns ercode Error return code:
- * MO_OK if successful;
- * MO_ABSENT if mouse not found;
- * MO_ALREADY if already installed
- * and MO_INSTALL is specified;
- * MO_NOT_INSTALLED if not installed
- * and MO_REMOVE is specified;
- * MO_BAD_OPT if option not
- * recognized.
- * b_mouse Number of mouse buttons (0 if no driver).
- * b_modispat If installed, this is the address of
- * the ISR control block of the
- * internal dispatcher;
- * if removed, this is zero.
- * b_mohanmask If installed, this is the user's call
- * mask;
- * if removed, this is zero.
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1989
- *
- **/
-
- #include <bmouse.h>
-
- /* Local static variables. */
-
- static ISRCTRL dispat_block = {0}; /* ISR control block. */
- static PMOHANDLER p_user_handler = 0; /* Pointer to user function. */
-
- /* Internal functions. */
-
- static void cdecl mo_dispatcher(ALLREG *,ISRCTRL *,ISRMSG *);
-
- int mohandlr(pfunc,call_mask,pstack,stksize,option)
- PMOHANDLER pfunc;
- unsigned call_mask;
- char *pstack;
- int stksize,option;
- {
- int result;
- unsigned new_mask;
-
- if (moequip() <= 0) /* Test mouse presence. */
- return MO_ABSENT;
-
- switch (option)
- {
- case MO_INSTALL:
- if (p_user_handler)
- result = MO_ALREADY;
- else
- {
- /* Set up dispatcher. */
- p_user_handler = pfunc;
- isprep(mo_dispatcher,"MOUSEDISPATCHER",&dispat_block,
- pstack,stksize,1);
-
- /* Install interrupt handler */
- /* if necessary. */
- if (b_mocatch)
- {
- /* MOCATCH installed; need not */
- /* install new handler, but */
- /* perhaps augment call mask. */
- new_mask = (call_mask | b_momask);
- if (new_mask == b_momask)
- result = MO_OK; /* No change in call mask. */
- else
- /* Install new call mask. */
- result = moinst(b_mocatch,new_mask);
- }
- else
- /* Install dispatcher directly. */
- result = moinst((void (far *) ()) &dispat_block,
- call_mask);
-
- if (result == MO_OK)
- {
- /* Set up pointer & call mask */
- /* so MOCATCH can call */
- /* dispatcher. */
- b_modispat = &dispat_block;
- b_mohanmask = call_mask;
- }
- else
- p_user_handler = 0;
- }
-
- break;
-
- case MO_REMOVE:
- if (!p_user_handler)
- result = MO_NOT_INSTALLED;
- else
- {
- b_mohanmask = 0;
- b_modispat = NIL;
- p_user_handler = 0;
- result = moinst(b_mocatch,b_momask);
- }
-
- break;
-
- default:
- result = MO_BAD_OPT;
- break;
- }
-
- return result;
- }
-
- /**
- *
- * Name mo_dispatcher -- Invoke user mouse interrupt handler.
- *
- * Description This function calls the user mouse interrupt handler.
- *
- * This function is built as an interrupt service routine
- * (ISR) to be called from the mouse driver via the ISR
- * dispatcher. If MOCATCH is installed, the mouse driver
- * calls MOCATCH directly, then MOCATCH calls this function
- * (via the ISR dispatcher) if the event is among those
- * specified in the call mask.
- *
- **/
-
- static void cdecl mo_dispatcher(pregs,pisrctrl,pmsg)
- ALLREG *pregs;
- ISRCTRL *pisrctrl;
- ISRMSG *pmsg;
- {
- ALLREG regs; /* Declare local copy of registers */
- /* so user handler can't affect *pregs.*/
- const char *p;
-
- p = (const char *) pisrctrl; /* Suppress compiler warning */
- p++; /* that pisrctrl isn't used. */
-
- if (p_user_handler)
- {
- regs = *pregs;
- p_user_handler(®s); /* Call user handler. */
- }
-
- pmsg->exit_style = IEXIT_RETF;
- }