home *** CD-ROM | disk | FTP | other *** search
- /* MOUSE - Module of mouse functions. To use it, include the MOUSE.H file
- * in your program. The following functions are public:
- *
- * MouseInit - Initialize mouse
- * GetMouseEvent - Get information about most recent mouse event
- * SetPtrVis - Set visibility of pointer to HIDE or SHOW
- * SetPtrPos - Set position of pointer
- * SetPtrShape - Set shape of pointer in graphics modes, or
- * character and color in text modes
- * GetPtrPos - Get pointer position and button status
- *
- * The following structure is defined:
- *
- * EVENT - Defines x, y, and mouse status of a mouse event
- */
-
- #include <graph.h>
- #include "mouse.h"
-
- /* Internal information used by various mouse functions. */
- struct MOUINFO
- {
- int fExist, fInit, fGraph;
- short xVirtual, yVirtual;
- short xActual, yActual;
- short xLast, yLast;
- unsigned fsBtnLast, cBtn;
- } static mi =
- {
- 1, 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0
- };
-
- /* MouseInit - Initialize mouse and turns on mouse pointer. Initializes
- * all internal variables used by other mouse functions. This function
- * should be called whenever a new video mode is set, since internal
- * variables are mode-dependent.
- *
- * Params: none
- *
- * Return: 0 if no mouse available, otherwise number of buttons available
- */
- int MouseInit()
- {
- struct videoconfig vc;
- char _far *pMode = (char _far *)0x00000449; /* Address for mode */
-
- /* Get video configuration. */
- _getvideoconfig( &vc );
-
- /* Handle special case of Hercules graphics. To use mouse with video
- * page 0. assume mode 6. To use mouse with page 1, assume mode 5.
- * Since the mouse functions couldn't easily detect and adjust for
- * page changes anyway, this code assumes page 0. Note also that the
- * mouse for Hercules graphics must be set in text mono mode.
- */
- if( vc.mode == _HERCMONO )
- {
- _setvideomode( _TEXTMONO );
- *pMode = 6;
- }
-
- mi.fInit = 1;
- _asm
- {
- sub ax, ax ; Mouse function 0, reset mouse
- int 33h
- mov mi.fExist, ax ; Set existence flag for future calls
- or ax, ax ; If AX = 0, there is no mouse
- jnz exist
- ret ; so quit
- exist:
- mov mi.cBtn, bx ; Save number of mouse buttons for return
- }
-
- /* Set graphics flag. */
- if( vc.numxpixels )
- {
- mi.fGraph = 1;
- mi.yActual = vc.numypixels - 1;
- mi.xActual = vc.numxpixels - 1;
- }
- else
- mi.fGraph = 0;
-
- /* The mouse works on a virtual screen of 640 x pixels by (8 * textrows)
- * vertical pixels. By default, it assumes 640 x 200 for 25-line mode.
- * You must call function 8 to adjust for other screen sizes.
- */
- mi.xVirtual = 639;
- if( mi.fGraph )
- mi.yVirtual = vc.numypixels - 1;
- else
- mi.yVirtual = (vc.numtextrows << 3) - 1;
-
- /* Reset Hercules graphics mode and reset the height. */
- if( vc.mode == _HERCMONO )
- {
- _setvideomode( _HERCMONO );
- mi.xVirtual = 719;
- }
-
- _asm
- {
- mov ax, 8 ; Set minimum and maximum vertical
- sub cx, cx ; Minimum is 0
- mov dx, mi.yVirtual ; Maximum is 8 * rows (or rows SHL 3)
- int 33h ; Adjust for 25, 30, 43, 50, or 60 lines
-
- mov ax, 1 ; Turn on mouse pointer
- int 33h
-
- mov ax, 3 ; Get initial position and button status
- int 33h
- mov mi.xLast, cx ; Save internally
- mov mi.yLast, dx
- mov mi.fsBtnLast, bx
- }
- return mi.cBtn; /* Return the number of mouse buttons */
- }
-
- /* GetMouseEvent - Check to see if there has been a mouse event. If event
- * occurred, update event structure.
- *
- * Params: pEvent - Pointer to event structure
- *
- * Return: 1 if event, 0 if no event
- */
- int GetMouseEvent( EVENT _far *pEvent )
- {
- int rtn;
-
- /* Make sure that mouse is initialized and exists. */
- if( !mi.fInit )
- MouseInit();
- if( !mi.fExist )
- return 0;
-
- _asm
- {
- mov ax, 3 ; Get Mouse position and button status
- int 33h
- sub ax, ax ; Assume no event
-
- cmp cx, mi.xLast ; Has column changed?
- jne event
- cmp dx, mi.yLast ; Has row changed?
- jne event
- cmp bx, mi.fsBtnLast ; Has button changed?
- je noevent
- event:
- mov ax, 1 ; If something changed, event occurred
- mov mi.xLast, cx ; Update internal variables
- mov mi.yLast, dx
- mov mi.fsBtnLast, bx
- noevent:
- mov rtn, ax ; Set return value
- }
-
- /* If event, put adjust values in structure. */
- if( rtn )
- {
- /* If graphics mode, adjust virtual mouse position to actual
- * screen coordinates.
- */
- if( mi.fGraph )
- {
- pEvent->x = ((long)mi.xLast * mi.xActual) / mi.xVirtual;
- pEvent->y = ((long)mi.yLast * mi.yActual) / mi.yVirtual;
- }
- /* If text mode, adjust virtual mouse position to 1-based
- * row/column.
- */
- else
- {
- pEvent->x = (mi.xLast >> 3) + 1;
- pEvent->y = (mi.yLast >> 3) + 1;
- }
- pEvent->fsBtn = mi.fsBtnLast;
- }
- return rtn;
- }
-
- /* GetPtrPos - Get mouse pointer position and button status regardless of
- * whether there was an event.
- *
- * Params: pEvent - Pointer to event structure
- *
- * Return: 0 if no mouse, otherwise 1
- */
- int GetPtrPos( EVENT _far *pEvent )
- {
- /* Make sure that mouse is initialized and exists. */
- if( !mi.fInit )
- MouseInit();
- if( !mi.fExist )
- return 0;
-
- _asm
- {
- mov ax, 3 ; Get Mouse position and button status
- int 33h
- les di, pEvent
- mov es:[di].x, cx
- mov es:[di].y, dx
- mov es:[di].fsBtn, bx
- }
-
- /* If graphics mode, adjust virtual mouse position to actual
- * screen coordinates.
- */
- if( mi.fGraph )
- {
- pEvent->x = ((long)pEvent->x * mi.xActual) / mi.xVirtual;
- pEvent->y = ((long)pEvent->y * mi.yActual) / mi.yVirtual;
- }
- /* If text mode, adjust virtual mouse position to 1-based
- * row/column.
- */
- else
- {
- pEvent->x >>= 3;
- pEvent->y >>= 3;
- pEvent->x++;
- pEvent->y++;
- }
- return 1;
- }
-
- /* SetPtrVis - Set pointer visibility.
- *
- * Params: state - SHOW or HIDE
- *
- * Return: 0 if no mouse, otherwise 1
- */
- int SetPtrVis( enum PTRVIS pv )
- {
- /* Make sure that mouse is initialized and exists. */
- if( !mi.fInit )
- MouseInit();
- if( !mi.fExist )
- return 0;
-
- _asm
- {
- mov ax, pv ; Show or hide mouse pointer
- int 33h
- }
- }
-
- /* SetPtrPos - Set mouse pointer position.
- *
- * Params: x - column position in text modes, actual x coordinate in graphics
- * y - row position in text modes, actual y coordinate in graphics
- *
- * Return: 0 if no mouse, otherwise 1
- */
- int SetPtrPos( short x, short y )
- {
- /* Make sure that mouse is initialized and exists. */
- if( !mi.fInit )
- MouseInit();
- if( !mi.fExist )
- return 0;
-
- /* If graphics, adjust actual coordinates to virtual coordinates. */
- if( mi.fGraph )
- {
- x = ((long)x * mi.xActual) / mi.xVirtual;
- y = ((long)y * mi.yActual) / mi.yVirtual;
- }
- /* If text, adjust row/column to 0-based virtual coordinates. */
- else
- {
- x--;
- y--;
- x <<= 3;
- y <<= 3;
- }
-
- _asm
- {
- mov ax, 4 ; Set mouse position
- mov cx, x
- mov dx, y
- int 33h
- }
- return 1;
- }
-
- /* SetPtrShape - Set mouse pointer shape.
- *
- * Params: x - column position in text modes, actual x coordinate in graphics
- * y - row position in text modes, actual y coordinate in graphics
- *
- * Return: 0 if no mouse, otherwise 1
- */
- int SetPtrShape( PTRSHAPE _far *ps )
- {
- /* Make sure that mouse is initialized and exists. */
- if( !mi.fInit )
- MouseInit();
- if( !mi.fExist )
- return 0;
-
- /* If graphics, use pointer shape bitmask array. */
- if( mi.fGraph )
- {
- _asm
- {
- les di, ps
- mov bx, es:[di].g.xHot ; Load hot spot offsets
- mov cx, es:[di].g.yHot
- mov dx, di
- add dx, 4
-
- mov ax, 9 ; Set graphics pointer
- int 33h
- }
- }
- /* If text, use pointer color/character values. */
- else
- {
- _asm
- {
- les di, ps
- mov bx, 0 ; Use software cursor
- mov cl, es:[di].t.chScreen
- mov ch, es:[di].t.atScreen
- mov dl, es:[di].t.chCursor
- mov dh, es:[di].t.atCursor
-
- mov ax, 10 ; Set text pointer
- int 33h
- }
- }
- return 1;
- }
-