home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / wct / mouse.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-11-23  |  38.2 KB  |  1,069 lines

  1. UNIT Mouse;
  2. { Mouse unit for Turbo Pascal.
  3.   The comments in this unit were basically copied directly
  4.   from the Advanced MS Dos Programing book, the section on
  5.   the Microsoft Mouse Driver, which was the source of all
  6.   the mouse interrupt functions and their parameters.
  7. }
  8.  
  9. { I have now done some error checking and debugging. Now - I hope - all
  10.   given procedures and functions will work. Contact me if not.
  11. }
  12. {  Andy Spiegl, Munich, Germany, 1991  }
  13. {  Kirchweg 11a, 8000 Muenchen 70      }
  14. {  Current E-Mail-Adr.: spiegl@informatik.tu-muenchen.de  }
  15.  
  16.  
  17. INTERFACE
  18.  
  19. USES
  20.   Dos, Crt;
  21.  
  22. CONST
  23.   LeftButton = 1;
  24.   RightButton = 2;
  25.   CenterButton = 4;
  26.   AnyButton = 7;
  27.  
  28. var
  29.   mouseon     : boolean;
  30.   mousebuttons: word;
  31.   mouseerr: boolean;
  32.  
  33. PROCEDURE InitMouse;
  34. { Initializes the mouse driver.
  35.   Note:    * After a call to this function the driver is initialized to the
  36.              following state:
  37.     - Mouse pointer at screen center and hidden.
  38.     - Display page is set to zero.
  39.     - Mouse pointer shape set to default arrow shape in graphics modes,
  40.       or reverse block in text modes.
  41.     - User mouse event handlers are disabled.
  42.     - Light pen emulation enabled.
  43.     - Mouse sensitivity set to default vales (see SetMouseSense)
  44.     - Pointer limits set to entire screen.
  45.     - Set mouseon to false
  46. }
  47.  
  48. PROCEDURE Showmouse;
  49. { Displays the mouse pointer, and cancels any pointer exclusion area. }
  50.  
  51. PROCEDURE Hidemouse;
  52. { Removes the mouse pointer from the screen, but continues to track the
  53.   position of the mouse. }
  54.  
  55. FUNCTION ButtonPressed(Mask : word) : boolean;
  56. { Returns a true value if the specified button(s) is pressed.
  57.   Call:    Mask = bit mask of desired button(s)
  58.                    bit(s)  Significance(if set)
  59.                      0       left button
  60.                      1       right button
  61.                      2       center button
  62.                      3-15    reserved(0)
  63.   Returns: True is button is pressed, false otherwise.
  64.   Note:    The constants LeftButton, RightButton, CenterButton, and
  65.            AnyButton can be used for the bit masking.  They equal 1, 2,
  66.            4 and 7 respectively.
  67. }
  68.  
  69. FUNCTION ButtonReleased(Mask : word) : boolean;
  70. { Returns a true value if the specified button(s) is not pressed.
  71.   Call:    Mask = bit mask of desired button(s)
  72.                    bit(s)  Significance(if set)
  73.                      0       left button
  74.                      1       right button
  75.                      2       center button
  76.                      3-15    reserved(0)
  77.   Returns: False is button is pressed, true otherwise.
  78.   Note:    The constants LeftButton, RightButton, CenterButton, and
  79.            AnyButton can be used for the bit masking.  They equal 1, 2,
  80.            4 and 7 respectively.
  81. }
  82.  
  83. PROCEDURE GetMousePosition(VAR Buttons, Horiz, Vert : word);
  84. { Returns the current mouse button status and pointer position.
  85.   Call:    nothing
  86.   Returns: Buttons = mouse button status
  87.            Horiz   = horizontal (X) coordinate
  88.            Vert    = vertical (Y) coordinate
  89.   Note:    Coordinates are in pixels regardless of the current display mode.
  90.            Position (0,0) is the upper left corner of the screen.
  91. }
  92.  
  93. FUNCTION MouseIn(x1,y1,x2,y2: word; var mx,my:word):boolean;
  94. { Returns true if mouse is within rectangle with upper-left
  95.   corner (x1,y1) and lower-right corner (x2,y2).
  96. }
  97.  
  98. PROCEDURE SetPointerPosition(Horiz, Vert : word);
  99. { Set the position of the pointer.  The pointer is displayed in the new
  100.   position unless it has been hidden using HidePointer or it is an exclusion
  101.   area defined by SetPointerExcl.
  102.   Call:    Horiz = horizontal (X) coordinate
  103.            Vert  = vertical (Y) coordinate
  104.   Returns: nothing
  105.   Notes:   * Coordinates are in pixels regardless of the current display mode.
  106.              Position (0,0) is the upper left corner of the screen.
  107.            * The position is adjusted if necessary to lie within the pointer
  108.              limits set by SetLimits.
  109. }
  110. PROCEDURE GetPressInfo(Button : word;
  111.                        VAR Stat, Count, Horiz, Vert : word);
  112. { Returns the current status of all mouse buttons, and the number of presses
  113.   and position of the last press for a specifed mouse button since the last
  114.   call to this procedure for that button.  The press counter for the button
  115.   is reset to zero.
  116.   Call:    Button = button identifier
  117.                      0 = left button
  118.                      1 = right button
  119.                      2 = center button
  120.   Returns: Stat   = button status
  121.                    bit(s)  Significance(if set)
  122.                      0       left button is down
  123.                      1       right button is down
  124.                      2       center button is down
  125.                      3-15    reserved(0)
  126.            Count  = button press counter
  127.            Horiz  = horizontal (X) coordinate of last button press
  128.            Vert   = vertical (Y) coordinate of last button press
  129.   Note:    The constants LeftButton, RightButton, CenterButton, and
  130.            AnyButton CANNOT be used for the bit masking.
  131. }
  132. PROCEDURE GetReleaseInfo(Button : word;
  133.                          VAR Stat, Count, Horiz, Vert : word);
  134. { Returns the current status of all mouse buttons, and the number of releases
  135.   and position of the last release for a specifed mouse button since the last
  136.   call to this procedure for that button.  The release counter for the button
  137.   is reset to zero.
  138.   Call:    Button = button identifier
  139.                      0 = left button
  140.                      1 = right button
  141.                      2 = center button
  142.   Returns: Stat   = button status
  143.                    bit(s)  Significance(if set)
  144.                      0       left button is down
  145.                      1       right button is down
  146.                      2       center button is down
  147.                      3-15    reserved(0)
  148.            Count  = button release counter
  149.            Horiz  = horizontal (X) coordinate of last button release
  150.            Vert   = vertical (Y) coordinate of last button release
  151.   Note:    The constants LeftButton, RightButton, CenterButton, and
  152.            AnyButton CANNOT be used for the bit masking.
  153. }
  154. PROCEDURE SetLimits(HorMin, HorMax, VerMin, VerMax : word);
  155. { Limits the mouse pointer to stay within a certian area.
  156.   Call:    HorMin = Minimum horizontal (X) coordinate
  157.            HorMax = Maximum horizontal (X) coordinate
  158.            VerMin = Minimum vertical (Y) coordinate
  159.            VerMax = Maximum vertical (Y) coordinate
  160.   Returns: nothing
  161.   Note:    If both HorMin and HorMax are zero then then the previous
  162.            horizontal limits remain unchanged; the same is true for
  163.            VerMin and VerMax.
  164. }
  165. PROCEDURE SetPointerShape(Horiz, Vert : word; BufferSeg, BufferOfs : word);
  166. { Defines the shape, color, and hot spot of the pointer in graphics modes.
  167.   Call:    Horiz  = hot spot offset from the left
  168.            Vert   = hot spot offset from the top
  169.            BufferSeg = Segment of image buffer of mouse pointer ['Seg(...)']
  170.            BufferOfs = Offset  of image buffer of mouse pointer ['Ofs(...)']
  171.   Returns: nothing
  172.   Note:    * The pointer image buffer is 64 bytes long.  The first 32 bytes
  173.              contain a bit mask which is ANDed with the screen image, and the
  174.              remaining 32 bytes are then XORed with the screen image.
  175.            * The hot spot is relative to the upper left corner of the pointer
  176.              image, and each offset must be in the range -16 to 16.  In display
  177.              modes 4 and 5, the horizontal offset must be an even number.
  178.            * Example:  ( in Basic unfortunately )
  179.  
  180.                10  ' Define the screen mask
  181.                20  '
  182.                30    cursor (0,0)  = &HFFFF       '1111111111111111
  183.                40    cursor (1,0)  = &HFFFF       '1111111111111111
  184.                50    cursor (2,0)  = &HFFFF       '1111111111111111
  185.                60    cursor (3,0)  = &HFFFF       '1111111111111111
  186.                70    cursor (4,0)  = &HFFFF       '1111111111111111
  187.                80    cursor (5,0)  = &HF00F       '1111000000001111
  188.                90    cursor (6,0)  = &H0000       '0000000000000000
  189.                100   cursor (7,0)  = &H0000       '0000000000000000
  190.                110   cursor (8,0)  = &H0000       '0000000000000000
  191.                120   cursor (9,0)  = &H0000       '0000000000000000
  192.                130   cursor (10,0) = &HF00F       '1111000000001111
  193.                140   cursor (11,0) = &HFFFF       '1111111111111111
  194.                150   cursor (12,0) = &HFFFF       '1111111111111111
  195.                160   cursor (13,0) = &HFFFF       '1111111111111111
  196.                170   cursor (14,0) = &HFFFF       '1111111111111111
  197.                180   cursor (15,0) = &HFFFF       '1111111111111111
  198.                190 '
  199.                200 ' Define the cursor mask
  200.                210 '
  201.                220   cursor (0,1)  = &H0000       '0000000000000000
  202.                230   cursor (1,1)  = &H0000       '0000000000000000
  203.                240   cursor (2,1)  = &H0000       '0000000000000000
  204.                250   cursor (3,1)  = &H0000       '0000000000000000
  205.                260   cursor (4,1)  = &H0000       '0000000000000000
  206.                270   cursor (5,1)  = &H0000       '0000000000000000
  207.                280   cursor (6,1)  = &H07E0       '0000011111100000
  208.                290   cursor (7,1)  = &H7FFE       '0111111111111110
  209.                300   cursor (8,1)  = &H7FFE       '0111111111111110
  210.                310   cursor (9,1)  = &H07E0       '0000011111100000
  211.                320   cursor (10,1) = &H0000       '0000000000000000
  212.                330   cursor (11,1) = &H0000       '0000000000000000
  213.                340   cursor (12,1) = &H0000       '0000000000000000
  214.                350   cursor (13,1) = &H0000       '0000000000000000
  215.                360   cursor (14,1) = &H0000       '0000000000000000
  216.                370   cursor (15,1) = &H0000       '0000000000000000
  217.                380 '
  218.                390 ' Set the cursor style and hot spot number of Mouse
  219.                400 '
  220.                410 '
  221.                420   G1% = 9
  222.                430   G2% = 6 ' horizontal hot spot
  223.                440   G3% = 5 ' vertical hot spot
  224.                450   CALL MOUSE ( G1%, G2%, G3%, cursor (0,0))
  225. }
  226. PROCEDURE SetTextPointer(PtrTyp, AND_Str, XOR_End : word);
  227. { Defines the shape and attributes of the mouse pointer in text modes.
  228.   Call:    PtrTyp  = pointer type
  229.                      0 = software cursor
  230.                      1 = hardware cursor
  231.            AND_Str = AND mask value (if PtrTyp = 0) or starting line for
  232.                      cursor (if PtrTyp = 1)
  233.            XOR_End = XOR mask value (if PtrTyp = 0) or ending line for
  234.                      cursor (if PtrTyp = 1)
  235.   Returns: nothing
  236.   Notes:   * If the software text cursor is selected, the masks in AND_Str and
  237.              XOR_End are mapped as follows:
  238.              Bit(s)   Significance
  239.              0-7      character code  (shown character !!!)
  240.              8-10     foreground color
  241.              11       intensity
  242.              12-14    background color
  243.              15       blink
  244.              For Example, the following call would yield a software cursor
  245.              that inverts the foreground and background colors:
  246.              SetTextPointer(0, $77FF, $7700);
  247.            * When the hardware text cursor is selected, the values in AND_Str
  248.              and XOR_End are the starting and ending lines for the blinking
  249.              cursor generated by the video adapter.  The maximum scan line
  250.              depends on the type of adapter and the current display mode.
  251. }
  252. PROCEDURE GetMotionCount(VAR Horiz, Vert : integer);
  253. { Returns the net mouse displacement since the last call to this procedure.
  254.   The returned value is in mickeys; a positive number indicates travel to the
  255.   right or downwards, a negative number indicates travel to the left or
  256.   upwards.  One mickey represents approximately 1/200 of an inch of mouse
  257.   movement.
  258.   Call:    nothing
  259.   Returns: Horiz = horizontal (X) mickey count
  260.            Vert  = vertical (Y) mickey count
  261. }
  262. PROCEDURE SetEventHandler(EventMask : word; HandlerSeg, HandlerOfs : word);
  263. { Sets the address and event mask for an application program's mouse event
  264.   handler.  The handler is called by the mouse drvier whenever the specifed
  265.   mouse events occur.
  266.   Call:    EventMask = event mask
  267.                    Bit(s)  Significance(if set)
  268.                      0       mouse movement
  269.                      1       left button pressed
  270.                      2       left button released
  271.                      3       right button pressed
  272.                      4       right button released
  273.                      5       center button pressed
  274.                      6       center button released
  275.                      7-15    reserved(0)
  276.       HandlerSeg = Segment Adress of the handler procedure
  277.       HandlerOfs = Offset  Adress of the handler procedure
  278.   Returns: nothing
  279.   Notes:   * The user-defined handler is entered from the mouse driver by a
  280.              far call with the registers set up as follows:
  281.              AX       mouse event flags (see event mask)
  282.              BX       button state
  283.                    Bit(s)  Significance(if set)
  284.                      0       left button is down
  285.                      1       right button is down
  286.                      2       center button is down
  287.                      3-15    reserved(0)
  288.              CX       horizontal (X) pointer coordinate
  289.              DX       vertical (Y) pointer coordinate
  290.              SI       last raw vertical mickey count
  291.              DI       last raw horizontal mickey count
  292.              DS       mouse driver data segment
  293.            * If an event does not generate a call to the user-defined handler
  294.              because its bit is not set in the event mask, it is still reported
  295.              in the event falgs during calls to the handler for events which
  296.              are enabled.
  297.            * VERY IMPORTANT:
  298.             · I have noticed that calling the DOS-unit procedure GETTIME,
  299.               GETDATE and even certain INTR or MSDOS calls while running a
  300.               mouse eventhandler is DEADLY !  Very unpleasant effects may
  301.               occur then, like 'NO ROM BASIC. SYSTEM HALTED' or 'Overlay
  302.               Manager not installed' messages etc.
  303.               Therefore I have added an extra procedure GET_TIME which re-
  304.               places the GETTIME procedure by a BIOS call. (See there)
  305.             · A handler routine that is supposed to work must look similar to
  306.               the following example: (note the assembler part at the end!)
  307.  
  308.    PROCEDURE handler
  309.       (Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP : WORD);
  310.  
  311.    INTERRUPT;
  312.  
  313.    BEGIN
  314.      mous.event     := AX;        [ 'mous' is a global record-variable ]
  315.      mous.btnStatus := BX;
  316.      mous.horiz     := CX;
  317.      mous.vert      := DX;
  318.      sound(mous.horiz+mous.vert);
  319.      if mous.horiz = 0 then Nosound;
  320.      inline (        [ Exit processing for far return to device driver ]
  321.           $8B/$E5/            [ MOV  SP, BP ]
  322.           $5D/                [ POP  BP ]
  323.           $07/                [ POP  ES ]
  324.           $1F/                [ POP  DS ]
  325.           $5F/                [ POP  DI ]
  326.           $5E/                [ POP  SI ]
  327.           $5A/                [ POP  DX ]
  328.           $59/                [ POP  CX ]
  329.           $5B/                [ POP  BX ]
  330.           $58/                [ POP  AX ]
  331.           $CB );              [ RETF    ]
  332.    END;
  333. }
  334. PROCEDURE SetLightPen(On_Off : word);
  335. { Turns the light pen emulation by the mouse driver for IBM BASIC on or off.
  336.   A "pen down" condition is created by pressing the left and right mouse
  337.   buttons simultaneosly.
  338.   Call:    On_Off = true to enable or false to disable emulation.
  339.   Returns: nothing
  340. }
  341. PROCEDURE SetPointerExcl(HorMin, VerMin, HorMax, VerMax : word);
  342. { Defines an exclusion area for the mouse pointer.  When the mouse pointer
  343.   lies within the specified area, it is not displayed.
  344.   Call:    HorMin = upper left X coordinate
  345.            VerMin = upper left Y coordinate
  346.            HorMax = lower right X coordinate
  347.            VerMax = lower right Y coordinate
  348.   Returns: nothing
  349.   Note:    The exclusion area is replaced by another call to this
  350.            procedure or cancelled by InitMouse and ShowMouse.
  351. }
  352. PROCEDURE SwapEventHandlers(VAR Mask : word;
  353.                             VAR HandlerSeg, HandlerOfs : word);
  354. { Set the address and event mask for an application program's mouse event
  355.   handler and returns the address and event mask for the previous handler.
  356.   The newly installed handler is called by the mouse driver whenever the
  357.   specified mouse events occur.
  358.   Call:    Mask    = event mask
  359.                    Bit(s)  Significance(if set)
  360.                      0       mouse movement
  361.                      1       left button pressed
  362.                      2       left button released
  363.                      3       right button pressed
  364.                      4       right button released
  365.                      5       center button pressed
  366.                      6       center button released
  367.                      7-15    reserved(0)
  368.            HandlerSeg = Segment Adress of the handler procedure
  369.            HandlerOfs = Offset  Adress of the handler procedure
  370.   Returns: Mask    = previous event mask
  371.            HandlerSeg = Segment Adress of the previous handler procedure
  372.            HandlerOfs = Offset  Adress of the previous handler procedure
  373.   Notes:   * The notes for SetEventHandler describe the information passed to
  374.              the user-defined event handler.  Also see SetAltEventHandler.
  375.            * Calls to the event handler are disabled with InitMouse or by
  376.              setting an event mask of zero.
  377. }
  378. FUNCTION GetSaveStateSize : word;
  379. { Returns the size of the buffer required to store the current state of the
  380.   mouse driver.
  381.   Note:    also see SaveDrvrState and RestoreDrvrState.
  382. }
  383. PROCEDURE SaveDrvrState(Buffer : pointer);
  384. { Saves the mouse driver state in a user buffer.  THe minimum size for the
  385.   buffer must be determined by GetSaveStateSize.
  386.   Call:    Buffer = pointer to the user defined buffer.
  387.   Returns: nothing
  388.   Note:    Use this procedure before executing a child program (Exec), in
  389.            case the child aslo uses the mouse. After the Exec call, restore
  390.            the previous mouse driver state using RestoreDrvrState.
  391. }
  392. PROCEDURE RestoreDrvrState(Buffer : pointer);
  393. { Restores the mouse driver state from a user buffer.
  394.   Call:    Buffer = pointer to the user defined buffer.
  395.   Returns: nothing
  396.   Note:    The mouse driver state must have been previously saved into the
  397.            same buffer with SaveDrvrState.  The format of the data in the
  398.            buffer in undocumented and subject to change.
  399. }
  400. PROCEDURE SetAltEventHandler(Mask : word; HandlerSeg, HandlerOfs : word;
  401.                              VAR Err: boolean);
  402. { Sets the address and event mask for an application program's mouse event
  403.   handler.  As many as three handlers with distinct event masks can be
  404.   registered with this function.  When an event occurs that matches one of the
  405.   masks, the corresponding handler is called by the mouse driver.
  406.   Call:    Mask    = event mask
  407.                    Bit(s)  Significance(if set)
  408.                      0       mouse movement
  409.                      1       left button pressed
  410.                      2       left button released
  411.                      3       right button pressed
  412.                      4       right button released
  413.                      5       Shift key pressed during button press or released
  414.                      6       Ctrl key pressed during button press or released
  415.                      7       Alt key pressed during button press or released
  416.                      8-15    reserved(0)
  417.            HandlerSeg = Segment Adress of the handler procedure
  418.            HandlerOfs = Offset  Adress of the handler procedure
  419.   Returns: Err     = false if successful, true otherwise
  420.   Notes:   * When this procedure is called, at least one of the bits 5, 6
  421.              and 7 must be set in Mask.
  422.            * The user-defined handler is entered from the mouse driver by a
  423.              far call with the registers set up as follows:
  424.              AX       mouse event flags (see event mask)
  425.              BX       button state
  426.                    Bit(s)  Significance(if set)
  427.                      0       left button is down
  428.                      1       right button is down
  429.                      2       center button is down
  430.                      3-15    reserved(0)
  431.              CX       horizontal (X) pointer coordinate
  432.              DX       vertical (Y) pointer coordinate
  433.              SI       last raw vertical mickey count
  434.              DI       last raw horizontal mickey count
  435.              DS       mouse driver data segment
  436.            * If an event does not generate a call to the user-defined handler
  437.              because its bit is not set in the event mask, it is still reported
  438.              in the event falgs during calls to the handler for events which
  439.              are enabled.
  440.            * Calls to the handler are disabled with InitMouse.
  441.            * Also see SetEventHandler and SwapEventHandlers.
  442. }
  443. PROCEDURE GetAltEventAdrs(VAR Mask : word; VAR HandlerSeg, HandlerOfs : word;
  444.                           VAR Err : boolean);
  445. { Returns the address for the mouse event handler matching the specified
  446.   event mask.
  447.   Call:    Mask    = event mask
  448.                       (see SetAltEventHandler)
  449.   Returns: Mask    = event mask
  450.            HandlerSeg = Segment Adress of the handler procedure
  451.            HandlerOfs = Offset  Adress of the handler procedure
  452.            Err     = false if successful, true if not successful (no handler
  453.                      installed or event mask does not match any installed
  454.                      handler.
  455.   Note:    SetAltEventHandler allows as many as three event handler with
  456.            distinct event masks to be installed.  This procedure can be
  457.            called to search for a handler that matches a specific event, so
  458.            that it can be replaced or disabled.
  459. }
  460. PROCEDURE SetMouseSense(Horiz, Vert, Double : word);
  461. { Set the number of mickeys per 8 pixels for horizontal and vertical mouse
  462.   motion and the threshold speed for doubleing pointer motion on the screen.
  463.   One mickey represents approximately 1/200 of an inch of mouse travel.
  464.   Call:    Horiz  = horizontal mickeys (1-32,767; default=8)
  465.            Vert   = vertical mickeys (1-32,767; default=16)
  466.            Double = double speed threshold in mickeys/second (default=64);
  467.   Returns: nothing
  468. }
  469. PROCEDURE GetMouseSense(VAR Horiz, Vert, Double : word);
  470. { Return the current mickeys to pixels ratios for vertical and horizontal
  471.   screen movement and the threshold speed for doubling of pointer motion.
  472.   Call:    nothing
  473.   Returns: Horiz  = horizontal mickeys (1-32,767; default=8)
  474.            Vert   = vertical mickeys (1-32,767; default=16)
  475.            Double = double speed threshold in mickeys/second (default=64);
  476. }
  477. PROCEDURE SetMouseIntr(Flags : word);
  478. { Sets the rate at which the mouse driver polls the status of the mouse.
  479.   Faster rates provide better resolution in graphics mode but may degrade
  480.   the performance of application programs.
  481.   Call:    Flags = interrupt rate flags
  482.                    Bit(s)    Significance(if set)
  483.                      0         no interrupts allowed
  484.                      1         30 interrupts/second
  485.                      2         50 interrupts/second
  486.                      3         100 interrupts/second
  487.                      4         200 interrupts/second
  488.                      5-15      reserved(0)
  489.   Returns: nothing
  490.   Notes:   * This procedure is applicable for the InPort Mouse only.
  491.            * If more than one bit is set in Flags, the lowest order bit
  492.              prevails.
  493. }
  494. PROCEDURE SetPointerPage(Page : word);
  495. { Selects the display page for the mouse pointer.
  496.   Call:    Page = display page
  497.   Returns: nothing
  498.   Note:    The valid page numbers depend on the current display mode.
  499. }
  500. FUNCTION GetPointerPage : word;
  501. { Returns the current display page for the mouse pointer.
  502. }
  503. PROCEDURE DisableMouseDrvr(VAR Handler : pointer; VAR Err : boolean);
  504. { Disables the mouse driver and returns the address of the previous Int 33H
  505.   handler.
  506.   Call:    nothing
  507.   Returns: Handler = pointer to previous Int 33H handler
  508.            Err     = false if successful, true otherwise
  509.   Notes:   * When this procedure is called, the mouse driver releases any
  510.              interrupt vectors it hase captured OTHER than Int 33H (which may
  511.              be Int 10H, Int 71H, and/or Int 74H).  The application program
  512.              can COMPLETE the process of logically removing the mouse driver
  513.              by restoring the original contents of the Int 33H vector with
  514.              SetIntVec using the pointer returned by the procedure.
  515.            * Also see EnableMouseDrvr.
  516. }
  517. PROCEDURE EnableMouseDrvr;
  518. { Enables the mouse driver and the servicing for mouse interrupts.
  519.   Call:    nothing
  520.   Returns: nothing
  521.   Note:    * Also see DisableMouseDrvr.
  522. }
  523. PROCEDURE ResetMouseDrvr(VAR Buttons : word; VAR Err : boolean);
  524. { Resets the mouse driver and returns driver status.  If the mouse pointer
  525.   was previously visible, it is removed from the screen, and any presviously
  526.   installed user event handlers for mouse events are disabled.
  527.   Call:    nothing
  528.   Returns: Buttons = number of mouse buttons
  529.            Err     = false if mouse support is available, true otherwise
  530.   Note:    This procedure differs from InitMouse in that there is no
  531.            initialization of the mouse hardware.
  532. }
  533. PROCEDURE SetMouseLang(LangNumber : word);
  534. { Selects the language that will be used by the mouse driver for prompts and
  535.   error messages.
  536.   Call:    LangNumber = language number
  537.                         0 = English
  538.                         1 = French
  539.                         2 = Dutch
  540.                         3 = German
  541.                         4 = Swedish
  542.                         5 = Finnish
  543.                         6 = Spanish
  544.                         7 = Portuguese
  545.                         8 = Italian
  546.   Returns: nothing
  547.   Note:    This procedure is only functional in international versions of
  548.            the Microsoft Mouse driver.
  549. }
  550. FUNCTION GetMouseLang : word;
  551. { Returns the number of the language that is used by the mouse driver for
  552.   prompts and error messages.
  553.   Call:    nothing
  554.   Returns: language number (see above)
  555.   Note:    This procedure is only functional in international versions of
  556.            the Microsoft Mouse drive.
  557. }
  558. PROCEDURE GetMouseInfo(VAR MajVer, MinVer, MouseType, IRQ : word);
  559. { Returns the mouse driver version number, mouse type, and the IRQ number of
  560.   the interrupt used by the mouse adapter.
  561.   Call:    nothing
  562.   Returns: MajVer    = major version number (6 for version 6.10, etc.)
  563.            MinVer    = minor version number (10 for version 6.10, etc.)
  564.            MouseType = mouse type
  565.                        1 = bus mouse
  566.                        2 = serial mouse
  567.                        3 = InPort mouse
  568.                        4 = PS/2 mouse
  569.                        5 = HP mouse
  570.            IRQ       = IRQ number
  571.                        0                = PS/2
  572.                        2, 3, 4, 5, or 7 = IRQ number
  573. }
  574. Procedure GetMouseTextPos(var buttons, x, y : word);
  575. { Returns the current mouse button status and text pointer position.
  576.   Call:    nothing
  577.   Returns: Buttons = mouse button status
  578.            x   = horizontal (X) coordinate
  579.            y   = vertical (Y) coordinate
  580.   Note: same function as GetMousePosition but in text coordinates
  581. }
  582. Procedure SetMouseTextPos(x, y : word);
  583. { Sets the position of the mouse pointer.  The pointer is displayed in the new
  584.   position unless it has been hidden using HidePointer or it is an exclusion
  585.   area defined by SetPointerExcl.
  586.   Call:    x = horizontal (X) coordinate
  587.            y = vertical (Y) coordinate
  588.   Returns: nothing
  589.   Notes:   * same function as SetPointerPosition but in text coordinates
  590.            * The position is adjusted if necessary to lie within the pointer
  591.              limits set by SetLimits.
  592. }
  593. Procedure SetMouseTextWin(x1, y1, x2, y2 : word);
  594. { Limits the mouse pointer to stay within a certian area.
  595.   Call:    x1 = Minimum horizontal (X) coordinate
  596.            y1 = Minimum vertical (Y) coordinate
  597.            x2 = Maximum horizontal (X) coordinate
  598.            y2 = Maximum vertical (Y) coordinate
  599.   Returns: nothing
  600.   Notes:   * If both x1 and x2 are zero then then the previous horizontal
  601.              limits remain unchanged; the same is true for y1 and y2.
  602.            * same function as SetLimits but in text coordinates
  603. }
  604. Procedure HideCursor;
  605. { Hides the cursor by setting its position outside the screen.
  606. }
  607. Procedure Get_time (var h, m, s, hund : byte;var timer : longint);
  608. { Replaces the GETTIME procedure of the DOS-unit because I have noticed
  609.   that calling this procedure while running a mouse eventhandler is DEADLY !
  610.   Very unpleasant effects may occur then, like 'NO ROM BASIC. SYSTEM HALTED'
  611.   or 'Overlay Manager not installed' messages etc.
  612.   The same is true with GETDATE and even certain INTR or MSDOS calls. If you
  613.   intend to use those, then find out a way to get around using the DOS-unit
  614.   procedures and use BIOS calls instead. (They SEEM (!!) to work.)
  615.  
  616.   Call:    nothing
  617.   Returns: h     = hour of current time
  618.            m     = minute of current time
  619.            s     = second of current time
  620.            hund  = hundredth of a second
  621.            timer = 4-byte-number showing the current time (see below)
  622.   Notes:   * hund doesn't return the exact value of onehundredth of a second.
  623.              This is only an estimation based on the timer which is called
  624.              only 18.2 times a second.
  625.            * timer is a longint value which is being set by the BIOS when the
  626.              computer is booted and then regularily (18.2 times a second)
  627.              increased by one. Therefore it shows the current time as a four
  628.              byte number.
  629. }
  630.  
  631. IMPLEMENTATION
  632.  
  633. CONST
  634.   MouseInt = $33;
  635.  
  636. VAR
  637.   Reg          : Registers;
  638.   saveX, saveY : Byte;
  639.   maxx, maxy: byte;
  640.  
  641. PROCEDURE InitMouse;
  642. { Iniialize the mouse driver, if present, and return the number of buttons. }
  643.  
  644. BEGIN
  645.   Reg.AX := 0;
  646.   intr(MouseInt, Reg);
  647.   mouseButtons := Reg.BX;
  648.   IF (Reg.AX = 0) THEN
  649.     mouseErr := true
  650.   ELSE begin
  651.     mouseErr := false;
  652.     mouseon:=false;
  653.     end
  654. END;
  655.  
  656. procedure showmouse;
  657. begin
  658.   if not mouseon then begin
  659.     reg.ax:=1;
  660.     intr(mouseint,reg);
  661.     mouseon:=true
  662.     end
  663. end;
  664.  
  665. procedure hidemouse;
  666. begin
  667.   if mouseon then begin
  668.     reg.ax:=2;
  669.     intr(mouseint,reg);
  670.     mouseon:=false
  671.     end
  672. end;
  673.  
  674. FUNCTION ButtonPressed(Mask : word) : boolean;
  675.  
  676. BEGIN
  677.   Reg.AX := 3;
  678.   intr(MouseInt, Reg);
  679.   buttonpressed:=(Reg.BX AND Mask) > 0;
  680. END;
  681.  
  682. FUNCTION ButtonReleased(Mask : word) : boolean;
  683.  
  684. BEGIN
  685.   Reg.AX := 3;
  686.   intr(MouseInt, Reg);
  687.   buttonreleased:=(Reg.BX AND Mask)<=0;
  688. END;
  689.  
  690. PROCEDURE GetMousePosition(VAR Buttons, Horiz, Vert : word);
  691.  
  692. BEGIN
  693.   Reg.AX := 3;
  694.   intr(MouseInt, Reg);
  695.   Buttons := Reg.BX;
  696.   Horiz := Reg.CX;
  697.   Vert := Reg.DX;
  698. END;
  699.  
  700. FUNCTION MouseIn(x1,y1,x2,y2: word; var mx,my:word):boolean;
  701. VAR b: word;
  702. BEGIN
  703.   GetMousePosition(b,mx,my);
  704.   MouseIn:=(mx>=x1) AND (mx<=x2) AND (my>=y1) AND (my<=y2)
  705. END;
  706.  
  707. PROCEDURE SetPointerPosition(Horiz, Vert : word);
  708.  
  709. BEGIN
  710.   Reg.AX := 4;
  711.   Reg.CX := Horiz;
  712.   Reg.DX := Vert;
  713.   intr(MouseInt, Reg);
  714. END;
  715.  
  716. PROCEDURE GetPressInfo(Button : word;
  717.              VAR Stat, Count, Horiz, Vert : word);
  718.  
  719. BEGIN
  720.   Reg.AX := 5;
  721.   Reg.BX := Button;
  722.   intr(MouseInt, Reg);
  723.   Stat := Reg.AX;
  724.   Count := Reg.BX;
  725.   Horiz := Reg.CX;
  726.   Vert := Reg.DX;
  727. END;
  728.  
  729. PROCEDURE GetReleaseInfo(Button : word;
  730.           VAR Stat, Count, Horiz, Vert : word);
  731.  
  732. BEGIN
  733.   Reg.AX := 6;
  734.   Reg.BX := Button;
  735.   intr(MouseInt, Reg);
  736.   Stat := Reg.AX;
  737.   Count := Reg.BX;
  738.   Horiz := Reg.CX;
  739.   Vert := Reg.DX;
  740. END;
  741.  
  742. PROCEDURE SetLimits(HorMin, HorMax, VerMin, VerMax : word);
  743.  
  744. BEGIN
  745.   IF (HorMin > 0) AND (HorMax > 0) THEN
  746.     BEGIN
  747.       Reg.AX := 7;
  748.       Reg.CX := HorMin;
  749.       Reg.DX := HorMax;
  750.       intr(MouseInt, Reg);
  751.     END;
  752.   IF (VerMin > 0) AND (VerMax > 0) THEN
  753.     BEGIN
  754.       Reg.AX := 8;
  755.       Reg.CX := VerMin;
  756.       Reg.DX := VerMax;
  757.       intr(MouseInt, Reg);
  758.     END;
  759. END;
  760.  
  761. PROCEDURE SetPointerShape(Horiz, Vert : word; BufferSeg, BufferOfs : word);
  762.  
  763. BEGIN
  764.   Reg.AX := 9;
  765.   Reg.BX := Horiz;
  766.   Reg.CX := Vert;
  767.   Reg.ES := BufferSeg;
  768.   Reg.DX := BufferOfs;
  769.   intr(MouseInt, Reg);
  770. END;
  771.  
  772. PROCEDURE SetTextPointer(PtrTyp, AND_Str, XOR_End : word);
  773.  
  774. BEGIN
  775.   Reg.AX := 10;
  776.   Reg.BX := PtrTyp;
  777.   Reg.CX := AND_Str;
  778.   Reg.DX := XOR_End;
  779.   intr(MouseInt, Reg);
  780. END;
  781.  
  782. PROCEDURE GetMotionCount(VAR Horiz, Vert : integer);
  783.  
  784. BEGIN
  785.   Reg.AX := 11;
  786.   intr(MouseInt, Reg);
  787.   Horiz := Reg.CX;
  788.   Vert := Reg.DX;
  789. END;
  790.  
  791. PROCEDURE SetEventHandler(EventMask : word; HandlerSeg, HandlerOfs : word);
  792.  
  793. BEGIN
  794.   Reg.AX := 12;
  795.   Reg.CX := EventMask;
  796.   Reg.ES := HandlerSeg;
  797.   Reg.DX := HandlerOfs;
  798.   intr(MouseInt, Reg);
  799. END;
  800.  
  801. PROCEDURE SetLightPen(On_Off : word);
  802.  
  803. BEGIN
  804.   IF (On_Off = 0) THEN
  805.     Reg.AX := 14
  806.   ELSE
  807.     Reg.AX := 13;
  808.   intr(MouseInt, Reg);
  809. END;
  810.  
  811. PROCEDURE SetPointerExcl(HorMin, VerMin, HorMax, VerMax : word);
  812.  
  813. BEGIN
  814.   Reg.AX := 16;
  815.   Reg.CX := HorMin;
  816.   Reg.SI := HorMax;
  817.   Reg.DX := VerMin;
  818.   Reg.DI := VerMax;
  819.   intr(MouseInt, Reg);
  820. END;
  821.  
  822. PROCEDURE SwapEventHandlers(VAR Mask : word;
  823.                             VAR HandlerSeg, HandlerOfs : word);
  824.  
  825. BEGIN
  826.   Reg.AX := 20;
  827.   Reg.CX := Mask;
  828.   Reg.ES := HandlerSeg;
  829.   Reg.DX := HandlerOfs;
  830.   intr(MouseInt, Reg);
  831.   Mask := Reg.CX;
  832.   HandlerSeg := Reg.ES;
  833.   HandlerOfs := Reg.DX;
  834. END;
  835.  
  836. FUNCTION GetSaveStateSize : word;
  837.  
  838. BEGIN
  839.   Reg.AX := 21;
  840.   intr(MouseInt, Reg);
  841.   GetSaveStateSize := Reg.BX;
  842. END;
  843.  
  844. PROCEDURE SaveDrvrState(Buffer : pointer);
  845.  
  846. BEGIN
  847.   Reg.AX := 22;
  848.   Reg.ES := Seg(Buffer);
  849.   Reg.DX := Ofs(Buffer);
  850.   intr(MouseInt, Reg);
  851. END;
  852.  
  853. PROCEDURE RestoreDrvrState(Buffer : pointer);
  854.  
  855. BEGIN
  856.   Reg.AX := 23;
  857.   Reg.ES := Seg(Buffer);
  858.   Reg.DX := Ofs(Buffer);
  859.   intr(MouseInt, Reg);
  860. END;
  861.  
  862. PROCEDURE SetAltEventHandler(Mask : word; HandlerSeg, HandlerOfs : word;
  863.                              VAR Err: boolean);
  864.  
  865. BEGIN
  866.   Reg.AX := 24;
  867.   Reg.CX := Mask;
  868.   Reg.ES := HandlerSeg;
  869.   Reg.DX := HandlerOfs;
  870.   intr(MouseInt, Reg);
  871.   IF (Reg.AX = 24) THEN
  872.     Err := false
  873.   ELSE
  874.     Err := true;
  875. END;
  876.  
  877. PROCEDURE GetAltEventAdrs(VAR Mask : word;
  878.                           VAR HandlerSeg, HandlerOfs : word;
  879.            VAR Err : boolean);
  880.  
  881. BEGIN
  882.   Reg.AX := 25;
  883.   Reg.CX := Mask;
  884.   intr(MouseInt, Reg);
  885.   IF (Reg.CX > 0) THEN
  886.     BEGIN
  887.       Mask := Reg.CX;
  888.       HandlerSeg := Reg.ES;
  889.       HandlerOfs := Reg.DX;
  890.       Err := false;
  891.     END
  892.   ELSE
  893.     Err := true;
  894. END;
  895.  
  896. PROCEDURE SetMouseSense(Horiz, Vert, Double : word);
  897.  
  898. BEGIN
  899.   Reg.AX := 26;
  900.   Reg.BX := Horiz;
  901.   Reg.CX := Vert;
  902.   Reg.DX := Double;
  903.   intr(MouseInt, Reg);
  904. END;
  905.  
  906. PROCEDURE GetMouseSense(VAR Horiz, Vert, Double : word);
  907.  
  908. BEGIN
  909.   Reg.AX := 27;
  910.   intr(MouseInt, Reg);
  911.   Horiz := Reg.BX;
  912.   Vert := Reg.CX;
  913.   Double := Reg.DX;
  914. END;
  915.  
  916. PROCEDURE SetMouseIntr(Flags : word);
  917.  
  918. BEGIN
  919.   Reg.AX := 28;
  920.   Reg.BX := Flags;
  921.   intr(MouseInt, Reg);
  922. END;
  923.  
  924. PROCEDURE SetPointerPage(Page : word);
  925.  
  926. BEGIN
  927.   Reg.AX := 29;
  928.   Reg.BX := Page;
  929.   intr(MouseInt, Reg);
  930. END;
  931.  
  932. FUNCTION GetPointerPage : word;
  933.  
  934. BEGIN
  935.   Reg.AX := 30;
  936.   intr(MouseInt, Reg);
  937.   GetPointerPage := Reg.BX;
  938. END;
  939.  
  940. PROCEDURE DisableMouseDrvr(VAR Handler : pointer; VAR Err : boolean);
  941.  
  942. BEGIN
  943.   Reg.AX := 31;
  944.   intr(MouseInt, Reg);
  945.   IF (Reg.AX = 31) THEN
  946.     BEGIN
  947.       Handler := ptr(Reg.ES, Reg.DX);
  948.       Err := false;
  949.     END
  950.   ELSE
  951.     Err := true;
  952. END;
  953.  
  954. PROCEDURE EnableMouseDrvr;
  955.  
  956. BEGIN
  957.   Reg.AX := 32;
  958.   intr(MouseInt, Reg);
  959. END;
  960.  
  961. PROCEDURE ResetMouseDrvr(VAR Buttons : word; VAR Err : boolean);
  962.  
  963. BEGIN
  964.   Reg.AX := 33;
  965.   intr(MouseInt, Reg);
  966.   IF (Reg.AX = $FFFF) THEN
  967.     BEGIN
  968.       Buttons := Reg.BX;
  969.       Err := false;
  970.     END
  971.   ELSE
  972.     Err := true;
  973. END;
  974.  
  975. PROCEDURE SetMouseLang(LangNumber : word);
  976.  
  977. BEGIN
  978.   Reg.AX := 34;
  979.   Reg.BX := LangNumber;
  980.   intr(MouseInt, Reg);
  981. END;
  982.  
  983. FUNCTION GetMouseLang : word;
  984.  
  985. BEGIN
  986.   Reg.AX := 35;
  987.   intr(MouseInt, Reg);
  988.   GetMouseLang := Reg.BX;
  989. END;
  990.  
  991. PROCEDURE GetMouseInfo(VAR MajVer, MinVer, MouseType, IRQ : word);
  992.  
  993. BEGIN
  994.   Reg.AX := 36;
  995.   intr(MouseInt, Reg);
  996.   MajVer := Reg.BH;
  997.   MinVer := Reg.BL;
  998.   MouseType := Reg.CH;
  999.   IRQ := Reg.CL;
  1000. END;
  1001.  
  1002. Procedure GetMouseTextPos(var buttons, x, y : word);
  1003. begin
  1004.   GetMousePosition(buttons, x, y);
  1005.   x := (x+8) div 8;
  1006.   y := (y+8) div 8;
  1007. end;
  1008.  
  1009. Procedure SetMouseTextPos(x, y : word);
  1010. begin
  1011.   x := x*8-8;
  1012.   y := y*8-8;
  1013.   SetPointerPosition(x,y);
  1014. end;
  1015.  
  1016. Procedure SetMouseTextWin(x1, y1, x2, y2 : word);
  1017. begin
  1018.   y1:=word(y1-1) shl 3;
  1019.   y2:=word(y2-1) shl 3;
  1020.   x1:=integer(x1-1) shl 3;
  1021.   x2:=integer(x2-1) shl 3;
  1022.   SetLimits(x1,x2,y1,y2);
  1023. end;
  1024.  
  1025. Procedure HideCursor;         { Sets cursor on position outside the screen }
  1026. begin
  1027.   Reg.ah := 2;                             { functionnumber for Set Cursor }
  1028.   Reg.bh := 0;                                             { screen page 0 }
  1029.   Reg.dh := maxY+1;               { one line after the lower screen border }
  1030.   Reg.dl := 0;                                                  { column 0 }
  1031.   intr($10, Reg);                                  { call BIOS-Video-Intr. }
  1032. end;
  1033.  
  1034. Procedure Get_time (var h, m, s, hund : byte;var timer : longint);
  1035. var regs : registers;
  1036.  
  1037. begin
  1038.   regs.ah:=$02;
  1039.   intr($1A,regs);                                               { BIOS-call }
  1040.   h    := (regs.ch shr 4)*10 + (regs.ch and 15);      { numbers in BCD-code }
  1041.   m    := (regs.cl shr 4)*10 + (regs.cl and 15);
  1042.   s    := (regs.dh shr 4)*10 + (regs.dh and 15);
  1043.   hund := (mem[$40:$6C] * 6) mod 100;   { Not the actual time ! Estimation! }
  1044.   timer := memL[$40:$6C];    { is increased 18.2 times a second, shows time }
  1045. end;
  1046.  
  1047.  
  1048. BEGIN
  1049.   { first off all find out the maximum x and y values in this videomode }
  1050.   saveX := whereX;
  1051.   saveY := whereY;
  1052.  
  1053.   gotoXY(1,1);
  1054.   maxX:=200;
  1055.   repeat
  1056.     dec(maxX);
  1057.     gotoXY(maxX,1);
  1058.   until wherex<>1;
  1059.  
  1060.   gotoXY(1,1);
  1061.   maxY:=100;
  1062.   repeat
  1063.     dec(maxY);
  1064.     gotoXY(1,maxY);
  1065.   until wherey<>1;
  1066.  
  1067.   gotoXY(saveX,saveY);
  1068. END.
  1069.