REM Mouse.bas demonstrates use of mouse functions. PD 2003.
REM Start with QBX /L QBX.QLB

' get include file.
REM $INCLUDE: 'mouse.inc'

' clear mouse buttons.
CALL MouseFunction(ButtonPress, 0)
CALL MouseFunction(ButtonPress, 1)

' store mouse position.
CALL MouseFunction(Position, 0)
Mouse.X = OutregsX.DX / 8 + 1
Mouse.Y = OutregsX.CX / 8 + 1
CLS

' show mouse cursor.
CALL MouseFunction(ShowMouse, 0)

DO
   IF INKEY$ <> "" THEN EXIT DO

   ' call mouse subroutine.
   CALL MouseDriver

   ' check left mouse button.
   IF Mouse.Button1 = 1 THEN
      CALL MouseFunction(HideMouse, 0)
      PRINT "Button 1 Pressed Row"; Mouse.Button1.Row; "Column"; Mouse.Button1.Column
      CALL MouseFunction(ShowMouse, 0)
   ELSE
      IF Mouse.Button1 = 2 THEN
         ' check mouse position.
         IF Mouse.Row OR Mouse.Column THEN
            CALL MouseFunction(HideMouse, 0)
            PRINT "Button 1 Moved from Row"; Mouse.Button1.Row; "Column"; Mouse.Button1.Column;
            PRINT "to Row"; Mouse.Row; "Column"; Mouse.Column
            CALL MouseFunction(ShowMouse, 0)
         END IF
      ELSE
         ' check mouse position.
         IF Mouse.Row OR Mouse.Column THEN
            CALL MouseFunction(HideMouse, 0)
            PRINT "Row"; Mouse.Row; "Column"; Mouse.Column
            CALL MouseFunction(ShowMouse, 0)
         END IF
      END IF
   END IF
   ' release time slice. (speeds up mouse in windows).
   Var = ReleaseTime

LOOP

' reset mouse activity.
CALL MouseFunction(HideMouse, 0)

END

REM $DYNAMIC
' subroutine to check mouse activity.
SUB MouseDriver
 ON LOCAL ERROR RESUME NEXT
 Mouse.Button1 = False
 Mouse.Button2 = False
 Mouse.Button3 = False
 Mouse.Row = False
 Mouse.Column = False
 ' read middle mouse button.
 CALL MouseFunction(ButtonPress, 2)
 IF (OutregsX.AX AND 4) = 4 THEN
    Mouse.Button3 = True
 END IF
 ' read right mouse button.
 CALL MouseFunction(ButtonPress, 1)
 IF (OutregsX.AX AND 2) = 2 THEN
    Mouse.Button2 = True
 END IF
 ' read left mouse button.
 CALL MouseFunction(ButtonPress, 0)
 IF (OutregsX.AX AND 1) = 1 THEN
    Var2 = OutregsX.CX / 8 + 1
    Var3 = OutregsX.DX / 8 + 1
    IF Var3 <> Mouse.Button1.X OR Var2 <> Mouse.Button1.Y THEN
       Mouse.Button1 = 1
       Mouse.Button1.X = Var3
       Mouse.Button1.Y = Var2
       Mouse.Button1.Row = Mouse.Button1.X
       Mouse.Button1.Column = Mouse.Button1.Y
       EXIT SUB
    END IF
    ' read mouse position
    CALL MouseFunction(Position, 0)
    Var2 = OutregsX.CX / 8 + 1
    Var3 = OutregsX.DX / 8 + 1
    IF Var3 <> Mouse.X OR Var2 <> Mouse.Y THEN
       Mouse.Button1 = 2
       Mouse.X = Var3
       Mouse.Y = Var2
       Mouse.Row = Mouse.X
       Mouse.Column = Mouse.Y
       EXIT SUB
    END IF
 END IF
 ' read mouse position
 CALL MouseFunction(Position, 0)
 Var2 = OutregsX.CX / 8 + 1
 Var3 = OutregsX.DX / 8 + 1
 IF Var3 <> Mouse.X OR Var2 <> Mouse.Y THEN
    Mouse.X = Var3
    Mouse.Y = Var2
    Mouse.Row = Mouse.X
    Mouse.Column = Mouse.Y
 END IF
END SUB

SUB MouseFunction (Var1, Var2)
 ' subroutine calls mouse bios function.
 ON LOCAL ERROR RESUME NEXT
 REM INT 33H:
 REM   AX=00 - initialize mouse.
 REM   AX=01 - show mouse cursor.
 REM   AX=02 - hide mouse cursor. (re-entrant).
 REM   AX=03 - return position and button status.
 REM   AX=04 - position mouse (CX=column, DX=row).
 REM   AX=05 - return button press data.
 InregsX.AX = Var1
 InregsX.BX = Var2
 CALL InterruptX(&H33, InregsX, OutregsX)
END SUB

' function to release time slice in windows.
FUNCTION ReleaseTime
 ON LOCAL ERROR RESUME NEXT
 InregsX.AX = &H1680
 InregsX.BX = &H0
 CALL InterruptX(&H2F, InregsX, OutregsX)
END FUNCTION
