add directory study
This commit is contained in:
587
study/sabre/os/files/HCI/mouse.txt
Normal file
587
study/sabre/os/files/HCI/mouse.txt
Normal file
@@ -0,0 +1,587 @@
|
||||
Programming the Microsoft Mouse
|
||||
-------------------------------
|
||||
|
||||
"A Mouse! What A Great Idea!!"
|
||||
|
||||
-W. Disney
|
||||
|
||||
|
||||
Written for the PC-GPE by bri (accbpf@vaxc.hofstra.edu)
|
||||
and Mark Feldman (pcgpe@geocities.com)
|
||||
|
||||
|
||||
Disclaimer
|
||||
----------
|
||||
|
||||
We assume no responsibility whatsoever for any effect that this file, the
|
||||
information contained therein or the use thereof has on you, your sanity,
|
||||
computer, spouse, children, pets or anything else related to you or your
|
||||
existance. No warranty is provided nor implied with this information.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Programming the mouse is one of the easiest tasks you'll ever have to
|
||||
undertake. Mouse drivers hook themselves into interrupt 33h, so you
|
||||
can just call driver-functions the same way you would BIOS functions.
|
||||
|
||||
Basics
|
||||
------
|
||||
|
||||
The first step is to initialize the mouse driver. You do this by setting
|
||||
the ax register to 0 and calling interrupt 33h. This will return a
|
||||
non-zero number in ax if the driver is installed(which usually means if
|
||||
the mouse is installed. From here on in, anything I say about the mouse
|
||||
actually refers to the driver).
|
||||
|
||||
To display the mouse cursor on the screen, set ax to 1 before calling int 33h.
|
||||
In text-mode you should get what appears to be a block-like text cursor, and
|
||||
in any graphics mode you should get the arrow by default(although we'll see
|
||||
how to change this later). The driver detects what mode you're in and draws
|
||||
the appropriate cursor.
|
||||
|
||||
To hide the mouse cursor, you set the ax register to 2 and call the interrupt.
|
||||
Showing and hiding the mouse cursor is something you'll probably have to do
|
||||
often when you draw images to the screen. Believe you me, having a mouse move
|
||||
across something you're drawing can really wreck you're display. To get around
|
||||
this, hide the mouse cursor, draw what's necessary, and re-display the mouse
|
||||
cursor.
|
||||
|
||||
Please note, mouse drivers often keep a 'display counter' that reads 0
|
||||
if the cursor is displayed and less then 0 if its hidden. Consecutive
|
||||
calls to hide the mouse cursor will decrement the counter and make it
|
||||
more and more negative-in which case it will take more calls to display
|
||||
the mouse cursor to get the counter to 0. Once the counter is 0, calls
|
||||
to display the mouse cursor have no effect on the counter. To read the
|
||||
state of the counter, you can call function 2Ah, and the counter is
|
||||
returned in the ax register. I'll touch on function 2Ah a bit more later.
|
||||
|
||||
Last but not least, we should be able to figure out if any buttons are
|
||||
pressed, if so which ones, and where the mouse is. This is easy, just
|
||||
set ax to 3 and call int 33h-the horizontal coordinate is returned
|
||||
in the cx register, the vertical coordinate in the dx register and
|
||||
bx has the button status. In bx, each bit reads 1 if a corresponding
|
||||
button is pressed-for example bit 0 is 1 if the left button is pressed,
|
||||
bit 1 is 1 if the right button is pressed, and bit 2 is 1 if the
|
||||
center button is pressed.
|
||||
|
||||
As for the coordinates-be careful, as a lot of mouse drivers use a "virtual
|
||||
screen" of 640x200 pixels-which mean if you're screen resolution isn't this-
|
||||
you'll have to do some converting.
|
||||
|
||||
|
||||
SETTING THE CURSOR SHAPE
|
||||
------------------------
|
||||
|
||||
When you use your mouse in a graphics mode, by default, you're stuck
|
||||
with the shape of the mouse cursor as an arrow. This is fine most of the
|
||||
time, but it can get boring after a while. Don't fret!!! You can alter the
|
||||
shape to accomodate your needs!
|
||||
|
||||
The graphics mode cursor image is a 16-by-16 pixel area on the screen
|
||||
that is defined by a 64 byte buffer passed to int 33h, function 9. The first
|
||||
32 bytes contain the cursor mask-the appearance of the cursor on the screen.
|
||||
The second 32 bytes is the screen mask-it defines the appearance of the
|
||||
screen image under the cursor. In this 64 byte buffer, each bit corresponds
|
||||
to 1 pixel, i.e. the first two bytes in both of the masks corresponds to the
|
||||
16 pixels that make up the top row of the cursor.
|
||||
|
||||
When you're designing the cursor mask, each bit is 1 if it is displayed,
|
||||
and 0 if it is not. On the screen mask, bits that are 1 are transparent.
|
||||
|
||||
The mouse driver takes the screen mask, and the cursor mask and shoves
|
||||
them together, coming up with the following:
|
||||
|
||||
|
||||
Screen Mask Bit is Cursor Mask Bit is Resulting Screen Bit is
|
||||
------------------ ------------------ -----------------------
|
||||
0 0 0
|
||||
0 1 1
|
||||
1 0 Bit is Not Changed
|
||||
1 1 Bit is Inverted
|
||||
|
||||
To set the shape you call Function 9h with ES holding the segment of your
|
||||
buffer containing the masks, and DX containing the offset of the buffer
|
||||
containing the cursor mask.
|
||||
|
||||
One other important thing to note: your cursor has a hot spot=the point
|
||||
on your mouse cursor that is where the cursor is actually pointing.
|
||||
Usually this is 1, 1(that is 1 pixel from the top of the cursor and
|
||||
1 from the right). But when you change the image of your mouse cursor
|
||||
you might need to change the hot spot. You can do this by setting CX
|
||||
and DX of Function 9 to the horizontal and vertical offset of the hot
|
||||
spot.
|
||||
|
||||
ODDS AND ENDS
|
||||
-------------
|
||||
|
||||
Well, there are a few odds and ends here that you might find useful.
|
||||
|
||||
You can set limits on where you want to allow the mouse cursor to roam.
|
||||
Function 7 & 8(AX= 7 & AX = 8) set the horizontal and vertical limits
|
||||
of the mouse cursor respectively. In both cases you input cx as the minimum
|
||||
coordinate in pixels, and dx as the maximum coordinate in pixels.
|
||||
|
||||
You can take the mouse and move it to a certain position on the screen
|
||||
from inside your program. That's function 4(ax=4). You specify the
|
||||
horizontal coordinate in CX, and the vertical coordinate in DX. If you
|
||||
specify a coordinate outside a range you've set using functions 7 & 8,
|
||||
the mouse driver will most likely put the cursor at the very edge of
|
||||
that boundary.
|
||||
|
||||
Lastly, you can set the amount of distance you're actual mouse moves
|
||||
to get the cursor on the screen to move. Mouse movement is measured
|
||||
in mickeys(I'm not joking here!) where each mickey is approximately
|
||||
1/200 of an inch. To adjust this use function 0Fh. CX should contain
|
||||
the number of horizontal mickeys, and dx the number of vertical ones.
|
||||
The numbers in CX and DX actually refer to the amount of mickeys needed
|
||||
to move the mouse cursor a total of 8 pixels. By default, CX is 8, while
|
||||
DX is 16. You can set a range of 1(hyper-active energetic mouse) to
|
||||
32,767(unbelievably sluggish and lazy).
|
||||
|
||||
|
||||
SLAM DUNKS AND LOW CEILINGS
|
||||
----------------------------
|
||||
(With special thanks to Feldman the Great for this section)
|
||||
|
||||
Yes, like the subject header, something else that has never mixed very well
|
||||
together was mouse and SVGA programming. The reason, of course is that your
|
||||
mouse driver is what takes care of the updating of the image of the mouse
|
||||
cursor in graphics mode.
|
||||
|
||||
You see, in the beginning, SVGA was created. This was widely regarded
|
||||
as a bad idea.
|
||||
|
||||
Sure it looked cool, and there were more pretty colors than you could shake
|
||||
a kaleidoscope at, but there was no standard. (This was before VESA, and sadly
|
||||
even today many mouse drivers don't use VESA) This left all SVGA chip
|
||||
makers to deviously make chips however they wanted, depending on what
|
||||
kind of mood they were in, and what they had had for lunch. As most
|
||||
SVGA chip designers rarely ate the same thing at lunchtime, you wound up
|
||||
with a googleplex full of SVGA cards that all were 110% incompatible
|
||||
with each other.
|
||||
|
||||
Remember what I said about your mouse driver handling your mouse cursor.
|
||||
Now mouse drivers had to know how to handle every single SVGA card, so
|
||||
they could draw the cursors correctly in SVGA mode. Mouse driver
|
||||
maufacturers got around this problem in a rather novel way: they ignored
|
||||
SVGA.
|
||||
|
||||
Because of this, most mouse drivers throw up their hands in disgust when
|
||||
confronted with the ugly head of SVGA and simply provide you with no mouse
|
||||
cursor at all. Likewise, if you're programming for Mode X, you're likely to
|
||||
run into the same trouble. You CAN get around this, however. How? you ask
|
||||
with baited breath. Simply install your own mouse handler(I'm using the word
|
||||
'simply' rather loosely here). What this will do, is cause the mouse driver
|
||||
to call one of your functions-and then you're responsible for updating the
|
||||
graphics cursor image on the screen.
|
||||
|
||||
Basically, you call Function 0Ch. CX contains the event mask: on what
|
||||
conditions the mouse driver will call your function. The mask is listed
|
||||
below:
|
||||
Bit If set
|
||||
0 Mouse Cursor 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
|
||||
|
||||
The ES register holds the segment of your mouse code that the driver
|
||||
should call, and DX holds the offset. (As an aside, I'd recommend
|
||||
doing the mouse handler itself in assembly, as getting it to work
|
||||
in C or Pascal is an uphill struggle at best).
|
||||
|
||||
When the mouse driver calls your function, AX will contain the event
|
||||
flag that you set earlier. BX will contain the button status: 0 if
|
||||
the left button is pressed, 1 if the right button is pressed, and 2
|
||||
if the center button is pressed. CX and DX contain the horizontal and
|
||||
vertical position of the mouse cursor respectively.
|
||||
|
||||
To disable an installed handler, simply call function 0Ch with an
|
||||
event mask of 0, or call Function 0h.
|
||||
|
||||
Well that about wraps it up...if you have any questions at all,
|
||||
please feel free to contact me (bri) at accbpf@vaxc.hofstra.edu and I'll
|
||||
do my best to answer them.
|
||||
|
||||
Quick Reference Guide to Interrupt 33h
|
||||
--------------------------------------
|
||||
|
||||
FUNCTION: AX = 0h
|
||||
Description: Determines whether a mouse is available and if it is
|
||||
initializes the mouse driver.
|
||||
Returns : AX = Non-Zero (If Mouse is installed, 0 if not)
|
||||
BX = Number of Mouse Buttons
|
||||
FUNCTION: AX = 1h
|
||||
Description: Increments the mouse cursor display counter.
|
||||
Returns : Nothing
|
||||
|
||||
FUNCTION: AX = 2h
|
||||
Description: Decrements the mouse cursor display counter.
|
||||
Returns : Nothing
|
||||
|
||||
FUNCTION: AX = 3h
|
||||
Description: Returns the current mouse position and button status.
|
||||
Returns : BX = Buttons status:
|
||||
Bit 0: Left Button
|
||||
Bit 1: Right Button
|
||||
Bit 2: Center Button
|
||||
CX = Horizontal Coordinate
|
||||
DX = Vertical Coordinate
|
||||
|
||||
FUNCTION: AX = 4h
|
||||
Description: Moves the mouse cursor to a certain position on the screen.
|
||||
Call With : CX = Horizontal Coordinate
|
||||
DX = Vertical Coordinate
|
||||
Returns : Nothing
|
||||
|
||||
FUNCTION: AX = 5h
|
||||
Description: Reports on the status and numbers of presses for a
|
||||
button.
|
||||
Call with : BX = Button to Check
|
||||
0 = Left Button
|
||||
1 = Right Button
|
||||
2 = Center Button
|
||||
Returns : AX = Button Status
|
||||
Bit 0 = Left Button
|
||||
Bit 1 = Right Button
|
||||
Bit 2 = Center Button
|
||||
BX = Button Press Counter
|
||||
CX = Horizontal Coordinate of Last Button Press
|
||||
DX = Vertical Coordinate of Last Button Press
|
||||
|
||||
FUNCTION: AX = 6h
|
||||
Description: Gets the button release information.
|
||||
Call With : BX = Button to Query
|
||||
0 = Left Button
|
||||
1 = Right Button
|
||||
2 = Center Button
|
||||
Returns : AX = Button Status(1 if pressed)
|
||||
Bit 0 = Left Button
|
||||
Bit 1 = Right Button
|
||||
Bit 2 = Center Button
|
||||
BX = Button Release counter
|
||||
CX = Horizontal Coordinate of last button release
|
||||
DX = Vertical Coordinate of last button release
|
||||
|
||||
FUNCTION: AX = 7h
|
||||
Description: Sets the horizontal limits for the mouse cursor.
|
||||
Calls With : CX = Minimum horizontal mouse coordinate.
|
||||
DX = Maximum horizontal mouse coordinate.
|
||||
|
||||
FUNCTION: AX = 8h
|
||||
Description: Sets the vertical limits for the mouse cursor.
|
||||
Call With : CX = Minimum vertical mouse coordinate.
|
||||
DX = Maximum vertical mouse coordinate.
|
||||
Returns : Nothing
|
||||
|
||||
FUNCTION: AX = 9h
|
||||
Description: Defines the shape of the graphics mode cursor.
|
||||
Call With : BX = Hoorizontal hot spot offset
|
||||
CX = Vertical hot spot offset
|
||||
ES = Segment of buffer containing cursor mask
|
||||
DX = Offset of buffer containing cusror mask
|
||||
|
||||
Returns : Nothing
|
||||
|
||||
FUNCTION: AX = 0Ah
|
||||
Description: Definesthe shape of the text mode cursor
|
||||
Call With : BX = Cursor Type
|
||||
0 = Software Cursor
|
||||
1 = Hardware cursor
|
||||
if BX = 0 then
|
||||
CX = Screen Mask value
|
||||
DX = Cursor Mask Value
|
||||
else
|
||||
CX = Starting Scan Line For Cursor
|
||||
DX = Ending Scan Line For Cursor
|
||||
|
||||
FUNCTION: AX = 0Bh
|
||||
Description: Returns the net mouse movement since the last call
|
||||
to this function(or since the mouse was initialized).
|
||||
Returns : CX = Horizontal mouse movement(in Mickeys)
|
||||
DX = Vertical mouse movement(in Mickeys)
|
||||
|
||||
FUNCTION: AX = 0Ch
|
||||
Description: Sets the user defined mouse handler.
|
||||
Call With : CX = Event Mask
|
||||
|
||||
Bit If set
|
||||
0 Mouse Cursor 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
|
||||
|
||||
ES = Segment of your mouse handler code
|
||||
DX = Offset of your mouse handler code
|
||||
Returns : AX = Event Mask
|
||||
BX = Button Status(1 if pressed)
|
||||
Bit 0 = Left Button
|
||||
Bit 1 = Right Button
|
||||
Bit 2 = Center Button
|
||||
CX = Horizontal Coordinate
|
||||
DX = Vertical Coordinate
|
||||
|
||||
FUNCTION: AX = 2Ah
|
||||
Description: Returns display counter state, and current hot spot
|
||||
Returns : BX = Horizontal offset of hot spot
|
||||
CX = Vertical offset of hot spot
|
||||
|
||||
|
||||
|
||||
A complete list of mouse function calls can be found in the file GMOUSE.TXT,
|
||||
the file contains calls for both Microsoft (2 button) and Genius (3 button)
|
||||
modes.
|
||||
|
||||
Writing Custom Handlers
|
||||
-----------------------
|
||||
|
||||
Most mouse drivers do not support SVGA modes, so you must write custom
|
||||
handlers if you want mouse support for these modes.
|
||||
|
||||
Rather than writing an entire mouse driver, you can write a simple handler
|
||||
routine to take care of the graphics and tell the mouse driver to call it
|
||||
whenever the mouse does anything. This function is descibed in the GMOUSE.DOC
|
||||
file, but this demo Pascal program shows the general idea. It sets mode 13h,
|
||||
resets the mouse and waits for a key to be pressed. Whenever you do anything
|
||||
to the mouse (moving it or pressing a button) the handler will get called
|
||||
and it will draw a pixel on the screen. The color of the pixel depends on
|
||||
which buttons are being pressed.
|
||||
|
||||
Uses Crt, Dos;
|
||||
|
||||
{$F+}
|
||||
{ called with bl = buttons, cx = x * 2, dx = y }
|
||||
procedure Handler; far; assembler;
|
||||
asm
|
||||
|
||||
{ This mouse "handler" just draws a pixel at the current mouse pos }
|
||||
pusha
|
||||
push es ; pusha doesn't save es
|
||||
mov ax, $A000
|
||||
mov es, ax
|
||||
shr cx, 1
|
||||
xchg dh, dl
|
||||
mov di, dx
|
||||
shr dx, 2
|
||||
add di, dx
|
||||
add di, cx
|
||||
mov al, bl
|
||||
inc al
|
||||
stosb
|
||||
pop es
|
||||
popa
|
||||
end;
|
||||
{$F-}
|
||||
|
||||
begin
|
||||
asm
|
||||
|
||||
{ Set graphics mode 13h }
|
||||
mov ax, $13
|
||||
int $10
|
||||
|
||||
{ Initialize mouse driver }
|
||||
xor ax, ax
|
||||
int $33
|
||||
|
||||
{ Install custom handler }
|
||||
mov ax, SEG Handler
|
||||
mov es, ax
|
||||
mov dx, OFS Handler
|
||||
mov ax, 12
|
||||
mov cx, $1F
|
||||
int $33
|
||||
|
||||
{ Wait for a key press }
|
||||
xor ah, ah
|
||||
int $16
|
||||
|
||||
{ Back to text mode }
|
||||
mov ax, 3
|
||||
int $10
|
||||
end;
|
||||
end.
|
||||
|
||||
|
||||
|
||||
|
||||
Alternatively you may wish to write your own interrupt handler to process
|
||||
mouse events as they happen. When a mouse event occurs, 3 interrupts are
|
||||
generated and the bytes are available via the COM port.
|
||||
|
||||
----------------------------
|
||||
| Interrupt Port |
|
||||
----------------------------
|
||||
| COM1 $0C $3F8 |
|
||||
| COM2 $0B $3F8 |
|
||||
----------------------------
|
||||
|
||||
The three bytes sent are formatted as follows:
|
||||
|
||||
|
||||
1st byte 2nd byte 3rd byte
|
||||
----------------- --------------- ---------------
|
||||
|-|1|?|?|X|X|Y|Y| - |0|X|X|X|X|X|X| |0|Y|Y|Y|Y|Y|Y|
|
||||
----------------- --------------- ---------------
|
||||
| | \ / \ / | |
|
||||
| | | | | |
|
||||
| | | ------------- ---------- |
|
||||
| | ---------- | \ \ |
|
||||
| | \_\_ _ _ _ _ _ _ \_\_ _ _ _ _ _ _
|
||||
| | |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_|
|
||||
| | X increment Y increment
|
||||
Left Button -- |
|
||||
Right Button ----
|
||||
|
||||
|
||||
The X and Y increment values are in 2's compliment signed char format. (BTW
|
||||
thanks go to Adam Seychell for posting this info to comp.os.msdos.programmer).
|
||||
|
||||
|
||||
A simple Borland Pascal 7.0 mouse handler follows. First we declare a few
|
||||
things we'll need:
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Uses Crt, Dos;
|
||||
|
||||
{$F+}
|
||||
|
||||
const COM1INTR = $0C;
|
||||
COM1PORT = $3F8;
|
||||
|
||||
var bytenum : word;
|
||||
combytes : array[0..2] of byte;
|
||||
x, y : longint;
|
||||
button1, button2 : boolean;
|
||||
MouseHandler : procedure;
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The bytenum variable is used to keep track of which byte is expected next
|
||||
(ie 0, 1 or 2). The combytes variable is simply an array to keep track of
|
||||
bytes received so far. The mouse position will be stored in the x and y
|
||||
variables (note that this example will not perfrom any range checking).
|
||||
button1 and button2 will be used to store the states of each of the buttons.
|
||||
MouseHandler will be used to store the normal mouse driver event handler.
|
||||
We'll also need it to reset everything once we are finished.
|
||||
|
||||
Here's the actual handler:
|
||||
|
||||
----------------------------------------------------------------------
|
||||
procedure MyMouseHandler; Interrupt;
|
||||
var dx, dy : integer;
|
||||
var inbyte : byte;
|
||||
begin
|
||||
|
||||
{ Get the port byte }
|
||||
inbyte := Port[COM1PORT];
|
||||
|
||||
{ Make sure we are properly "synched" }
|
||||
if (inbyte and 64) = 64 then bytenum := 0;
|
||||
|
||||
{ Store the byte and adjust bytenum }
|
||||
combytes[bytenum] := inbyte;
|
||||
inc(bytenum);
|
||||
|
||||
{ Have we received all 3 bytes? }
|
||||
if bytenum = 3 then
|
||||
begin
|
||||
|
||||
{ Yes, so process them }
|
||||
dx := (combytes[0] and 3) shl 6 + combytes[1];
|
||||
dy := (combytes[0] and 12) shl 4 + combytes[2];
|
||||
if dx >= 128 then dx := dx - 256;
|
||||
if dy >= 128 then dy := dy - 256;
|
||||
x := x + dx;
|
||||
y := y + dy;
|
||||
button1 := (combytes[0] And 32) <> 0;
|
||||
button2 := (combytes[0] And 16) <> 0;
|
||||
|
||||
{ And start on first byte again }
|
||||
bytenum := 0;
|
||||
end;
|
||||
|
||||
{ Acknowledge the interrupt }
|
||||
Port[$20] := $20;
|
||||
end;
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Once again pretty simple stuff. We just read the byte from the com1 port and
|
||||
figure out if it's time to do anything yet. If bit 6 is set to 1 then we
|
||||
know that it's meant to be the first byte of the 3, so we reset our
|
||||
bytenum variable to zero (in a perfect world bytes would always come in 3's
|
||||
and we would never need to check, but it never hurts to be careful).
|
||||
|
||||
When 3 bytes have been received we simple decode them according to the
|
||||
diagram above and update the appropriate variables accordingly.
|
||||
|
||||
The 'Port[$20] := $20;' command just lets the interrupt controller know we
|
||||
have processed the interrupt so it can send us the next one when it wants to.
|
||||
|
||||
Note that the above "handler" does nothing more than keep track of the
|
||||
current mouse position and button states. If we were writing a proper mouse
|
||||
driver for an SVGA game we would also have to write custom cursor routines.
|
||||
I'll leave that bit to you!
|
||||
|
||||
To actually install our mouse driver we'll have to set up all the variables,
|
||||
save the address of the current mouse handler and install our own. We'll
|
||||
also need call the existing mouse driver to set up the COM1 port to make
|
||||
sure it sends us the mouse bytes as it receives them. We could do this
|
||||
ourselves, but why make life harder than it already is?
|
||||
|
||||
----------------------------------------------------------------------
|
||||
procedure InitMyDriver;
|
||||
begin
|
||||
|
||||
{ Initialize the normal mouse handler }
|
||||
asm
|
||||
mov ax, 0
|
||||
int $33
|
||||
end;
|
||||
|
||||
{ Initialize some of the variables we'll be using }
|
||||
bytenum := 0;
|
||||
x := 0;
|
||||
y := 0;
|
||||
button1 := false;
|
||||
button2 := false;
|
||||
|
||||
{ Save the current mouse handler and set up our own }
|
||||
GetIntVec(COM1INTR, @MouseHandler);
|
||||
SetIntVec(COM1INTR, Addr(MyMouseHandler));
|
||||
end;
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
||||
And finally when our program is finished it'll need to clean up after
|
||||
itself and return control back to the normal mouse driver:
|
||||
|
||||
----------------------------------------------------------------------
|
||||
procedure CleanUpMyDriver;
|
||||
begin
|
||||
SetIntVec(COM1INTR, @MouseHandler);
|
||||
end;
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
||||
This little bit of source will test the above code. It does nothing more
|
||||
than repeatedly write the mouse position and button states to the screen
|
||||
until a keyboard key is pressed:
|
||||
|
||||
----------------------------------------------------------------------
|
||||
begin
|
||||
ClrScr;
|
||||
InitMyDriver;
|
||||
while not keypressed do
|
||||
WriteLn(x : 5, y : 5, button1 : 7, button2 : 7);
|
||||
CleanUpMyDriver;
|
||||
end.
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user