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 *******************************************************************/
18 #include "hardware/mouse.h"
19 #include "hardware/ps2.h"
20 #include "hardware/pic.h"
21 #include "hardware/video/vga.h"
24 #include "bios/bios.h"
25 #include "bios/bios32/bios32p.h"
28 #include "dos32krnl/dos.h"
30 /* PRIVATE VARIABLES **********************************************************/
32 #define MICKEYS_PER_CELL_HORIZ 8
33 #define MICKEYS_PER_CELL_VERT 16
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 COORD Position
= DriverState
.Position
;
47 /* Apply the clipping rectangle */
48 if (Position
.X
< DriverState
.MinX
) Position
.X
= DriverState
.MinX
;
49 if (Position
.X
> DriverState
.MaxX
) Position
.X
= DriverState
.MaxX
;
50 if (Position
.Y
< DriverState
.MinY
) Position
.Y
= DriverState
.MinY
;
51 if (Position
.Y
> DriverState
.MaxY
) Position
.Y
= DriverState
.MaxY
;
53 if (Bda
->VideoMode
<= 3)
56 WORD CellX
= Position
.X
/ 8;
57 WORD CellY
= Position
.Y
/ 8;
58 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Bda
->VideoPage
* Bda
->VideoPageSize
);
60 EmulatorReadMemory(&EmulatorContext
,
62 + (CellY
* Bda
->ScreenColumns
+ CellX
) * sizeof(WORD
),
66 DriverState
.Character
= Character
;
67 Character
&= DriverState
.TextCursor
.ScreenMask
;
68 Character
^= DriverState
.TextCursor
.CursorMask
;
70 EmulatorWriteMemory(&EmulatorContext
,
72 + (CellY
* Bda
->ScreenColumns
+ CellX
) * sizeof(WORD
),
78 // TODO: NOT IMPLEMENTED
83 static VOID
EraseMouseCursor(VOID
)
85 COORD Position
= DriverState
.Position
;
87 /* Apply the clipping rectangle */
88 if (Position
.X
< DriverState
.MinX
) Position
.X
= DriverState
.MinX
;
89 if (Position
.X
> DriverState
.MaxX
) Position
.X
= DriverState
.MaxX
;
90 if (Position
.Y
< DriverState
.MinY
) Position
.Y
= DriverState
.MinY
;
91 if (Position
.Y
> DriverState
.MaxY
) Position
.Y
= DriverState
.MaxY
;
93 if (Bda
->VideoMode
<= 3)
95 WORD CellX
= Position
.X
/ 8;
96 WORD CellY
= Position
.Y
/ 8;
97 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Bda
->VideoPage
* Bda
->VideoPageSize
);
99 EmulatorWriteMemory(&EmulatorContext
,
101 + (CellY
* Bda
->ScreenColumns
+ CellX
) * sizeof(WORD
),
102 (LPVOID
)&DriverState
.Character
,
107 // TODO: NOT IMPLEMENTED
112 static VOID
ToMouseCoordinates(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
= DriverState
.MinX
+ ((Position
->X
* Width
) / Resolution
.X
);
125 Position
->Y
= DriverState
.MinY
+ ((Position
->Y
* Height
) / Resolution
.Y
);
128 static VOID
FromMouseCoordinates(PCOORD Position
)
130 COORD Resolution
= VgaGetDisplayResolution();
131 WORD Width
= DriverState
.MaxX
- DriverState
.MinX
+ 1;
132 WORD Height
= DriverState
.MaxY
- DriverState
.MinY
+ 1;
134 if (!VgaGetDoubleVisionState(NULL
, NULL
))
140 Position
->X
= ((Position
->X
- DriverState
.MinX
) * Resolution
.X
) / Width
;
141 Position
->Y
= ((Position
->Y
- DriverState
.MinY
) * Resolution
.Y
) / Height
;
144 static VOID
CallMouseUserHandlers(USHORT CallMask
)
147 USHORT AX
, BX
, CX
, DX
, SI
, DI
;
148 COORD Position
= DriverState
.Position
;
150 ToMouseCoordinates(&Position
);
153 if ((DriverState
.Handler0
.CallMask
& CallMask
) != 0 &&
154 DriverState
.Handler0
.Callback
!= (ULONG
)NULL
)
157 * Set the parameters for the callback.
158 * NOTE: In text modes, the row and column will be reported
159 * as a multiple of the cell size, typically 8x8 pixels.
170 setBX(DriverState
.ButtonState
);
173 setSI(MICKEYS_PER_CELL_HORIZ
);
174 setDI(MICKEYS_PER_CELL_VERT
);
176 DPRINT("Calling Handler0 %04X:%04X with CallMask 0x%04X\n",
177 HIWORD(DriverState
.Handler0
.Callback
),
178 LOWORD(DriverState
.Handler0
.Callback
),
181 /* Call the callback */
182 RunCallback16(&DosContext
, DriverState
.Handler0
.Callback
);
192 for (i
= 0; i
< ARRAYSIZE(DriverState
.Handlers
); ++i
)
194 /* Call the suitable handlers */
195 if ((DriverState
.Handlers
[i
].CallMask
& CallMask
) != 0 &&
196 DriverState
.Handlers
[i
].Callback
!= (ULONG
)NULL
)
199 * Set the parameters for the callback.
200 * NOTE: In text modes, the row and column will be reported
201 * as a multiple of the cell size, typically 8x8 pixels.
212 setBX(DriverState
.ButtonState
);
215 setSI(MICKEYS_PER_CELL_HORIZ
);
216 setDI(MICKEYS_PER_CELL_VERT
);
218 DPRINT1("Calling Handler[%d] %04X:%04X with CallMask 0x%04X\n",
220 HIWORD(DriverState
.Handlers
[i
].Callback
),
221 LOWORD(DriverState
.Handlers
[i
].Callback
),
224 /* Call the callback */
225 RunCallback16(&DosContext
, DriverState
.Handlers
[i
].Callback
);
237 static inline VOID
DosUpdatePosition(PCOORD NewPosition
)
239 COORD Resolution
= VgaGetDisplayResolution();
241 /* Check for text mode */
242 if (!VgaGetDoubleVisionState(NULL
, NULL
))
248 if (DriverState
.ShowCount
> 0) EraseMouseCursor();
249 DriverState
.Position
= *NewPosition
;
250 if (DriverState
.ShowCount
> 0) PaintMouseCursor();
252 /* Call the mouse handlers */
253 CallMouseUserHandlers(0x0001); // We use MS MOUSE v1.0+ format
256 static inline VOID
DosUpdateButtons(BYTE ButtonState
)
259 USHORT CallMask
= 0x0000; // We use MS MOUSE v1.0+ format
261 for (i
= 0; i
< NUM_MOUSE_BUTTONS
; i
++)
263 BOOLEAN OldState
= (DriverState
.ButtonState
>> i
) & 1;
264 BOOLEAN NewState
= (ButtonState
>> i
) & 1;
266 if (NewState
> OldState
)
269 DriverState
.PressCount
[i
]++;
270 DriverState
.LastPress
[i
] = DriverState
.Position
;
272 CallMask
|= (1 << (2 * i
+ 1));
274 else if (NewState
< OldState
)
277 DriverState
.ReleaseCount
[i
]++;
278 DriverState
.LastRelease
[i
] = DriverState
.Position
;
280 CallMask
|= (1 << (2 * i
+ 2));
284 DriverState
.ButtonState
= ButtonState
;
286 /* Call the mouse handlers */
287 CallMouseUserHandlers(CallMask
);
290 static VOID WINAPI
DosMouseIrq(LPWORD Stack
)
293 SHORT DeltaX
, DeltaY
;
297 /* Read the whole packet at once */
298 Flags
= IOReadB(PS2_DATA_PORT
);
300 DeltaX
= IOReadB(PS2_DATA_PORT
);
302 DeltaY
= IOReadB(PS2_DATA_PORT
);
304 /* Adjust the sign */
305 if (Flags
& MOUSE_X_SIGN
) DeltaX
= -DeltaX
;
306 if (Flags
& MOUSE_Y_SIGN
) DeltaY
= -DeltaY
;
308 /* Update the counters */
309 DriverState
.HorizCount
+= DeltaX
;
310 DriverState
.VertCount
+= DeltaY
;
313 * Get the absolute position directly from the mouse, this is the only
314 * way to perfectly synchronize the host and guest mouse pointer.
316 MouseGetDataFast(&Position
, &ButtonState
);
318 /* Call the update subroutines */
319 DosUpdatePosition(&Position
);
320 DosUpdateButtons(ButtonState
);
322 /* Complete the IRQ */
323 PicIRQComplete(Stack
);
326 static VOID WINAPI
DosMouseService(LPWORD Stack
)
335 DriverState
.ShowCount
= 0;
336 DriverState
.ButtonState
= 0;
338 /* Initialize the default clipping range */
339 DriverState
.MinX
= 0;
340 DriverState
.MaxX
= MOUSE_MAX_HORIZ
- 1;
341 DriverState
.MinY
= 0;
342 DriverState
.MaxY
= MOUSE_MAX_VERT
- 1;
344 /* Set the default text cursor */
345 DriverState
.TextCursor
.ScreenMask
= 0xFFFF; /* Display everything */
346 DriverState
.TextCursor
.CursorMask
= 0xFF00; /* ... but with inverted attributes */
348 /* Set the default graphics cursor */
349 DriverState
.GraphicsCursor
.HotSpot
.X
= 3;
350 DriverState
.GraphicsCursor
.HotSpot
.Y
= 1;
352 DriverState
.GraphicsCursor
.ScreenMask
[0] = 0xC3FF; // 1100001111111111
353 DriverState
.GraphicsCursor
.ScreenMask
[1] = 0xC0FF; // 1100000011111111
354 DriverState
.GraphicsCursor
.ScreenMask
[2] = 0xC07F; // 1100000001111111
355 DriverState
.GraphicsCursor
.ScreenMask
[3] = 0xC01F; // 1100000000011111
356 DriverState
.GraphicsCursor
.ScreenMask
[4] = 0xC00F; // 1100000000001111
357 DriverState
.GraphicsCursor
.ScreenMask
[5] = 0xC007; // 1100000000000111
358 DriverState
.GraphicsCursor
.ScreenMask
[6] = 0xC003; // 1100000000000011
359 DriverState
.GraphicsCursor
.ScreenMask
[7] = 0xC007; // 1100000000000111
360 DriverState
.GraphicsCursor
.ScreenMask
[8] = 0xC01F; // 1100000000011111
361 DriverState
.GraphicsCursor
.ScreenMask
[9] = 0xC01F; // 1100000000011111
362 DriverState
.GraphicsCursor
.ScreenMask
[10] = 0xC00F; // 1100000000001111
363 DriverState
.GraphicsCursor
.ScreenMask
[11] = 0xC60F; // 1100011000001111
364 DriverState
.GraphicsCursor
.ScreenMask
[12] = 0xFF07; // 1111111100000111
365 DriverState
.GraphicsCursor
.ScreenMask
[13] = 0xFF07; // 1111111100000111
366 DriverState
.GraphicsCursor
.ScreenMask
[14] = 0xFF87; // 1111111110000111
367 DriverState
.GraphicsCursor
.ScreenMask
[15] = 0xFFCF; // 1111111111001111
369 DriverState
.GraphicsCursor
.CursorMask
[0] = 0x0000; // 0000000000000000
370 DriverState
.GraphicsCursor
.CursorMask
[1] = 0x1C00; // 0001110000000000
371 DriverState
.GraphicsCursor
.CursorMask
[2] = 0x1F00; // 0001111100000000
372 DriverState
.GraphicsCursor
.CursorMask
[3] = 0x1F80; // 0001111110000000
373 DriverState
.GraphicsCursor
.CursorMask
[4] = 0x1FE0; // 0001111111100000
374 DriverState
.GraphicsCursor
.CursorMask
[5] = 0x1FF0; // 0001111111110000
375 DriverState
.GraphicsCursor
.CursorMask
[6] = 0x1FF8; // 0001111111111000
376 DriverState
.GraphicsCursor
.CursorMask
[7] = 0x1FE0; // 0001111111100000
377 DriverState
.GraphicsCursor
.CursorMask
[8] = 0x1FC0; // 0001111111000000
378 DriverState
.GraphicsCursor
.CursorMask
[9] = 0x1FC0; // 0001111111000000
379 DriverState
.GraphicsCursor
.CursorMask
[10] = 0x19E0; // 0001100111100000
380 DriverState
.GraphicsCursor
.CursorMask
[11] = 0x00E0; // 0000000011100000
381 DriverState
.GraphicsCursor
.CursorMask
[12] = 0x0070; // 0000000001110000
382 DriverState
.GraphicsCursor
.CursorMask
[13] = 0x0070; // 0000000001110000
383 DriverState
.GraphicsCursor
.CursorMask
[14] = 0x0030; // 0000000000110000
384 DriverState
.GraphicsCursor
.CursorMask
[15] = 0x0000; // 0000000000000000
386 /* Initialize the counters */
387 DriverState
.HorizCount
= DriverState
.VertCount
= 0;
389 for (i
= 0; i
< NUM_MOUSE_BUTTONS
; i
++)
391 DriverState
.PressCount
[i
] = DriverState
.ReleaseCount
[i
] = 0;
394 /* Return mouse information */
395 setAX(0xFFFF); // Hardware & driver installed
396 setBX(NUM_MOUSE_BUTTONS
);
401 /* Show Mouse Cursor */
404 DriverState
.ShowCount
++;
405 if (DriverState
.ShowCount
== 1) PaintMouseCursor();
410 /* Hide Mouse Cursor */
413 DriverState
.ShowCount
--;
414 if (DriverState
.ShowCount
== 0) EraseMouseCursor();
419 /* Return Position And Button Status */
422 COORD Position
= DriverState
.Position
;
423 ToMouseCoordinates(&Position
);
425 setBX(DriverState
.ButtonState
);
431 /* Position Mouse Cursor */
434 COORD Position
= { getCX(), getDX() };
435 FromMouseCoordinates(&Position
);
437 DriverState
.Position
= Position
;
441 /* Return Button Press Data */
444 WORD Button
= getBX();
445 COORD LastPress
= DriverState
.LastPress
[Button
];
446 ToMouseCoordinates(&LastPress
);
448 setAX(DriverState
.ButtonState
);
449 setBX(DriverState
.PressCount
[Button
]);
453 /* Reset the counter */
454 DriverState
.PressCount
[Button
] = 0;
459 /* Return Button Release Data */
462 WORD Button
= getBX();
463 COORD LastRelease
= DriverState
.LastRelease
[Button
];
464 ToMouseCoordinates(&LastRelease
);
466 setAX(DriverState
.ButtonState
);
467 setBX(DriverState
.ReleaseCount
[Button
]);
468 setCX(LastRelease
.X
);
469 setDX(LastRelease
.Y
);
471 /* Reset the counter */
472 DriverState
.ReleaseCount
[Button
] = 0;
478 /* Define Horizontal Cursor Range */
484 if (!VgaGetDoubleVisionState(NULL
, NULL
))
491 DPRINT("Setting mouse horizontal range: %u - %u\n", Min
, Max
);
492 DriverState
.MinX
= Min
;
493 DriverState
.MaxX
= Max
;
497 /* Define Vertical Cursor Range */
503 if (!VgaGetDoubleVisionState(NULL
, NULL
))
510 DPRINT("Setting mouse vertical range: %u - %u\n", Min
, Max
);
511 DriverState
.MinY
= Min
;
512 DriverState
.MaxY
= Max
;
516 /* Define Graphics Cursor */
519 PWORD MaskBitmap
= (PWORD
)SEG_OFF_TO_PTR(getES(), getDX());
521 DriverState
.GraphicsCursor
.HotSpot
.X
= getBX();
522 DriverState
.GraphicsCursor
.HotSpot
.Y
= getCX();
524 RtlCopyMemory(DriverState
.GraphicsCursor
.ScreenMask
,
526 sizeof(DriverState
.GraphicsCursor
.ScreenMask
));
528 RtlCopyMemory(DriverState
.GraphicsCursor
.CursorMask
,
530 sizeof(DriverState
.GraphicsCursor
.CursorMask
));
535 /* Define Text Cursor */
542 /* Define software cursor */
543 DriverState
.TextCursor
.ScreenMask
= getCX();
544 DriverState
.TextCursor
.CursorMask
= getDX();
546 else if (BX
== 0x0001)
548 /* Define hardware cursor */
549 DPRINT1("Defining hardware cursor is unimplemented\n");
551 // CX == start scan line
552 // DX == end scan line
556 DPRINT1("Invalid BX value 0x%04X\n", BX
);
562 /* Read Motion Counters */
565 setCX(DriverState
.HorizCount
);
566 setDX(DriverState
.VertCount
);
568 /* Reset the counters */
569 DriverState
.HorizCount
= DriverState
.VertCount
= 0;
574 /* Define Interrupt Subroutine Parameters, compatible MS MOUSE v1.0+ */
577 DriverState
.Handler0
.CallMask
= getCX();
578 DriverState
.Handler0
.Callback
= MAKELONG(getDX(), getES()); // Far pointer to the callback
579 DPRINT1("Define callback 0x%04X, %04X:%04X\n",
580 DriverState
.Handler0
.CallMask
,
581 HIWORD(DriverState
.Handler0
.Callback
),
582 LOWORD(DriverState
.Handler0
.Callback
));
586 /* Define Mickey/Pixel Ratio */
589 /* This call should be completely ignored */
593 /* Exchange Interrupt Subroutines, compatible MS MOUSE v3.0+ (see function 0x0C) */
596 USHORT OldCallMask
= DriverState
.Handler0
.CallMask
;
597 ULONG OldCallback
= DriverState
.Handler0
.Callback
;
599 DriverState
.Handler0
.CallMask
= getCX();
600 DriverState
.Handler0
.Callback
= MAKELONG(getDX(), getES()); // Far pointer to the callback
602 /* Return old callmask in CX and callback vector in ES:DX */
604 setES(HIWORD(OldCallback
));
605 setDX(LOWORD(OldCallback
));
610 /* Return Driver Storage Requirements */
613 setBX(sizeof(MOUSE_DRIVER_STATE
));
617 /* Save Driver State */
620 *((PMOUSE_DRIVER_STATE
)SEG_OFF_TO_PTR(getES(), getDX())) = DriverState
;
624 /* Restore Driver State */
627 DriverState
= *((PMOUSE_DRIVER_STATE
)SEG_OFF_TO_PTR(getES(), getDX()));
631 /* Set Alternate Mouse User Handler, compatible MS MOUSE v6.0+ */
635 * Up to three handlers can be defined by separate calls to this
636 * function, each with a different combination of shift states in
637 * the call mask; calling this function again with a call mask of
638 * 0000h undefines the specified handler (official documentation);
639 * specifying the same call mask and an address of 0000h:0000h
640 * undefines the handler (real life).
641 * See Ralf Brown: http://www.ctyme.com/intr/rb-5981.htm
642 * for more information.
646 USHORT CallMask
= getCX();
647 ULONG Callback
= MAKELONG(getDX(), getES()); // Far pointer to the callback
648 BOOLEAN Success
= FALSE
;
650 DPRINT1("Define v6.0+ callback 0x%04X, %04X:%04X\n",
651 CallMask
, HIWORD(Callback
), LOWORD(Callback
));
653 if (CallMask
== 0x0000)
656 * Find the handler entry corresponding to the given
657 * callback and undefine it.
659 for (i
= 0; i
< ARRAYSIZE(DriverState
.Handlers
); ++i
)
661 if (DriverState
.Handlers
[i
].Callback
== Callback
)
663 /* Found it, undefine the handler */
664 DriverState
.Handlers
[i
].CallMask
= 0x0000;
665 DriverState
.Handlers
[i
].Callback
= (ULONG
)NULL
;
671 else if (Callback
== (ULONG
)NULL
)
674 * Find the handler entry corresponding to the given
675 * callmask and undefine it.
677 for (i
= 0; i
< ARRAYSIZE(DriverState
.Handlers
); ++i
)
679 if (DriverState
.Handlers
[i
].CallMask
== CallMask
)
681 /* Found it, undefine the handler */
682 DriverState
.Handlers
[i
].CallMask
= 0x0000;
683 DriverState
.Handlers
[i
].Callback
= (ULONG
)NULL
;
692 * Try to find a handler entry corresponding to the given
693 * callmask to redefine it, otherwise find an empty handler
694 * entry and set the new handler in there.
697 USHORT EmptyHandler
= 0xFFFF; // Invalid handler
699 for (i
= 0; i
< ARRAYSIZE(DriverState
.Handlers
); ++i
)
701 /* Find the first empty handler */
702 if (EmptyHandler
== 0xFFFF &&
703 DriverState
.Handlers
[i
].CallMask
== 0x0000 &&
704 DriverState
.Handlers
[i
].Callback
== (ULONG
)NULL
)
709 if (DriverState
.Handlers
[i
].CallMask
== CallMask
)
711 /* Found it, redefine the handler */
712 DriverState
.Handlers
[i
].CallMask
= CallMask
;
713 DriverState
.Handlers
[i
].Callback
= Callback
;
720 * If we haven't found anything and we found
721 * an empty handler, set it.
723 if (!Success
&& EmptyHandler
!= 0xFFFF
724 /* && EmptyHandler < ARRAYSIZE(DriverState.Handlers) */)
726 DriverState
.Handlers
[EmptyHandler
].CallMask
= CallMask
;
727 DriverState
.Handlers
[EmptyHandler
].Callback
= Callback
;
732 /* If we failed, set error code */
733 if (!Success
) setAX(0xFFFF);
738 /* Return User Alternate Interrupt Vector, compatible MS MOUSE v6.0+ */
742 USHORT CallMask
= getCX();
744 BOOLEAN Success
= FALSE
;
747 * Find the handler entry corresponding to the given callmask.
749 for (i
= 0; i
< ARRAYSIZE(DriverState
.Handlers
); ++i
)
751 if (DriverState
.Handlers
[i
].CallMask
== CallMask
)
754 Callback
= DriverState
.Handlers
[i
].Callback
;
762 /* Return the callback vector in BX:DX */
763 setBX(HIWORD(Callback
));
764 setDX(LOWORD(Callback
));
768 /* We failed, set error code */
775 /* Disable Mouse Driver */
785 /* Enable Mouse Driver */
794 DPRINT1("BIOS Function INT 33h, AX = 0x%04X NOT IMPLEMENTED\n", getAX());
799 /* PUBLIC FUNCTIONS ***********************************************************/
801 VOID
DosMouseEnable(VOID
)
805 DriverEnabled
= TRUE
;
807 /* Get the old IRQ handler */
808 OldIrqHandler
= ((PDWORD
)BaseAddress
)[MOUSE_IRQ_INT
];
810 /* Set the IRQ handler */
811 RegisterDosInt32(MOUSE_IRQ_INT
, DosMouseIrq
);
815 VOID
DosMouseDisable(VOID
)
819 /* Restore the old IRQ handler */
820 ((PDWORD
)BaseAddress
)[MOUSE_IRQ_INT
] = OldIrqHandler
;
822 DriverEnabled
= FALSE
;
826 VOID
DosMouseUpdatePosition(PCOORD NewPosition
)
828 SHORT DeltaX
= NewPosition
->X
- DriverState
.Position
.X
;
829 SHORT DeltaY
= NewPosition
->Y
- DriverState
.Position
.Y
;
831 if (!DriverEnabled
) return;
833 DriverState
.HorizCount
+= (DeltaX
* MICKEYS_PER_CELL_HORIZ
) / 8;
834 DriverState
.VertCount
+= (DeltaY
* MICKEYS_PER_CELL_VERT
) / 8;
836 if (DriverState
.ShowCount
> 0) EraseMouseCursor();
837 DriverState
.Position
= *NewPosition
;
838 if (DriverState
.ShowCount
> 0) PaintMouseCursor();
840 /* Call the mouse handlers */
841 // if (DeltaX || DeltaY)
842 CallMouseUserHandlers(0x0001); // We use MS MOUSE v1.0+ format
845 VOID
DosMouseUpdateButtons(WORD ButtonState
)
848 USHORT CallMask
= 0x0000; // We use MS MOUSE v1.0+ format
850 if (!DriverEnabled
) return;
852 for (i
= 0; i
< NUM_MOUSE_BUTTONS
; i
++)
854 BOOLEAN OldState
= (DriverState
.ButtonState
>> i
) & 1;
855 BOOLEAN NewState
= (ButtonState
>> i
) & 1;
857 if (NewState
> OldState
)
860 DriverState
.PressCount
[i
]++;
861 DriverState
.LastPress
[i
] = DriverState
.Position
;
863 CallMask
|= (1 << (2 * i
+ 1));
865 else if (NewState
< OldState
)
868 DriverState
.ReleaseCount
[i
]++;
869 DriverState
.LastRelease
[i
] = DriverState
.Position
;
871 CallMask
|= (1 << (2 * i
+ 2));
875 DriverState
.ButtonState
= ButtonState
;
877 /* Call the mouse handlers */
878 CallMouseUserHandlers(CallMask
);
881 BOOLEAN
DosMouseInitialize(VOID
)
883 /* Clear the state */
884 RtlZeroMemory(&DriverState
, sizeof(DriverState
));
886 /* Initialize the interrupt handler */
887 RegisterDosInt32(DOS_MOUSE_INTERRUPT
, DosMouseService
);
893 VOID
DosMouseCleanup(VOID
)
895 if (DriverState
.ShowCount
> 0) EraseMouseCursor();