3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: mouse.c,v 1.17 2003/02/15 19:16:33 gvg Exp $
21 * PROJECT: ReactOS kernel
23 * FILE: subsys/win32k/eng/mouse.c
24 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * 06-06-2001 CSH Created
28 /* INCLUDES ******************************************************************/
31 #include <ddk/ntddk.h>
32 #include <win32k/dc.h>
33 #include "../../drivers/input/include/mouse.h"
35 #include "include/msgqueue.h"
40 /* GLOBALS *******************************************************************/
42 static BOOLEAN SafetySwitch
= FALSE
;
43 static BOOLEAN SafetySwitch2
= FALSE
;
44 static BOOLEAN MouseEnabled
= FALSE
;
45 static LONG mouse_x
, mouse_y
;
46 static UINT mouse_width
= 0, mouse_height
= 0;
48 static UCHAR DefaultCursor
[256] = {
49 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00,
62 0x00, 0xC0, 0x00, 0x00,
63 0x00, 0xC0, 0x00, 0x00,
64 0x01, 0x80, 0x00, 0x00,
65 0x01, 0x80, 0x00, 0x00,
66 0x03, 0x00, 0x00, 0x00,
67 0x43, 0x00, 0x00, 0x00,
68 0x66, 0x00, 0x00, 0x00,
69 0x76, 0x00, 0x00, 0x00,
70 0x7E, 0x00, 0x00, 0x00,
71 0x7F, 0xC0, 0x00, 0x00,
72 0x7F, 0x80, 0x00, 0x00,
73 0x7F, 0x00, 0x00, 0x00,
74 0x7E, 0x00, 0x00, 0x00,
75 0x7C, 0x00, 0x00, 0x00,
76 0x78, 0x00, 0x00, 0x00,
77 0x70, 0x00, 0x00, 0x00,
78 0x60, 0x00, 0x00, 0x00,
79 0x40, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00,
82 0xFF, 0xFF, 0xFF, 0xFF,
83 0xFF, 0xFF, 0xFF, 0xFF,
84 0xFF, 0xFF, 0xFF, 0xFF,
85 0xFF, 0xFF, 0xFF, 0xFF,
86 0xFF, 0xFF, 0xFF, 0xFF,
87 0xFF, 0xFF, 0xFF, 0xFF,
88 0xFF, 0xFF, 0xFF, 0xFF,
89 0xFF, 0xFF, 0xFF, 0xFF,
90 0xFF, 0xFF, 0xFF, 0xFF,
91 0xFF, 0xFF, 0xFF, 0xFF,
92 0xFF, 0xFF, 0xFF, 0xFF,
93 0xFF, 0xFF, 0xFF, 0xFF,
94 0xFF, 0x3F, 0xFF, 0xFF,
95 0xFE, 0x1F, 0xFF, 0xFF,
96 0xFE, 0x1F, 0xFF, 0xFF,
97 0xFC, 0x3F, 0xFF, 0xFF,
98 0x7C, 0x3F, 0xFF, 0xFF,
99 0x38, 0x7F, 0xFF, 0xFF,
100 0x18, 0x7F, 0xFF, 0xFF,
101 0x00, 0xFF, 0xFF, 0xFF,
102 0x00, 0xFF, 0xFF, 0xFF,
103 0x00, 0x0F, 0xFF, 0xFF,
104 0x00, 0x1F, 0xFF, 0xFF,
105 0x00, 0x3F, 0xFF, 0xFF,
106 0x00, 0x7F, 0xFF, 0xFF,
107 0x00, 0xFF, 0xFF, 0xFF,
108 0x01, 0xFF, 0xFF, 0xFF,
109 0x03, 0xFF, 0xFF, 0xFF,
110 0x07, 0xFF, 0xFF, 0xFF,
111 0x0F, 0xFF, 0xFF, 0xFF,
112 0x1F, 0xFF, 0xFF, 0xFF,
113 0x3F, 0xFF, 0xFF, 0xFF};
115 /* FUNCTIONS *****************************************************************/
118 MouseSafetyOnDrawStart(PSURFOBJ SurfObj
, PSURFGDI SurfGDI
, LONG HazardX1
,
119 LONG HazardY1
, LONG HazardX2
, LONG HazardY2
)
121 * FUNCTION: Notify the mouse driver that drawing is about to begin in
122 * a rectangle on a particular surface.
128 /* Mouse is not allowed to move if GDI is busy drawing */
129 SafetySwitch2
= TRUE
;
136 if (SurfObj
->iType
!= STYPE_DEVICE
|| MouseEnabled
== FALSE
)
141 if (HazardX1
> HazardX2
)
143 tmp
= HazardX2
; HazardX2
= HazardX1
; HazardX1
= tmp
;
145 if (HazardY1
> HazardY2
)
147 tmp
= HazardY2
; HazardY2
= HazardY1
; HazardY1
= tmp
;
150 if (((mouse_x
+ mouse_width
) >= HazardX1
) && (mouse_x
<= HazardX2
) &&
151 ((mouse_y
+ mouse_height
) >= HazardY1
) && (mouse_y
<= HazardY2
))
154 SurfGDI
->MovePointer(SurfObj
, -1, -1, &MouseRect
);
161 MouseSafetyOnDrawEnd(PSURFOBJ SurfObj
, PSURFGDI SurfGDI
)
163 * FUNCTION: Notify the mouse driver that drawing has finished on a surface.
173 if (SurfObj
->iType
!= STYPE_DEVICE
|| MouseEnabled
== FALSE
)
180 SurfGDI
->MovePointer(SurfObj
, mouse_x
, mouse_y
, &MouseRect
);
181 SafetySwitch
= FALSE
;
184 SafetySwitch2
= FALSE
;
190 MouseGDICallBack(PMOUSE_INPUT_DATA Data
, ULONG InputCount
)
192 * FUNCTION: Call by the mouse driver when input events occur.
196 LONG mouse_cx
= 0, mouse_cy
= 0;
197 HDC hDC
= W32kGetScreenDC();
204 LARGE_INTEGER LargeTickCount
;
206 static ULONG ButtonsDown
= 0;
207 const UINT MouseButtonDownMessage
[3] =
208 {WM_RBUTTONDOWN
, WM_MBUTTONDOWN
, WM_LBUTTONDOWN
};
209 const UINT MouseButtonUpMessage
[3] =
210 {WM_RBUTTONUP
, WM_MBUTTONUP
, WM_LBUTTONUP
};
211 const ULONG MouseButtonFlag
[3] = {MK_RBUTTON
, MK_MBUTTON
, MK_LBUTTON
};
213 KeQueryTickCount(&LargeTickCount
);
214 TickCount
= LargeTickCount
.u
.LowPart
;
221 dc
= DC_HandleToPtr(hDC
);
222 SurfObj
= (PSURFOBJ
)AccessUserObject(dc
->Surface
);
223 SurfGDI
= (PSURFGDI
)AccessInternalObject(dc
->Surface
);
224 DC_ReleasePtr( hDC
);
226 /* Compile the total mouse movement change and dispatch button events. */
227 for (i
= 0; i
< InputCount
; i
++)
229 mouse_cx
+= Data
[i
].LastX
;
230 mouse_cy
+= Data
[i
].LastY
;
232 Msg
.wParam
= ButtonsDown
;
233 Msg
.lParam
= MAKELPARAM(mouse_x
+ mouse_cx
, mouse_y
+ mouse_cy
);
234 Msg
.message
= WM_MOUSEMOVE
;
235 Msg
.time
= TickCount
;
236 Msg
.pt
.x
= mouse_x
+ mouse_cx
;
237 Msg
.pt
.y
= mouse_y
+ mouse_cy
;
238 MsqInsertSystemMessage(&Msg
);
240 for (j
= 0; j
< 3; j
++)
242 ULONG Flag
= MouseButtonFlag
[j
];
243 if (Data
[i
].ButtonData
& (1 << j
) && !(ButtonsDown
& Flag
))
247 Msg
.wParam
= ButtonsDown
;
248 Msg
.message
= MouseButtonDownMessage
[j
];
249 MsqInsertSystemMessage(&Msg
);
251 if (!(Data
[i
].ButtonData
& (1 << j
)) && (ButtonsDown
& Flag
))
253 ButtonsDown
&= ~Flag
;
255 Msg
.wParam
= ButtonsDown
;
256 Msg
.message
= MouseButtonUpMessage
[j
];
257 MsqInsertSystemMessage(&Msg
);
262 /* If the mouse moved then move the pointer. */
263 if (mouse_cx
!= 0 || mouse_cy
!= 0)
268 mouse_x
= max(mouse_x
, 0);
269 mouse_y
= max(mouse_y
, 0);
270 mouse_x
= min(mouse_x
, 620);
271 mouse_y
= min(mouse_y
, 460);
273 if (SafetySwitch
== FALSE
&& SafetySwitch2
== FALSE
)
275 SurfGDI
->MovePointer(SurfObj
, mouse_x
, mouse_y
, &MouseRect
);
281 EnableMouse(HDC hDisplayDC
)
291 dc
= DC_HandleToPtr(hDisplayDC
);
293 SurfObj
= (PSURFOBJ
)AccessUserObject(dc
->Surface
);
294 SurfGDI
= (PSURFGDI
)AccessInternalObject(dc
->Surface
);
295 DC_ReleasePtr( hDisplayDC
);
297 /* Create the default mouse cursor. */
302 hMouseSurf
= EngCreateBitmap(MouseSize
, 4, BMF_1BPP
, 0, DefaultCursor
);
303 MouseSurf
= (PSURFOBJ
)AccessUserObject(hMouseSurf
);
305 /* Tell the display driver to set the pointer shape. */
306 SurfGDI
->SetPointerShape(SurfObj
, MouseSurf
, NULL
, NULL
, 0, 0, 320, 240,
314 MouseEnabled
= FALSE
;