Unit Mouse;

{ ------------------------------------------------------------------------- }
{                                                                           }
{ Minimal Microsoft Mouse Driver Interface Unit                             }
{                                                                           }
{ ------------------------------------------------------------------------- }

Interface

Uses Dos;

Const MouseInterrupt: Byte = $33;

Var
  MouseOn      : Boolean;
  MouseVisible : Boolean;

Procedure MouseInit;           { Initializes mouse driver if one is present }
Procedure ToggleMouseVisibility;      { Toggles mouse cursor visible/hidden }
Procedure MouseReset;    { Resets mouse driver, if active, to default state }
Function  GetMousePosition(Var MouseX,MouseY,MouseButtons: Word): Boolean;

Implementation

Procedure MouseInit;
Var
  Regs   : Registers;
  Vector : Pointer;
  OpCode : ^Byte;

Begin
  GetIntVec(MouseInterrupt,Vector);
  If Vector = Nil Then Exit;
  OpCode := Vector;                                { Mouse interrupt vector }
  If OpCode^ = $CF Then Exit;       { IRET opcode indicates no mouse driver }
  Regs.AX := 0;
  Intr(MouseInterrupt,Regs);
  If Regs.AX = $FFFF Then                { -1 indicates mouse driver active }
  Begin
    MouseOn      := True;
    MouseVisible := False;
  End;
End; { MouseInit }


Procedure ToggleMouseVisibility;
Var Regs: Registers;
Begin
  If MouseOn Then
  Begin
    If MouseVisible
     Then Regs.AX := $0002
     Else Regs.AX := $0001;
    Intr(MouseInterrupt,Regs);
    MouseVisible := Not MouseVisible;    { Track mouse visible/hidden state }
  End;
End; { ToggleMouseVisibility }


Procedure MouseReset;
Begin
  If MouseVisible Then ToggleMouseVisibility;
  MouseInit;
End; { MouseReset }


Function GetMousePosition(Var MouseX,MouseY,MouseButtons: Word): Boolean;

{ ------------------------------------------------------------------------- }
{                                                                           }
{ Stores mouse coordinates and button state info in parameters if mouse     }
{ driver active                                                             }
{                                                                           }
{ Returns:        True if mouse driver is active                            }
{                 False if mouse driver is not active                       }
{                                                                           }
{ ------------------------------------------------------------------------- }

Var Regs: Registers;
Begin
  If Not MouseOn Then            { If mouse driver not active, return false }
  Begin
    GetMousePosition := False;
    Exit;
  End;
  Regs.AX := $0003;
  Intr(MouseInterrupt,Regs);
  MouseButtons     := Regs.BX;                   { Store mouse button state }
  MouseX           := Regs.CX;                   { Store mouse x coordinate }
  MouseY           := Regs.DX;                   { Store mouse y coordinate }
  GetMousePosition := True;
End; { GetMousePosition }


Begin
  MouseOn      := False;
  MouseVisible := False;
End.