2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
5 * PURPOSE: VDM 32-bit compatible MOUSE.COM driver
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
9 /* INCLUDES *******************************************************************/
16 #include "hardware/mouse.h"
17 #include "hardware/ps2.h"
18 #include "hardware/pic.h"
19 #include "hardware/video/vga.h"
22 #include "bios/bios.h"
23 #include "bios/bios32/bios32p.h"
26 #include "dos32krnl/dos.h"
28 /* PRIVATE VARIABLES **********************************************************/
30 #define MICKEYS_PER_CELL_HORIZ 8
31 #define MICKEYS_PER_CELL_VERT 16
33 static MOUSE_PACKET Packet
;
34 static INT ByteCounter
= 0;
35 static BOOLEAN DriverEnabled
= FALSE
;
36 static MOUSE_DRIVER_STATE DriverState
;
37 static DWORD OldIrqHandler
;
39 /* PRIVATE FUNCTIONS **********************************************************/
41 extern VOID WINAPI
BiosMouseIrq(LPWORD Stack
);
43 static VOID
PaintMouseCursor(VOID
)
45 if (Bda
->VideoMode
<= 3)
48 WORD CellX
= DriverState
.Position
.X
/ 8;
49 WORD CellY
= DriverState
.Position
.Y
/ 8;
50 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Bda
->VideoPage
* Bda
->VideoPageSize
);
52 EmulatorReadMemory(&EmulatorContext
,
54 + (CellY
* Bda
->ScreenColumns
+ CellX
) * sizeof(WORD
),
58 DriverState
.Character
= Character
;
59 Character
&= DriverState
.TextCursor
.ScreenMask
;
60 Character
^= DriverState
.TextCursor
.CursorMask
;
62 EmulatorWriteMemory(&EmulatorContext
,
64 + (CellY
* Bda
->ScreenColumns
+ CellX
) * sizeof(WORD
),
70 // TODO: NOT IMPLEMENTED
75 static VOID
EraseMouseCursor(VOID
)
77 if (Bda
->VideoMode
<= 3)
79 WORD CellX
= DriverState
.Position
.X
/ 8;
80 WORD CellY
= DriverState
.Position
.Y
/ 8;
81 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Bda
->VideoPage
* Bda
->VideoPageSize
);
83 EmulatorWriteMemory(&EmulatorContext
,
85 + (CellY
* Bda
->ScreenColumns
+ CellX
) * sizeof(WORD
),
86 (LPVOID
)&DriverState
.Character
,
91 // TODO: NOT IMPLEMENTED
96 static VOID
ToMouseCoordinates(PCOORD Position
)
98 COORD Resolution
= VgaGetDisplayResolution();
99 WORD Width
= DriverState
.MaxX
- DriverState
.MinX
+ 1;
100 WORD Height
= DriverState
.MaxY
- DriverState
.MinY
+ 1;
102 if (!VgaGetDoubleVisionState(NULL
, NULL
))
108 Position
->X
= DriverState
.MinX
+ ((Position
->X
* Width
) / Resolution
.X
);
109 Position
->Y
= DriverState
.MinY
+ ((Position
->Y
* Height
) / Resolution
.Y
);
112 static VOID
FromMouseCoordinates(PCOORD Position
)
114 COORD Resolution
= VgaGetDisplayResolution();
115 WORD Width
= DriverState
.MaxX
- DriverState
.MinX
+ 1;
116 WORD Height
= DriverState
.MaxY
- DriverState
.MinY
+ 1;
118 if (!VgaGetDoubleVisionState(NULL
, NULL
))
124 Position
->X
= (((Position
->X
- DriverState
.MinX
) * Resolution
.X
) / Width
);
125 Position
->Y
= (((Position
->Y
- DriverState
.MinY
) * Resolution
.Y
) / Height
);
128 static VOID
CallMouseUserHandlers(USHORT CallMask
)
131 USHORT AX
, BX
, CX
, DX
, SI
, DI
;
132 COORD Position
= DriverState
.Position
;
134 ToMouseCoordinates(&Position
);
137 if ((DriverState
.Handler0
.CallMask
& CallMask
) != 0 &&
138 DriverState
.Handler0
.Callback
!= (ULONG
)NULL
)
141 * Set the parameters for the callback.
142 * NOTE: In text modes, the row and column will be reported
143 * as a multiple of the cell size, typically 8x8 pixels.
154 setBX(DriverState
.ButtonState
);
157 setSI(MICKEYS_PER_CELL_HORIZ
);
158 setDI(MICKEYS_PER_CELL_VERT
);
160 DPRINT("Calling Handler0 %04X:%04X with CallMask 0x%04X\n",
161 HIWORD(DriverState
.Handler0
.Callback
),
162 LOWORD(DriverState
.Handler0
.Callback
),
165 /* Call the callback */
166 RunCallback16(&DosContext
, DriverState
.Handler0
.Callback
);
176 for (i
= 0; i
< sizeof(DriverState
.Handlers
)/sizeof(DriverState
.Handlers
[0]); ++i
)
178 /* Call the suitable handlers */
179 if ((DriverState
.Handlers
[i
].CallMask
& CallMask
) != 0 &&
180 DriverState
.Handlers
[i
].Callback
!= (ULONG
)NULL
)
183 * Set the parameters for the callback.
184 * NOTE: In text modes, the row and column will be reported
185 * as a multiple of the cell size, typically 8x8 pixels.
196 setBX(DriverState
.ButtonState
);
199 setSI(MICKEYS_PER_CELL_HORIZ
);
200 setDI(MICKEYS_PER_CELL_VERT
);
202 DPRINT1("Calling Handler[%d] %04X:%04X with CallMask 0x%04X\n",
204 HIWORD(DriverState
.Handlers
[i
].Callback
),
205 LOWORD(DriverState
.Handlers
[i
].Callback
),
208 /* Call the callback */
209 RunCallback16(&DosContext
, DriverState
.Handlers
[i
].Callback
);
221 static inline VOID
DosUpdatePosition(PCOORD NewPosition
)
223 COORD Resolution
= VgaGetDisplayResolution();
225 /* Check for text mode */
226 if (!VgaGetDoubleVisionState(NULL
, NULL
))
232 if (DriverState
.ShowCount
> 0) EraseMouseCursor();
233 DriverState
.Position
= *NewPosition
;
235 /* Apply the clipping rectangle */
236 if (DriverState
.Position
.X
< DriverState
.MinX
) DriverState
.Position
.X
= DriverState
.MinX
;
237 if (DriverState
.Position
.X
> DriverState
.MaxX
) DriverState
.Position
.X
= DriverState
.MaxX
;
238 if (DriverState
.Position
.Y
< DriverState
.MinY
) DriverState
.Position
.Y
= DriverState
.MinY
;
239 if (DriverState
.Position
.Y
> DriverState
.MaxY
) DriverState
.Position
.Y
= DriverState
.MaxY
;
241 if (DriverState
.ShowCount
> 0) PaintMouseCursor();
243 /* Call the mouse handlers */
244 CallMouseUserHandlers(0x0001); // We use MS MOUSE v1.0+ format
247 static inline VOID
DosUpdateButtons(BYTE ButtonState
)
250 USHORT CallMask
= 0x0000; // We use MS MOUSE v1.0+ format
252 for (i
= 0; i
< NUM_MOUSE_BUTTONS
; i
++)
254 BOOLEAN OldState
= (DriverState
.ButtonState
>> i
) & 1;
255 BOOLEAN NewState
= (ButtonState
>> i
) & 1;
257 if (NewState
> OldState
)
260 DriverState
.PressCount
[i
]++;
261 DriverState
.LastPress
[i
] = DriverState
.Position
;
263 CallMask
|= (1 << (2 * i
+ 1));
265 else if (NewState
< OldState
)
268 DriverState
.ReleaseCount
[i
]++;
269 DriverState
.LastRelease
[i
] = DriverState
.Position
;
271 CallMask
|= (1 << (2 * i
+ 2));
275 DriverState
.ButtonState
= ButtonState
;
277 /* Call the mouse handlers */
278 CallMouseUserHandlers(CallMask
);
281 static VOID WINAPI
DosMouseIrq(LPWORD Stack
)
290 Packet
.Flags
= IOReadB(PS2_DATA_PORT
);
296 Packet
.HorzCounter
= IOReadB(PS2_DATA_PORT
);
302 Packet
.VertCounter
= IOReadB(PS2_DATA_PORT
);
308 /* Shouldn't happen */
313 if (++ByteCounter
== 3)
315 SHORT DeltaX
= Packet
.HorzCounter
;
316 SHORT DeltaY
= Packet
.VertCounter
;
318 /* Adjust the sign */
319 if (Packet
.Flags
& MOUSE_X_SIGN
) DeltaX
= -DeltaX
;
320 if (Packet
.Flags
& MOUSE_Y_SIGN
) DeltaY
= -DeltaY
;
322 DriverState
.HorizCount
+= DeltaX
;
323 DriverState
.VertCount
+= DeltaY
;
329 * Get the absolute position directly from the mouse, this is the only
330 * way to perfectly synchronize the host and guest mouse pointer.
332 MouseGetDataFast(&Position
, &ButtonState
);
334 /* Call the update subroutines */
335 DosUpdatePosition(&Position
);
336 DosUpdateButtons(ButtonState
);
338 /* Complete the IRQ */
339 PicIRQComplete(Stack
);
342 static VOID WINAPI
DosMouseService(LPWORD Stack
)
351 DriverState
.ShowCount
= 0;
352 DriverState
.ButtonState
= 0;
354 /* Initialize the default clipping range */
355 DriverState
.MinX
= 0;
356 DriverState
.MaxX
= MOUSE_MAX_HORIZ
- 1;
357 DriverState
.MinY
= 0;
358 DriverState
.MaxY
= MOUSE_MAX_VERT
- 1;
360 /* Set the default text cursor */
361 DriverState
.TextCursor
.ScreenMask
= 0xFFFF; /* Display everything */
362 DriverState
.TextCursor
.CursorMask
= 0xFF00; /* ... but with inverted attributes */
364 /* Set the default graphics cursor */
365 DriverState
.GraphicsCursor
.HotSpot
.X
= 3;
366 DriverState
.GraphicsCursor
.HotSpot
.Y
= 1;
368 DriverState
.GraphicsCursor
.ScreenMask
[0] = 0xC3FF; // 1100001111111111
369 DriverState
.GraphicsCursor
.ScreenMask
[1] = 0xC0FF; // 1100000011111111
370 DriverState
.GraphicsCursor
.ScreenMask
[2] = 0xC07F; // 1100000001111111
371 DriverState
.GraphicsCursor
.ScreenMask
[3] = 0xC01F; // 1100000000011111
372 DriverState
.GraphicsCursor
.ScreenMask
[4] = 0xC00F; // 1100000000001111
373 DriverState
.GraphicsCursor
.ScreenMask
[5] = 0xC007; // 1100000000000111
374 DriverState
.GraphicsCursor
.ScreenMask
[6] = 0xC003; // 1100000000000011
375 DriverState
.GraphicsCursor
.ScreenMask
[7] = 0xC007; // 1100000000000111
376 DriverState
.GraphicsCursor
.ScreenMask
[8] = 0xC01F; // 1100000000011111
377 DriverState
.GraphicsCursor
.ScreenMask
[9] = 0xC01F; // 1100000000011111
378 DriverState
.GraphicsCursor
.ScreenMask
[10] = 0xC00F; // 1100000000001111
379 DriverState
.GraphicsCursor
.ScreenMask
[11] = 0xC60F; // 1100011000001111
380 DriverState
.GraphicsCursor
.ScreenMask
[12] = 0xFF07; // 1111111100000111
381 DriverState
.GraphicsCursor
.ScreenMask
[13] = 0xFF07; // 1111111100000111
382 DriverState
.GraphicsCursor
.ScreenMask
[14] = 0xFF87; // 1111111110000111
383 DriverState
.GraphicsCursor
.ScreenMask
[15] = 0xFFCF; // 1111111111001111
385 DriverState
.GraphicsCursor
.CursorMask
[0] = 0x0000; // 0000000000000000
386 DriverState
.GraphicsCursor
.CursorMask
[1] = 0x1C00; // 0001110000000000
387 DriverState
.GraphicsCursor
.CursorMask
[2] = 0x1F00; // 0001111100000000
388 DriverState
.GraphicsCursor
.CursorMask
[3] = 0x1F80; // 0001111110000000
389 DriverState
.GraphicsCursor
.CursorMask
[4] = 0x1FE0; // 0001111111100000
390 DriverState
.GraphicsCursor
.CursorMask
[5] = 0x1FF0; // 0001111111110000
391 DriverState
.GraphicsCursor
.CursorMask
[6] = 0x1FF8; // 0001111111111000
392 DriverState
.GraphicsCursor
.CursorMask
[7] = 0x1FE0; // 0001111111100000
393 DriverState
.GraphicsCursor
.CursorMask
[8] = 0x1FC0; // 0001111111000000
394 DriverState
.GraphicsCursor
.CursorMask
[9] = 0x1FC0; // 0001111111000000
395 DriverState
.GraphicsCursor
.CursorMask
[10] = 0x19E0; // 0001100111100000
396 DriverState
.GraphicsCursor
.CursorMask
[11] = 0x00E0; // 0000000011100000
397 DriverState
.GraphicsCursor
.CursorMask
[12] = 0x0070; // 0000000001110000
398 DriverState
.GraphicsCursor
.CursorMask
[13] = 0x0070; // 0000000001110000
399 DriverState
.GraphicsCursor
.CursorMask
[14] = 0x0030; // 0000000000110000
400 DriverState
.GraphicsCursor
.CursorMask
[15] = 0x0000; // 0000000000000000
402 /* Initialize the counters */
403 DriverState
.HorizCount
= DriverState
.VertCount
= 0;
405 for (i
= 0; i
< NUM_MOUSE_BUTTONS
; i
++)
407 DriverState
.PressCount
[i
] = DriverState
.ReleaseCount
[i
] = 0;
410 /* Return mouse information */
411 setAX(0xFFFF); // Hardware & driver installed
412 setBX(NUM_MOUSE_BUTTONS
);
417 /* Show Mouse Cursor */
420 DriverState
.ShowCount
++;
421 if (DriverState
.ShowCount
== 1) PaintMouseCursor();
426 /* Hide Mouse Cursor */
429 DriverState
.ShowCount
--;
430 if (DriverState
.ShowCount
== 0) EraseMouseCursor();
435 /* Return Position And Button Status */
438 COORD Position
= DriverState
.Position
;
439 ToMouseCoordinates(&Position
);
441 setBX(DriverState
.ButtonState
);
447 /* Position Mouse Cursor */
450 COORD Position
= { getCX(), getDX() };
451 FromMouseCoordinates(&Position
);
453 DriverState
.Position
= Position
;
457 /* Return Button Press Data */
460 WORD Button
= getBX();
461 COORD LastPress
= DriverState
.LastPress
[Button
];
462 ToMouseCoordinates(&LastPress
);
464 setAX(DriverState
.ButtonState
);
465 setBX(DriverState
.PressCount
[Button
]);
469 /* Reset the counter */
470 DriverState
.PressCount
[Button
] = 0;
475 /* Return Button Release Data */
478 WORD Button
= getBX();
479 COORD LastRelease
= DriverState
.LastRelease
[Button
];
480 ToMouseCoordinates(&LastRelease
);
482 setAX(DriverState
.ButtonState
);
483 setBX(DriverState
.ReleaseCount
[Button
]);
484 setCX(LastRelease
.X
);
485 setDX(LastRelease
.Y
);
487 /* Reset the counter */
488 DriverState
.ReleaseCount
[Button
] = 0;
494 /* Define Horizontal Cursor Range */
497 DPRINT("Setting mouse horizontal range: %u - %u\n", getCX(), getDX());
498 DriverState
.MinX
= getCX();
499 DriverState
.MaxX
= getDX();
503 /* Define Vertical Cursor Range */
506 DPRINT("Setting mouse vertical range: %u - %u\n", getCX(), getDX());
507 DriverState
.MinY
= getCX();
508 DriverState
.MaxY
= getDX();
512 /* Define Graphics Cursor */
515 PWORD MaskBitmap
= (PWORD
)SEG_OFF_TO_PTR(getES(), getDX());
517 DriverState
.GraphicsCursor
.HotSpot
.X
= getBX();
518 DriverState
.GraphicsCursor
.HotSpot
.Y
= getCX();
520 RtlCopyMemory(DriverState
.GraphicsCursor
.ScreenMask
,
522 sizeof(DriverState
.GraphicsCursor
.ScreenMask
));
524 RtlCopyMemory(DriverState
.GraphicsCursor
.CursorMask
,
526 sizeof(DriverState
.GraphicsCursor
.CursorMask
));
531 /* Define Text Cursor */
538 /* Define software cursor */
539 DriverState
.TextCursor
.ScreenMask
= getCX();
540 DriverState
.TextCursor
.CursorMask
= getDX();
542 else if (BX
== 0x0001)
544 /* Define hardware cursor */
545 DPRINT1("Defining hardware cursor is unimplemented\n");
547 // CX == start scan line
548 // DX == end scan line
552 DPRINT1("Invalid BX value 0x%04X\n", BX
);
558 /* Read Motion Counters */
561 setCX(DriverState
.HorizCount
);
562 setDX(DriverState
.VertCount
);
564 /* Reset the counters */
565 DriverState
.HorizCount
= DriverState
.VertCount
= 0;
570 /* Define Interrupt Subroutine Parameters, compatible MS MOUSE v1.0+ */
573 DriverState
.Handler0
.CallMask
= getCX();
574 DriverState
.Handler0
.Callback
= MAKELONG(getDX(), getES()); // Far pointer to the callback
575 DPRINT1("Define callback 0x%04X, %04X:%04X\n",
576 DriverState
.Handler0
.CallMask
,
577 HIWORD(DriverState
.Handler0
.Callback
),
578 LOWORD(DriverState
.Handler0
.Callback
));
582 /* Define Mickey/Pixel Ratio */
585 /* This call should be completely ignored */
589 /* Exchange Interrupt Subroutines, compatible MS MOUSE v3.0+ (see function 0x0C) */
592 USHORT OldCallMask
= DriverState
.Handler0
.CallMask
;
593 ULONG OldCallback
= DriverState
.Handler0
.Callback
;
595 DriverState
.Handler0
.CallMask
= getCX();
596 DriverState
.Handler0
.Callback
= MAKELONG(getDX(), getES()); // Far pointer to the callback
598 /* Return old callmask in CX and callback vector in ES:DX */
600 setES(HIWORD(OldCallback
));
601 setDX(LOWORD(OldCallback
));
606 /* Return Driver Storage Requirements */
609 setBX(sizeof(MOUSE_DRIVER_STATE
));
613 /* Save Driver State */
616 *((PMOUSE_DRIVER_STATE
)SEG_OFF_TO_PTR(getES(), getDX())) = DriverState
;
620 /* Restore Driver State */
623 DriverState
= *((PMOUSE_DRIVER_STATE
)SEG_OFF_TO_PTR(getES(), getDX()));
627 /* Set Alternate Mouse User Handler, compatible MS MOUSE v6.0+ */
631 * Up to three handlers can be defined by separate calls to this
632 * function, each with a different combination of shift states in
633 * the call mask; calling this function again with a call mask of
634 * 0000h undefines the specified handler (official documentation);
635 * specifying the same call mask and an address of 0000h:0000h
636 * undefines the handler (real life).
637 * See Ralf Brown: http://www.ctyme.com/intr/rb-5981.htm
638 * for more information.
642 USHORT CallMask
= getCX();
643 ULONG Callback
= MAKELONG(getDX(), getES()); // Far pointer to the callback
644 BOOLEAN Success
= FALSE
;
646 DPRINT1("Define v6.0+ callback 0x%04X, %04X:%04X\n",
647 CallMask
, HIWORD(Callback
), LOWORD(Callback
));
649 if (CallMask
== 0x0000)
652 * Find the handler entry corresponding to the given
653 * callback and undefine it.
655 for (i
= 0; i
< sizeof(DriverState
.Handlers
)/sizeof(DriverState
.Handlers
[0]); ++i
)
657 if (DriverState
.Handlers
[i
].Callback
== Callback
)
659 /* Found it, undefine the handler */
660 DriverState
.Handlers
[i
].CallMask
= 0x0000;
661 DriverState
.Handlers
[i
].Callback
= (ULONG
)NULL
;
667 else if (Callback
== (ULONG
)NULL
)
670 * Find the handler entry corresponding to the given
671 * callmask and undefine it.
673 for (i
= 0; i
< sizeof(DriverState
.Handlers
)/sizeof(DriverState
.Handlers
[0]); ++i
)
675 if (DriverState
.Handlers
[i
].CallMask
== CallMask
)
677 /* Found it, undefine the handler */
678 DriverState
.Handlers
[i
].CallMask
= 0x0000;
679 DriverState
.Handlers
[i
].Callback
= (ULONG
)NULL
;
688 * Try to find a handler entry corresponding to the given
689 * callmask to redefine it, otherwise find an empty handler
690 * entry and set the new handler in there.
693 USHORT EmptyHandler
= 0xFFFF; // Invalid handler
695 for (i
= 0; i
< sizeof(DriverState
.Handlers
)/sizeof(DriverState
.Handlers
[0]); ++i
)
697 /* Find the first empty handler */
698 if (EmptyHandler
== 0xFFFF &&
699 DriverState
.Handlers
[i
].CallMask
== 0x0000 &&
700 DriverState
.Handlers
[i
].Callback
== (ULONG
)NULL
)
705 if (DriverState
.Handlers
[i
].CallMask
== CallMask
)
707 /* Found it, redefine the handler */
708 DriverState
.Handlers
[i
].CallMask
= CallMask
;
709 DriverState
.Handlers
[i
].Callback
= Callback
;
716 * If we haven't found anything and we found
717 * an empty handler, set it.
719 if (!Success
&& EmptyHandler
!= 0xFFFF
720 /* && EmptyHandler < sizeof(DriverState.Handlers)/sizeof(DriverState.Handlers[0]) */)
722 DriverState
.Handlers
[EmptyHandler
].CallMask
= CallMask
;
723 DriverState
.Handlers
[EmptyHandler
].Callback
= Callback
;
728 /* If we failed, set error code */
729 if (!Success
) setAX(0xFFFF);
734 /* Return User Alternate Interrupt Vector, compatible MS MOUSE v6.0+ */
738 USHORT CallMask
= getCX();
740 BOOLEAN Success
= FALSE
;
743 * Find the handler entry corresponding to the given callmask.
745 for (i
= 0; i
< sizeof(DriverState
.Handlers
)/sizeof(DriverState
.Handlers
[0]); ++i
)
747 if (DriverState
.Handlers
[i
].CallMask
== CallMask
)
750 Callback
= DriverState
.Handlers
[i
].Callback
;
758 /* Return the callback vector in BX:DX */
759 setBX(HIWORD(Callback
));
760 setDX(LOWORD(Callback
));
764 /* We failed, set error code */
771 /* Disable Mouse Driver */
781 /* Enable Mouse Driver */
790 DPRINT1("BIOS Function INT 33h, AX = 0x%04X NOT IMPLEMENTED\n", getAX());
795 /* PUBLIC FUNCTIONS ***********************************************************/
797 VOID
DosMouseEnable(VOID
)
801 DriverEnabled
= TRUE
;
803 /* Get the old IRQ handler */
804 OldIrqHandler
= ((PDWORD
)BaseAddress
)[MOUSE_IRQ_INT
];
806 /* Set the IRQ handler */
807 RegisterDosInt32(MOUSE_IRQ_INT
, DosMouseIrq
);
809 /* Enable packet reporting */
810 IOWriteB(PS2_CONTROL_PORT
, 0xD4);
811 IOWriteB(PS2_DATA_PORT
, 0xF4);
813 /* Read the mouse ACK reply */
818 VOID
DosMouseDisable(VOID
)
822 /* Restore the old IRQ handler */
823 ((PDWORD
)BaseAddress
)[MOUSE_IRQ_INT
] = OldIrqHandler
;
825 DriverEnabled
= FALSE
;
829 VOID
DosMouseUpdatePosition(PCOORD NewPosition
)
831 SHORT DeltaX
= NewPosition
->X
- DriverState
.Position
.X
;
832 SHORT DeltaY
= NewPosition
->Y
- DriverState
.Position
.Y
;
834 if (!DriverEnabled
) return;
836 DriverState
.HorizCount
+= (DeltaX
* MICKEYS_PER_CELL_HORIZ
) / 8;
837 DriverState
.VertCount
+= (DeltaY
* MICKEYS_PER_CELL_VERT
) / 8;
839 if (DriverState
.ShowCount
> 0) EraseMouseCursor();
840 DriverState
.Position
= *NewPosition
;
841 if (DriverState
.ShowCount
> 0) PaintMouseCursor();
843 /* Call the mouse handlers */
844 // if (DeltaX || DeltaY)
845 CallMouseUserHandlers(0x0001); // We use MS MOUSE v1.0+ format
848 VOID
DosMouseUpdateButtons(WORD ButtonState
)
851 USHORT CallMask
= 0x0000; // We use MS MOUSE v1.0+ format
853 if (!DriverEnabled
) return;
855 for (i
= 0; i
< NUM_MOUSE_BUTTONS
; i
++)
857 BOOLEAN OldState
= (DriverState
.ButtonState
>> i
) & 1;
858 BOOLEAN NewState
= (ButtonState
>> i
) & 1;
860 if (NewState
> OldState
)
863 DriverState
.PressCount
[i
]++;
864 DriverState
.LastPress
[i
] = DriverState
.Position
;
866 CallMask
|= (1 << (2 * i
+ 1));
868 else if (NewState
< OldState
)
871 DriverState
.ReleaseCount
[i
]++;
872 DriverState
.LastRelease
[i
] = DriverState
.Position
;
874 CallMask
|= (1 << (2 * i
+ 2));
878 DriverState
.ButtonState
= ButtonState
;
880 /* Call the mouse handlers */
881 CallMouseUserHandlers(CallMask
);
884 BOOLEAN
DosMouseInitialize(VOID
)
886 /* Clear the state */
887 RtlZeroMemory(&DriverState
, sizeof(DriverState
));
889 /* Initialize the interrupt handler */
890 RegisterDosInt32(DOS_MOUSE_INTERRUPT
, DosMouseService
);
896 VOID
DosMouseCleanup(VOID
)
898 if (DriverState
.ShowCount
> 0) EraseMouseCursor();