From: 890491g@dragon.acadiau.ca (Don Graves)
Newsgroups: comp.lang.pascal
Subject: mouse unit
Date: 10 Sep 92 18:36:25 GMT
Organization: Acadia University


	Okay, here is the mouse unit I promised everyone who asked
for it.  It is not the complete version, since some things weren't really
needed and/or completed.  Anyway, have fun!


{-----------------------------------------------------------------------------}
Unit MouseGeneral;  (Version 1.0)
ZDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?
3  MICROSOFT MOUSE DRIVER ROUTINES FOR TURBO PASCAL 6.0  3
@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDY
By: Don Graves (don.graves@dragon.acadiau.ca OR 890491g@ace.acadiau.ca)
    Acadia University
    Wolfville, N.S., Canada
    BOP IXO
Completed: August 3, 1992
{-----------------------------------------------------------------------------}
The following is a brief description of the functions, procedures, variables,
and constants available to the user.
These routines were made available for those who want to use the mouse in
their applications but want to avoid the messy details of the Microsoft Mouse
Interrupts.

REMEMBER:  When you include this unit in the USES clause, make sure that you
spell out the whole unit name MouseGeneral, and not just MouseGen.

This is only a first release, so there might be errors in the way the
routines behave.  I don't think there are any problems, but you never know.
If anyone discovers any problems, then maybe I can correct them if I'm
notified.

If you find this unit useful, then I am happy.  This unit is totally free and
I give no guarantees or warrantees etc.  I welcome all comments/criticisms.

-Regards
                                                        Don Graves
{-----------------------------------------------------------------------------}

{---------------------------------}
Interface
{---------------------------------}
Const
    button_left: Byte = 1;    { Button state values.                          }
    button_right: Byte = 2;   {                                               }
    button_middle: Byte = 4;  {                                               }

    mousemoves_mask: Word = 1;     {------------------------------------------}
    leftpress_mask: Word = 2;      { Handler masks - can be used in handler   }
    leftrelease_mask: Word = 4;    { function parameters.                     }
    rightpress_mask: Word = 8;     {                                          }
    rightrelease_mask: Word = 16;  { Combinations can be used:                }
    middlepress_mask: Word = 32;   { e.g. mousemoves_mask + rightpress_mask   }
    middlerelease_mask: Word = 64; {------------------------------------------}
{---------------------------------}
Var
    BUTTONS: Word; { Holds value for number of buttons present reported by    }
                   { initialization (reset) of MS mouse driver.               }

    MOUSE_PRESENT: Boolean; { TRUE if MS mouse driver present.  FALSE if not. }

    MAX_X: Word;  { These four variables hold the coordinates to the window   }
    MAX_Y: Word;  { area that is accessible to the mouse.  MIN_X and MAX_X    }
    MIN_X: Word;  { hold the leftmost and rightmost coordinates, and MIN_Y    }
    MIN_Y: Word;  { and MAX_Y hold the uppermost and lowermost coordinates.   }

    leftmousepressX: Word;    { Coordinates for where the last time the       }
    leftmousepressY: Word;    { cooresponding mouse button was PRESSED (NOT   }
    rightmousepressX: Word;   { DEPRESSED).  These values are updated every   }
    rightmousepressY: Word;   { time the X_Button_Pressed() functions are     }
    middlemousepressX: Word;  { invoked.                                      }
    middlemousepressY: Word;  {

    leftmousedepressX: Word;    { Coordinates for where the last time the     }
    leftmousedepressY: Word;    { cooresponding mouse button was DEPRESSED    }
    rightmousedepressX: Word;   { (NOT PRESSED).  These values are updated    }
    rightmousedepressY: Word;   { every time the X_Button_Depressed()         }
    middlemousedepressX: Word;  { functions are invoked.                      }
    middlemousedepressY: Word;  {

    leftmouseclickX: Word;    { Coordinates for where the last time the       }
    leftmouseclickY: Word;    { cooresponding mouse button was used (NOT      }
    rightmouseclickX: Word;   { PRESSED OR DEPRESSED).  These values are      }
    rightmouseclickY: Word;   { updated every time the X_Button_Clicked()     }
    middlemouseclickX: Word;  { functions are invoked.  Pressing and          }
    middlemouseclickY: Word;  { depressing are not a factor.                  }

    hideleft: Word;    { Coordinates for the window where the mouse is meant  }
    hidetop: Word;     { to be invisible.                                     }
    hideright: Word;   {                                                      }
    hidebottom: Word;  {                                                      }

    Xdisable: Word;  { Coordinate for where the mouse was when it was last    }
    Ydisable: Word;  { disabled.                                              }

    eventX: Word;  { Coordinates for last user interrupt call according to    }
    eventY: Word;  { the default handler.                                     }
        { If you write your own interrupt handler routine, you may            }
        { want to manipulate these four variables within it.                  }
    eventstate: Word; { Button state from last call of default handler.       }
    eventhappened: Boolean; { TRUE if event occurred, FALSE otherwise.        }
{---------------------------------}
Function ResetMouse: Boolean;
    { Resets the mouse driver.  Returns TRUE if mouse driver installed, FALSE }
    { otherwise.  It also initializes all the variables (coordinate, etc.).   }
    { This routine is automatically called when MouseGeneral is included in   }
    { the USES clause.                                                        }

Procedure SetMouseXRange (minx, maxx: Word);
    { Makes it so that the mouse will be restricted to column coordinates X   }
    { where minx <= X <= maxx.                                                }

Procedure SetMouseYRange (miny, maxy: Word);
    { Makes it so that the mouse will be restricted to row coordinates Y      }
    { where miny <= Y <= maxY.                                                }

Procedure SetMouseWindow (left, top, right, bottom: Word);
    { Bounds the mouse cursor to a window by calling SetMouseXRange and      }
    { SetMouseYRange.                                                        }

Procedure ShowMouse;
    { Makes the mouse cursor visible.                                        }

Procedure HideMouse;
    { Makes the mouse cursor invisible.                                      }

Function WhereMouseX: Word;
    { Returns current X coordinate of mouse.                                 }

Function WhereMouseY: Word;
    { Returns current Y coordinate of mouse.                                 }

Function Left_Button_Clicked: Boolean;
    { Returns TRUE if the left button was clicked, and FALSE otherwise.      }

Function Right_Button_Clicked: Boolean;
    { Returns TRUE if the right button was clicked, and FALSE otherwise.     }

Function Middle_Button_Clicked: Boolean;
    { Returns TRUE if the middle button was clicked, and FALSE otherwise.    }

Function Left_Button_Pressed: Boolean;
    { Returns TRUE if the left button was pressed, and FALSE otherwise.      }

Function Right_Button_Pressed: Boolean;
    { Returns TRUE if the right button was pressed, and FALSE otherwise.     }

Function Middle_Button_Pressed: Boolean;
    { Returns TRUE if the middle button was pressed, and FALSE otherwise.    }

Function Left_Button_Depressed: Boolean;
    { Returns TRUE if the left button was depressed, and FALSE otherwise.    }

Function Right_Button_Depressed: Boolean;
    { Returns TRUE if the right button was depressed, and FALSE otherwise.   }

Function Middle_Button_Depressed: Boolean;
    { Returns TRUE if the middle button was depressed, and FALSE otherwise.  }

Procedure PositionMouseCursor (x, y: Word);
    { Positions the mouse on the screen at (x,y).                            }

Procedure SetMousePage (pg: Integer);
    { Sets the mouse display page.                                           }

Function GetMousePage: Integer;
    { Returns the current mouse display page.                                }

Function MouseMoved (fromx, fromy: Word;
                     Var distanceX, distanceY: Integer): Boolean;
    { Returns TRUE if the mouse is not at (fromx, fromy) and returns FALSE   }
    { otherwise.  The distance between WhereMouseX and 'fromx' is returned   }
    { through 'distanceX'.  The distance between WhereMouseY and 'fromy' is  }
    { returned through 'distanceY'.                                          }

Procedure SetDoubleSpeedThreshold (mickeyspersecond: Word);
    { Sets the double-speed threshold of the mouse in mickeys per second.    }
    { The normal and default value is 64.                                    }

Procedure SetMouseSensitivity (hspeed, vspeed, dspeedthres: Word);
    { Procedure to set the sensitivity of the mouse.  'hspeed' is horizontal }
    { speed, 'vspeed' is vertical speed, and 'dspeedthres' is double-speed   }
    { threshold.                                                             }

Procedure GetMouseSensitivity (Var hspeed, vspeed, dspeedthres: Word);
    { Returns through parameters the mouse sensitivity.                      }

Procedure SetMickeyPixelRatio (hmpp, vmpp: Word);
    { Sets the horizontal and vertical mickeys per pixel ratios.             }

Procedure SetSWTextMCursor (backcolor, forecolor: Byte; charac: Char);
    { Changes the cursor and attributes of the mouse cursor.                 }
    {                                                                        }
    { SetSWTextMCursor (RED, YELLOW, 'P') will make a yellow 'P' on top of a }
    { red background.                                                        }
    { SetSWTextMCursor (RED, YELLOW+BLINK, will make the 'P' blink.          }

Procedure SetHWTextMCursor (startscanline, stopscanline: Word);
    { Sets the hardware scanlines for the mouse.  Values are 0..7 for color  }
    { adapters and 0..12 for monochrome.                                     }

Procedure NormalTextMCursor;
    { Restores the normal mouse text cursor.                                 }

Procedure SetGraphicMCursor (hotx, hoty: ShortInt; mousepointerdata: Pointer);
    { Sets the graphics cursor in graphics mode.  'hotx' and 'hoty'          }
    { represent the part of the cursor that is relevant for defining cursor  }
    { location.    (-16 - 16)                                                }
    { 'mousepointerdata' is a pointer to an array of 32 words.  The first 16 }
    { words represent the mouse cursor and the second 16 words represent the }
    { screen mask.  Ex.:                                                     }
    { SetGraphicMCursor (1, 1, @mycursor)                                    }

Procedure SetLargeGraphicMCursor (hotx, hoty: ShortInt; xsize, ysize: Word;
                                  biggraphicmouse: Pointer);
    { Same as above, except you can use large cursors.                       }
    { 'xsize' and 'ysize' represent the rows and cols in the cursor.         }
    { 'biggraphicmouse' is a pointer to a bitmap of screen and cursor maps.  }

Procedure LightPenEmulationOn;
    { Turns on light pen emulation.                                          }

Procedure LightPenEmulationOff;
    { Turns off light pen emulation.                                         }

Procedure DisableMouseDriver;
    { Disables the mouse driver.                                             }

Procedure EnableMouseDriver;
    { Enables the mouse driver and places it where it was diabled.           }

Procedure SoftwareResetMouse;
    { Initializes (does not reset) the mouse driver.                         }

Function GetMouseDriverStorage: Word;
    { Returns the storage requirements for the mouse driver state.           }

Procedure SaveMouseDriverState (driversize: Word; driverstate: Pointer);
    { Saves the mouse driver state.  'driversize' is the size buffer size    }
    { for saving the driver information in bytes.                            }
    { 'driverstate' is a pointer to this buffer.                             }
    { Use GetMouseDriverStorage to determine 'driversize'.                   }

Procedure RestoreMouseDriverState (driversize: Word; driverstate: Pointer);
    { Restores the mouse driver state pointed to by 'driverstate'.           }

Procedure SetMouseAcceleration (accprofile: Byte);
    { Sets the acceleration profile (1-4).                                   }

Procedure SetHideRegion (left, top, right, bottom: Word);
    { Defines the region for the mouse to be invisible.                      }

Procedure SetInterruptHandler (mask: Word; handler: Pointer);
    { Sets up an interrupt handler routine for the mouse.                    }

Procedure SetDefaultHandler (mask: Word);
    { Sets the default handler.                                              }

Function GetLastEvent (Var evx, evy, evstate: Word): Boolean;
    { Returns TRUE if the event handler was invoked and FALSE otherwise.     }
    { It uses the EVENT variables (described above).                         }

Procedure SwapInterruptHandlers (newhandler: Pointer; newmask: Word;
                                 Var oldhandler: Pointer; oldmask: Word);
    { Swaps interrupt handler routines.                                      }
{-----------------------------------------------------------------------------}





------------------------------ UNIT STARTS HERE ------------------------------

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
Unit MouseGeneral;
{ By: Don Graves of Acadia University, Wolfville, N.S., Canada              }
{ Completed: August 3, 1992                                                 }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
Interface
{---------------------------------}
Uses Dos;
{---------------------------------}
Const
    button_left: Byte = 1;
    button_right: Byte = 2;
    button_middle: Byte = 4;
    mousemoves_mask: Word = 1;
    leftpress_mask: Word = 2;
    leftrelease_mask: Word = 4;
    rightpress_mask: Word = 8;
    rightrelease_mask: Word = 16;
    middlepress_mask: Word = 32;
    middlerelease_mask: Word = 64;
{---------------------------------}
Var BUTTONS: Word;
    MOUSE_PRESENT: Boolean;
    MAX_X, MAX_Y, MIN_X, MIN_Y: Word;
    leftmousepressX, leftmousepressY: Word;
    leftmouseclickX, leftmouseclickY: Word;
    leftmousedepressX, leftmousedepressY: Word;
    rightmousepressX, rightmousepressY: Word;
    rightmouseclickX, rightmouseclickY: Word;
    rightmousedepressX, rightmousedepressY: Word;
    middlemousepressX, middlemousepressY: Word;
    middlemouseclickX, middlemouseclickY: Word;
    middlemousedepressX, middlemousedepressY: Word;
    hideleft, hidetop, hideright, hidebottom: Word;
    Xdisable, Ydisable: Word;
    eventX, eventY: Word;
    eventstate: Word;
    eventhappened: Boolean;
{---------------------------------}
Function ResetMouse: Boolean;
Procedure SetMouseXRange (minx, maxx: Word);
Procedure SetMouseYRange (miny, maxy: Word);
Procedure SetMouseWindow (left, top, right, bottom: Word);
Procedure ShowMouse;
Procedure HideMouse;
Function WhereMouseX: Word;
Function WhereMouseY: Word;
Function MouseMoved (fromx, fromy: Word; Var distanceX, distanceY: Integer): Boolean;
Function Left_Button_Clicked: Boolean;
Function Right_Button_Clicked: Boolean;
Function Middle_Button_Clicked: Boolean;
Function Left_Button_Pressed: Boolean;
Function Right_Button_Pressed: Boolean;
Function Middle_Button_Pressed: Boolean;
Function Left_Button_Depressed: Boolean;
Function Right_Button_Depressed: Boolean;
Function Middle_Button_Depressed: Boolean;
Procedure PositionMouseCursor (x, y: Word);
Procedure SetMousePage (pg: Integer);
Function GetMousePage: Integer;
Procedure SetDoubleSpeedThreshold (mickeyspersecond: Word);
Procedure SetMouseSensitivity (hspeed, vspeed, dspeedthres: Word);
Procedure GetMouseSensitivity (Var hspeed, vspeed, dspeedthres: Word);
Procedure SetMickeyPixelRatio (hmpp, vmpp: Word);
Procedure SetSWTextMCursor (backcolor, forecolor: Byte; charac: Char);
Procedure SetHWTextMCursor (startscanline, stopscanline: Word);
Procedure NormalTextMCursor;
Procedure SetGraphicMCursor (hotx, hoty: ShortInt; mousepointerdata: Pointer);
Procedure SetWatchCursor;
Procedure SetNormalArrowCursor;
Procedure SetUpArrowCursor;
Procedure SetLeftArrowCursor;
Procedure SetCheckMarkCursor;
Procedure SetPointingHandCursor;
Procedure SetDiagonalCrossCursor;
Procedure SetRectangularCrossCursor;
Procedure SetHourglassCursor;
Procedure SetNewWatchCursor;
Procedure SetLargeGraphicMCursor (hotx, hoty: ShortInt; xsize, ysize: Word; biggraphicmouse: Pointer);
Procedure LightPenEmulationOn;
Procedure LightPenEmulationOff;
Procedure DisableMouseDriver;
Procedure EnableMouseDriver;
Procedure SoftwareResetMouse;
Function GetMouseDriverStorage: Word;
Procedure SaveMouseDriverState (driversize: Word; driverstate: Pointer);
Procedure RestoreMouseDriverState (driversize: Word; driverstate: Pointer);
Procedure SetMouseAcceleration (accprofile: Byte);
Procedure SetHideRegion (left, top, right, bottom: Word);
Procedure SetInterruptHandler (mask: Word; handler: Pointer);
Procedure SetDefaultHandler (mask: Word);
Function GetLastEvent (Var evx, evy, evstate: Word): Boolean;
Procedure SwapInterruptHandlers (newhandler: Pointer; newmask: Word; Var oldhandler: Pointer; oldmask: Word);
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
Implementation
{---------------------------------}
Var regs: Registers;
    show_hide: Integer;
{---------------------------------}
Procedure SetInterruptHandler (mask: Word; handler: Pointer);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $000C;
        regs.cx := mask;
        regs.es := Seg (handler^);
        regs.dx := Ofs (handler^);
        Intr ($33, regs);
    End;
End;
{---------------------------------}
{$F+} Procedure DefaultHandler; assembler; {$F-}
Asm
    push ds; { save TP mouse driver }
    mov ax, SEG @data;
    mov ds, ax; { ds = TP:ds, not the driver's ds }
    mov eventX, cx; { where in the x region did it occur }
    mov eventY, dx;
    mov eventstate, bx;
    mov eventhappened, 1; { eventHapppened := true }
    pop ds; { restore driver's ds }
    ret;
End;
{---------------------------------}
Procedure SetDefaultHandler (mask: Word);
Begin
    SetInterruptHandler (mask, @DefaultHandler);
End;
{---------------------------------}
Function GetLastEvent (Var evx, evy, evstate: Word): Boolean;
Var gle: Boolean;
Begin
    gle := eventhappened;
    eventhappened := FALSE;
    If (gle) Then
    Begin
        evx := eventX;
        evy := eventY;
        eventstate := evstate;
    End;
    GetLastEvent := gle;
End;
{---------------------------------}
Procedure SwapInterruptHandlers (newhandler: Pointer; newmask: Word; Var oldhandler: Pointer; oldmask: Word);
begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0014;
        regs.cx := newmask;
	    regs.es := Seg (newhandler^);
	    regs.dx := Ofs (newhandler^);
        Intr ($33, regs);
        oldmask := regs.cx;
        oldhandler := Ptr (regs.es, regs.dx);
    End;
End;
{---------------------------------}
Procedure SetHideRegion (left, top, right, bottom: Word);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        hideleft := left;
        hidetop := top;
        hideright := right;
        hidebottom := bottom;
        regs.ax := $0010;
        regs.cx := left;
        regs.dx := top;
        regs.si := right;
        regs.di := bottom;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure SetMouseAcceleration (accprofile: Byte);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $002D;
        regs.bx := accprofile;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Function GetMouseDriverStorage: Word;
Var sz: Word;
Begin
    sz := 0;
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0015;
        Intr ($33, regs);
        sz := regs.bx;
    End;
    GetMouseDriverStorage := sz;
End;
{---------------------------------}
Procedure SaveMouseDriverState (driversize: Word; driverstate: Pointer);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0016;
        regs.bx := driversize;
        regs.es := Seg (driverstate^);
        regs.dx := Ofs (driverstate^);
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure RestoreMouseDriverState (driversize: Word; driverstate: Pointer);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0017;
        regs.bx := driversize;
        regs.es := Seg (driverstate^);
        regs.dx := Ofs (driverstate^);
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure DisableMouseDriver;
Begin
    If (MOUSE_PRESENT) Then
    Begin
        Xdisable := WhereMouseX;
        Ydisable := WhereMouseY;
        regs.ax := $001F;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure EnableMouseDriver;
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0020;
        Intr ($33, regs);
        PositionMouseCursor (Xdisable, Ydisable);
    End;
End;
{---------------------------------}
Procedure SoftwareResetMouse;
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0021;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure LightPenEmulationOn;
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $000D;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure LightPenEmulationOff;
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $000E;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure SetLargeGraphicMCursor (hotx, hoty: ShortInt; xsize, ysize: Word; biggraphicmouse: Pointer);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0012;
        regs.bh := xsize;
        regs.ch := ysize;
        regs.bl := hotx;
        regs.cl := hoty;
        regs.dx := Ofs (biggraphicmouse^);
        regs.es := Seg (biggraphicmouse^);
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure SetGraphicMCursor (hotx, hoty: ShortInt; mousepointerdata: Pointer);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0009;
        regs.bx := hotx;
        regs.cx := hoty;
        regs.dx := Ofs (mousepointerdata^);
        regs.es := Seg (mousepointerdata^);
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure SetHWTextMCursor (startscanline, stopscanline: Word);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $000A;
        regs.bx := 1;
        regs.cx := startscanline;
        regs.dx := stopscanline;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure SetSWTextMCursor (backcolor, forecolor: Byte; charac: Char);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $000A;
        regs.bx := 0;
        regs.cl := 0;
        regs.ch := 0;
        regs.dh := backcolor*16+forecolor;
        regs.dl := Ord (charac);
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure NormalTextMCursor;
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $000A;
        regs.bx := 0;
        regs.cl := $FF;
        regs.ch := $FF;
        regs.dl := $00;
        regs.dh := $77;
        Intr ($33, regs);
     End;
End;
{---------------------------------}
Procedure SetMickeyPixelRatio (hmpp, vmpp: Word);
Begin
    If ((MOUSE_PRESENT) And (hmpp > 0) And (vmpp > 0)) Then
    Begin
        regs.ax := $000F;
        regs.cx := hmpp;
        regs.dx := vmpp;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure SetDoubleSpeedThreshold (mickeyspersecond: Word);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0013;
        regs.dx := mickeyspersecond;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure SetMouseSensitivity (hspeed, vspeed, dspeedthres: Word);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $001A;
        regs.bx := hspeed;
        regs.cx := vspeed;
        regs.dx := dspeedthres;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure GetMouseSensitivity (Var hspeed, vspeed, dspeedthres: Word);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $001B;
        Intr ($33, regs);
        hspeed := regs.bx;
        vspeed := regs.cx;
        dspeedthres := regs.dx;
    End;
End;
{---------------------------------}
Function ResetMouse: Boolean;
Begin
    regs.ax := $0000;
    Intr ($33, regs);
    BUTTONS := regs.bx;
    MOUSE_PRESENT := (regs.ax = $FFFF);
    show_hide := 0; {0 = mouse not displayed, 1 = mouse displayed}
    MIN_X := 0;
    MIN_Y := 0;
    MAX_X := 79*8;
    MAX_Y := 24*8;
    leftmousepressX := 0;       leftmousepressY := 0;
    leftmousedepressX := 0;     leftmousedepressY := 0;
    middlemousepressX := 0;     middlemousepressY := 0;
    middlemousedepressX := 0;   middlemousedepressY := 0;
    rightmousepressX := 0;      rightmousepressY := 0;
    rightmousedepressX := 0;    rightmousedepressY := 0;
    leftmouseclickX := 0;       leftmouseclickY := 0;
    middlemouseclickX := 0;     middlemouseclickY := 0;
    rightmouseclickX := 0;      rightmouseclickY := 0;
    hideleft := 0;              hidetop := 0;
    hideright := 0;             hidebottom := 0;
    Xdisable := 0;              Ydisable := 0;
    eventX := 0;                eventY := 0;
    eventstate := 0;
    eventhappened := FALSE;
    ResetMouse := (regs.ax = $FFFF);
End;
{---------------------------------}
Function MouseMoved (fromx, fromy: Word; Var distanceX, distanceY: Integer): Boolean;
Var mvd: Boolean;
    wx, wy: Integer;
Begin
    mvd := FALSE;
    distanceX := WhereMouseX - fromx;
    distanceY := WhereMouseY - fromy;
    If ((distanceX <> 0) Or (distanceY <> 0)) Then
        mvd := TRUE;
    MouseMoved := mvd;
End;
{---------------------------------}
Function WhereMouseX: Word;
Var wmx: Word;
Begin
    wmx := 0;
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0003;
        Intr ($33, regs);
        wmx := regs.cx;
    End;
    WhereMouseX := wmx;
End;
{---------------------------------}
Function WhereMouseY: Word;
Var wmy: Word;
Begin
    wmy := 0;
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0003;
        Intr ($33, regs);
        wmy := regs.dx;
    End;
    WhereMouseY := wmy;
End;
{---------------------------------}
Function Middle_Button_Clicked: Boolean;
Var mclicked: Boolean;
Begin
    mclicked := FALSE;
    If ((MOUSE_PRESENT) And (BUTTONS = 3)) Then
    Begin
        regs.ax := $0003;
        Intr ($33, regs);
        mclicked := ((regs.bx And 4) = 4);
        middlemouseclickX := regs.cx;
        middlemouseclickY := regs.dx;
    End;
    Middle_Button_Clicked := mclicked;
End;
{---------------------------------}
Function Left_Button_Clicked: Boolean;
Var lclicked: Boolean;
Begin
    lclicked := FALSE;
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0003;
        Intr ($33, regs);
        lclicked := ((regs.bx And 1) = 1);
        leftmouseclickX := regs.cx;
        leftmouseclickY := regs.dx;
    End;
    Left_Button_Clicked := lclicked;
End;
{---------------------------------}
Function Right_Button_Clicked: Boolean;
Var rclicked: Boolean;
Begin
    rclicked := FALSE;
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0003;
        Intr ($33, regs);
        rclicked := ((regs.bx And 2) = 2);
        rightmouseclickX := regs.cx;
        rightmouseclickY := regs.dx;
    End;
    Right_Button_Clicked := rclicked;
End;
{---------------------------------}
Procedure ShowMouse;
Begin
    If ((MOUSE_PRESENT) And (show_hide <> 1)) Then
    Begin
        Repeat
            regs.ax := $0001;
            Intr ($33, regs);
            Inc (show_hide, 1);
        Until (show_hide = 1);
    End;
End;
{---------------------------------}
Procedure HideMouse;
Begin
    If ((MOUSE_PRESENT) And (show_hide <> 0)) Then
    Begin
        Repeat
            regs.ax := $0002;
            Intr ($33, regs);
            Dec (show_hide, 1);
        Until (show_hide = 0);
    End;
End;
{---------------------------------}
Procedure PositionMouseCursor (x, y: Word);
Begin
    If ((MOUSE_PRESENT) And
        (x >= MIN_X) And (x <= MAX_X) AND
        (y >= MIN_Y) And (y <= MAX_Y)) Then
    Begin
        regs.ax := $0004;
        regs.cx := x;
        regs.dx := y;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Procedure SetMousePage (pg: Integer);
Begin
    If ((MOUSE_PRESENT) And (pg >=0)) Then
    Begin
        regs.ax := $001D;
        regs.bx := pg;
        Intr ($33, regs);
    End;
End;
{---------------------------------}
Function GetMousePage: Integer;
Var pg: Integer;
Begin
    pg := 0;
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $001E;
        pg := regs.bx;
        Intr ($33, regs);
    End;
    GetMousePage := pg;
End;
{---------------------------------}
Procedure SetMouseWindow (left, top, right, bottom: Word);
Begin
    If (MOUSE_PRESENT) Then
    Begin
        SetMouseXRange (left, right);
        SetMouseYRange (top, bottom);
        PositionMouseCursor (MIN_X, MIN_Y);
    End;
End;
{---------------------------------}
Procedure SetMouseXRange (minx, maxx: Word);
Begin
    If (MOUSE_PRESENT) Then
        If ((minx < maxx) And (minx >= 0)) Then
        Begin
            regs.ax := $0007;
            regs.cx := minx;
            regs.dx := maxx;
            Intr ($33, regs);
            MIN_X := minx;
            MAX_X := maxx;
        End;
End;
{---------------------------------}
Procedure SetMouseYRange (miny, maxy: Word);
Begin
    If (MOUSE_PRESENT) Then
        If ((miny < maxy) And (miny >= 0)) Then
        Begin
            regs.ax := $0008;
            regs.cx := miny;
            regs.dx := maxy;
            Intr ($33, regs);
            MIN_Y := miny;
            MAX_Y := maxy;
        End;
End;
{---------------------------------}
Function Left_Button_Pressed: Boolean;
Var lpressed: Boolean;
Begin
    lpressed := FALSE;
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0005;
        regs.bx := $0000;
        Intr ($33, regs);
        leftmousepressX := regs.cx;
        leftmousepressY := regs.dx;
        lpressed := ((regs.ax And button_left) = button_left);
    End;
    Left_Button_Pressed := lpressed;
End;
{---------------------------------}
Function Right_Button_Pressed: Boolean;
Var rpressed: Boolean;
Begin
    rpressed := FALSE;
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0005;
        regs.bx := $0001;
        Intr ($33, regs);
        rightmousepressX := regs.cx;
        rightmousepressY := regs.dx;
        rpressed := ((regs.ax And button_right) = button_right);
    End;
    Right_Button_Pressed := rpressed;
End;
{---------------------------------}
Function Middle_Button_Pressed: Boolean;
Var mpressed: Boolean;
Begin
    mpressed := FALSE;
    If ((MOUSE_PRESENT) And (BUTTONS = 3)) Then
    Begin
        regs.ax := $0005;
        regs.bx := $0002;
        Intr ($33, regs);
        middlemousepressX := regs.cx;
        middlemousepressY := regs.dx;
        mpressed := ((regs.ax And button_middle) = button_middle);
    End;
    Middle_Button_Pressed := mpressed;
End;
{---------------------------------}
Function Left_Button_Depressed: Boolean;
Var ldpressed: Boolean;
Begin
    ldpressed := FALSE;
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0006;
        regs.bx := $0000;
        Intr ($33, regs);
        leftmousedepressX := regs.cx;
        leftmousedepressY := regs.dx;
        ldpressed := Not ((regs.ax And button_left) = button_left);
    End;
    Left_Button_Depressed := ldpressed;
End;
{---------------------------------}
Function Right_Button_Depressed: Boolean;
Var rdpressed: Boolean;
Begin
    rdpressed := FALSE;
    If (MOUSE_PRESENT) Then
    Begin
        regs.ax := $0006;
        regs.bx := $0001;
        Intr ($33, regs);
        rightmousedepressX := regs.cx;
        rightmousedepressY := regs.dx;
        rdpressed := Not ((regs.ax And button_right) = button_right);
    End;
    Right_Button_Depressed := rdpressed;
End;
{---------------------------------}
Function Middle_Button_Depressed: Boolean;
Var mdpressed: Boolean;
Begin
    mdpressed := FALSE;
    If ((MOUSE_PRESENT) And (BUTTONS = 3)) Then
    Begin
        regs.ax := $0006;
        regs.bx := $0002;
        Intr ($33, regs);
        middlemousedepressX := regs.cx;
        middlemousedepressY := regs.dx;
        mdpressed := Not ((regs.ax And button_middle) = button_middle);
    End;
    Middle_Button_Depressed := mdpressed;
End;
{---------------------------------}
{ Procedure HerculesCheck; }
{ NOT IMPLEMENTED PROPERLY - maybe someone can do this for me }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
Begin
{    HerculesCheck;}
    MOUSE_PRESENT := ResetMouse;
    HideMouse;
    PositionMouseCursor (0, 0);
End.
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
------------------------------ UNIT ENDS HERE --------------------------------
-- 
--
Don Graves
Acadia University, Wolfville, N.S. Canada
don.graves@dragon.acadiau.ca || 890491g@ace.acadiau.ca
Newsgroups: comp.lang.apl