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

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

implemented SendInput

File size: 11.7 KB
Line 
1/* $Id: winmouse.cpp,v 1.17 2001-09-27 10:02:38 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 dprintf(("not implemented"));
251}
252
253
254ODINFUNCTION1(DWORD, TrackMouseEvent,
255 DWORD, param1)
256{
257 dprintf(("not implemented"));
258 return 0;
259}
260
261
262/*****************************************************************************
263 * Name : UINT SendInput
264 * Purpose : The SendInput function synthesizes keystrokes, mouse motions,
265 * and button clicks
266 * Parameters: UINT nInputs // count if input events
267 * LPINPUT pInputs // array of input structures
268 * int chSize // size of structure
269 * Variables :
270 * Result : number of events successfully inserted,
271 * 0 if the input was already blocked by another thread
272 * Remark :
273 * Status : UNTESTED STUB
274 *
275 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
276 *****************************************************************************/
277
278ODINFUNCTION3(UINT, SendInput,
279 UINT, nInputs,
280 LPINPUT, pInputs,
281 int, chSize)
282{
283 dprintf(("not correctly implemented"));
284
285 // The simulated input is sent to the
286 // foreground thread's message queue.
287 // (WM_KEYUP, WM_KEYDOWN)
288 // After GetMessage or PeekMessage,
289 // TranslateMessage posts an appropriate
290 // WM_CHAR message.
291 HWND hwnd = GetForegroundWindow();
292
293 LPINPUT piBase = pInputs;
294 for (int i = 0;
295 i < nInputs;
296 i++,
297 piBase++)
298 {
299 switch(piBase->type)
300 {
301 case INPUT_MOUSE:
302 {
303 PMOUSEINPUT p = (PMOUSEINPUT)&piBase->mi;
304 MSG msg;
305
306 // simulate mouse input message
307 // @@@PH
308 }
309 break;
310
311 // compose a keyboard input message
312 case INPUT_KEYBOARD:
313 {
314 PKEYBDINPUT p = (PKEYBDINPUT)&piBase->ki;
315 MSG msg;
316 BOOL fUnicode = (p->dwFlags & KEYEVENTF_UNICODE) == KEYEVENTF_UNICODE;
317
318 // build keyboard message
319 msg.message = (p->dwFlags & KEYEVENTF_KEYUP) ? WM_KEYUP : WM_KEYDOWN;
320
321 if (p->dwFlags & KEYEVENTF_SCANCODE)
322 {
323 // keystroke is identified by the scancode
324 if (fUnicode)
325 msg.wParam = MapVirtualKeyW(p->wScan, 1);
326 else
327 msg.wParam = MapVirtualKeyA(p->wScan, 1);
328 }
329 else
330 msg.wParam = p->wVk;
331
332 msg.lParam = 0x0000001 | // repeat count
333 ( (p->wScan & 0xff) << 16); // scan code
334
335 if (p->dwFlags & KEYEVENTF_EXTENDEDKEY)
336 msg.lParam |= (1 << 24);
337
338 // set additional message flags
339 if (msg.message == WM_KEYDOWN)
340 {
341 // @@@PH
342 // bit 30 - previous key state cannot be set, how to determine?
343 }
344 else
345 {
346 // WM_KEYUP -> previous key is always 1, transistion state
347 // always 1
348 msg.lParam |= (1 << 30);
349 msg.lParam |= (1 << 31);
350 }
351
352 msg.time = p->time;
353
354 // @@@PH
355 // unknown: do we have to post or to send the message?
356
357 if (fUnicode)
358 SendMessageW(hwnd, msg.message, msg.wParam, msg.lParam);
359 else
360 SendMessageA(hwnd, msg.message, msg.wParam, msg.lParam);
361
362 SetMessageExtraInfo( (LPARAM)p->dwExtraInfo );
363 }
364 break;
365
366 case INPUT_HARDWARE:
367 {
368 PHARDWAREINPUT p = (PHARDWAREINPUT)&piBase->hi;
369
370 // @@@PH
371 // not supported for the time being
372 }
373 break;
374
375 default:
376 dprintf(("unsupported input packet type %d",
377 piBase->type));
378 break;
379 }
380 }
381
382 return 0;
383}
384
385/*****************************************************************************
386 * Name : BOOL WIN32API DragDetect
387 * Purpose : The DragDetect function captures the mouse and tracks its movement
388 * Parameters: HWND hwnd
389 * POINT pt
390 * Variables :
391 * Result : If the user moved the mouse outside of the drag rectangle while
392 * holding the left button down, the return value is TRUE.
393 * If the user did not move the mouse outside of the drag rectangle
394 * while holding the left button down, the return value is FALSE.
395 * Remark :
396 * Status : UNTESTED STUB
397 *
398 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
399 *****************************************************************************/
400ODINFUNCTION2(BOOL, DragDetect,
401 HWND, hwnd,
402 POINT, pt)
403{
404 dprintf(("not implemented"));
405
406 return (FALSE);
407}
408//******************************************************************************
409//******************************************************************************
Note: See TracBrowser for help on using the repository browser.