[comp.lang.pascal] Mouse unit

wct@po.CWRU.Edu (William C. Thompson) (04/17/91)

Here's a long awaited mouse unit...

UNIT Mouse;
{ Mouse unit for Turbo Pascal.
  The comments in this unit were basically copied directly
  from the Advanced MS Dos Programing book, the section on
  the Microsoft Mouse Driver, which was the source of all
  the mouse interrupt functions and their parameters.
}


INTERFACE

USES
  Dos;

CONST
  LeftButton = 1;
  RightButton = 2;
  CenterButton = 4;
  AnyButton = 7;

PROCEDURE InitMouse(VAR Buttons : word; VAR Err : boolean);
{ Initializes the mouse driver.
  Call:    nothing
  Returns: Buttons = number of mouse buttons
	   Err     = false if mouse support is available, true otherwise
  Note:    * After a call to this function the driver is initialized to the
	     following state:
	     - Mouse pointer at screen center and hidden.
	     - Display page is set to zero.
	     - Mouse pointer shape set to default arrow shape in graphics modes,
	       or reverse block in text modes.
	     - User mouse event handlers are disabled.
	     - Light pen emulation enabled.
	     - Mouse sensitivity set to default vales (see SetMouseSense)
	     - Pointer limits set to entire screen.
}
PROCEDURE ShowPointer;
{ Displays the mouse pointer, and cancels any pointer exclusion area.
  Call:    nothing
  Returns: nothing
  Note:    * A counter is maintained which is decremented by HidePointer and is
	     incremented (if nonzero) by this function.  The mouse pointer is
	     displayed any time the counter is zero.  The counter is set to -1
	     when the mouse driver is reset.
}
PROCEDURE HidePointer;
{ Removes the mouse pointer from the screen, but continues to track the
  position of the mouse.
  Call:    nothing
  Returns: nothing
  Note:    * see ShowPointer
}
FUNCTION ButtonPressed(Mask : word) : boolean;
{ Returns a true value if the specified button(s) is pressed.
  Call:    Mask = bit mask of desired button(s)
		  bit(s)  Significance(if set)
		  0       left button
		  1       right button
		  2       center button
		  3-15    reserved(0)
  Returns: True is button is pressed, false otherwise.
  Note:    * The constants LeftButton, RightButton, CenterButton, and
	     AnyButton can be used for the bit masking.  They equal 1, 2,
	     4, and 7 respectivly.
}
PROCEDURE GetMousePosition(VAR Buttons, Horiz, Vert : word);
{ Returns the current mouse button status and pointer position.
  Call:    nothing
  Returns: Buttons = mouse button status
	   Horiz   = horizontal (X) coordinate
	   Vert    = vertical (Y) coordinate
  Note:    * Coordinates are in pixels regardless of the current display mode.
	     Position (0,0) is the upper left corner of the screen.
}

FUNCTION MouseIn(x1,y1,x2,y2: word):boolean;
{ Returns true if mouse is within rectangle with upper-left
  corner (x1,y1) and lower-right corner (x2,y2).
}

PROCEDURE SetPointerPosition(Horiz, Vert : word);
{ Set the position of the pointer.  The pointer is displayed in the new
  position unless it has been hidden using HidePointer or it is an exclusion
  area defined by SetPointerExcl.
  Call:    Horiz = horizontal (X) coordinate
	   Vert  = vertical (Y) coordinate
  Returns: nothing
  Notes:   * Coordinates are in pixels regardless of the current display mode.
	     Position (0,0) is the upper left corner of the screen.
	   * The position is adjusted if necessary to lie within the pointer
	     limits set by SetLimits.
}
PROCEDURE GetPressInfo(Button : word;
		       VAR Stat, Count, Horiz, Vert : word);
{ Returns the current status of all mouse buttons, and the number of presses
  and position of the last press for a specifed mouse button since the last
  call to this procedure for that button.  The press counter for the button
  is reset to zero.
  Call:    Button = button identifier
		    0 = left button
		    1 = right button
		    2 = center button
  Returns: Stat   = button status
		    bit(s)  Significance(if set)
		    0       left button is down
		    1       right button is down
		    2       center button is down
		    3-15    reserved(0)
	   Count  = button press counter
	   Horiz  = horizontal (X) coordinate of last button press
	   Vert   = vertical (Y) coordinate of last button press
}
PROCEDURE GetReleaseInfo(Button : word;
			 VAR Stat, Count, Horiz, Vert : word);
{ Returns the current status of all mouse buttons, and the number of releases
  and position of the last release for a specifed mouse button since the last
  call to this procedure for that button.  The release counter for the button
  is reset to zero.
  Call:    Button = button identifier
		    0 = left button
		    1 = right button
		    2 = center button
  Returns: Stat   = button status
		    bit(s)  Significance(if set)
		    0       left button is down
		    1       right button is down
		    2       center button is down
		    3-15    reserved(0)
	   Count  = button release counter
	   Horiz  = horizontal (X) coordinate of last button release
	   Vert   = vertical (Y) coordinate of last button release
}
PROCEDURE SetLimits(HorMin, HorMax, VerMin, VerMax : word);
{ Limits the mouse pointer to stay within a certian area.
  Call:    HorMin = Minimum horizontal (X) coordinate
	   HorMax = Maximum horizontal (X) coordinate
	   VerMin = Minimum vertical (Y) coordinate
	   VerMax = Maximum vertical (Y) coordinate
  Returns: nothing
  Note:    * If both HorMin and HorMax are zero then then the previous
	     horizontal limits remain unchanged; the same is true for
	     VerMin and VerMax.
}
PROCEDURE SetPointerShape(Horiz, Vert : word; Buffer : pointer);
{ Defines the shape, color, and hot spot of the pointer in graphics modes.
  Call:    Horiz  = hot spot offset from the left
	   Vert   = hot spot offset from the top
	   Buffer = pointer to mouse pointer image buffer
  Returns: nothing
  Note:    * The pointer image buffer is 64 bytes long.  The first 32 bytes
	     contain a bit mask which is ANDed with the screen image, and the
	     remaining 32 bytes are then XORed with the screen image.
	   * The hot spot is relative to the upper left corner of the pointer
	     image, and each offset must be in the range -16 to 16.  In display
	     modes 4 and 5, the horizontal offset must be an even number.
}
PROCEDURE SetTextPointer(PtrTyp, AND_Str, XOR_End : word);
{ Defines the shape and attributes of the mouse pointer in text modes.
  Call:    PtrTyp  = pointer type
		     0 = software cursor
		     1 = hardware cursor
	   AND_Str = AND mask value (if PtrTyp = 0) or starting line for
		     cursor (if PtrTyp = 1)
	   XOR_End = XOR mask value (if PtrTyp = 0) or ending line for
		     cursor (if PtrTyp = 1)
  Returns: nothing
  Notes:   * If the software text cursor is selected, the masks in AND_Str and
	     XOR_End are mapped as follows:
	     Bit(s)   Significance
	     0-7      character code
	     8-10     foreground color
	     11       intensity
	     12-14    background color
	     15       blink
	     For Example, the following call would yeild a software cursor
	     that inverts the foreground and background colors:
	     SetTextPointer(0, $77FF, $7700);
	   * When the hardware text cursor is selected, the values in AND_Str
	     and XOR_End are the starting and ending lines for the blinking
	     cursor generated by the video adapter.  The maximum scan line
	     depends on the type of adapter and the current display mode.
}
PROCEDURE GetMotionCount(VAR Horiz, Vert : word);
{ Returns the net mouse displacement since the last call to this procedure.
  The returned value is in mickeys; a positive number indicates travel to the
  right or downwards, a negative number indicates travel to the left or
  upwards.  One mickey represents approximately 1/200 of an inch of mouse
  movement.
  Call:    nothing
  Returns: Horiz = horizontal (X) mickey count
	   Vert  = vertical (Y) mickey count
}
PROCEDURE SetEventHandler(EventMask : word; Handler : pointer);
{ Sets the address and event mask for an application program's mouse event
  handler.  The handler is called by the mouse drvier whenever the specifed
  mouse events occur.
  Call:    EventMask = event mask
		       Bit(s)  Significance(if set)
		       0       mouse movement
		       1       left button pressed
		       2       left button released
		       3       right button pressed
		       4       right button released
		       5       center button pressed
		       6       center button released
		       7-15    reserved(0)
	   Handler   = Pointer to the handler procedure
  Returns: nothing
  Notes:   * The user-defined handler is entered from the mouse driver by a
	     far call with the registers set up as follows:
	     AX       mouse event flags (see event mask)
	     BX       button state
		      Bit(s)  Significance(if set)
		      0       left button is down
		      1       right button is down
		      2       center button is down
		      3-15    reserved(0)
	     CX       horizontal (X) pointer coordinate
	     DX       vertical (Y) pointer coordinate
	     SI       last raw vertical mickey count
	     DI       last raw horizontal mickey count
	     DS       mouse driver data segment
	   * If an event does not generate a call to the user-defined handler
	     because its bit is not set in the event mask, it is still reported
	     in the event falgs during calls to the handler for events which
	     are enabled.
}
PROCEDURE SetLightPen(On_Off : word);
{ Turns the light pen emulation by the mouse driver for IBM BASIC on or off.
  A "pen down" condition is created by pressing the left and right mouse
  buttons simultaneosly.
  Call:    On_Off = true to enable or false to disable emulation.
  Returns: nothing
}
PROCEDURE SetPointerExcl(HorMin, VerMin, HorMax, VerMax : word);
{ Defines an exclusion area for the mouse pointer.  When the mouse pointer
  lies within the specified area, it is not displayed.
  Call:    HorMin = upper left X coordinate
	   VerMin = upper left Y coordinate
	   HorMax = lower right X coordinate
	   VerMax = lower right Y coordinate
  Returns: nothing
  Note:    *  The exclusion area is replaced by another call to this
	      procdure or cancelled by InitMouse and ShowPointer.
}
PROCEDURE SwapEventHandlers(VAR Mask : word; VAR Buffer : pointer);
{ Set the address and event mask for an application program's mouse event
  handler and returns the address and event mask for the previous handler.
  The newly installed handler is called by the mouse driver whenever the
  specified mouse events occur.
  Call:    Mask    = event mask
		     Bit(s)  Significance(if set)
		     0       mouse movement
		     1       left button pressed
		     2       left button released
		     3       right button pressed
		     4       right button released
		     5       center button pressed
		     6       center button released
		     7-15    reserved(0)
	   Handler = Pointer to the handler procedure
  Returns: Mask    = previous event mask
	   Handler = pointer to previous handler
  Notes:   * The notes for SetEventHandler describe the information passed to
	     the user-defined event handler.  Also see SetAltEventHandler.
	   * Calls to the event handler are disabled with InitMouse or by
	     setting an event mask of zero.
}
FUNCTION GetSaveStateSize : word;
{ Returns the size of the buffer required to store the current state of the
  mouse driver.
  Note:    * also see SaveDrvrState and RestoreDrvrState.
}
PROCEDURE SaveDrvrState(Buffer : pointer);
{ Saves the mouse driver state in a user buffer.  THe minimum size for the
  buffer must be determined by GetSaveStateSize.
  Call:    Buffer = pointer to the user defined buffer.
  Returns: nothing
  Note:    * Use this procedure before executing a child program (Exec), in
	     case the child aslo uses the mouse. After the Exec call, restore
	     the previous mouse driver state using RestoreDrvrState.
}
PROCEDURE RestoreDrvrState(Buffer : pointer);
{ Restores the mouse driver state from a user buffer.
  Call:    Buffer = pointer to the user defined buffer.
  Returns: nothing
  Note:    * The mouse driver state must have been previously saved into the
	     same buffer with SaveDrvrState.  The format of the data in the
	     buffer in undocumented and subject to change.
}
PROCEDURE SetAltEventHandler(Mask : word; Handler : pointer; VAR Err: boolean);
{ Sets the address and event mask for an application program's mouse event
  handler.  As many as three handlers with distinct event masks can be
  registered with this function.  When an event occurs that matches one of the
  masks, the corresponding handler is called by the mouse driver.
  Call:    Mask    = event mask
		     Bit(s)  Significance(if set)
		     0       mouse movement
		     1       left button pressed
		     2       left button released
		     3       right button pressed
		     4       right button released
		     5       Shift key pressed during button press or release
		     6       Ctrl key pressed during button press or release
		     7       Alt key pressed during button press or release
		     8-15    reserved(0)
	   Handler = Pointer to the handler procedure
  Returns: Err     = false if successful, true otherwise
  Notes:   * When this procedure is called, at least one of the bits 5, 6, and
	     7 must be set in Mask.
	   * The user-defined handler is entered from the mouse driver by a
	     far call with the registers set up as follows:
	     AX       mouse event flags (see event mask)
	     BX       button state
		      Bit(s)  Significance(if set)
		      0       left button is down
		      1       right button is down
		      2       center button is down
		      3-15    reserved(0)
	     CX       horizontal (X) pointer coordinate
	     DX       vertical (Y) pointer coordinate
	     SI       last raw vertical mickey count
	     DI       last raw horizontal mickey count
	     DS       mouse driver data segment
	   * If an event does not generate a call to the user-defined handler
	     because its bit is not set in the event mask, it is still reported
	     in the event falgs during calls to the handler for events which
	     are enabled.
	   * Calls to the handler are disabled with InitMouse.
	   * Also see SetEventHandler and SwapEventHandlers.
}
PROCEDURE GetAltEventAdrs(VAR Mask : word; VAR Handler : pointer;
			  VAR Err : boolean);
{ Returns the address for the mouse event handler matching the specified
  event mask.
  Call:    Mask    = event mask
		     (see SetAltEventHandler)
  Returns: Mask    = event mask
	   Handler = pointer to the alternate event handler
	   Err     = false if successful, true if not successful (no handler
		     installed or event mask does not match any installed
		     handler.
  Note:    * SetAltEventHandler allows as many as three event handler with
	     distinct event masks to be installed.  This procedure can be
	     called to search for a handler that matches a specific event, so
	     that it can be replaced or disabled.
}
PROCEDURE SetMouseSense(Horiz, Vert, Double : word);
{ Set the number of mickeys per 8 pixels for horizontal and vertical mouse
  motion and the threshold speed for doubleing pointer motion on the screen.
  One mickey represents approximately 1/200 of an inch of mouse travel.
  Call:    Horiz  = horizontal mickeys (1-32,767; default=8)
	   Vert   = vertical mickeys (1-32,767; default=16)
	   Double = double speed threshold in mickeys/second (default=64);
  Returns: nothing
}
PROCEDURE GetMouseSense(VAR Horiz, Vert, Double : word);
{ Return the current mickeys to pixels ratios for vertical and horizontal
  screen movement and the threshold speed for doubling of pointer motion.
  Call:    nothing
  Returns: Horiz  = horizontal mickeys (1-32,767; default=8)
	   Vert   = vertical mickeys (1-32,767; default=16)
	   Double = double speed threshold in mickeys/second (default=64);
}
PROCEDURE SetMouseIntr(Flags : word);
{ Sets the rate at which the mouse driver polls the status of the mouse.
  Faster rates provide better resolution in graphics mode but may degrade
  the performance of application programs.
  Call:    Flags = interrupt rate flags
		   Bit(s)    Significance(if set)
		   0         no interrupts allowed
		   1         30 interrupts/second
		   2         50 interrupts/second
		   3         100 interrupts/second
		   4         200 interrupts/second
		   5-15      reserved(0)
  Returns: nothing
  Notes:   * This procedure is applicable for the InPort Mouse only.
	   * In more than one bit is set in Flags, the lowest order bit
	     prevails.
}
PROCEDURE SetPointerPage(Page : word);
{ Selects the display page for the mouse pointer.
  Call:    Page = display page
  Returns: nothing
  Note:    * The valid page numbers depend on the current display mode.
}
FUNCTION GetPointerPage : word;
{ Returns the current display page for the mouse pointer.
}
PROCEDURE DisableMouseDrvr(VAR Handler : pointer; VAR Err : boolean);
{ Disables the mouse driver and returns the address of the previous Int 33H
  handler.
  Call:    nothing
  Returns: Handler = pointer to previous Int 33H handler
	   Err     = false if successful, true otherwise
  Notes:   * When this procedure is called, the mouse driver releases any
	     interrupt vectors it hase captured OTHER than Int 33H (which may
	     be Int 10H, Int 71H, and/or Int 74H).  The application program
	     can COMPLETE the process of logically removing the mouse driver
	     by restoring the original contents of the Int 33H vector with
	     SetIntVec using the pointer returned by the procedure.
	   * Also see EnableMouseDrvr.
}
PROCEDURE EnableMouseDrvr;
{ Enables the mouse driver and the servicing fo mouse interrupts.
  Call:    nothing
  Returns: nothing
  Note:    * Also see DisableMouseDrvr
}
PROCEDURE ResetMouseDrvr(VAR Buttons : word; VAR Err : boolean);
{ Resets the mouse driver and returns driver status.  If the mouse pointer was
  previously visible, is is removed trom the screen, and any presoiusly
  installed user event handlers for mouse events are disabled.
  Call:    nothing
  Returns: Buttons = number of mouse buttons
	   Err     = false if mouse support is available, true otherwise
  Note:    * This procedure differ from InitMouse in that there is no
	     initialization of the mouse hardware.
}
PROCEDURE SetMouseLang(LangNumber : word);
{ Selects the language that will be used by the mouse driver for prompts and
  error messages.
  Call:    LangNumber = language number
			0 = English
			1 = French
			2 = Dutch
			3 = German
			4 = Swedish
			5 = Finnish
			6 = Spanish
			7 = Portuguese
			8 = Italian
  Returns: nothing
  Note:    * This procedure is only functional in international versions of
	     the Microsoft Mouse drive.
}
FUNCTION GetMouseLang : word;
{ Returns the number of the language that is used by the mouse driver for
  prompts and error messages.
  Call:    nothing
  Returns: language number (see above)
  Note:    * This procedure is only functional in international versions of
	     the Microsoft Mouse drive.
}
PROCEDURE GetMouseInfo(VAR MajVer, MinVer, MouseType, IRQ : word);
{ Returns the mouse driver version number, mouse type, and the IRQ number of
  the interrupt used by the mouse adapter.
  Call:    nothing
  Returns: MajVer    = major version number (6 for version 6.10, etc.)
	   MinVer    = minor version number (10 for version 6.10, etc.)
	   MouseType = mouse type
		       1 = bus mouse
		       2 = serial mouse
		       3 = InPort mouse
		       4 = PS/2 mouse
		       5 = HP mouse
	   IRQ       = IRQ number
		       0                = PS/2
		       2, 3, 4, 5, or 7 = IRQ number
}


IMPLEMENTATION

CONST
  MouseInt = $33;

VAR
  Reg : Registers;


PROCEDURE InitMouse(VAR Buttons : word; VAR Err : boolean);
{ Iniialize the mouse driver, if present, and return the number of buttons. }

BEGIN
  Reg.AX := 0;
  intr(MouseInt, Reg);
  Buttons := Reg.BX;
  IF (Reg.AX = 0) THEN
    Err := true
  ELSE
    Err := false;
END;

PROCEDURE ShowPointer;

BEGIN
  Reg.AX := 1;
  intr(MouseInt, Reg);
END;

PROCEDURE HidePointer;

BEGIN
  Reg.AX := 2;
  intr(MouseInt, Reg);
END;

FUNCTION ButtonPressed(Mask : word) : boolean;

BEGIN
  Reg.AX := 3;
  intr(MouseInt, Reg);
  IF (Reg.BX > 0) THEN
    ButtonPressed := true
  ELSE
    ButtonPressed := false;
END;

PROCEDURE GetMousePosition(VAR Buttons, Horiz, Vert : word);

BEGIN
  Reg.AX := 3;
  intr(MouseInt, Reg);
  Buttons := Reg.BX;
  Horiz := Reg.CX;
  Vert := Reg.DX;
END;

FUNCTION MouseIn(x1,y1,x2,y2: word):boolean;
VAR b,x,y: word;
BEGIN
  GetMousePosition(b,x,y);
  MouseIn:=(x>=x1) AND (x<=x2) AND (y>=y1) AND (y<=y2)
END;

PROCEDURE SetPointerPosition(Horiz, Vert : word);

BEGIN
  Reg.AX := 4;
  Reg.CX := Horiz;
  Reg.DX := Vert;
  intr(MouseInt, Reg);
END;

PROCEDURE GetPressInfo(Button : word;
		       VAR Stat, Count, Horiz, Vert : word);

BEGIN
  Reg.AX := 5;
  Reg.BX := Button;
  intr(MouseInt, Reg);
  Stat := Reg.AX;
  Count := Reg.BX;
  Horiz := Reg.CX;
  Vert := Reg.DX;
END;

PROCEDURE GetReleaseInfo(Button : word;
			 VAR Stat, Count, Horiz, Vert : word);

BEGIN
  Reg.AX := 6;
  Reg.BX := Button;
  intr(MouseInt, Reg);
  Stat := Reg.AX;
  Count := Reg.BX;
  Horiz := Reg.CX;
  Vert := Reg.DX;
END;

PROCEDURE SetLimits(HorMin, HorMax, VerMin, VerMax : word);

BEGIN
  IF (HorMin > 0) AND (HorMax > 0) THEN
    BEGIN
      Reg.AX := 7;
      Reg.CX := HorMin;
      Reg.DX := HorMax;
      intr(MouseInt, Reg);
    END;
  IF (VerMin > 0) AND (VerMax > 0) THEN
    BEGIN
      Reg.AX := 8;
      Reg.CX := VerMin;
      Reg.DX := VerMax;
      intr(MouseInt, Reg);
    END;
END;

PROCEDURE SetPointerShape(Horiz, Vert : word; Buffer : pointer);

BEGIN
  Reg.AX := 9;
  Reg.BX := Horiz;
  Reg.CX := Vert;
  Reg.ES := Seg(Buffer);
  Reg.DX := Ofs(Buffer);
  intr(MouseInt, Reg);
END;

PROCEDURE SetTextPointer(PtrTyp, AND_Str, XOR_End : word);

BEGIN
  Reg.AX := 10;
  Reg.BX := PtrTyp;
  Reg.CX := AND_Str;
  Reg.DX := XOR_End;
  intr(MouseInt, Reg);
END;

PROCEDURE GetMotionCount(VAR Horiz, Vert : word);

BEGIN
  Reg.AX := 11;
  intr(MouseInt, Reg);
  Horiz := Reg.CX;
  Vert := Reg.DX;
END;

PROCEDURE SetEventHandler(EventMask : word; Handler : pointer);

BEGIN
  Reg.AX := 12;
  Reg.CX := EventMask;
  Reg.ES := seg(Handler);
  Reg.DX := ofs(Handler);
  intr(MouseInt, Reg);
END;

PROCEDURE SetLightPen(On_Off : word);

BEGIN
  IF (On_Off = 0) THEN
    Reg.AX := 14
  ELSE
    Reg.AX := 13;
  intr(MouseInt, Reg);
END;

PROCEDURE SetPointerExcl(HorMin, VerMin, HorMax, VerMax : word);

BEGIN
  Reg.AX := 16;
  Reg.CX := HorMin;
  Reg.SI := HorMax;
  Reg.DX := VerMin;
  Reg.DI := VerMax;
  intr(MouseInt, Reg);
END;

PROCEDURE SwapEventHandlers(VAR Mask : word; VAR Buffer : pointer);

BEGIN
  Reg.AX := 20;
  Reg.CX := Mask;
  Reg.ES := Seg(Buffer);
  Reg.DX := Ofs(Buffer);
  intr(MouseInt, Reg);
  Mask := Reg.CX;
  Buffer := Ptr(Reg.ES, Reg.DX);
END;

FUNCTION GetSaveStateSize : word;

BEGIN
  Reg.AX := 21;
  intr(MouseInt, Reg);
  GetSaveStateSize := Reg.BX;
END;

PROCEDURE SaveDrvrState(Buffer : pointer);

BEGIN
  Reg.AX := 22;
  Reg.ES := Seg(Buffer);
  Reg.DX := Ofs(Buffer);
  intr(MouseInt, Reg);
END;

PROCEDURE RestoreDrvrState(Buffer : pointer);

BEGIN
  Reg.AX := 23;
  Reg.ES := Seg(Buffer);
  Reg.DX := Ofs(Buffer);
  intr(MouseInt, Reg);
END;

PROCEDURE SetAltEventHandler(Mask : word; Handler : pointer; VAR Err: boolean);

BEGIN
  Reg.AX := 24;
  Reg.CX := Mask;
  Reg.ES := Seg(Handler);
  Reg.DX := Ofs(Handler);
  intr(MouseInt, Reg);
  IF (Reg.AX = 24) THEN
    Err := false
  ELSE
    Err := true;
END;

PROCEDURE GetAltEventAdrs(VAR Mask : word; VAR Handler : pointer;
			  VAR Err : boolean);

BEGIN
  Reg.AX := 25;
  Reg.CX := Mask;
  intr(MouseInt, Reg);
  IF (Reg.CX > 0) THEN
    BEGIN
      Mask := Reg.CX;
      Handler := Ptr(Reg.ES, Reg.DX);
      Err := false;
    END
  ELSE
    Err := true;
END;

PROCEDURE SetMouseSense(Horiz, Vert, Double : word);

BEGIN
  Reg.AX := 26;
  Reg.BX := Horiz;
  Reg.CX := Vert;
  Reg.DX := Double;
  intr(MouseInt, Reg);
END;

PROCEDURE GetMouseSense(VAR Horiz, Vert, Double : word);

BEGIN
  Reg.AX := 27;
  intr(MouseInt, Reg);
  Horiz := Reg.BX;
  Vert := Reg.CX;
  Double := Reg.DX;
END;

PROCEDURE SetMouseIntr(Flags : word);

BEGIN
  Reg.AX := 28;
  Reg.BX := Flags;
  intr(MouseInt, Reg);
END;

PROCEDURE SetPointerPage(Page : word);

BEGIN
  Reg.AX := 29;
  Reg.BX := Page;
  intr(MouseInt, Reg);
END;

FUNCTION GetPointerPage : word;

BEGIN
  Reg.AX := 30;
  intr(MouseInt, Reg);
  GetPointerPage := Reg.BX;
END;

PROCEDURE DisableMouseDrvr(VAR Handler : pointer; VAR Err : boolean);

BEGIN
  Reg.AX := 31;
  intr(MouseInt, Reg);
  IF (Reg.AX = 31) THEN
    BEGIN
      Handler := ptr(Reg.ES, Reg.DX);
      Err := false;
    END
  ELSE
    Err := true;
END;

PROCEDURE EnableMouseDrvr;

BEGIN
  Reg.AX := 32;
  intr(MouseInt, Reg);
END;

PROCEDURE ResetMouseDrvr(VAR Buttons : word; VAR Err : boolean);

BEGIN
  Reg.AX := 33;
  intr(MouseInt, Reg);
  IF (Reg.AX = $FFFF) THEN
    BEGIN
      Buttons := Reg.BX;
      Err := false;
    END
  ELSE
    Err := true;
END;

PROCEDURE SetMouseLang(LangNumber : word);

BEGIN
  Reg.AX := 34;
  Reg.BX := LangNumber;
  intr(MouseInt, Reg);
END;

FUNCTION GetMouseLang : word;

BEGIN
  Reg.AX := 35;
  intr(MouseInt, Reg);
  GetMouseLang := Reg.BX;
END;

PROCEDURE GetMouseInfo(VAR MajVer, MinVer, MouseType, IRQ : word);

BEGIN
  Reg.AX := 36;
  intr(MouseInt, Reg);
  MajVer := Reg.BH;
  MinVer := Reg.BL;
  MouseType := Reg.CH;
  IRQ := Reg.CL;
END;

END.
-- 
Ticking away, the moments that make up a dull day.   | William C. Thompson
You fritter and waste the hours in an offhand way.   | Michelson 620D (wct)
Kicking around on a piece of ground in your hometown,| a.k.a. Master of Time,
waiting for someone or something to show you the way.| Space, and Dimension