source: trunk/src/user32/winmouse.cpp@ 6972

Last change on this file since 6972 was 6972, checked in by phaller, 24 years ago

enabled low-level keyboard hook

File size: 11.9 KB
Line 
1/* $Id: winmouse.cpp,v 1.18 2001-10-09 05:18:05 phaller Exp $ */
2/*
3 * Mouse handler for DINPUT
4 *
5 * Copyright 1999-2001 Sander van Leeuwen
6 *
7 * TODO: SwapMouseButton:
8 * We shouldn't let win32 apps change this for the whole system
9 * better to change mouse button message translation instead
10 *
11 * Project Odin Software License can be found in LICENSE.TXT
12 *
13 */
14
15#include <odin.h>
16#include <odinwrap.h>
17#include <os2sel.h>
18
19#include <os2win.h>
20#include <misc.h>
21#include "win32wbase.h"
22#include <winuser32.h>
23#include <winuser.h>
24#include <win\mouse.h>
25#include "winmouse.h"
26#include "oslibmsg.h"
27#include "pmwindow.h"
28#include "oslibwin.h"
29
30#define DBG_LOCALLOG DBG_winmouse
31#include "dbglocal.h"
32
33
34ODINDEBUGCHANNEL(USER32-WINMOUSE)
35
36
37/****************************************************************************
38 * local variables
39 ****************************************************************************/
40
41LPMOUSE_EVENT_PROC mouseHandler = NULL;
42WNDPROC keyboardHandler = NULL;
43
44
45//******************************************************************************
46//******************************************************************************
47ODINPROCEDURE1(MOUSE_Enable,
48 LPMOUSE_EVENT_PROC, lpMouseEventProc)
49{
50 if(lpMouseEventProc == (LPMOUSE_EVENT_PROC)-1)
51 mouseHandler = NULL;
52 else
53 mouseHandler = lpMouseEventProc;
54}
55//******************************************************************************
56//******************************************************************************
57ODINPROCEDURE1(KEYBOARD_Enable,
58 WNDPROC, handler)
59{
60 keyboardHandler = handler;
61}
62//******************************************************************************
63//******************************************************************************
64BOOL DInputKeyBoardHandler(MSG *msg)
65{
66 if(!ISKDB_CAPTURED())
67 return FALSE;
68
69 return keyboardHandler(msg->hwnd, msg->message, msg->wParam, msg->lParam);
70}
71//******************************************************************************
72//******************************************************************************
73BOOL DInputMouseHandler(HWND hwnd, ULONG msg, ULONG x, ULONG y)
74{
75 WINE_MOUSEEVENT mouseEvent;
76 DWORD dwFlags = MOUSEEVENTF_ABSOLUTE;
77
78 if(!ISMOUSE_CAPTURED())
79 return FALSE;
80
81 mouseEvent.magic = WINE_MOUSEEVENT_MAGIC;
82 mouseEvent.hWnd = hwnd;
83 mouseEvent.time = OSLibWinQueryMsgTime();
84 mouseEvent.keyState = 0; //not used in dinput right now
85 switch(msg)
86 {
87 case WM_NCLBUTTONDOWN:
88 case WM_LBUTTONDOWN:
89 dwFlags |= MOUSEEVENTF_LEFTDOWN;
90 break;
91 case WM_NCLBUTTONUP:
92 case WM_LBUTTONUP:
93 dwFlags |= MOUSEEVENTF_LEFTUP;
94 break;
95 case WM_NCRBUTTONUP:
96 case WM_RBUTTONUP:
97 dwFlags |= MOUSEEVENTF_RIGHTUP;
98 break;
99 case WM_NCRBUTTONDOWN:
100 case WM_RBUTTONDOWN:
101 dwFlags |= MOUSEEVENTF_RIGHTDOWN;
102 break;
103 case WM_NCMBUTTONUP:
104 case WM_MBUTTONUP:
105 dwFlags |= MOUSEEVENTF_MIDDLEUP;
106 break;
107 case WM_NCMBUTTONDOWN:
108 case WM_MBUTTONDOWN:
109 dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
110 break;
111 case WM_MOUSEMOVE:
112 case WM_NCMOUSEMOVE:
113 dwFlags |= MOUSEEVENTF_MOVE;
114 break;
115 default:
116 //TODO: handle double clicks???
117 return FALSE;
118 }
119
120 x = (((long)x << 16) + ScreenWidth-1) / ScreenWidth;
121 y = (((long)y << 16) + ScreenHeight-1) / ScreenHeight;
122
123 return mouseHandler(dwFlags, x, y, 0, (DWORD)&mouseEvent);
124}
125//******************************************************************************
126//******************************************************************************
127ODINFUNCTION0(HWND, GetCapture)
128{
129 return OS2ToWin32Handle(OSLibWinQueryCapture());
130}
131//******************************************************************************
132//******************************************************************************
133ODINFUNCTION1(HWND, SetCapture,
134 HWND, hwnd)
135{
136 HWND hwndPrev = GetCapture();
137 BOOL rc;
138
139 if(hwnd == 0)
140 {
141 ReleaseCapture();
142 return hwndPrev;
143 }
144
145 if(hwnd == hwndPrev)
146 {
147 dprintf(("USER32: SetCapture %x; already set to that window; ignore", hwnd));
148 return hwndPrev;
149 }
150
151 if(hwndPrev != NULL)
152 {
153 //SvL: WinSetCapture returns an error if mouse is already captured
154 OSLibWinSetCapture(0);
155 }
156
157 rc = OSLibWinSetCapture(Win32ToOS2Handle(hwnd));
158 dprintf(("USER32: SetCapture %x (prev %x) returned %d", hwnd, hwndPrev, rc));
159 if(hwndPrev)
160 {
161 SendMessageA(hwndPrev, WM_CAPTURECHANGED, 0L, hwnd);
162 }
163 return hwndPrev;
164}
165//******************************************************************************
166//******************************************************************************
167ODINFUNCTION0(BOOL, ReleaseCapture)
168{
169 HWND hwndPrev;
170 BOOL ret;
171
172 hwndPrev = GetCapture();
173 ret = OSLibWinSetCapture(0);
174 if(hwndPrev)
175 {
176 SendMessageA(hwndPrev, WM_CAPTURECHANGED, 0L, 0L);
177 }
178 return ret;
179}
180//******************************************************************************
181//******************************************************************************
182ODINFUNCTION0(UINT, GetDoubleClickTime)
183{
184 UINT result = OSLibWinQuerySysValue(SVOS_DBLCLKTIME);
185 if(result == 0)
186 SetLastError(ERROR_INVALID_PARAMETER); //TODO: ????
187
188 return result;
189}
190//******************************************************************************
191//******************************************************************************
192ODINFUNCTION1(BOOL, SetDoubleClickTime,
193 UINT, uInterval)
194{
195 BOOL ret = TRUE;
196
197 ret = OSLibWinSetSysValue(SVOS_DBLCLKTIME, uInterval);
198 if(ret == FALSE )
199 {
200 SetLastError(ERROR_INVALID_PARAMETER); //TODO: ????
201 }
202 return (ret);
203}
204//******************************************************************************
205//TODO: we shouldn't let win32 apps change this for the whole system
206// better to change mouse button message translation instead
207BOOL OPEN32API __SwapMouseButton(BOOL swapFlag);
208
209inline BOOL _SwapMouseButton(BOOL swapFlag)
210{
211 BOOL yyrc;
212 USHORT sel = RestoreOS2FS();
213
214 yyrc = __SwapMouseButton(swapFlag);
215 SetFS(sel);
216
217 return yyrc;
218}
219
220//******************************************************************************
221ODINFUNCTION1(BOOL, SwapMouseButton,
222 BOOL, fSwap)
223{
224 return _SwapMouseButton(fSwap);
225}
226
227/*****************************************************************************
228 * Name : VOID WIN32API mouse_event
229 * Purpose : The mouse_event function synthesizes mouse motion and button clicks.
230 * Parameters: DWORD dwFlags flags specifying various motion/click variants
231 * DWORD dx horizontal mouse position or position change
232 * DWORD dy vertical mouse position or position change
233 * DWORD cButtons unused, reserved for future use, set to zero
234 * DWORD dwExtraInfo 32 bits of application-defined information
235 * Variables :
236 * Result :
237 * Remark :
238 * Status : UNTESTED STUB
239 *
240 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
241 *****************************************************************************/
242
243ODINPROCEDURE5(mouse_event,
244 DWORD, dwFlags,
245 DWORD, dx,
246 DWORD, dy,
247 DWORD, cButtons,
248 DWORD, dwExtraInfo)
249{
250 INPUT i;
251
252 // format input packet
253 i.type = INPUT_MOUSE;
254 i.mi.dx = dx;
255 i.mi.dy = dy;
256 i.mi.mouseData = cButtons; // PH: is this really correct?
257 i.mi.dwFlags = dwFlags;
258 i.mi.dwExtraInfo = dwExtraInfo;
259
260 // forward to more modern API
261 SendInput(1, &i, sizeof(i) );
262}
263
264
265ODINFUNCTION1(DWORD, TrackMouseEvent,
266 DWORD, param1)
267{
268 dprintf(("not implemented"));
269 return 0;
270}
271
272
273/*****************************************************************************
274 * Name : UINT SendInput
275 * Purpose : The SendInput function synthesizes keystrokes, mouse motions,
276 * and button clicks
277 * Parameters: UINT nInputs // count if input events
278 * LPINPUT pInputs // array of input structures
279 * int chSize // size of structure
280 * Variables :
281 * Result : number of events successfully inserted,
282 * 0 if the input was already blocked by another thread
283 * Remark :
284 * Status : UNTESTED STUB
285 *
286 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
287 *****************************************************************************/
288
289ODINFUNCTION3(UINT, SendInput,
290 UINT, nInputs,
291 LPINPUT, pInputs,
292 int, chSize)
293{
294 dprintf(("not correctly implemented"));
295
296 // The simulated input is sent to the
297 // foreground thread's message queue.
298 // (WM_KEYUP, WM_KEYDOWN)
299 // After GetMessage or PeekMessage,
300 // TranslateMessage posts an appropriate
301 // WM_CHAR message.
302 HWND hwnd = GetForegroundWindow();
303
304 LPINPUT piBase = pInputs;
305 for (int i = 0;
306 i < nInputs;
307 i++,
308 piBase++)
309 {
310 switch(piBase->type)
311 {
312 case INPUT_MOUSE:
313 {
314 PMOUSEINPUT p = (PMOUSEINPUT)&piBase->mi;
315 MSG msg;
316
317 // simulate mouse input message
318 // @@@PH
319 }
320 break;
321
322 // compose a keyboard input message
323 case INPUT_KEYBOARD:
324 {
325 PKEYBDINPUT p = (PKEYBDINPUT)&piBase->ki;
326 MSG msg;
327 BOOL fUnicode = (p->dwFlags & KEYEVENTF_UNICODE) == KEYEVENTF_UNICODE;
328
329 // build keyboard message
330 msg.message = (p->dwFlags & KEYEVENTF_KEYUP) ? WM_KEYUP : WM_KEYDOWN;
331
332 if (p->dwFlags & KEYEVENTF_SCANCODE)
333 {
334 // keystroke is identified by the scancode
335 if (fUnicode)
336 msg.wParam = MapVirtualKeyW(p->wScan, 1);
337 else
338 msg.wParam = MapVirtualKeyA(p->wScan, 1);
339 }
340 else
341 msg.wParam = p->wVk;
342
343 msg.lParam = 0x0000001 | // repeat count
344 ( (p->wScan & 0xff) << 16); // scan code
345
346 if (p->dwFlags & KEYEVENTF_EXTENDEDKEY)
347 msg.lParam |= (1 << 24);
348
349 // set additional message flags
350 if (msg.message == WM_KEYDOWN)
351 {
352 // @@@PH
353 // bit 30 - previous key state cannot be set, how to determine?
354 }
355 else
356 {
357 // WM_KEYUP -> previous key is always 1, transistion state
358 // always 1
359 msg.lParam |= (1 << 30);
360 msg.lParam |= (1 << 31);
361 }
362
363 msg.time = p->time;
364
365 // @@@PH
366 // unknown: do we have to post or to send the message?
367
368 if (fUnicode)
369 PostMessageW(hwnd, msg.message, msg.wParam, msg.lParam);
370 else
371 PostMessageA(hwnd, msg.message, msg.wParam, msg.lParam);
372
373 SetMessageExtraInfo( (LPARAM)p->dwExtraInfo );
374 }
375 break;
376
377 case INPUT_HARDWARE:
378 {
379 PHARDWAREINPUT p = (PHARDWAREINPUT)&piBase->hi;
380
381 // @@@PH
382 // not supported for the time being
383 }
384 break;
385
386 default:
387 dprintf(("unsupported input packet type %d",
388 piBase->type));
389 break;
390 }
391 }
392
393 return 0;
394}
395
396/*****************************************************************************
397 * Name : BOOL WIN32API DragDetect
398 * Purpose : The DragDetect function captures the mouse and tracks its movement
399 * Parameters: HWND hwnd
400 * POINT pt
401 * Variables :
402 * Result : If the user moved the mouse outside of the drag rectangle while
403 * holding the left button down, the return value is TRUE.
404 * If the user did not move the mouse outside of the drag rectangle
405 * while holding the left button down, the return value is FALSE.
406 * Remark :
407 * Status : UNTESTED STUB
408 *
409 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
410 *****************************************************************************/
411ODINFUNCTION2(BOOL, DragDetect,
412 HWND, hwnd,
413 POINT, pt)
414{
415 dprintf(("not implemented"));
416
417 return (FALSE);
418}
419//******************************************************************************
420//******************************************************************************
Note: See TracBrowser for help on using the repository browser.