home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Iteraction library - windows. *
- * *
- * Written by Gershon Elber, Oct. 1990 *
- *******************************************************************************
- * W A R N I N G : This module assumes mouse driver was installed using *
- * one of the following program: mouse.com or mouse.sys. *
- * *
- * This module can be compiled in any model (tiny..huge) *
- * *
- * The following routines are available: *
- * 1. MouseSetResolution(int Resolution) - set mouse rosolution. *
- * 2. MouseDetect() - returns TRUE if mouse detected in system. *
- * 3. MouseInit() - must be called first before any other call. *
- * 4. MouseShowCorsur() - show mouse cursor. *
- * 5. MouseHideCorsur() - hide mouse cursor. *
- * 6. MouseSetPosition() - set mouse XY position. *
- * 7. MouseQueryBuffer() - returns event ring buffer status. *
- * 8. MouseQueryDataBuffer() - returns event ring buffer data status. *
- * 9. MouseGetBuffer() - returns next event from ring buffer. *
- * 10.MouseFlushBuffer() - clear all data currently in buffer. *
- * 11.MouseClose() - must be called last before application program dies. *
- * *
- * Note that as the mouse driver is used asyncronically (i.e. interrupts) *
- * fail to call MouseInit() at the begining or even worse, call *
- * MouseClose() in the end is an invitation for total system disaster! *
- * *
- * Written by: Gershon Elber IBM PC Ver 0.1, Sep. 1988 *
- * *
- * Ver 0.2 - No interrupt vector is used (MouseHandler is called directly). *
- ******************************************************************************/
-
- /* #define DEBUG * Uncomment it for simple test routine. */
-
- #include <dos.h>
- #include <stdio.h>
- #include "MouseDrv.h"
-
- #ifdef DEBUG
- #include <conio.h>
- #endif DEBUG
-
- #define ABS(x) ((x) > 0 ? (x) : (-(x)))
-
- /* Two external integers defined Mouse Range (start from 0): */
- int MSMouseXmax = 1000,
- MSMouseYmax = 1000;
-
- static int BufferHead, BufferTail, BufferFull, /* Implement ring buffer. */
- BufferOverRun, /* Over run error in mouse buffer. */
- MouseBuffer[BUFFER_SIZE][2], /* Mouse event to save. */
- WasMouseSetUp = FALSE, /* TRUE - mouse successfully installed. */
- SkipMouseEvents = 1; /* Number of move events to skip + 1. */
- static struct SREGS SRegs;
-
- static void MouseSysCall(int Func, int *m2, int *m3, int *m4);
-
- /**************************************************************************
- * Static routine that is used to save DS register, so it can be restore *
- * when the Mouse Handler is invoked. This routine is used only to *
- * allocate space in the code segment for one integer (DS), and is never *
- * been called. If you have better solution how to restore DS let me know! *
- **************************************************************************/
- static void far SaveDSOnThisRoutine(void)
- {
- SRegs.ds = _DS; /* Looks like something useful - its NOT! */
- }
-
- /**************************************************************************
- * Set resolution for mouse. *
- **************************************************************************/
- void MouseSetResolution(int Resolution)
- {
- MSMouseXmax = MSMouseYmax = Resolution;
- }
-
- /**************************************************************************
- * Mouse detect routine. Does three step test: *
- * 1. Test if there is none NULL vector in vector interrupt 0x33 which *
- * should hold the mouse driver. *
- * 2. Test if that pointer is pointing on IRET instruction or not. *
- * 3. Test if the mouse is connected by calling to the mouse driver - *
- * sys call 0x00. *
- **************************************************************************/
- int MouseDetect(void)
- {
- unsigned char far *Ptr;
- union REGS Regs;
-
- /* Look if anything is installed in the mouse interrupt vector: */
- if (((Ptr = (unsigned char far *) getvect(0x33)) == NULL) ||
- (*Ptr == 0xcf /* IRET */)) return FALSE;
-
- Regs.x.ax = 0; /* Select reset and test function. */
- /* interrupt 51 decimal is used by mouse device driver itself: */
- int86x(0x33, &Regs, &Regs, &SRegs);
-
- return (Regs.x.ax);
- }
-
- /**************************************************************************
- * This is the mouse handler itself: called from mouse driver on events. *
- * The x, y coordinates are saved as two integers in the buffer as follows:*
- * X is positive if Left Button is pressed, Negative otherwise. *
- * Y is positive if Right Button is pressed, Negative otherwise. *
- * Note 1 is added to X, Y to make them none zero... *
- * Also note DS must be restore before data (event buffer) is accessed. *
- **************************************************************************/
- static void far MouseHandler(void)
- {
- static int Skip = 0;
- int far *RestoreDS = (int far *) SaveDSOnThisRoutine;
- int Buttons = _BX, X = _CX, Y = _DX, SaveDS = _DS;
-
- _DS = *RestoreDS;
-
- if (Skip++ < SkipMouseEvents && !Buttons) return;
- Skip = 0;
-
- if (BufferFull)
- BufferOverRun = TRUE; /* Buffer overflow. */
- else {
- if (Buttons > 0x03) Buttons = 0x03;
- MouseBuffer[BufferHead][0] = (Buttons & 0x01 ? X+1 : -X-1);
- MouseBuffer[BufferHead++][1] = (Buttons & 0x02 ? Y+1 : -Y-1);
- if (BufferHead == BUFFER_SIZE) BufferHead = 0;
- if (BufferHead == BufferTail) BufferFull = TRUE;
- }
- _DS = SaveDS;
- }
-
- /**************************************************************************
- * See all description on all functions available (0-16, 19) on page 54 in *
- * Microsoft Mouse manual. *
- **************************************************************************/
- static void MouseSysCall(int Func, int *m2, int *m3, int *m4)
- {
- union REGS Regs;
-
- Regs.x.ax = Func; /* Select the requested function. */
- Regs.x.bx = *m2;
- Regs.x.cx = *m3;
- Regs.x.dx = *m4;
-
- /* interrupt 51 decimal is used by mouse device driver itself: */
- int86x(0x33, &Regs, &Regs, &SRegs);
-
- *m2 = Regs.x.bx;
- *m3 = Regs.x.cx;
- *m4 = Regs.x.dx;
- }
-
- /**************************************************************************
- * Mouse Initialization: return NULL if succesful, else error msg string. *
- **************************************************************************/
- char *MouseInit(int Sensitivity)
- {
- int far *SaveDS;
- int m2, m3, m4;
-
- if (WasMouseSetUp)
- return "MouseInit: Mouse already initialized, ignored.";
- if (MSMouseXmax == 0 || MSMouseYmax == 0)
- return "MouseInit: Mouse range was not initialized by graphic driver.";
-
- SkipMouseEvents = 0; /* Takes too much time to redraw cursor... */
-
- SRegs.ds = _DS; /* In case the communication with the driver needs that. */
- SaveDS = (int far *) SaveDSOnThisRoutine;
- *SaveDS = _DS;
-
- BufferHead = BufferTail = 0; /* Reset the Buffer pointers. */
- BufferFull = BufferOverRun = FALSE;
-
- MouseSysCall(0, &m2, &m3, &m4); /* Install Mouse. */
-
- m3 = 0;
- m4 = MSMouseXmax;
- MouseSysCall(7, &m2, &m3, &m4); /* Set Column Range. */
- m3 = 0;
- m4 = MSMouseYmax;
- MouseSysCall(8, &m2, &m3, &m4); /* Set Row Range. */
- m3 = Sensitivity;
- m4 = Sensitivity;
- MouseSysCall(15, &m2, &m3, &m4); /* Set Mickeys Per 8 pixels. */
-
- m3 = 0x2b;/* Set bits 0, 1, 3, 5 - intrpt on mouse move & button pressed.*/
- m4 = FP_OFF(MouseHandler);
- SRegs.es = FP_SEG(MouseHandler);
- MouseSysCall(12, &m2, &m3, &m4); /* Link the MouseHandler() routine. */
-
- WasMouseSetUp = TRUE;
-
- return NULL;
- }
-
- /**************************************************************************
- * Mouse Closing: *
- **************************************************************************/
- void MouseClose(void)
- {
- int m2, m3, m4;
-
- if (!WasMouseSetUp) return; /* Install mouse first! */
-
- m3 = 0x00; /* No interrupts any more... */
- MouseSysCall(12, &m2, &m3, &m4);
-
- WasMouseSetUp = FALSE;
- }
-
- /**************************************************************************
- * Routine returns TRUE if buffer is not empty. *
- **************************************************************************/
- int MouseQueryBuffer(void)
- {
- return (BufferFull || BufferHead != BufferTail);
- }
-
- /**************************************************************************
- * Routine to return Mouse buffer status: *
- * Returns TRUE if buffer is not empty. In addition sets X, Y, Buttons to *
- * the end of buffer without modifying the buffer, and set OverRunError. *
- **************************************************************************/
- int MouseQueryDataBuffer(int *X, int *Y, int *Buttons, int *OverRunError)
- {
- if (BufferFull || BufferHead != BufferTail) {
- *X = ABS(MouseBuffer[BufferTail][0]) - 1;
- *Y = ABS(MouseBuffer[BufferTail][1]) - 1;
- *Buttons = (MouseBuffer[BufferTail][0] > 0 ? 0x01 : 0x00) +
- (MouseBuffer[BufferTail][1] > 0 ? 0x02 : 0x00);
- *OverRunError = BufferOverRun;
- return TRUE;
- }
- else
- return FALSE;
- }
-
- /**************************************************************************
- * Routine to get one event from buffer. waits for one if buffer empty. *
- * Returns OverRun status - TRUE if over run occurs. In addition sets *
- * X, Y, Buttons to the end of buffer, and increment. *
- **************************************************************************/
- int MouseGetBuffer(int *X, int *Y, int *Buttons)
- {
- /* Wait for event if buffer is empty: */
- while (!(BufferFull || BufferHead != BufferTail));
-
- *X = ABS(MouseBuffer[BufferTail][0]) - 1;
- *Y = ABS(MouseBuffer[BufferTail][1]) - 1;
- *Buttons = (MouseBuffer[BufferTail][0] > 0 ? 0x01 : 0x00) +
- (MouseBuffer[BufferTail][1] > 0 ? 0x02 : 0x00);
-
- disable(); /* No interrupts now! */
- if (BufferHead == BufferTail) BufferFull = FALSE;
- if (++BufferTail == BUFFER_SIZE) BufferTail = 0;
- enable(); /* interrupts o.k. now. */
-
- return BufferOverRun;
- }
-
- /**************************************************************************
- * Routine to flush and clear all the mouse event buffer. *
- **************************************************************************/
- void MouseFlushBuffer(void)
- {
- disable(); /* No interrupts now! */
- BufferHead = BufferTail;
- BufferFull = BufferOverRun = FALSE;
- enable(); /* interrupts o.k. now. */
- }
-
- /**************************************************************************
- * Mouse Show Cursor: *
- **************************************************************************/
- void MouseShowCursor(void)
- {
- int m2, x, y;
-
- MouseSysCall(1, &m2, &x, &y); /* Show cursor. */
- }
-
- /**************************************************************************
- * Mouse Hide Cursor: *
- **************************************************************************/
- void MouseHideCursor(void)
- {
- int m2, x, y;
-
- MouseSysCall(2, &m2, &x, &y); /* Hide cursor. */
- }
-
- /**************************************************************************
- * Mouse Set Position: *
- **************************************************************************/
- void MouseSetPosition(int X, int Y)
- {
- int dummy;
-
- MouseSysCall(4, &dummy, &X, &Y); /* Set position. */
- }
-
- #ifdef DEBUG
-
- /**************************************************************************
- * Routine to make some sound with given Frequency, Time milliseconds: *
- **************************************************************************/
- void GGTone(int Frequency, int Duration)
- {
- sound(Frequency);
- delay(Duration);
- nosound();
- }
-
- /**************************************************************************
- * Exit routine. *
- **************************************************************************/
- void MyExit(int ErrCode)
- {
- exit(ErrCode);
- }
-
- /**************************************************************************
- * Simple test routine: *
- **************************************************************************/
- void main(void)
- {
- int X, Y, Buttons;
-
- if (!MouseDetect()) {
- fprintf(stderr, "No mouse was detected, can'nt continue\n");
- MyExit(1);
- }
-
- MSMouseXmax = 1000;
- MSMouseYmax = 1000;
-
- clrscr(); /* Clear screen. */
- MouseInit(10); /* Install Mouse. */
- MouseShowCursor();
-
- gotoxy (2, 10);
- printf("Press any button, or move mouse to get events. Press both buttons to exit.");
-
- do {
- while (!kbhit() && !MouseQueryBuffer());
- if (kbhit()) break;
-
- if (MouseGetBuffer (&X, &Y, &Buttons)) {
- gotoxy(33, 15);
- printf("Over Run Error");
- MouseFlushBuffer();
- sleep(1);
- gotoxy(33, 15);
- printf(" ");
- }
-
- gotoxy(20, 5);
- printf("Head = %3d, Tail = %3d, Full = %3d\n",
- BufferHead, BufferTail, BufferFull);
-
- gotoxy(16, 1);
- if ((Buttons & 0x01) != 0)
- printf(" Left ");
- else if ((Buttons & 0x02) != 0)
- printf("Right ");
- else
- printf(" No ");
- printf("Button was pushed at X=%-3d Y=%-3d", X, Y);
- }
- while ((Buttons & 0x03) != 0x03); /* Both buttons were pushed. */
-
- MouseHideCursor();
- MouseClose();
- clrscr(); /* Clear screen. */
- }
-
- #endif DEBUG
-