ReactOS 0.4.16-dev-2491-g3dc6630
input.c
Go to the documentation of this file.
1/* Test Key event to Key message translation
2 *
3 * Copyright 2003 Rein Klazes
4 * Copyright 2019 Remi Bernon for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21/* test whether the right type of messages:
22 * WM_KEYUP/DOWN vs WM_SYSKEYUP/DOWN are sent in case of combined
23 * keystrokes.
24 *
25 * For instance <ALT>-X can be accomplished by
26 * the sequence ALT-KEY-DOWN, X-KEY-DOWN, ALT-KEY-UP, X-KEY-UP
27 * but also X-KEY-DOWN, ALT-KEY-DOWN, X-KEY-UP, ALT-KEY-UP
28 * Whether a KEY or a SYSKEY message is sent is not always clear, it is
29 * also not the same in WINNT as in WIN9X */
30
31/* NOTE that there will be test failures under WIN9X
32 * No applications are known to me that rely on this
33 * so I don't fix it */
34
35/* TODO:
36 * 1. extend it to the wm_command and wm_syscommand notifications
37 * 2. add some more tests with special cases like dead keys or right (alt) key
38 * 3. there is some adapted code from input.c in here. Should really
39 * make that code exactly the same.
40 * 4. resolve the win9x case when there is a need or the testing frame work
41 * offers a nice way.
42 * 5. The test app creates a window, the user should not take the focus
43 * away during its short existence. I could do something to prevent that
44 * if it is a problem.
45 *
46 */
47
48#include <stdarg.h>
49#include <assert.h>
50
51#include "windef.h"
52#include "winbase.h"
53#include "wingdi.h"
54#include "winuser.h"
55#include "wingdi.h"
56#include "winnls.h"
57#include "winreg.h"
58#include "ddk/hidsdi.h"
59#include "imm.h"
60#include "kbd.h"
61
62#include "wine/test.h"
63#ifdef __REACTOS__
64/* printf with temp buffer allocation */
65const char *wine_dbg_sprintf( const char *format, ... )
66{
67 static const int max_size = 200;
68 static char buffer[256];
69 char *ret;
70 int len;
72
74 ret = buffer;
76 if (len == -1 || len >= max_size) ret[max_size-1] = 0;
78 return ret;
79}
80#endif
81
82#define check_member_( file, line, val, exp, fmt, member ) \
83 ok_(file, line)( (val).member == (exp).member, "got " #member " " fmt "\n", (val).member )
84#define check_member( val, exp, fmt, member ) \
85 check_member_( __FILE__, __LINE__, val, exp, fmt, member )
86
87static const char *debugstr_ok( const char *cond )
88{
89 int c, n = 0;
90 /* skip possible casts */
91 while ((c = *cond++))
92 {
93 if (c == '(') n++;
94 if (!n) break;
95 if (c == ')') n--;
96 }
97 if (!strchr( cond - 1, '(' )) return wine_dbg_sprintf( "got %s", cond - 1 );
98 return wine_dbg_sprintf( "%.*s returned", (int)strcspn( cond - 1, "( " ), cond - 1 );
99}
100
101#define ok_eq( e, r, t, f, ... ) \
102 do \
103 { \
104 t v = (r); \
105 ok( v == (e), "%s " f "\n", debugstr_ok( #r ), v, ##__VA_ARGS__ ); \
106 } while (0)
107#define ok_ne( e, r, t, f, ... ) \
108 do \
109 { \
110 t v = (r); \
111 ok( v != (e), "%s " f "\n", debugstr_ok( #r ), v, ##__VA_ARGS__ ); \
112 } while (0)
113#define ok_rect( e, r ) \
114 do \
115 { \
116 RECT v = (r); \
117 ok( EqualRect( &v, &(e) ), "%s %s\n", debugstr_ok(#r), wine_dbgstr_rect(&v) ); \
118 } while (0)
119#define ok_point( e, r ) \
120 do \
121 { \
122 POINT v = (r); \
123 ok( !memcmp( &v, &(e), sizeof(v) ), "%s %s\n", debugstr_ok(#r), wine_dbgstr_point(&v) ); \
124 } while (0)
125#define ok_ret( e, r ) ok_eq( e, r, UINT_PTR, "%Iu, error %ld", GetLastError() )
126
128{
133};
134
136{
138
139 union
140 {
141 struct
142 {
148 struct
149 {
150 UINT msg;
156 struct
157 {
158 UINT msg;
161 UINT flags;
165 struct
166 {
167 HWND hwnd;
169 RAWKEYBOARD kbd;
171 };
172
176};
177
178static const struct user_call empty_sequence[] = {{0}};
179static struct user_call current_sequence[1024];
181
182static const char *debugstr_wm( UINT msg )
183{
184 switch (msg)
185 {
186 case WM_CHAR: return "WM_CHAR";
187 case WM_KEYDOWN: return "WM_KEYDOWN";
188 case WM_KEYUP: return "WM_KEYUP";
189 case WM_SYSCHAR: return "WM_SYSCHAR";
190 case WM_SYSCOMMAND: return "WM_SYSCOMMAND";
191 case WM_SYSKEYDOWN: return "WM_SYSKEYDOWN";
192 case WM_SYSKEYUP: return "WM_SYSKEYUP";
193 case WM_MOUSEMOVE: return "WM_MOUSEMOVE";
194 case WM_LBUTTONDOWN: return "WM_LBUTTONDOWN";
195 case WM_LBUTTONUP: return "WM_LBUTTONUP";
196 case WM_LBUTTONDBLCLK: return "WM_LBUTTONDBLCLK";
197 case WM_NCHITTEST: return "WM_NCHITTEST";
198 }
199 return wine_dbg_sprintf( "%#x", msg );
200}
201
202static const char *debugstr_vk( UINT vkey )
203{
204 switch (vkey)
205 {
206 case VK_CONTROL: return "VK_CONTROL";
207 case VK_LCONTROL: return "VK_LCONTROL";
208 case VK_LMENU: return "VK_LMENU";
209 case VK_LSHIFT: return "VK_LSHIFT";
210 case VK_MENU: return "VK_MENU";
211 case VK_RCONTROL: return "VK_RCONTROL";
212 case VK_RMENU: return "VK_RMENU";
213 case VK_RSHIFT: return "VK_RSHIFT";
214 case VK_SHIFT: return "VK_SHIFT";
215 }
216
217 if (vkey >= '0' && vkey <= '9') return wine_dbg_sprintf( "%c", vkey );
218 if (vkey >= 'A' && vkey <= 'Z') return wine_dbg_sprintf( "%c", vkey );
219 return wine_dbg_sprintf( "%#x", vkey );
220}
221
222#define ok_call( a, b ) ok_call_( __FILE__, __LINE__, a, b )
223static int ok_call_( const char *file, int line, const struct user_call *expected, const struct user_call *received )
224{
225 int ret;
226
227 if ((ret = expected->func - received->func)) goto done;
228
229 switch (expected->func)
230 {
231 case MSG_TEST_WIN:
232 if ((ret = expected->message.hwnd - received->message.hwnd)) goto done;
233 if ((ret = expected->message.msg - received->message.msg)) goto done;
234 if ((ret = (expected->message.wparam - received->message.wparam))) goto done;
235 if ((ret = (expected->message.lparam - received->message.lparam))) goto done;
236 break;
237 case LL_HOOK_KEYBD:
238 if ((ret = expected->ll_hook_kbd.msg - received->ll_hook_kbd.msg)) goto done;
239 if ((ret = (expected->ll_hook_kbd.scan - received->ll_hook_kbd.scan))) goto done;
240 if ((ret = expected->ll_hook_kbd.vkey - received->ll_hook_kbd.vkey)) goto done;
241 if ((ret = (expected->ll_hook_kbd.flags - received->ll_hook_kbd.flags))) goto done;
242 if ((ret = (expected->ll_hook_kbd.extra - received->ll_hook_kbd.extra))) goto done;
243 break;
244 case LL_HOOK_MOUSE:
245 if ((ret = expected->ll_hook_ms.msg - received->ll_hook_ms.msg)) goto done;
246 if ((ret = expected->ll_hook_ms.point.x - received->ll_hook_ms.point.x)) goto done;
247 if ((ret = expected->ll_hook_ms.point.y - received->ll_hook_ms.point.y)) goto done;
248 if ((ret = (expected->ll_hook_ms.data - received->ll_hook_ms.data))) goto done;
249 if ((ret = (expected->ll_hook_ms.flags - received->ll_hook_ms.flags))) goto done;
250 if (0 && (ret = expected->ll_hook_ms.time - received->ll_hook_ms.time)) goto done;
251 if ((ret = (expected->ll_hook_ms.extra - received->ll_hook_ms.extra))) goto done;
252 break;
254 if ((ret = expected->raw_input.hwnd - received->raw_input.hwnd)) goto done;
255 if ((ret = expected->raw_input.code - received->raw_input.code)) goto done;
256 if ((ret = expected->raw_input.kbd.MakeCode - received->raw_input.kbd.MakeCode)) goto done;
257 if ((ret = expected->raw_input.kbd.Flags - received->raw_input.kbd.Flags)) goto done;
258 if ((ret = expected->raw_input.kbd.VKey - received->raw_input.kbd.VKey)) goto done;
259 if ((ret = expected->raw_input.kbd.Message - received->raw_input.kbd.Message)) goto done;
260 if ((ret = expected->raw_input.kbd.ExtraInformation - received->raw_input.kbd.ExtraInformation)) goto done;
261 break;
262 }
263
264done:
265 if (ret && broken( expected->broken )) return ret;
266
267 switch (received->func)
268 {
269 case MSG_TEST_WIN:
270 todo_wine_if( expected->todo || expected->todo_value )
271 ok_(file, line)( !ret, "got MSG_TEST_WIN hwnd %p, msg %s, wparam %#Ix, lparam %#Ix\n", received->message.hwnd,
272 debugstr_wm(received->message.msg), received->message.wparam, received->message.lparam );
273 return ret;
274 case LL_HOOK_KEYBD:
275 todo_wine_if( expected->todo || expected->todo_value )
276 ok_(file, line)( !ret, "got LL_HOOK_KEYBD msg %s scan %#x, vkey %s, flags %#x, extra %#Ix\n", debugstr_wm(received->ll_hook_kbd.msg),
277 received->ll_hook_kbd.scan, debugstr_vk(received->ll_hook_kbd.vkey), received->ll_hook_kbd.flags,
278 received->ll_hook_kbd.extra );
279 return ret;
280 case LL_HOOK_MOUSE:
281 todo_wine_if( expected->todo || expected->todo_value )
282 ok_(file, line)( !ret, "got LL_HOOK_MOUSE msg %s, point %s, data %#x, flags %#x, time %u, extra %#Ix\n", debugstr_wm(received->ll_hook_ms.msg),
283 wine_dbgstr_point(&received->ll_hook_ms.point), received->ll_hook_ms.data, received->ll_hook_ms.flags, received->ll_hook_ms.time,
284 received->ll_hook_ms.extra );
285 return ret;
287 todo_wine_if( expected->todo || expected->todo_value )
288 ok_(file, line)( !ret, "got WM_INPUT key hwnd %p, code %d, make_code %#x, flags %#x, vkey %s, message %s, extra %#lx\n",
289 received->raw_input.hwnd, received->raw_input.code, received->raw_input.kbd.MakeCode,
290 received->raw_input.kbd.Flags, debugstr_vk(received->raw_input.kbd.VKey),
291 debugstr_wm(received->raw_input.kbd.Message), received->raw_input.kbd.ExtraInformation );
292 return ret;
293 }
294
295 switch (expected->func)
296 {
297 case MSG_TEST_WIN:
298 todo_wine_if( expected->todo || expected->todo_value )
299 ok_(file, line)( !ret, "MSG_TEST_WIN hwnd %p, %s, wparam %#Ix, lparam %#Ix\n", expected->message.hwnd,
300 debugstr_wm(expected->message.msg), expected->message.wparam, expected->message.lparam );
301 break;
302 case LL_HOOK_KEYBD:
303 todo_wine_if( expected->todo || expected->todo_value )
304 ok_(file, line)( !ret, "LL_HOOK_KBD msg %s scan %#x, vkey %s, flags %#x, extra %#Ix\n", debugstr_wm(expected->ll_hook_kbd.msg),
305 expected->ll_hook_kbd.scan, debugstr_vk(expected->ll_hook_kbd.vkey), expected->ll_hook_kbd.flags,
306 expected->ll_hook_kbd.extra );
307 break;
308 case LL_HOOK_MOUSE:
309 todo_wine_if( expected->todo || expected->todo_value )
310 ok_(file, line)( !ret, "LL_HOOK_MOUSE msg %s, point %s, data %#x, flags %#x, time %u, extra %#Ix\n", debugstr_wm(received->ll_hook_ms.msg),
311 wine_dbgstr_point(&received->ll_hook_ms.point), received->ll_hook_ms.data, received->ll_hook_ms.flags, received->ll_hook_ms.time,
312 received->ll_hook_ms.extra );
313 return ret;
315 todo_wine_if( expected->todo || expected->todo_value )
316 ok_(file, line)( !ret, "got WM_INPUT key hwnd %p, code %d, make_code %#x, flags %#x, vkey %s, message %s, extra %#lx\n",
317 expected->raw_input.hwnd, expected->raw_input.code, expected->raw_input.kbd.MakeCode,
318 expected->raw_input.kbd.Flags, debugstr_vk(expected->raw_input.kbd.VKey),
319 debugstr_wm(expected->raw_input.kbd.Message), expected->raw_input.kbd.ExtraInformation );
320 return ret;
321 }
322
323 return 0;
324}
325
326#define ok_seq( a ) ok_seq_( __FILE__, __LINE__, a, #a )
327static void ok_seq_( const char *file, int line, const struct user_call *expected, const char *context )
328{
329 const struct user_call *received = current_sequence;
330 UINT i = 0, ret;
331
332 while (expected->func || received->func)
333 {
334 winetest_push_context( "%s %u%s%s", context, i++, !expected->func ? " (spurious)" : "",
335 !received->func ? " (missing)" : "" );
337 if (ret && expected->todo && expected->func &&
338 !strcmp( winetest_platform, "wine" ))
339 expected++;
340 else if (ret && broken(expected->broken))
341 expected++;
342 else
343 {
344 if (expected->func) expected++;
345 if (received->func) received++;
346 }
348 }
349
352}
353
356
358{
359 struct user_call call =
360 {
361 .func = LL_HOOK_KEYBD, .ll_hook_kbd =
362 {
363 .msg = msg, .scan = info->scanCode, .vkey = info->vkCode,
364 .flags = info->flags, .extra = info->dwExtraInfo
365 }
366 };
368 {
370 ok( index < ARRAY_SIZE(current_sequence), "got %lu calls\n", index );
371 current_sequence[index] = call;
372 }
373}
374
376{
377 struct user_call call =
378 {
379 .func = LL_HOOK_MOUSE, .ll_hook_ms =
380 {
381 .msg = msg, .point = info->pt, .data = info->mouseData, .flags = info->flags,
382 .time = info->time, .extra = info->dwExtraInfo
383 }
384 };
386 {
388 ok( index < ARRAY_SIZE(current_sequence), "got %lu calls\n", index );
389 current_sequence[index] = call;
390 }
391}
392
394{
395 RAWINPUT rawinput;
396 UINT size = sizeof(rawinput), ret;
397
398 ret = GetRawInputData( handle, RID_INPUT, &rawinput, &size, sizeof(RAWINPUTHEADER) );
399 ok_ne( ret, (UINT)-1, UINT, "%u" );
400
401 if (rawinput.header.dwType == RIM_TYPEKEYBOARD)
402 {
403 struct user_call call =
404 {
406 .raw_input = {.hwnd = hwnd, .code = GET_RAWINPUT_CODE_WPARAM(wparam), .kbd = rawinput.data.keyboard}
407 };
409 ok( index < ARRAY_SIZE(current_sequence), "got %lu calls\n", index );
410 if (!append_message_hwnd) call.message.hwnd = 0;
411 current_sequence[index] = call;
412 }
413}
414
416{
417 if (msg == WM_INPUT) append_rawinput_message( hwnd, wparam, (HRAWINPUT)lparam );
418 else if (!p_accept_message || p_accept_message( msg ))
419 {
420 struct user_call call = {.func = MSG_TEST_WIN, .message = {.hwnd = hwnd, .msg = msg, .wparam = wparam, .lparam = lparam}};
422 ok( index < ARRAY_SIZE(current_sequence), "got %lu calls\n", index );
423 if (!append_message_hwnd) call.message.hwnd = 0;
424 current_sequence[index] = call;
425 }
426}
427
429{
431 return DefWindowProcW( hwnd, msg, wparam, lparam );
432}
433
434/* globals */
435#define DESKTOP_ALL_ACCESS 0x01ff
436
437static BOOL (WINAPI *pEnableMouseInPointer)( BOOL );
438static BOOL (WINAPI *pIsMouseInPointerEnabled)(void);
439static BOOL (WINAPI *pGetCurrentInputMessageSource)( INPUT_MESSAGE_SOURCE *source );
440static BOOL (WINAPI *pGetPointerType)(UINT32, POINTER_INPUT_TYPE*);
441static BOOL (WINAPI *pGetPointerInfo)(UINT32, POINTER_INFO*);
442static BOOL (WINAPI *pGetPointerInfoHistory)(UINT32, UINT32*, POINTER_INFO*);
443static BOOL (WINAPI *pGetPointerFrameInfo)(UINT32, UINT32*, POINTER_INFO*);
444static BOOL (WINAPI *pGetPointerFrameInfoHistory)(UINT32, UINT32*, UINT32*, POINTER_INFO*);
445static int (WINAPI *pGetMouseMovePointsEx) (UINT, LPMOUSEMOVEPOINT, LPMOUSEMOVEPOINT, int, DWORD);
446static UINT (WINAPI *pGetRawInputDeviceList) (PRAWINPUTDEVICELIST, PUINT, UINT);
447static UINT (WINAPI *pGetRawInputDeviceInfoW) (HANDLE, UINT, void *, UINT *);
448static UINT (WINAPI *pGetRawInputDeviceInfoA) (HANDLE, UINT, void *, UINT *);
449static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
450static HKL (WINAPI *pLoadKeyboardLayoutEx)(HKL, const WCHAR *, UINT);
451
452/**********************adapted from input.c **********************************/
453
455
456static void init_function_pointers(void)
457{
458 HMODULE hdll = GetModuleHandleA("user32");
459
460#define GET_PROC(func) \
461 if (!(p ## func = (void*)GetProcAddress(hdll, #func))) \
462 trace("GetProcAddress(%s) failed\n", #func)
463
464 GET_PROC(EnableMouseInPointer);
465 GET_PROC(IsMouseInPointerEnabled);
466 GET_PROC(GetCurrentInputMessageSource);
467 GET_PROC(GetMouseMovePointsEx);
469 GET_PROC(GetPointerInfoHistory);
470 GET_PROC(GetPointerFrameInfo);
471 GET_PROC(GetPointerFrameInfoHistory);
477
478 hdll = GetModuleHandleA("kernel32");
480#undef GET_PROC
481
482 if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 ))
483 is_wow64 = FALSE;
484}
485
486#define run_in_process( a, b ) run_in_process_( __FILE__, __LINE__, a, b )
487static void run_in_process_( const char *file, int line, char **argv, const char *args )
488{
489 STARTUPINFOA startup = {.cb = sizeof(STARTUPINFOA)};
491 char cmdline[MAX_PATH * 2];
492 DWORD ret;
493
494 sprintf( cmdline, "%s %s %s", argv[0], argv[1], args );
496 ok_(file, line)( ret, "CreateProcessA failed, error %lu\n", GetLastError() );
497 if (!ret) return;
498
499 wait_child_process( info.hProcess );
500 CloseHandle( info.hThread );
501 CloseHandle( info.hProcess );
502}
503
504#define run_in_desktop( a, b, c ) run_in_desktop_( __FILE__, __LINE__, a, b, c )
505static void run_in_desktop_( const char *file, int line, char **argv,
506 const char *args, BOOL input )
507{
508 const char *desktop_name = "WineTest Desktop";
509 STARTUPINFOA startup = {.cb = sizeof(STARTUPINFOA)};
511 HDESK old_desktop, desktop;
512 char cmdline[MAX_PATH * 2];
513 DWORD ret;
514
515 old_desktop = OpenInputDesktop( 0, FALSE, DESKTOP_ALL_ACCESS );
516 ok_(file, line)( !!old_desktop, "OpenInputDesktop failed, error %lu\n", GetLastError() );
517 desktop = CreateDesktopA( desktop_name, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
518 ok_(file, line)( !!desktop, "CreateDesktopA failed, error %lu\n", GetLastError() );
519 if (input)
520 {
521 ret = SwitchDesktop( desktop );
522 ok_(file, line)( ret, "SwitchDesktop failed, error %lu\n", GetLastError() );
523 }
524
525 startup.lpDesktop = (char *)desktop_name;
526 sprintf( cmdline, "%s %s %s", argv[0], argv[1], args );
528 ok_(file, line)( ret, "CreateProcessA failed, error %lu\n", GetLastError() );
529 if (!ret) return;
530
531 wait_child_process( info.hProcess );
532 CloseHandle( info.hThread );
533 CloseHandle( info.hProcess );
534
535 if (input)
536 {
537 ret = SwitchDesktop( old_desktop );
538 ok_(file, line)( ret, "SwitchDesktop failed, error %lu\n", GetLastError() );
539 }
540 ret = CloseDesktop( desktop );
541 ok_(file, line)( ret, "CloseDesktop failed, error %lu\n", GetLastError() );
542 ret = CloseDesktop( old_desktop );
543 ok_(file, line)( ret, "CloseDesktop failed, error %lu\n", GetLastError() );
544}
545
546#define wait_messages( a, b ) msg_wait_for_events_( __FILE__, __LINE__, 0, NULL, a, b )
547#define msg_wait_for_events( a, b, c ) msg_wait_for_events_( __FILE__, __LINE__, a, b, c, FALSE )
548static DWORD msg_wait_for_events_( const char *file, int line, DWORD count, HANDLE *events, DWORD timeout, BOOL append_peeked )
549{
550 DWORD ret, end = GetTickCount() + min( timeout, 5000 );
551 MSG msg;
552
554 {
555 while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
556 {
557 if (append_peeked) append_message( msg.hwnd, msg.message, msg.wParam, msg.lParam );
560 }
561 if (ret < count) return ret;
562 if (timeout >= 5000) continue;
563 if (end <= GetTickCount()) timeout = 0;
564 else timeout = end - GetTickCount();
565 }
566
567 if (timeout >= 5000) ok_(file, line)( 0, "MsgWaitForMultipleObjects returned %#lx\n", ret );
568 else ok_(file, line)( ret == WAIT_TIMEOUT, "MsgWaitForMultipleObjects returned %#lx\n", ret );
569 return ret;
570}
571
573{
574 return (message >= WM_KEYFIRST && message <= WM_KEYLAST);
575}
576
578{
579 return (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST);
580}
581
582#define create_foreground_window( a ) create_foreground_window_( __FILE__, __LINE__, a, 5 )
584{
585 for (;;)
586 {
587 HWND hwnd;
588 BOOL ret;
589
590 hwnd = CreateWindowW( L"static", NULL, WS_POPUP | (fullscreen ? 0 : WS_VISIBLE),
591 100, 100, 200, 200, NULL, NULL, NULL, NULL );
592 ok_(file, line)( hwnd != NULL, "CreateWindowW failed, error %lu\n", GetLastError() );
593
594 if (fullscreen)
595 {
596 HMONITOR hmonitor = MonitorFromWindow( hwnd, MONITOR_DEFAULTTOPRIMARY );
597 MONITORINFO mi = {.cbSize = sizeof(MONITORINFO)};
598
599 ok_(file, line)( hmonitor != NULL, "MonitorFromWindow failed, error %lu\n", GetLastError() );
600 ret = GetMonitorInfoW( hmonitor, &mi );
601 ok_(file, line)( ret, "GetMonitorInfoW failed, error %lu\n", GetLastError() );
604 ok_(file, line)( ret, "SetWindowPos failed, error %lu\n", GetLastError() );
605 }
606 wait_messages( 100, FALSE );
607
608 if (GetForegroundWindow() == hwnd) return hwnd;
609 ok_(file, line)( retries > 0, "failed to create foreground window\n" );
610 if (!retries--) return hwnd;
611
613 ok_(file, line)( ret, "DestroyWindow failed, error %lu\n", GetLastError() );
614 wait_messages( 0, FALSE );
615 }
616}
617
618/* try to make sure pending X events have been processed before continuing */
619static void empty_message_queue(void)
620{
621 MSG msg;
622 int diff = 200;
623 int min_timeout = 50;
624 DWORD time = GetTickCount() + diff;
625
626 while (diff > 0)
627 {
628 if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT) break;
629 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
630 {
631 if (is_keyboard_message(msg.message) || is_mouse_message(msg.message))
632 ok(msg.time != 0, "message %#x has time set to 0\n", msg.message);
633
636 }
637 diff = time - GetTickCount();
638 }
639}
640
642{
646 struct user_call expect[8];
652};
653
655{
656 KBDLLHOOKSTRUCT *hook_info = (KBDLLHOOKSTRUCT *)lparam;
657
658 if (code == HC_ACTION)
659 {
660 append_ll_hook_kbd( wparam, hook_info );
661
662if(0) /* For some reason not stable on Wine */
663{
665 ok(!(GetAsyncKeyState(hook_info->vkCode) & 0x8000), "key %lx should be up\n", hook_info->vkCode);
666 else if (wparam == WM_KEYUP || wparam == WM_SYSKEYUP)
667 ok(GetAsyncKeyState(hook_info->vkCode) & 0x8000, "key %lx should be down\n", hook_info->vkCode);
668}
669
670 if (winetest_debug > 1)
671 trace("Hook: w=%Ix vk:%8lx sc:%8lx fl:%8lx %Ix\n", wparam,
672 hook_info->vkCode, hook_info->scanCode, hook_info->flags, hook_info->dwExtraInfo);
673 }
674 return CallNextHookEx( 0, code, wparam, lparam );
675}
676
677#define check_keyboard_state( a, b ) check_keyboard_state_( __LINE__, a, b )
678static void check_keyboard_state_( int line, const BYTE expect_state[256], const BOOL todo_state[256] )
679{
680 BYTE state[256];
681 UINT i;
682
684 for (i = 0; i < ARRAY_SIZE(state); i++)
685 {
686 todo_wine_if( todo_state[i] )
687 ok_(__FILE__, line)( (expect_state[i] & 0x80) == (state[i] & 0x80),
688 "got %s: %#x\n", debugstr_vk( i ), state[i] );
689 }
690}
691
692#define check_keyboard_async( a, b ) check_keyboard_async_( __LINE__, a, b )
693static void check_keyboard_async_( int line, const BYTE expect_state[256], const BOOL todo_state[256] )
694{
695 UINT i;
696
697 /* TODO: figure out if the async state for vkey 0 provides any information and
698 * add it to the check. */
699 for (i = 1; i < 256; i++)
700 {
702 todo_wine_if( todo_state[i] )
703 ok_(__FILE__, line)( (expect_state[i] & 0x80) == (state & 0x80),
704 "async got %s: %#x\n", debugstr_vk( i ), state );
705 }
706}
707
708static void clear_keyboard_state( void )
709{
710 static BYTE empty_state[256] = {0};
712 BYTE lock_keys[] = {VK_NUMLOCK, VK_CAPITAL, VK_SCROLL};
713 UINT i;
714
715 for (i = 0; i < ARRAY_SIZE(lock_keys); ++i)
716 {
717 if (GetKeyState( lock_keys[i] ) & 0x0001)
718 {
719 input.ki.wVk = lock_keys[i];
720 SendInput( 1, &input, sizeof(input) );
721 input.ki.dwFlags = KEYEVENTF_KEYUP;
722 SendInput( 1, &input, sizeof(input) );
723 wait_messages( 5, FALSE );
726 }
727 }
728
729 SetKeyboardState( empty_state );
730}
731
732#define check_send_input_keyboard_test( a, b ) check_send_input_keyboard_test_( a, #a, b )
733static void check_send_input_keyboard_test_( const struct send_input_keyboard_test *test, const char *context, BOOL peeked )
734{
736 UINT i;
737
740
741 for (i = 0; test->vkey || test->scan; i++, test++)
742 {
743 winetest_push_context( "%u", i );
744
745 input.ki.wScan = test->flags & (KEYEVENTF_SCANCODE | KEYEVENTF_UNICODE) ? test->scan : (i + 1);
746 input.ki.dwFlags = test->flags;
747 input.ki.wVk = test->vkey;
748 ok_ret( 1, SendInput( 1, &input, sizeof(input) ) );
749 wait_messages( 5, peeked );
750
751 ok_seq( test->expect );
752 check_keyboard_state( test->expect_state, test->todo_state );
753 if (test->async) check_keyboard_async( test->expect_async, test->todo_async );
754
756 }
757
760}
761
763{
765}
766
768{
769 typedef struct
770 {
771 UINT64 pCharModifiers;
772 UINT64 pVkToWcharTable;
773 UINT64 pDeadKey;
774 UINT64 pKeyNames;
775 UINT64 pKeyNamesExt;
776 UINT64 pKeyNamesDead;
777 UINT64 pusVSCtoVK;
778 BYTE bMaxVSCtoVK;
779 UINT64 pVSCtoVK_E0;
780 UINT64 pVSCtoVK_E1;
781 DWORD fLocaleFlags;
782 } KBDTABLES64;
783
784 WCHAR layout_path[MAX_PATH] = {L"System\\CurrentControlSet\\Control\\Keyboard Layouts\\"}, value[MAX_PATH];
785 KBDTABLES *(CDECL *pKbdLayerDescriptor)(void);
786 DWORD value_size = sizeof(value), flags;
789
790 ok_ret( 1, GetKeyboardLayoutNameW( layout_path + wcslen(layout_path) ) );
792 ok_ret( 0, RegGetValueW( HKEY_LOCAL_MACHINE, layout_path, L"Layout File", RRF_RT_REG_SZ,
793 NULL, (void *)&value, &value_size) );
794
797 ok_ne( NULL, module, HMODULE, "%p" );
798 pKbdLayerDescriptor = (void *)GetProcAddress( module, "KbdLayerDescriptor" );
800 ok_ne( NULL, pKbdLayerDescriptor, void *, "%p" );
801 /* FIXME: Wine doesn't implement ALTGR behavior */
802 if (!pKbdLayerDescriptor) return FALSE;
803 tables = pKbdLayerDescriptor();
804 ok_ne( NULL, tables, KBDTABLES *, "%p" );
805 flags = is_wow64 ? ((KBDTABLES64 *)tables)->fLocaleFlags : tables->fLocaleFlags;
806 ok_ret( 1, FreeLibrary( module ) );
807
808 trace( "%s flags %#lx\n", debugstr_w(value), flags );
809 return !!(flags & KLLF_ALTGR);
810}
811
812static void get_test_scan( WORD vkey, WORD *scan, WCHAR *wch, WCHAR *wch_shift )
813{
815 BYTE state[256] = {0};
816
818 ok_ne( 0, *scan, WORD, "%#x" );
819 ok_ret( 1, ToUnicodeEx( vkey, *scan, state, wch, 1, 0, hkl ) );
820 state[VK_SHIFT] = 0x80;
821 ok_ret( 1, ToUnicodeEx( vkey, *scan, state, wch_shift, 1, 0, hkl ) );
822}
823
824static void test_SendInput_keyboard_messages( WORD vkey, WORD scan, WCHAR wch, WCHAR wch_shift, WCHAR wch_control, HKL hkl )
825{
826#define WIN_MSG(m, w, l, ...) {.func = MSG_TEST_WIN, .message = {.msg = m, .wparam = w, .lparam = l}, ## __VA_ARGS__}
827#define KBD_HOOK(m, s, v, f, ...) {.func = LL_HOOK_KEYBD, .ll_hook_kbd = {.msg = m, .scan = s, .vkey = v, .flags = f}, ## __VA_ARGS__}
828
829#define KEY_HOOK_(m, s, v, f, ...) KBD_HOOK( m, s, v, LLKHF_INJECTED | (m == WM_KEYUP || m == WM_SYSKEYUP ? LLKHF_UP : 0) | (f), ## __VA_ARGS__ )
830#define KEY_HOOK(m, s, v, ...) KEY_HOOK_( m, s, v, 0, ## __VA_ARGS__ )
831
832#define KEY_MSG_(m, s, v, f, ...) WIN_MSG( m, v, MAKELONG(1, (s) | (m == WM_KEYUP || m == WM_SYSKEYUP ? (KF_UP | KF_REPEAT) : 0) | (f)), ## __VA_ARGS__ )
833#define KEY_MSG(m, s, v, ...) KEY_MSG_( m, s, v, 0, ## __VA_ARGS__ )
834
835 struct send_input_keyboard_test lmenu_vkey[] =
836 {
837 {.vkey = VK_LMENU, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
838 .expect = {KEY_HOOK_(WM_SYSKEYDOWN, 1, VK_LMENU, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYDOWN, 1, VK_MENU, KF_ALTDOWN), {0}}},
839 {
840 .vkey = vkey, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80, /*[vkey] = 0x80*/},
841 .expect =
842 {
843 KEY_HOOK_(WM_SYSKEYDOWN, 2, vkey, LLKHF_ALTDOWN, .todo_value = TRUE),
847 {0}
848 }
849 },
850 {.vkey = vkey, .flags = KEYEVENTF_KEYUP, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
851 .expect = {KEY_HOOK_(WM_SYSKEYUP, 3, vkey, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYUP, 3, vkey, KF_ALTDOWN), {0}}},
852 {.vkey = VK_LMENU, .flags = KEYEVENTF_KEYUP,
853 .expect = {KEY_HOOK(WM_KEYUP, 4, VK_LMENU), KEY_MSG(WM_KEYUP, 4, VK_MENU), {0}}},
854 {0},
855 };
856
857 struct send_input_keyboard_test lmenu_vkey_peeked[] =
858 {
859 {.vkey = VK_LMENU, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
860 .expect = {KEY_HOOK_(WM_SYSKEYDOWN, 1, VK_LMENU, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYDOWN, 1, VK_MENU, KF_ALTDOWN), {0}}},
861 {
862 .vkey = vkey, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80, /*[vkey] = 0x80*/},
863 .expect =
864 {
865 KEY_HOOK_(WM_SYSKEYDOWN, 2, vkey, LLKHF_ALTDOWN, .todo_value = TRUE),
868 {0}
869 }
870 },
871 {.vkey = vkey, .flags = KEYEVENTF_KEYUP, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
872 .expect = {KEY_HOOK_(WM_SYSKEYUP, 3, vkey, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYUP, 3, vkey, KF_ALTDOWN), {0}}},
873 {.vkey = VK_LMENU, .flags = KEYEVENTF_KEYUP,
874 .expect = {KEY_HOOK(WM_KEYUP, 4, VK_LMENU), KEY_MSG(WM_KEYUP, 4, VK_MENU), {0}}},
875 {0},
876 };
877
878 struct send_input_keyboard_test lcontrol_vkey[] =
879 {
880 {.vkey = VK_LCONTROL, .expect_state = {[VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
881 .expect = {KEY_HOOK(WM_KEYDOWN, 1, VK_LCONTROL), KEY_MSG(WM_KEYDOWN, 1, VK_CONTROL), {0}}},
882 {.vkey = vkey, .expect_state = {[VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80, /*[vkey] = 0x80*/},
883 .expect = {KEY_HOOK(WM_KEYDOWN, 2, vkey), KEY_MSG(WM_KEYDOWN, 2, vkey), WIN_MSG(WM_CHAR, wch_control, MAKELONG(1, 2)), {0}}},
884 {.vkey = vkey, .flags = KEYEVENTF_KEYUP, .expect_state = {[VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
885 .expect = {KEY_HOOK(WM_KEYUP, 3, vkey), KEY_MSG(WM_KEYUP, 3, vkey), {0}}},
886 {.vkey = VK_LCONTROL, .flags = KEYEVENTF_KEYUP,
887 .expect = {KEY_HOOK(WM_KEYUP, 4, VK_LCONTROL), KEY_MSG(WM_KEYUP, 4, VK_CONTROL), {0}}},
888 {0},
889 };
890
891 struct send_input_keyboard_test lmenu_lcontrol_vkey[] =
892 {
893 {.vkey = VK_LMENU, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
894 .expect = {KEY_HOOK_(WM_SYSKEYDOWN, 1, VK_LMENU, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYDOWN, 1, VK_MENU, KF_ALTDOWN), {0}}},
895 {.vkey = VK_LCONTROL, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80, [VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
897 {.vkey = vkey, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80, [VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80, /*[vkey] = 0x80*/},
898 .expect = {KEY_HOOK(WM_KEYDOWN, 3, vkey), KEY_MSG_(WM_KEYDOWN, 3, vkey, KF_ALTDOWN), {0}}},
899 {.vkey = vkey, .flags = KEYEVENTF_KEYUP, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80, [VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
900 .expect = {KEY_HOOK(WM_KEYUP, 4, vkey), KEY_MSG_(WM_KEYUP, 4, vkey, KF_ALTDOWN), {0}}},
901 {.vkey = VK_LCONTROL, .flags = KEYEVENTF_KEYUP, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
902 .expect = {KEY_HOOK_(WM_SYSKEYUP, 5, VK_LCONTROL, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYUP, 5, VK_CONTROL, KF_ALTDOWN), {0}}},
903 {.vkey = VK_LMENU, .flags = KEYEVENTF_KEYUP,
904 .expect = {KEY_HOOK(WM_KEYUP, 6, VK_LMENU), KEY_MSG(WM_KEYUP, 6, VK_MENU), {0}}},
905 {0},
906 };
907
908 struct send_input_keyboard_test shift_vkey[] =
909 {
910 {.vkey = VK_LSHIFT, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80},
911 .expect = {KEY_HOOK(WM_KEYDOWN, 1, VK_LSHIFT), KEY_MSG(WM_KEYDOWN, 1, VK_SHIFT), {0}}},
912 {.vkey = vkey, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80, /*[vkey] = 0x80*/},
913 .expect = {KEY_HOOK(WM_KEYDOWN, 2, vkey), KEY_MSG(WM_KEYDOWN, 2, vkey), WIN_MSG(WM_CHAR, wch_shift, MAKELONG(1, 2)), {0}}},
914 {.vkey = vkey, .flags = KEYEVENTF_KEYUP, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80},
915 .expect = {KEY_HOOK(WM_KEYUP, 3, vkey), KEY_MSG(WM_KEYUP, 3, vkey), {0}}},
916 {.vkey = VK_LSHIFT, .flags = KEYEVENTF_KEYUP,
917 .expect = {KEY_HOOK(WM_KEYUP, 4, VK_LSHIFT), KEY_MSG(WM_KEYUP, 4, VK_SHIFT), {0}}},
918 {0},
919 };
920
921 static const struct send_input_keyboard_test rshift[] =
922 {
923 {.vkey = VK_RSHIFT, .expect_state = {[VK_SHIFT] = 0x80, [VK_RSHIFT] = 0x80}, .todo_state = {[VK_RSHIFT] = TRUE, [VK_LSHIFT] = TRUE},
924 .expect = {KEY_HOOK_(WM_KEYDOWN, 1, VK_RSHIFT, LLKHF_EXTENDED, .todo_value = TRUE), KEY_MSG(WM_KEYDOWN, 1, VK_SHIFT), {0}}},
925 {.vkey = VK_RSHIFT, .flags = KEYEVENTF_KEYUP, .expect_state = {0},
926 .expect = {KEY_HOOK_(WM_KEYUP, 2, VK_RSHIFT, LLKHF_EXTENDED, .todo_value = TRUE), KEY_MSG(WM_KEYUP, 2, VK_SHIFT), {0}}},
927 {0},
928 };
929 static const struct send_input_keyboard_test lshift_ext[] =
930 {
931 {.vkey = VK_LSHIFT, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_SHIFT] = 0x80, [VK_RSHIFT] = 0x80},
934 .expect = {KEY_HOOK_(WM_KEYUP, 2, VK_LSHIFT, LLKHF_EXTENDED), KEY_MSG(WM_KEYUP, 2, VK_SHIFT), {0}}},
935 {0},
936 };
937 static const struct send_input_keyboard_test rshift_ext[] =
938 {
939 {.vkey = VK_RSHIFT, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_SHIFT] = 0x80, [VK_RSHIFT] = 0x80},
941 {.vkey = VK_RSHIFT, .flags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY, .expect_state = {0},
942 .expect = {KEY_HOOK_(WM_KEYUP, 2, VK_RSHIFT, LLKHF_EXTENDED), KEY_MSG(WM_KEYUP, 2, VK_SHIFT), {0}}},
943 {0},
944 };
945 static const struct send_input_keyboard_test shift[] =
946 {
947 {.vkey = VK_SHIFT, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80},
948 .expect = {KEY_HOOK(WM_KEYDOWN, 1, VK_LSHIFT), KEY_MSG(WM_KEYDOWN, 1, VK_SHIFT), {0}}},
949 {.vkey = VK_SHIFT, .flags = KEYEVENTF_KEYUP,
950 .expect = {KEY_HOOK(WM_KEYUP, 2, VK_LSHIFT), KEY_MSG(WM_KEYUP, 2, VK_SHIFT), {0}}},
951 {0},
952 };
953 static const struct send_input_keyboard_test shift_ext[] =
954 {
955 {.vkey = VK_SHIFT, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_SHIFT] = 0x80, [VK_RSHIFT] = 0x80},
956 .expect = {KEY_HOOK_(WM_KEYDOWN, 1, VK_LSHIFT, LLKHF_EXTENDED, .todo_value = TRUE), KEY_MSG(WM_KEYDOWN, 1, VK_SHIFT), {0}}},
958 .expect = {KEY_HOOK_(WM_KEYUP, 2, VK_LSHIFT, LLKHF_EXTENDED, .todo_value = TRUE), KEY_MSG(WM_KEYUP, 2, VK_SHIFT), {0}}},
959 {0},
960 };
961
962 static const struct send_input_keyboard_test rcontrol[] =
963 {
964 {.vkey = VK_RCONTROL, .expect_state = {[VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
965 .expect = {KEY_HOOK(WM_KEYDOWN, 1, VK_RCONTROL), KEY_MSG(WM_KEYDOWN, 1, VK_CONTROL), {0}}},
966 {.vkey = VK_RCONTROL, .flags = KEYEVENTF_KEYUP,
967 .expect = {KEY_HOOK(WM_KEYUP, 2, VK_RCONTROL), KEY_MSG(WM_KEYUP, 2, VK_CONTROL), {0}}},
968 {0},
969 };
970 static const struct send_input_keyboard_test lcontrol_ext[] =
971 {
972 {.vkey = VK_LCONTROL, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_CONTROL] = 0x80, [VK_RCONTROL] = 0x80},
976 {0},
977 };
978 static const struct send_input_keyboard_test rcontrol_ext[] =
979 {
980 {.vkey = VK_RCONTROL, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_CONTROL] = 0x80, [VK_RCONTROL] = 0x80},
984 {0},
985 };
986 static const struct send_input_keyboard_test control[] =
987 {
988 {.vkey = VK_CONTROL, .expect_state = {[VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
989 .expect = {KEY_HOOK(WM_KEYDOWN, 1, VK_LCONTROL), KEY_MSG(WM_KEYDOWN, 1, VK_CONTROL), {0}}},
990 {.vkey = VK_CONTROL, .flags = KEYEVENTF_KEYUP, .expect_state = {0},
991 .expect = {KEY_HOOK(WM_KEYUP, 2, VK_LCONTROL), KEY_MSG(WM_KEYUP, 2, VK_CONTROL), {0}}},
992 {0},
993 };
994 static const struct send_input_keyboard_test control_ext[] =
995 {
996 {.vkey = VK_CONTROL, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_CONTROL] = 0x80, [VK_RCONTROL] = 0x80},
1000 {0},
1001 };
1002
1003 static const struct send_input_keyboard_test rmenu[] =
1004 {
1005 {.vkey = VK_RMENU, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
1006 .expect = {KEY_HOOK_(WM_SYSKEYDOWN, 1, VK_RMENU, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYDOWN, 1, VK_MENU, KF_ALTDOWN), {0}}},
1007 {.vkey = VK_RMENU, .flags = KEYEVENTF_KEYUP,
1008 .expect = {KEY_HOOK(WM_KEYUP, 2, VK_RMENU, .todo_value = TRUE), KEY_MSG(WM_SYSKEYUP, 2, VK_MENU), WIN_MSG(WM_SYSCOMMAND, SC_KEYMENU, 0), {0}}},
1009 {0},
1010 };
1011 static const struct send_input_keyboard_test lmenu_ext[] =
1012 {
1013 {.vkey = VK_LMENU, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_MENU] = 0x80, [VK_RMENU] = 0x80},
1015 {.vkey = VK_LMENU, .flags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY,
1017 {0},
1018 };
1019 static const struct send_input_keyboard_test rmenu_ext[] =
1020 {
1021 {.vkey = VK_RMENU, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_MENU] = 0x80, [VK_RMENU] = 0x80},
1023 {.vkey = VK_RMENU, .flags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY,
1025 {0},
1026 };
1027 static const struct send_input_keyboard_test menu[] =
1028 {
1029 {.vkey = VK_MENU, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
1030 .expect = {KEY_HOOK_(WM_SYSKEYDOWN, 1, VK_LMENU, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYDOWN, 1, VK_MENU, KF_ALTDOWN), {0}}},
1031 {.vkey = VK_MENU, .flags = KEYEVENTF_KEYUP, .expect_state = {0},
1032 .expect = {KEY_HOOK(WM_KEYUP, 2, VK_LMENU, .todo_value = TRUE), KEY_MSG(WM_SYSKEYUP, 2, VK_MENU), WIN_MSG(WM_SYSCOMMAND, SC_KEYMENU, 0), {0}}},
1033 {0},
1034 };
1035 static const struct send_input_keyboard_test menu_ext[] =
1036 {
1037 {.vkey = VK_MENU, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_MENU] = 0x80, [VK_RMENU] = 0x80},
1039 {.vkey = VK_MENU, .flags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY,
1041 {0},
1042 };
1043
1044 static const struct send_input_keyboard_test rmenu_peeked[] =
1045 {
1046 {.vkey = VK_RMENU, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
1047 .expect = {KEY_HOOK_(WM_SYSKEYDOWN, 1, VK_RMENU, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYDOWN, 1, VK_MENU, KF_ALTDOWN), {0}}},
1048 {.vkey = VK_RMENU, .flags = KEYEVENTF_KEYUP,
1049 .expect = {KEY_HOOK(WM_KEYUP, 2, VK_RMENU, .todo_value = TRUE), KEY_MSG(WM_SYSKEYUP, 2, VK_MENU), {0}}},
1050 {0},
1051 };
1052 static const struct send_input_keyboard_test lmenu_ext_peeked[] =
1053 {
1054 {.vkey = VK_LMENU, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_MENU] = 0x80, [VK_RMENU] = 0x80},
1056 {.vkey = VK_LMENU, .flags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY,
1057 .expect = {KEY_HOOK_(WM_KEYUP, 2, VK_LMENU, LLKHF_EXTENDED, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYUP, 2, VK_MENU, KF_EXTENDED), {0}}},
1058 {0},
1059 };
1060 static const struct send_input_keyboard_test rmenu_ext_peeked[] =
1061 {
1062 {.vkey = VK_RMENU, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_MENU] = 0x80, [VK_RMENU] = 0x80},
1064 {.vkey = VK_RMENU, .flags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY,
1065 .expect = {KEY_HOOK_(WM_KEYUP, 2, VK_RMENU, LLKHF_EXTENDED, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYUP, 2, VK_MENU, KF_EXTENDED), {0}}},
1066 {0},
1067 };
1068 static const struct send_input_keyboard_test menu_peeked[] =
1069 {
1070 {.vkey = VK_MENU, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
1071 .expect = {KEY_HOOK_(WM_SYSKEYDOWN, 1, VK_LMENU, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYDOWN, 1, VK_MENU, KF_ALTDOWN), {0}}},
1072 {.vkey = VK_MENU, .flags = KEYEVENTF_KEYUP, .expect_state = {0},
1073 .expect = {KEY_HOOK(WM_KEYUP, 2, VK_LMENU, .todo_value = TRUE), KEY_MSG(WM_SYSKEYUP, 2, VK_MENU), {0}}},
1074 {0},
1075 };
1076 static const struct send_input_keyboard_test menu_ext_peeked[] =
1077 {
1078 {.vkey = VK_MENU, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_MENU] = 0x80, [VK_RMENU] = 0x80},
1080 {.vkey = VK_MENU, .flags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY,
1081 .expect = {KEY_HOOK_(WM_KEYUP, 2, VK_RMENU, LLKHF_EXTENDED, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYUP, 2, VK_MENU, KF_EXTENDED), {0}}},
1082 {0},
1083 };
1084
1085 struct send_input_keyboard_test rmenu_altgr[] =
1086 {
1087 {
1088 .vkey = VK_RMENU, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80, [VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
1089 .expect =
1090 {
1092 KEY_HOOK_(WM_SYSKEYDOWN, 1, VK_RMENU, LLKHF_ALTDOWN, .todo_value = TRUE),
1095 {0}
1096 }
1097 },
1098 {
1099 .vkey = VK_RMENU, .flags = KEYEVENTF_KEYUP,
1100 .expect =
1101 {
1102 KEY_HOOK(WM_KEYUP, 0x21d, VK_LCONTROL),
1106 {0}
1107 }
1108 },
1109 {0},
1110 };
1111 struct send_input_keyboard_test rmenu_ext_altgr[] =
1112 {
1113 {
1114 .vkey = VK_RMENU, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_MENU] = 0x80, [VK_RMENU] = 0x80, [VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
1115 .expect =
1116 {
1121 {0}
1122 }
1123 },
1124 {
1126 .expect =
1127 {
1128 KEY_HOOK(WM_KEYUP, 0x21d, VK_LCONTROL),
1129 KEY_HOOK_(WM_KEYUP, 2, VK_RMENU, LLKHF_EXTENDED, .todo_value = TRUE),
1132 {0}
1133 }
1134 },
1135 {0},
1136 };
1137 struct send_input_keyboard_test menu_ext_altgr[] =
1138 {
1139 {
1140 .vkey = VK_MENU, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_MENU] = 0x80, [VK_RMENU] = 0x80, [VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
1141 .expect =
1142 {
1147 {0}
1148 }
1149 },
1150 {
1151 .vkey = VK_MENU, .flags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY,
1152 .expect =
1153 {
1154 KEY_HOOK(WM_KEYUP, 0x21d, VK_LCONTROL),
1155 KEY_HOOK_(WM_KEYUP, 2, VK_RMENU, LLKHF_EXTENDED, .todo_value = TRUE),
1158 {0}
1159 }
1160 },
1161 {0},
1162 };
1163
1164 static const struct send_input_keyboard_test lrshift_ext[] =
1165 {
1166 {.vkey = VK_LSHIFT, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80},
1167 .expect = {KEY_HOOK(WM_KEYDOWN, 1, VK_LSHIFT), KEY_MSG(WM_KEYDOWN, 1, VK_SHIFT), {0}}},
1168 {.vkey = VK_RSHIFT, .flags = KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80, [VK_RSHIFT] = 0x80},
1169 .expect = {KEY_HOOK_(WM_KEYDOWN, 2, VK_RSHIFT, LLKHF_EXTENDED), KEY_MSG_(WM_KEYDOWN, 2, VK_SHIFT, KF_REPEAT, .todo_value = TRUE), {0}}},
1170 {.vkey = VK_RSHIFT, .flags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80},
1171 .expect = {KEY_HOOK_(WM_KEYUP, 3, VK_RSHIFT, LLKHF_EXTENDED), {0, .todo = TRUE}, {0}}},
1172 {.vkey = VK_LSHIFT, .flags = KEYEVENTF_KEYUP,
1173 .expect = {KEY_HOOK(WM_KEYUP, 4, VK_LSHIFT), KEY_MSG(WM_KEYUP, 4, VK_SHIFT), {0}}},
1174 {0},
1175 };
1176
1177 struct send_input_keyboard_test rshift_scan[] =
1178 {
1179 {.scan = 0x36, .flags = KEYEVENTF_SCANCODE, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80},
1180 .expect = {KEY_HOOK(WM_KEYDOWN, 0x36, VK_RSHIFT), KEY_MSG(WM_KEYDOWN, 0x36, VK_SHIFT), {0}}},
1181 {.scan = scan, .flags = KEYEVENTF_SCANCODE, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80, /*[vkey] = 0x80*/},
1182 .expect = {KEY_HOOK(WM_KEYDOWN, scan, vkey), KEY_MSG(WM_KEYDOWN, scan, vkey), WIN_MSG(WM_CHAR, wch_shift, MAKELONG(1, scan)), {0}}},
1183 {.scan = scan, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80},
1184 .expect = {KEY_HOOK(WM_KEYUP, scan, vkey), KEY_MSG(WM_KEYUP, scan, vkey), {0}}},
1185 {.scan = 0x36, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP,
1186 .expect = {KEY_HOOK(WM_KEYUP, 0x36, VK_RSHIFT), KEY_MSG(WM_KEYUP, 0x36, VK_SHIFT), {0}}},
1187 {0},
1188 };
1189
1190 struct send_input_keyboard_test rctrl_scan[] =
1191 {
1192 {.scan = 0xe01d, .flags = KEYEVENTF_SCANCODE, .expect_state = {[VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
1193 .expect = {KEY_HOOK(WM_KEYDOWN, 0x1d, VK_LCONTROL), KEY_MSG(WM_KEYDOWN, 0x1d, VK_CONTROL), {0}}},
1194 {.scan = 0xe01d, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP,
1195 .expect = {KEY_HOOK(WM_KEYUP, 0x1d, VK_LCONTROL), KEY_MSG(WM_KEYUP, 0x1d, VK_CONTROL), {0}}},
1196 {.scan = 0x1d, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_EXTENDEDKEY, .expect_state = {[VK_CONTROL] = 0x80, [VK_RCONTROL] = 0x80},
1197 .expect = {KEY_HOOK_(WM_KEYDOWN, 0x1d, VK_RCONTROL, LLKHF_EXTENDED, .todo_value = TRUE), KEY_MSG(WM_KEYDOWN, 0x11d, VK_CONTROL), {0}}},
1198 {.scan = 0x1d, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
1199 .expect = {KEY_HOOK_(WM_KEYUP, 0x1d, VK_RCONTROL, LLKHF_EXTENDED, .todo_value = TRUE), KEY_MSG(WM_KEYUP, 0x11d, VK_CONTROL), {0}}},
1200 {0},
1201 };
1202
1203 struct send_input_keyboard_test unicode[] =
1204 {
1205 {.scan = 0x3c0, .flags = KEYEVENTF_UNICODE, .expect_state = {[VK_PACKET] = 0x80},
1206 .expect = {KEY_HOOK(WM_KEYDOWN, 0x3c0, VK_PACKET), KEY_MSG(WM_KEYDOWN, 0, VK_PACKET, .todo_value = TRUE), WIN_MSG(WM_CHAR, 0x3c0, 1), {0}}},
1207 {.scan = 0x3c0, .flags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP,
1208 .expect = {KEY_HOOK(WM_KEYUP, 0x3c0, VK_PACKET, .todo_value = TRUE), KEY_MSG(WM_KEYUP, 0, VK_PACKET, .todo_value = TRUE), {0}}},
1209 {0},
1210 };
1211
1212 struct send_input_keyboard_test lmenu_unicode[] =
1213 {
1214 {.vkey = VK_LMENU, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
1215 .expect = {KEY_HOOK_(WM_SYSKEYDOWN, 1, VK_LMENU, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYDOWN, 1, VK_MENU, KF_ALTDOWN), {0}}},
1216 {
1217 .scan = 0x3c0, .flags = KEYEVENTF_UNICODE, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80, [VK_PACKET] = 0x80},
1218 .expect =
1219 {
1220 KEY_HOOK_(WM_SYSKEYDOWN, 0x3c0, VK_PACKET, LLKHF_ALTDOWN, .todo_value = TRUE),
1221 KEY_MSG_(WM_SYSKEYDOWN, 0, VK_PACKET, KF_ALTDOWN, .todo_value = TRUE),
1222 WIN_MSG(WM_SYSCHAR, 0x3c0, MAKELONG(1, KF_ALTDOWN), .todo_value = TRUE),
1224 {0},
1225 },
1226 },
1227 {.scan = 0x3c0, .flags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
1228 .expect = {KEY_HOOK_(WM_SYSKEYUP, 0x3c0, VK_PACKET, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYUP, 0, VK_PACKET, KF_ALTDOWN, .todo_value = TRUE), {0}}},
1229 {.vkey = VK_LMENU, .flags = KEYEVENTF_KEYUP,
1230 .expect = {KEY_HOOK(WM_KEYUP, 4, VK_LMENU), KEY_MSG(WM_KEYUP, 4, VK_MENU), {0}}},
1231 {0},
1232 };
1233 struct send_input_keyboard_test lmenu_unicode_peeked[] =
1234 {
1235 {.vkey = VK_LMENU, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
1236 .expect = {KEY_HOOK_(WM_SYSKEYDOWN, 1, VK_LMENU, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYDOWN, 1, VK_MENU, KF_ALTDOWN), {0}}},
1237 {
1238 .scan = 0x3c0, .flags = KEYEVENTF_UNICODE, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80, [VK_PACKET] = 0x80},
1239 .expect =
1240 {
1241 KEY_HOOK_(WM_SYSKEYDOWN, 0x3c0, VK_PACKET, LLKHF_ALTDOWN, .todo_value = TRUE),
1242 KEY_MSG_(WM_SYSKEYDOWN, 0, VK_PACKET, KF_ALTDOWN, .todo_value = TRUE),
1243 WIN_MSG(WM_SYSCHAR, 0x3c0, MAKELONG(1, KF_ALTDOWN), .todo_value = TRUE),
1244 {0},
1245 },
1246 },
1247 {.scan = 0x3c0, .flags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP, .expect_state = {[VK_MENU] = 0x80, [VK_LMENU] = 0x80},
1248 .expect = {KEY_HOOK_(WM_SYSKEYUP, 0x3c0, VK_PACKET, LLKHF_ALTDOWN, .todo_value = TRUE), KEY_MSG_(WM_SYSKEYUP, 0, VK_PACKET, KF_ALTDOWN, .todo_value = TRUE), {0}}},
1249 {.vkey = VK_LMENU, .flags = KEYEVENTF_KEYUP,
1250 .expect = {KEY_HOOK(WM_KEYUP, 4, VK_LMENU), KEY_MSG(WM_KEYUP, 4, VK_MENU), {0}}},
1251 {0},
1252 };
1253
1254 struct send_input_keyboard_test unicode_vkey[] =
1255 {
1256#if defined(__REACTOS__) && defined(_MSC_VER)
1257 {.scan = 0x3c0, .vkey = vkey, .flags = KEYEVENTF_UNICODE, .expect_state = { 0 /*[vkey] = 0x80*/},
1258#else
1259 {.scan = 0x3c0, .vkey = vkey, .flags = KEYEVENTF_UNICODE, .expect_state = {/*[vkey] = 0x80*/},
1260#endif
1261 .expect = {KEY_HOOK(WM_KEYDOWN, 0xc0, vkey), KEY_MSG(WM_KEYDOWN, 0xc0, vkey), WIN_MSG(WM_CHAR, wch, MAKELONG(1, 0xc0)), {0}}},
1262 {.scan = 0x3c0, .vkey = vkey, .flags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP,
1263 .expect = {KEY_HOOK(WM_KEYUP, 0xc0, vkey), KEY_MSG(WM_KEYUP, 0xc0, vkey), {0}}},
1264 {0},
1265 };
1266
1267 struct send_input_keyboard_test unicode_vkey_ctrl[] =
1268 {
1269 {.scan = 0x3c0, .vkey = VK_CONTROL, .flags = KEYEVENTF_UNICODE, .expect_state = {[VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
1270 .expect = {KEY_HOOK(WM_KEYDOWN, 0xc0, VK_LCONTROL), KEY_MSG(WM_KEYDOWN, 0xc0, VK_CONTROL), {0}}},
1271 {.scan = 0x3c0, .vkey = VK_CONTROL, .flags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP,
1272 .expect = {KEY_HOOK(WM_KEYUP, 0xc0, VK_LCONTROL), KEY_MSG(WM_KEYUP, 0xc0, VK_CONTROL), {0}}},
1273 {0},
1274 };
1275
1276 struct send_input_keyboard_test unicode_vkey_packet[] =
1277 {
1278 {.scan = 0x3c0, .vkey = VK_PACKET, .flags = KEYEVENTF_UNICODE, .expect_state = {[VK_PACKET] = 0x80},
1279 .expect = {KEY_HOOK(WM_KEYDOWN, 0xc0, VK_PACKET), KEY_MSG(WM_KEYDOWN, 0, VK_PACKET, .todo_value = TRUE), WIN_MSG(WM_CHAR, 0xc0, 1), {0}}},
1280 {.scan = 0x3c0, .vkey = VK_PACKET, .flags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP,
1281 .expect = {KEY_HOOK(WM_KEYUP, 0xc0, VK_PACKET), KEY_MSG(WM_KEYUP, 0, VK_PACKET, .todo_value = TRUE), {0}}},
1282 {0},
1283 };
1284
1285 struct send_input_keyboard_test numpad_scan[] =
1286 {
1287 {.scan = 0x4b, .flags = KEYEVENTF_SCANCODE, .expect_state = {[VK_LEFT] = 0x80},
1288 .expect = {KEY_HOOK(WM_KEYDOWN, 0x4b, VK_LEFT), KEY_MSG(WM_KEYDOWN, 0x4b, VK_LEFT), {0}}},
1289 {.scan = 0x4b, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP,
1290 .expect = {KEY_HOOK(WM_KEYUP, 0x4b, VK_LEFT), KEY_MSG(WM_KEYUP, 0x4b, VK_LEFT), {0}}},
1291 {0},
1292 };
1293
1294 struct send_input_keyboard_test numpad_scan_numlock[] =
1295 {
1296 {.scan = 0x45, .flags = KEYEVENTF_SCANCODE, .expect_state = {[VK_NUMLOCK] = 0x80},
1297 .expect = {KEY_HOOK(WM_KEYDOWN, 0x45, VK_NUMLOCK), KEY_MSG(WM_KEYDOWN, 0x45, VK_NUMLOCK), {0}}},
1298 {.scan = 0x45, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, .expect_state = {[VK_NUMLOCK] = 0x01},
1299 .expect = {KEY_HOOK(WM_KEYUP, 0x45, VK_NUMLOCK), KEY_MSG(WM_KEYUP, 0x45, VK_NUMLOCK), {0}}},
1300 {
1301 .scan = 0x4b, .flags = KEYEVENTF_SCANCODE,
1302 .expect_state = {[VK_NUMPAD4] = 0x80, [VK_NUMLOCK] = 0x01},
1303 .todo_state = {[VK_NUMPAD4] = TRUE, [VK_LEFT] = TRUE},
1304 .expect =
1305 {
1306 KEY_HOOK(WM_KEYDOWN, 0x4b, VK_NUMPAD4, .todo_value = TRUE),
1307 KEY_MSG(WM_KEYDOWN, 0x4b, VK_NUMPAD4, .todo_value = TRUE),
1308 WIN_MSG(WM_CHAR, '4', MAKELONG(1, 0x4b), .todo_value = TRUE),
1309 {0}
1310 }
1311 },
1312 {
1313 .scan = 0x4b, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, .expect_state = {[VK_NUMLOCK] = 0x01},
1314 .expect =
1315 {
1316 KEY_HOOK(WM_KEYUP, 0x4b, VK_NUMPAD4, .todo_value = TRUE),
1317 KEY_MSG(WM_KEYUP, 0x4b, VK_NUMPAD4, .todo_value = TRUE),
1318 {0}
1319 }
1320 },
1321 {0},
1322 };
1323
1324#undef WIN_MSG
1325#undef KBD_HOOK
1326#undef KEY_HOOK_
1327#undef KEY_HOOK
1328#undef KEY_MSG_
1329#undef KEY_MSG
1330
1331 BOOL altgr = keyboard_layout_has_altgr(), skip_altgr = FALSE;
1333 HHOOK hook;
1334 HWND hwnd;
1335
1336 /* on 32-bit with ALTGR keyboard, the CONTROL key is sent to the hooks without the
1337 * LLKHF_INJECTED flag, skip the tests to keep it simple */
1338 if (altgr && sizeof(void *) == 4 && !is_wow64) skip_altgr = TRUE;
1339
1340 hwnd = CreateWindowW( L"static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL );
1341 ok_ne( NULL, hwnd, HWND, "%p" );
1342 wait_messages( 100, FALSE );
1343
1344 /* If we have had a spurious layout change, wch(_shift) may be incorrect. */
1345 if (GetKeyboardLayout( 0 ) != hkl)
1346 {
1347 win_skip( "Spurious keyboard layout changed detected (expected: %p got: %p)\n",
1348 hkl, GetKeyboardLayout( 0 ) );
1349 ok_ret( 1, DestroyWindow( hwnd ) );
1350 wait_messages( 100, FALSE );
1352 return;
1353 }
1354
1356 ok_ne( NULL, hook, HHOOK, "%p" );
1357
1360
1361 lmenu_vkey_peeked[1].expect_state[vkey] = 0x80;
1362 lmenu_vkey[1].expect_state[vkey] = 0x80;
1363 lcontrol_vkey[1].expect_state[vkey] = 0x80;
1364 lmenu_lcontrol_vkey[2].expect_state[vkey] = 0x80;
1365 shift_vkey[1].expect_state[vkey] = 0x80;
1366 rshift_scan[1].expect_state[vkey] = 0x80;
1367 unicode_vkey[0].expect_state[vkey] = 0x80;
1368
1369 /* test peeked messages */
1370 winetest_push_context( "peek" );
1371 check_send_input_keyboard_test( lmenu_vkey_peeked, TRUE );
1372 check_send_input_keyboard_test( lcontrol_vkey, TRUE );
1373 check_send_input_keyboard_test( lmenu_lcontrol_vkey, TRUE );
1374 check_send_input_keyboard_test( shift_vkey, TRUE );
1376 check_send_input_keyboard_test( lshift_ext, TRUE );
1377 check_send_input_keyboard_test( rshift_ext, TRUE );
1381 check_send_input_keyboard_test( lcontrol_ext, TRUE );
1382 check_send_input_keyboard_test( rcontrol_ext, TRUE );
1384 check_send_input_keyboard_test( control_ext, TRUE );
1385 if (skip_altgr) skip( "skipping rmenu_altgr test\n" );
1386 else if (altgr) check_send_input_keyboard_test( rmenu_altgr, TRUE );
1387 else check_send_input_keyboard_test( rmenu_peeked, TRUE );
1388 check_send_input_keyboard_test( lmenu_ext_peeked, TRUE );
1389 if (skip_altgr) skip( "skipping rmenu_ext_altgr test\n" );
1390 else if (altgr) check_send_input_keyboard_test( rmenu_ext_altgr, TRUE );
1391 else check_send_input_keyboard_test( rmenu_ext_peeked, TRUE );
1392 check_send_input_keyboard_test( menu_peeked, TRUE );
1393 if (skip_altgr) skip( "skipping menu_ext_altgr test\n" );
1394 else if (altgr) check_send_input_keyboard_test( menu_ext_altgr, TRUE );
1395 else check_send_input_keyboard_test( menu_ext_peeked, TRUE );
1396 check_send_input_keyboard_test( lrshift_ext, TRUE );
1397 check_send_input_keyboard_test( rshift_scan, TRUE );
1398 /* Skip on Korean layouts since they map the right control key to VK_HANJA */
1399 if (hkl == (HKL)0x04120412) skip( "skipping rctrl_scan test on Korean layout" );
1400 else check_send_input_keyboard_test( rctrl_scan, TRUE );
1402 check_send_input_keyboard_test( lmenu_unicode_peeked, TRUE );
1403 check_send_input_keyboard_test( unicode_vkey, TRUE );
1404 check_send_input_keyboard_test( unicode_vkey_ctrl, TRUE );
1405 check_send_input_keyboard_test( unicode_vkey_packet, TRUE );
1406 check_send_input_keyboard_test( numpad_scan, TRUE );
1407 check_send_input_keyboard_test( numpad_scan_numlock, TRUE );
1409
1410 wait_messages( 100, FALSE );
1412
1413 /* test received messages */
1415 ok_ne( 0, old_proc, LONG_PTR, "%#Ix" );
1416
1417 winetest_push_context( "receive" );
1419 check_send_input_keyboard_test( lcontrol_vkey, FALSE );
1420 check_send_input_keyboard_test( lmenu_lcontrol_vkey, FALSE );
1428 check_send_input_keyboard_test( lcontrol_ext, FALSE );
1429 check_send_input_keyboard_test( rcontrol_ext, FALSE );
1431 check_send_input_keyboard_test( control_ext, FALSE );
1432 if (skip_altgr) skip( "skipping rmenu_altgr test\n" );
1433 else if (altgr) check_send_input_keyboard_test( rmenu_altgr, FALSE );
1436 if (skip_altgr) skip( "skipping rmenu_ext_altgr test\n" );
1437 else if (altgr) check_send_input_keyboard_test( rmenu_ext_altgr, FALSE );
1438 else check_send_input_keyboard_test( rmenu_ext, FALSE );
1440 if (skip_altgr) skip( "skipping menu_ext_altgr test\n" );
1441 else if (altgr) check_send_input_keyboard_test( menu_ext_altgr, FALSE );
1442 else check_send_input_keyboard_test( menu_ext, FALSE );
1443 check_send_input_keyboard_test( lrshift_ext, FALSE );
1444 check_send_input_keyboard_test( rshift_scan, FALSE );
1445 /* Skip on Korean layouts since they map the right control key to VK_HANJA */
1446 if (hkl == (HKL)0x04120412) skip( "skipping rctrl_scan test on Korean layout" );
1447 else check_send_input_keyboard_test( rctrl_scan, FALSE );
1449 check_send_input_keyboard_test( lmenu_unicode, FALSE );
1450 check_send_input_keyboard_test( unicode_vkey, FALSE );
1451 check_send_input_keyboard_test( unicode_vkey_ctrl, FALSE );
1452 check_send_input_keyboard_test( unicode_vkey_packet, FALSE );
1453 check_send_input_keyboard_test( numpad_scan, FALSE );
1454 check_send_input_keyboard_test( numpad_scan_numlock, FALSE );
1456
1457 ok_ret( 1, DestroyWindow( hwnd ) );
1459
1460 wait_messages( 100, FALSE );
1463}
1464
1465static void test_keynames(void)
1466{
1467 int i, len;
1468 char buff[256];
1469
1470 for (i = 0; i < 512; i++)
1471 {
1472 strcpy(buff, "----");
1473 len = GetKeyNameTextA(i << 16, buff, sizeof(buff));
1474 ok(len || !buff[0], "%d: Buffer is not zeroed\n", i);
1475 }
1476}
1477
1479{
1480 return is_keyboard_message( msg ) || msg == WM_INPUT;
1481}
1482
1484{
1485#define WIN_MSG(m, w, l, ...) {.func = MSG_TEST_WIN, .message = {.msg = m, .wparam = w, .lparam = l}, ## __VA_ARGS__}
1486#define RAW_KEY(s, f, v, m, ...) {.func = RAW_INPUT_KEYBOARD, .raw_input.kbd = {.MakeCode = s, .Flags = f, .VKey = v, .Message = m}, ## __VA_ARGS__}
1487#define KEY_MSG(m, s, v, ...) WIN_MSG( m, v, MAKELONG(1, (s) | (m == WM_KEYUP || m == WM_SYSKEYUP ? (KF_UP | KF_REPEAT) : 0)), ## __VA_ARGS__ )
1488 struct send_input_keyboard_test raw_legacy[] =
1489 {
1490 {.vkey = vkey,
1491 .expect = {RAW_KEY(1, RI_KEY_MAKE, vkey, WM_KEYDOWN), KEY_MSG(WM_KEYDOWN, 1, vkey), WIN_MSG(WM_CHAR, wch, MAKELONG(1, 1)), {0}}},
1492 {.vkey = vkey, .flags = KEYEVENTF_KEYUP,
1493 .expect = {RAW_KEY(2, RI_KEY_BREAK, vkey, WM_KEYUP), KEY_MSG(WM_KEYUP, 2, vkey), {0}}},
1494 {0},
1495 };
1496 struct send_input_keyboard_test raw_nolegacy[] =
1497 {
1498 {.vkey = vkey, .async = TRUE, .expect = {RAW_KEY(1, RI_KEY_MAKE, vkey, WM_KEYDOWN), {0}}},
1499 {.vkey = vkey, .flags = KEYEVENTF_KEYUP, .expect = {RAW_KEY(2, RI_KEY_BREAK, vkey, WM_KEYUP), {0}}},
1500 {0},
1501 };
1502 struct send_input_keyboard_test raw_vk_packet_legacy[] =
1503 {
1504 {.vkey = VK_PACKET, .expect_state = {[VK_PACKET] = 0x80},
1505 .expect = {RAW_KEY(1, RI_KEY_MAKE, VK_PACKET, WM_KEYDOWN), KEY_MSG(WM_KEYDOWN, 1, VK_PACKET), {0, .todo = TRUE}}},
1506 {.vkey = VK_PACKET, .flags = KEYEVENTF_KEYUP,
1507 .expect = {RAW_KEY(2, RI_KEY_BREAK, VK_PACKET, WM_KEYUP), KEY_MSG(WM_KEYUP, 2, VK_PACKET), {0}}},
1508 {0},
1509 };
1510 struct send_input_keyboard_test raw_vk_packet_nolegacy[] =
1511 {
1512 {.vkey = VK_PACKET, .async = TRUE, .expect_async = {[VK_PACKET] = 0x80},
1513 .expect = {RAW_KEY(1, RI_KEY_MAKE, VK_PACKET, WM_KEYDOWN), {0}}},
1514 {.vkey = VK_PACKET, .flags = KEYEVENTF_KEYUP, .expect = {RAW_KEY(2, RI_KEY_BREAK, VK_PACKET, WM_KEYUP), {0}}},
1515 {0},
1516 };
1517 struct send_input_keyboard_test raw_unicode_legacy[] =
1518 {
1519 {.scan = 0x3c0, .flags = KEYEVENTF_UNICODE, .expect_state = {[VK_PACKET] = 0x80},
1520 .expect = {KEY_MSG(WM_KEYDOWN, 0, VK_PACKET, .todo_value = TRUE), WIN_MSG(WM_CHAR, 0x3c0, 1), {0}}},
1521 {.scan = 0x3c0, .flags = KEYEVENTF_KEYUP | KEYEVENTF_UNICODE,
1522 .expect = {KEY_MSG(WM_KEYUP, 0, VK_PACKET, .todo_value = TRUE), {0}}},
1523 {0},
1524 };
1525 struct send_input_keyboard_test raw_unicode_nolegacy[] =
1526 {
1527 {.scan = 0x3c0, .flags = KEYEVENTF_UNICODE, .async = TRUE, .expect_async = {[VK_PACKET] = 0x80}},
1528 {.scan = 0x3c0, .flags = KEYEVENTF_KEYUP | KEYEVENTF_UNICODE},
1529 {0},
1530 };
1531 struct send_input_keyboard_test raw_unicode_vkey_ctrl_legacy[] =
1532 {
1533 {.scan = 0x3c0, .vkey = VK_CONTROL, .flags = KEYEVENTF_UNICODE,
1534 .expect_state = {[VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80},
1535 .expect = {KEY_MSG(WM_KEYDOWN, 0xc0, VK_CONTROL), {0}}},
1536 {.scan = 0x3c0, .vkey = VK_CONTROL, .flags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP,
1537 .expect = {KEY_MSG(WM_KEYUP, 0xc0, VK_CONTROL), {0}}},
1538 {0},
1539 };
1540 struct send_input_keyboard_test raw_unicode_vkey_ctrl_nolegacy[] =
1541 {
1542 {.scan = 0x3c0, .vkey = VK_CONTROL, .flags = KEYEVENTF_UNICODE, .async = TRUE,
1543 .expect_async = {[VK_CONTROL] = 0x80, [VK_LCONTROL] = 0x80}},
1544 {.scan = 0x3c0, .vkey = VK_CONTROL, .flags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP},
1545 {0},
1546 };
1547#undef WIN_MSG
1548#undef RAW_KEY
1549#undef KEY_MSG
1550 RAWINPUTDEVICE rid = {.usUsagePage = HID_USAGE_PAGE_GENERIC, .usUsage = HID_USAGE_GENERIC_KEYBOARD};
1551 int receive;
1552 HWND hwnd;
1553
1554 raw_legacy[0].expect_state[vkey] = 0x80;
1555 raw_nolegacy[0].expect_async[vkey] = 0x80;
1556
1557 hwnd = CreateWindowW( L"static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL );
1558 ok_ne( NULL, hwnd, HWND, "%p" );
1559 wait_messages( 100, FALSE );
1560
1561 /* If we have had a spurious layout change, wch may be incorrect. */
1562 if (GetKeyboardLayout( 0 ) != hkl)
1563 {
1564 win_skip( "Spurious keyboard layout changed detected (expected: %p got: %p)\n",
1565 hkl, GetKeyboardLayout( 0 ) );
1566 ok_ret( 1, DestroyWindow( hwnd ) );
1567 wait_messages( 100, FALSE );
1569 return;
1570 }
1571
1573
1574 for (receive = 0; receive <= 1; receive++)
1575 {
1576 winetest_push_context( receive ? "receive" : "peek" );
1577
1578 if (receive)
1579 {
1580 /* test received messages */
1582 ok_ne( 0, old_proc, LONG_PTR, "%#Ix" );
1583 }
1584
1585 rid.dwFlags = 0;
1586 ok_ret( 1, RegisterRawInputDevices( &rid, 1, sizeof(rid) ) );
1587
1588 /* get both WM_INPUT and legacy messages */
1589 check_send_input_keyboard_test( raw_legacy, !receive );
1590 check_send_input_keyboard_test( raw_vk_packet_legacy, !receive );
1591 /* no WM_INPUT message for unicode */
1592 check_send_input_keyboard_test( raw_unicode_legacy, !receive );
1593 check_send_input_keyboard_test( raw_unicode_vkey_ctrl_legacy, !receive );
1594
1595 rid.dwFlags = RIDEV_REMOVE;
1596 ok_ret( 1, RegisterRawInputDevices( &rid, 1, sizeof(rid) ) );
1597
1598 rid.dwFlags = RIDEV_NOLEGACY;
1599 ok_ret( 1, RegisterRawInputDevices( &rid, 1, sizeof(rid) ) );
1600
1601 /* get only WM_INPUT messages */
1602 check_send_input_keyboard_test( raw_nolegacy, !receive );
1603 check_send_input_keyboard_test( raw_vk_packet_nolegacy, !receive );
1604 /* no WM_INPUT message for unicode */
1605 check_send_input_keyboard_test( raw_unicode_nolegacy, !receive );
1606 check_send_input_keyboard_test( raw_unicode_vkey_ctrl_nolegacy, !receive );
1607
1608 rid.dwFlags = RIDEV_REMOVE;
1609 ok_ret( 1, RegisterRawInputDevices( &rid, 1, sizeof(rid) ) );
1610
1612 }
1613
1614 ok_ret( 1, DestroyWindow( hwnd ) );
1615 wait_messages( 100, FALSE );
1617
1619}
1620
1621static void test_GetMouseMovePointsEx( char **argv )
1622{
1623#define BUFLIM 64
1624#define MYERROR 0xdeadbeef
1625 int i, count, retval;
1626 MOUSEMOVEPOINT in;
1627 MOUSEMOVEPOINT out[200];
1628 POINT point;
1629 INPUT input;
1630
1631 /* Get a valid content for the input struct */
1632 if(!GetCursorPos(&point)) {
1633 win_skip("GetCursorPos() failed with error %lu\n", GetLastError());
1634 return;
1635 }
1636 memset(&in, 0, sizeof(MOUSEMOVEPOINT));
1637 in.x = point.x;
1638 in.y = point.y;
1639
1640 /* test first parameter
1641 * everything different than sizeof(MOUSEMOVEPOINT)
1642 * is expected to fail with ERROR_INVALID_PARAMETER
1643 */
1645 retval = pGetMouseMovePointsEx(0, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1647 {
1648 win_skip( "GetMouseMovePointsEx broken on WinME\n" );
1649 return;
1650 }
1651 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1653 "expected error ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1654
1656 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1657 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1659 "expected error ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1660
1662 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)+1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1663 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1665 "expected error ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1666
1667 /* test second and third parameter
1668 */
1670 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1671 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1673 "expected error ERROR_NOACCESS, got %lu\n", GetLastError());
1674
1676 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1677 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1679 "expected error ERROR_NOACCESS, got %lu\n", GetLastError());
1680
1682 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1683 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1685 "expected error ERROR_NOACCESS, got %lu\n", GetLastError());
1686
1688 count = 0;
1689 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, count, GMMP_USE_DISPLAY_POINTS);
1690 if (retval == -1)
1691 ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %lu\n", GetLastError());
1692 else
1693 ok(retval == count, "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1694
1695 /* test fourth parameter
1696 * a value higher than 64 is expected to fail with ERROR_INVALID_PARAMETER
1697 */
1699 count = -1;
1700 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1701 ok(retval == count, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1703 "expected error ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1704
1706 count = 0;
1707 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1708 if (retval == -1)
1709 ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %lu\n", GetLastError());
1710 else
1711 ok(retval == count, "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1712
1714 count = BUFLIM;
1715 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1716 if (retval == -1)
1717 ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %lu\n", GetLastError());
1718 else
1719 ok((0 <= retval) && (retval <= count), "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1720
1722 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1723 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1725 "expected error ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1726
1727 /* it was not possible to force an error with the fifth parameter on win2k */
1728
1729 /* test combinations of wrong parameters to see which error wins */
1731 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1732 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1734 "expected error ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1735
1737 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1738 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1740 "expected error ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1741
1743 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1744 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1746 "expected error ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1747
1749 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1750 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1752 "expected error ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1753
1754 /* more than 64 to be sure we wrap around */
1755 for (i = 0; i < 67; i++)
1756 {
1757 in.x = i;
1758 in.y = i*2;
1759 SetCursorPos( in.x, in.y );
1760 }
1761
1763 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS );
1764 ok( retval == 64, "expected to get 64 mouse move points but got %d\n", retval );
1765 ok( GetLastError() == MYERROR, "expected error to stay %x, got %lx\n", MYERROR, GetLastError() );
1766
1767 for (i = 0; i < retval; i++)
1768 {
1769 ok( out[i].x == in.x && out[i].y == in.y, "wrong position %d, expected %dx%d got %dx%d\n", i, in.x, in.y, out[i].x, out[i].y );
1770 in.x--;
1771 in.y -= 2;
1772 }
1773
1774 in.x = 1500;
1775 in.y = 1500;
1777 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS );
1778 ok( retval == -1, "expected to get -1 but got %d\n", retval );
1779 ok( GetLastError() == ERROR_POINT_NOT_FOUND, "expected error to be set to %x, got %lx\n", ERROR_POINT_NOT_FOUND, GetLastError() );
1780
1781 /* make sure there's no deduplication */
1782 in.x = 6;
1783 in.y = 6;
1784 SetCursorPos( in.x, in.y );
1785 SetCursorPos( in.x, in.y );
1786 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS );
1787 ok( retval == 64, "expected to get 64 mouse move points but got %d\n", retval );
1788 ok( out[0].x == 6 && out[0].y == 6, "expected cursor position to be 6x6 but got %d %d\n", out[0].x, out[0].y );
1789 ok( out[1].x == 6 && out[1].y == 6, "expected cursor position to be 6x6 but got %d %d\n", out[1].x, out[1].y );
1790
1791 /* make sure 2 events are distinguishable by their timestamps */
1792 in.x = 150;
1793 in.y = 75;
1794 SetCursorPos( 30, 30 );
1795 SetCursorPos( in.x, in.y );
1796 SetCursorPos( 150, 150 );
1797 Sleep( 3 );
1798 SetCursorPos( in.x, in.y );
1799
1800 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS );
1801 ok( retval == 64, "expected to get 64 mouse move points but got %d\n", retval );
1802 ok( out[0].x == 150 && out[0].y == 75, "expected cursor position to be 150x75 but got %d %d\n", out[0].x, out[0].y );
1803 ok( out[1].x == 150 && out[1].y == 150, "expected cursor position to be 150x150 but got %d %d\n", out[1].x, out[1].y );
1804 ok( out[2].x == 150 && out[2].y == 75, "expected cursor position to be 150x75 but got %d %d\n", out[2].x, out[2].y );
1805
1806 in.time = out[2].time;
1807 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS );
1808 ok( retval == 62, "expected to get 62 mouse move points but got %d\n", retval );
1809 ok( out[0].x == 150 && out[0].y == 75, "expected cursor position to be 150x75 but got %d %d\n", out[0].x, out[0].y );
1810 ok( out[1].x == 30 && out[1].y == 30, "expected cursor position to be 30x30 but got %d %d\n", out[1].x, out[1].y );
1811
1812 /* events created through other means should also be on the list with correct extra info */
1813 mouse_event( MOUSEEVENTF_MOVE, -13, 17, 0, 0xcafecafe );
1814 ok( GetCursorPos( &point ), "failed to get cursor position\n" );
1815 ok( in.x != point.x && in.y != point.y, "cursor didn't change position after mouse_event()\n" );
1816 in.time = 0;
1817 in.x = point.x;
1818 in.y = point.y;
1819 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS );
1820 ok( retval == 64, "expected to get 64 mouse move points but got %d\n", retval );
1821 ok( out[0].dwExtraInfo == 0xcafecafe, "wrong extra info, got 0x%Ix expected 0xcafecafe\n", out[0].dwExtraInfo );
1822
1823 input.type = INPUT_MOUSE;
1824 memset( &input, 0, sizeof(input) );
1825 input.mi.dwFlags = MOUSEEVENTF_MOVE;
1826 input.mi.dwExtraInfo = 0xdeadbeef;
1827 input.mi.dx = -17;
1828 input.mi.dy = 13;
1829 SendInput( 1, (INPUT *)&input, sizeof(INPUT) );
1830 ok( GetCursorPos( &point ), "failed to get cursor position\n" );
1831 ok( in.x != point.x && in.y != point.y, "cursor didn't change position after mouse_event()\n" );
1832 in.time = 0;
1833 in.x = point.x;
1834 in.y = point.y;
1835 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS );
1836 ok( retval == 64, "expected to get 64 mouse move points but got %d\n", retval );
1837 ok( out[0].dwExtraInfo == 0xdeadbeef, "wrong extra info, got 0x%Ix expected 0xdeadbeef\n", out[0].dwExtraInfo );
1838
1839 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM, GMMP_USE_HIGH_RESOLUTION_POINTS );
1840 todo_wine ok( retval == 64, "expected to get 64 high resolution mouse move points but got %d\n", retval );
1841
1842 run_in_process( argv, "test_GetMouseMovePointsEx_process" );
1843#undef BUFLIM
1844#undef MYERROR
1845}
1846
1848{
1849 int retval;
1850 MOUSEMOVEPOINT in;
1851 MOUSEMOVEPOINT out[64], out2[64];
1852 POINT point;
1853 HDESK desk0, desk1;
1854 HWINSTA winstation0, winstation1;
1855
1856 memset( out, 0, sizeof(out) );
1857 memset( out2, 0, sizeof(out2) );
1858
1859 /* move point history is shared between desktops within the same windowstation */
1860 ok( GetCursorPos( &point ), "failed to get cursor position\n" );
1861 in.time = 0;
1862 in.x = point.x;
1863 in.y = point.y;
1864 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out, ARRAY_SIZE(out), GMMP_USE_DISPLAY_POINTS );
1865 ok( retval == 64, "expected to get 64 mouse move points but got %d\n", retval );
1866
1868 ok( desk0 != NULL, "OpenInputDesktop has failed with %ld\n", GetLastError() );
1869 desk1 = CreateDesktopA( "getmousemovepointsex_test_desktop", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
1870 ok( desk1 != NULL, "CreateDesktopA failed with %ld\n", GetLastError() );
1871
1872 ok( SetThreadDesktop( desk1 ), "SetThreadDesktop failed!\n" );
1873 ok( SwitchDesktop( desk1 ), "SwitchDesktop failed\n" );
1874
1875 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out2, ARRAY_SIZE(out2), GMMP_USE_DISPLAY_POINTS );
1876 ok( retval == 64, "expected to get 64 mouse move points but got %d\n", retval );
1877
1878 ok( memcmp( out, out2, sizeof(out2) ) == 0, "expected to get exact same history on the new desktop\n" );
1879
1880 in.time = 0;
1881 in.x = 38;
1882 in.y = 27;
1883 SetCursorPos( in.x, in.y );
1884
1885 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out2, ARRAY_SIZE(out2), GMMP_USE_DISPLAY_POINTS );
1886 ok( retval == 64, "expected to get 64 mouse move points but got %d\n", retval );
1887
1888 ok( SetThreadDesktop( desk0 ), "SetThreadDesktop failed!\n" );
1889 ok( SwitchDesktop( desk0 ), "SwitchDesktop failed\n" );
1890
1891 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out, ARRAY_SIZE(out), GMMP_USE_DISPLAY_POINTS );
1892 ok( retval == 64, "expected to get 64 mouse move points but got %d\n", retval );
1893 ok( memcmp( out, out2, sizeof( out2 ) ) == 0, "expected to get exact same history on the old desktop\n" );
1894
1895 CloseDesktop( desk1 );
1896 CloseDesktop( desk0 );
1897
1898 /* non-default windowstations are non-interactive */
1899 winstation0 = GetProcessWindowStation();
1900 ok( winstation0 != NULL, "GetProcessWindowStation has failed with %ld\n", GetLastError() );
1902 ok( desk0 != NULL, "OpenInputDesktop has failed with %ld\n", GetLastError() );
1903 winstation1 = CreateWindowStationA( "test_winstation", 0, WINSTA_ALL_ACCESS, NULL );
1904
1905 if (winstation1 == NULL && GetLastError() == ERROR_ACCESS_DENIED)
1906 {
1907 win_skip("not enough privileges for CreateWindowStation\n");
1908 CloseDesktop( desk0 );
1909 CloseWindowStation( winstation0 );
1910 return;
1911 }
1912
1913 ok( winstation1 != NULL, "CreateWindowStationA has failed with %ld\n", GetLastError() );
1914 ok( SetProcessWindowStation( winstation1 ), "SetProcessWindowStation has failed\n" );
1915
1916 desk1 = CreateDesktopA( "getmousemovepointsex_test_desktop", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
1917 ok( desk1 != NULL, "CreateDesktopA failed with %ld\n", GetLastError() );
1918 ok( SetThreadDesktop( desk1 ), "SetThreadDesktop failed!\n" );
1919
1920 SetLastError( 0xDEADBEEF );
1921 retval = pGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), &in, out, ARRAY_SIZE(out), GMMP_USE_DISPLAY_POINTS );
1922 todo_wine ok( retval == -1, "expected to get -1 mouse move points but got %d\n", retval );
1923 todo_wine ok( GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED got %ld\n", GetLastError() );
1924
1925 ok( SetProcessWindowStation( winstation0 ), "SetProcessWindowStation has failed\n" );
1926 ok( SetThreadDesktop( desk0 ), "SetThreadDesktop failed!\n" );
1927 CloseDesktop( desk1 );
1928 CloseWindowStation( winstation1 );
1929 CloseDesktop( desk0 );
1930 CloseWindowStation( winstation0 );
1931}
1932
1934{
1935 RAWINPUTDEVICELIST devices[32];
1936 UINT ret, oret, devcount, odevcount, i;
1937 DWORD err;
1938 BOOLEAN br;
1939
1940 SetLastError(0xdeadbeef);
1941 ret = pGetRawInputDeviceList(NULL, NULL, 0);
1942 err = GetLastError();
1943 ok(ret == -1, "expected -1, got %d\n", ret);
1944 ok(err == ERROR_INVALID_PARAMETER, "expected 87, got %ld\n", err);
1945
1946 SetLastError(0xdeadbeef);
1947 ret = pGetRawInputDeviceList(NULL, NULL, sizeof(devices[0]));
1948 err = GetLastError();
1949 ok(ret == -1, "expected -1, got %d\n", ret);
1950 ok(err == ERROR_NOACCESS, "expected 998, got %ld\n", err);
1951
1952 devcount = 0;
1953 ret = pGetRawInputDeviceList(NULL, &devcount, sizeof(devices[0]));
1954 ok(ret == 0, "expected 0, got %d\n", ret);
1955 ok(devcount > 0, "expected non-zero\n");
1956
1957 SetLastError(0xdeadbeef);
1958 devcount = 0;
1959 ret = pGetRawInputDeviceList(devices, &devcount, sizeof(devices[0]));
1960 err = GetLastError();
1961 ok(ret == -1, "expected -1, got %d\n", ret);
1962 ok(err == ERROR_INSUFFICIENT_BUFFER, "expected 122, got %ld\n", err);
1963 ok(devcount > 0, "expected non-zero\n");
1964
1965 /* devcount contains now the correct number of devices */
1966 ret = pGetRawInputDeviceList(devices, &devcount, sizeof(devices[0]));
1967 ok(ret > 0, "expected non-zero\n");
1968
1969 if (devcount)
1970 {
1971 RID_DEVICE_INFO info;
1972 UINT size;
1973
1974 SetLastError( 0xdeadbeef );
1975 ret = pGetRawInputDeviceInfoW( UlongToHandle( 0xdeadbeef ), RIDI_DEVICEINFO, NULL, NULL );
1976 ok( ret == ~0U, "GetRawInputDeviceInfoW returned %#x, expected ~0.\n", ret );
1977 ok( GetLastError() == ERROR_NOACCESS, "GetRawInputDeviceInfoW last error %#lx, expected 0xdeadbeef.\n", GetLastError() );
1978
1979 SetLastError( 0xdeadbeef );
1980 size = 0xdeadbeef;
1981 ret = pGetRawInputDeviceInfoW( UlongToHandle( 0xdeadbeef ), RIDI_DEVICEINFO, NULL, &size );
1982 ok( ret == ~0U, "GetRawInputDeviceInfoW returned %#x, expected ~0.\n", ret );
1983 ok( size == 0xdeadbeef, "GetRawInputDeviceInfoW returned size %#x, expected 0.\n", size );
1984 ok( GetLastError() == ERROR_INVALID_HANDLE, "GetRawInputDeviceInfoW last error %#lx, expected 0xdeadbeef.\n", GetLastError() );
1985
1986 SetLastError( 0xdeadbeef );
1987 size = 0xdeadbeef;
1988 ret = pGetRawInputDeviceInfoW( devices[0].hDevice, 0xdeadbeef, NULL, &size );
1989 ok( ret == ~0U, "GetRawInputDeviceInfoW returned %#x, expected ~0.\n", ret );
1990 ok( size == 0xdeadbeef, "GetRawInputDeviceInfoW returned size %#x, expected 0.\n", size );
1991 ok( GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputDeviceInfoW last error %#lx, expected 0xdeadbeef.\n", GetLastError() );
1992
1993 SetLastError( 0xdeadbeef );
1994 ret = pGetRawInputDeviceInfoW( devices[0].hDevice, RIDI_DEVICEINFO, &info, NULL );
1995 ok( ret == ~0U, "GetRawInputDeviceInfoW returned %#x, expected ~0.\n", ret );
1996 ok( GetLastError() == ERROR_NOACCESS, "GetRawInputDeviceInfoW last error %#lx, expected 0xdeadbeef.\n", GetLastError() );
1997
1998 SetLastError( 0xdeadbeef );
1999 size = 0;
2000 ret = pGetRawInputDeviceInfoW( devices[0].hDevice, RIDI_DEVICEINFO, &info, &size );
2001 ok( ret == ~0U, "GetRawInputDeviceInfoW returned %#x, expected ~0.\n", ret );
2002 ok( size == sizeof(info), "GetRawInputDeviceInfoW returned size %#x, expected %#Ix.\n", size, sizeof(info) );
2003 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetRawInputDeviceInfoW last error %#lx, expected 0xdeadbeef.\n", GetLastError() );
2004 }
2005
2006 for(i = 0; i < devcount; ++i)
2007 {
2008 WCHAR name[128];
2009 char nameA[128];
2010 UINT sz, len;
2011 RID_DEVICE_INFO info;
2012 HANDLE file;
2013 char *ppd;
2014
2015 /* get required buffer size */
2016 name[0] = '\0';
2017 sz = 5;
2018 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICENAME, name, &sz);
2019 ok(ret == -1, "GetRawInputDeviceInfo gave wrong failure: %ld\n", err);
2020 ok(sz > 5 && sz < ARRAY_SIZE(name), "Size should have been set and not too large (got: %u)\n", sz);
2021
2022 /* buffer size for RIDI_DEVICENAME is in CHARs, not BYTEs */
2023 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICENAME, name, &sz);
2024 ok(ret == sz, "GetRawInputDeviceInfo gave wrong return: %ld\n", err);
2025 len = lstrlenW(name);
2026 ok(len + 1 == ret, "GetRawInputDeviceInfo returned wrong length (name: %u, ret: %u)\n", len + 1, ret);
2027
2028 /* test A variant with same size */
2029 ret = pGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, nameA, &sz);
2030 ok(ret == sz, "GetRawInputDeviceInfoA gave wrong return: %ld\n", err);
2031 len = strlen(nameA);
2032 ok(len + 1 == ret, "GetRawInputDeviceInfoA returned wrong length (name: %u, ret: %u)\n", len + 1, ret);
2033
2034 /* buffer size for RIDI_DEVICEINFO is in BYTEs */
2035 memset(&info, 0, sizeof(info));
2036 info.cbSize = sizeof(info);
2037 sz = sizeof(info) - 1;
2038 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz);
2039 ok(ret == -1, "GetRawInputDeviceInfo gave wrong failure: %ld\n", err);
2040 ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n");
2041
2042 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz);
2043 ok(ret == sizeof(info), "GetRawInputDeviceInfo gave wrong return: %ld\n", err);
2044 ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n");
2045 ok(info.dwType == devices[i].dwType, "GetRawInputDeviceInfo set wrong type: 0x%lx\n", info.dwType);
2046
2047 memset(&info, 0, sizeof(info));
2048 info.cbSize = sizeof(info);
2049 ret = pGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz);
2050 ok(ret == sizeof(info), "GetRawInputDeviceInfo gave wrong return: %ld\n", err);
2051 ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n");
2052 ok(info.dwType == devices[i].dwType, "GetRawInputDeviceInfo set wrong type: 0x%lx\n", info.dwType);
2053
2054 /* setupapi returns an NT device path, but CreateFile() < Vista can't
2055 * understand that; so use the \\?\ prefix instead */
2056 name[1] = '\\';
2058 ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %lu\n", wine_dbgstr_w(name), GetLastError());
2059
2060 sz = 0;
2061 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_PREPARSEDDATA, NULL, &sz);
2062 ok(ret == 0, "GetRawInputDeviceInfo gave wrong return: %u\n", ret);
2063 ok((info.dwType == RIM_TYPEHID && sz != 0) ||
2064 (info.dwType != RIM_TYPEHID && sz == 0),
2065 "Got wrong PPD size for type 0x%lx: %u\n", info.dwType, sz);
2066
2067 ppd = malloc(sz);
2068 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_PREPARSEDDATA, ppd, &sz);
2069 ok(ret == sz, "GetRawInputDeviceInfo gave wrong return: %u, should be %u\n", ret, sz);
2070
2071 if (file != INVALID_HANDLE_VALUE && ret == sz)
2072 {
2073 PHIDP_PREPARSED_DATA preparsed;
2074
2075 if (info.dwType == RIM_TYPEHID)
2076 {
2077 br = HidD_GetPreparsedData(file, &preparsed);
2078 ok(br == TRUE, "HidD_GetPreparsedData failed\n");
2079
2080 if (br)
2081 ok(!memcmp(preparsed, ppd, sz), "Expected to get same preparsed data\n");
2082 }
2083 else
2084 {
2085 /* succeeds on hardware, fails in some VMs */
2086 br = HidD_GetPreparsedData(file, &preparsed);
2087 ok(br == TRUE || broken(br == FALSE), "HidD_GetPreparsedData failed\n");
2088 }
2089
2090 if (br)
2091 HidD_FreePreparsedData(preparsed);
2092 }
2093
2094 free(ppd);
2095
2097 }
2098
2099 /* check if variable changes from larger to smaller value */
2100 devcount = odevcount = ARRAY_SIZE(devices);
2101 oret = ret = pGetRawInputDeviceList(devices, &odevcount, sizeof(devices[0]));
2102 ok(ret > 0, "expected non-zero\n");
2103 ok(devcount == odevcount, "expected %d, got %d\n", devcount, odevcount);
2104 devcount = odevcount;
2105 odevcount = ARRAY_SIZE(devices);
2106 ret = pGetRawInputDeviceList(NULL, &odevcount, sizeof(devices[0]));
2107 ok(ret == 0, "expected 0, got %d\n", ret);
2108 ok(odevcount == oret, "expected %d, got %d\n", oret, odevcount);
2109}
2110
2111static void test_GetRawInputData(void)
2112{
2113 UINT size = 0;
2114
2115 /* Null raw input handle */
2116 SetLastError( 0xdeadbeef );
2117 ok_ret( (UINT)-1, GetRawInputData( NULL, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER) ) );
2119}
2120
2122{
2123 HWND hwnd;
2124 RAWINPUTDEVICE raw_devices[2] = {0};
2125 UINT count, raw_devices_count;
2126 MSG msg;
2127
2128 raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
2129 raw_devices[0].usUsage = HID_USAGE_GENERIC_GAMEPAD;
2130 raw_devices[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
2131 raw_devices[1].usUsage = HID_USAGE_GENERIC_JOYSTICK;
2132
2134
2135 SetLastError( 0xdeadbeef );
2136 ok_ret( 0, RegisterRawInputDevices( NULL, 0, 0 ) );
2138
2139 SetLastError( 0xdeadbeef );
2140 ok_ret( 0, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), 0 ) );
2142
2143 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) );
2144
2145 SetLastError( 0xdeadbeef );
2148
2149 SetLastError( 0xdeadbeef );
2150 ok_ret( (UINT)-1, GetRegisteredRawInputDevices( NULL, &raw_devices_count, 0 ) );
2152
2153 raw_devices_count = 0;
2154 ok_ret( 0, GetRegisteredRawInputDevices( NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE) ) );
2155 ok_eq( 2, raw_devices_count, UINT, "%u" );
2156
2157 SetLastError( 0xdeadbeef );
2158 raw_devices_count = 0;
2159 count = GetRegisteredRawInputDevices( raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE) );
2160 if (broken(count == 0) /* depends on windows versions */)
2161 win_skip( "Ignoring GetRegisteredRawInputDevices success\n" );
2162 else
2163 {
2164 ok_eq( -1, count, int, "%d" );
2165 ok_eq( 0, raw_devices_count, UINT, "%u" );
2167 }
2168
2169 SetLastError( 0xdeadbeef );
2170 raw_devices_count = 1;
2171 ok_ret( (UINT)-1, GetRegisteredRawInputDevices( raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE) ) );
2172 ok_eq( 2, raw_devices_count, UINT, "%u" );
2174
2175 memset( raw_devices, 0, sizeof(raw_devices) );
2176 raw_devices_count = ARRAY_SIZE(raw_devices);
2177 ok_ret( 2, GetRegisteredRawInputDevices( raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE) ) );
2178 ok_eq( 2, raw_devices_count, UINT, "%u" );
2179 ok_eq( HID_USAGE_PAGE_GENERIC, raw_devices[0].usUsagePage, USHORT, "%#x" );
2180 ok_eq( HID_USAGE_GENERIC_JOYSTICK, raw_devices[0].usUsage, USHORT, "%#x" );
2181 ok_eq( HID_USAGE_PAGE_GENERIC, raw_devices[1].usUsagePage, USHORT, "%#x" );
2182 ok_eq( HID_USAGE_GENERIC_GAMEPAD, raw_devices[1].usUsage, USHORT, "%#x" );
2183
2184 /* RIDEV_INPUTSINK requires hwndTarget != NULL */
2185 raw_devices[0].dwFlags = RIDEV_INPUTSINK;
2186 raw_devices[0].hwndTarget = 0;
2187 raw_devices[1].dwFlags = RIDEV_INPUTSINK;
2188 raw_devices[1].hwndTarget = 0;
2189
2190 SetLastError(0xdeadbeef);
2191 ok_ret( 0, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) );
2193
2194 raw_devices[0].hwndTarget = hwnd;
2195 raw_devices[1].hwndTarget = hwnd;
2196 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) );
2197
2198 /* RIDEV_DEVNOTIFY send messages for any pre-existing device */
2199 raw_devices[0].dwFlags = RIDEV_DEVNOTIFY;
2200 raw_devices[0].hwndTarget = 0;
2201 raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
2202 raw_devices[0].usUsage = HID_USAGE_GENERIC_MOUSE;
2203 raw_devices[1].dwFlags = RIDEV_DEVNOTIFY;
2204 raw_devices[1].hwndTarget = 0;
2205 raw_devices[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
2206 raw_devices[1].usUsage = HID_USAGE_GENERIC_KEYBOARD;
2207
2208 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) );
2209 while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
2210 {
2211 ok_ne( WM_INPUT_DEVICE_CHANGE, msg.message, UINT, "%#x" );
2214 }
2215
2216 /* RIDEV_DEVNOTIFY send messages only to hwndTarget */
2217 raw_devices[0].hwndTarget = hwnd;
2218 raw_devices[1].hwndTarget = hwnd;
2219
2220 count = 0;
2221 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) );
2222 while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
2223 {
2224 if (msg.message == WM_INPUT_DEVICE_CHANGE) count++;
2227 }
2228 ok( count >= 2, "got %u messages\n", count );
2229
2230 count = 0;
2231 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) );
2232 while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
2233 {
2234 if (msg.message == WM_INPUT_DEVICE_CHANGE) count++;
2237 }
2238 ok( count >= 2, "got %u messages\n", count );
2239
2240 /* RIDEV_REMOVE requires hwndTarget == NULL */
2241 raw_devices[0].dwFlags = RIDEV_REMOVE;
2242 raw_devices[0].hwndTarget = hwnd;
2243 raw_devices[1].dwFlags = RIDEV_REMOVE;
2244 raw_devices[1].hwndTarget = hwnd;
2245
2246 SetLastError(0xdeadbeef);
2247 ok_ret( 0, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) );
2249
2250 raw_devices[0].hwndTarget = 0;
2251 raw_devices[1].hwndTarget = 0;
2252 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) );
2253
2254 ok_ret( 1, DestroyWindow( hwnd ) );
2255}
2256
2258
2259typedef struct
2260{
2266
2267#ifdef _WIN64
2268typedef RAWINPUTHEADER RAWINPUTHEADER64;
2269typedef RAWINPUT RAWINPUT64;
2270#else
2271typedef struct
2272{
2278
2279typedef struct
2280{
2282 union {
2283 RAWMOUSE mouse;
2284 RAWKEYBOARD keyboard;
2285 RAWHID hid;
2287} RAWINPUT64;
2288#endif
2289
2291{
2292 if (msg == WM_INPUT)
2293 {
2294 UINT i, size, rawinput_size, iteration = rawinputbuffer_wndproc_count++;
2295 char buffer[16 * sizeof(RAWINPUT64)];
2296 RAWINPUT64 *rawbuffer64 = (RAWINPUT64 *)buffer;
2297 RAWINPUT *rawbuffer = (RAWINPUT *)buffer;
2298 HRAWINPUT handle = (HRAWINPUT)lparam;
2299 RAWINPUT rawinput = {{0}};
2300
2302
2303 if (is_wow64) rawinput_size = sizeof(RAWINPUTHEADER64) + sizeof(RAWKEYBOARD);
2304 else rawinput_size = sizeof(RAWINPUTHEADER) + sizeof(RAWKEYBOARD);
2305
2306 size = sizeof(buffer);
2307 memset( buffer, 0, sizeof(buffer) );
2308 ok_ret( 3, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER)) );
2309 ok_eq( sizeof(buffer), size, UINT, "%u" );
2310
2311 for (i = 0; i < 3; ++i)
2312 {
2313 winetest_push_context( "%u", i );
2314 if (is_wow64)
2315 {
2316 RAWINPUT64 *rawinput = (RAWINPUT64 *)(buffer + i * rawinput_size);
2317 ok_eq( RIM_TYPEKEYBOARD, rawinput->header.dwType, UINT, "%u" );
2318 ok_eq( rawinput_size, rawinput->header.dwSize, UINT, "%u" );
2319 ok_eq( wparam, rawinput->header.wParam, WPARAM, "%Iu" );
2320 ok_eq( i + 2, rawinput->data.keyboard.MakeCode, WPARAM, "%Iu" );
2321 }
2322 else
2323 {
2324 RAWINPUT *rawinput = (RAWINPUT *)(buffer + i * rawinput_size);
2325 ok_eq( RIM_TYPEKEYBOARD, rawinput->header.dwType, UINT, "%u" );
2326 ok_eq( rawinput_size, rawinput->header.dwSize, UINT, "%u" );
2327 ok_eq( wparam, rawinput->header.wParam, WPARAM, "%Iu" );
2328 ok_eq( i + 2, rawinput->data.keyboard.MakeCode, WPARAM, "%Iu" );
2329 }
2331 }
2332
2333 /* the first event should be removed by the next GetRawInputBuffer call
2334 * and the others should do another round through the message loop but not more */
2335 if (iteration == 0)
2336 {
2337 keybd_event( 'X', 5, 0, 0 );
2338 keybd_event( 'X', 6, KEYEVENTF_KEYUP, 0 );
2339 keybd_event( 'X', 2, KEYEVENTF_KEYUP, 0 );
2340 keybd_event( 'X', 3, 0, 0 );
2341 keybd_event( 'X', 4, KEYEVENTF_KEYUP, 0 );
2342
2343 /* even though rawinput_size is the minimum required size,
2344 * it needs one more byte to return success */
2345 size = sizeof(rawinput) + 1;
2346 memset( buffer, 0, sizeof(buffer) );
2347 ok_ret( 1, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) );
2348 if (is_wow64) ok_eq( 5, rawbuffer64->data.keyboard.MakeCode, WPARAM, "%Iu" );
2349 else ok_eq( 5, rawbuffer->data.keyboard.MakeCode, WPARAM, "%Iu" );
2350
2351 /* peek the messages now, they should still arrive in the correct order */
2353 wait_messages( 0, FALSE );
2355
2356 /* reading the message data now should fail, the data
2357 * from the first message has been overwritten. */
2358 SetLastError( 0xdeadbeef );
2359 size = sizeof(rawinput);
2360 ok_ret( (UINT)-1, GetRawInputData( handle, RID_HEADER, &rawinput, &size, sizeof(RAWINPUTHEADER) ) );
2362 }
2363 else
2364 {
2365 SetLastError( 0xdeadbeef );
2366 ok_ret( (UINT)-1, GetRawInputData( handle, RID_HEADER, &rawinput, &size, 0) );
2368
2369 SetLastError( 0xdeadbeef );
2370 ok_ret( (UINT)-1, GetRawInputData( handle, RID_HEADER, &rawinput, &size, sizeof(RAWINPUTHEADER) + 1 ) );
2372
2373 size = sizeof(RAWINPUTHEADER);
2374 rawinput_size = sizeof(RAWINPUTHEADER) + sizeof(RAWKEYBOARD);
2375 ok_ret( sizeof(RAWINPUTHEADER), GetRawInputData( handle, RID_HEADER, &rawinput, &size, sizeof(RAWINPUTHEADER) ) );
2376 ok_eq( rawinput_size, rawinput.header.dwSize, UINT, "%u" );
2377 ok_eq( RIM_TYPEKEYBOARD, rawinput.header.dwType, UINT, "%u" );
2378
2379
2380 SetLastError( 0xdeadbeef );
2381 ok_ret( (UINT)-1, GetRawInputData( handle, RID_INPUT, &rawinput, &size, 0) );
2383
2384 SetLastError( 0xdeadbeef );
2385 ok_ret( (UINT)-1, GetRawInputData( handle, RID_INPUT, &rawinput, &size, sizeof(RAWINPUTHEADER) + 1 ) );
2387
2388 SetLastError( 0xdeadbeef );
2389 size = 0;
2390 ok_ret( (UINT)-1, GetRawInputData( handle, RID_INPUT, &rawinput, &size, sizeof(RAWINPUTHEADER) ) );
2392
2393 SetLastError( 0xdeadbeef );
2394 size = sizeof(rawinput);
2395 ok_ret( (UINT)-1, GetRawInputData( handle, 0, &rawinput, &size, sizeof(RAWINPUTHEADER) ) );
2397
2398 SetLastError( 0xdeadbeef );
2399 size = sizeof(rawinput);
2400 ok_ret( rawinput_size, GetRawInputData( handle, RID_INPUT, &rawinput, &size, sizeof(RAWINPUTHEADER) ) );
2401 ok_eq( 6, rawinput.data.keyboard.MakeCode, UINT, "%u" );
2402
2403 SetLastError( 0xdeadbeef );
2404 size = sizeof(buffer);
2405 if (sizeof(void *) == 8)
2406 {
2407 ok_ret( (UINT)-1, GetRawInputData( handle, RID_INPUT, &rawinput, &size, sizeof(RAWINPUTHEADER32) ) );
2408 ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputData returned %08lx\n", GetLastError());
2409 }
2410 else if (is_wow64)
2411 {
2412 todo_wine
2413 ok_ret( rawinput_size, GetRawInputData( handle, RID_INPUT, &rawinput, &size, sizeof(RAWINPUTHEADER64) ) );
2414 ok_eq( 6, rawinput.data.keyboard.MakeCode, UINT, "%u" );
2415 todo_wine
2416 ok_ret( 0xdeadbeef, GetLastError() );
2417 }
2418 else
2419 {
2420 ok_ret( (UINT)-1, GetRawInputData( handle, RID_INPUT, &rawinput, &size, sizeof(RAWINPUTHEADER64) ) );
2421 ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputData returned %08lx\n", GetLastError());
2422 }
2423 }
2424
2426 return 0;
2427 }
2428
2429 return DefWindowProcW( hwnd, msg, wparam, lparam );
2430}
2431
2432static void test_GetRawInputBuffer(void)
2433{
2434 unsigned int size, rawinput_size, header_size;
2435 RAWINPUTDEVICE raw_devices[1];
2436 char buffer[16 * sizeof(RAWINPUT64)];
2437 RAWINPUT64 *rawbuffer64 = (RAWINPUT64 *)buffer;
2438 RAWINPUT *rawbuffer = (RAWINPUT *)buffer;
2439 DWORD t1, t2, t3, now, pos1, pos2;
2440 LPARAM extra_info1, extra_info2;
2441 INPUT_MESSAGE_SOURCE source;
2442 POINT pt;
2443 HWND hwnd;
2444 BOOL ret;
2445
2446 if (is_wow64) rawinput_size = sizeof(RAWINPUTHEADER64) + sizeof(RAWMOUSE);
2447 else rawinput_size = sizeof(RAWINPUTHEADER) + sizeof(RAWMOUSE);
2448
2451
2452 if (pGetCurrentInputMessageSource)
2453 {
2454 ret = pGetCurrentInputMessageSource( &source );
2455 ok( ret, "got error %lu.\n", GetLastError() );
2456 ok( !source.deviceType, "got %#x.\n", source.deviceType );
2457 ok( !source.originId, "got %#x.\n", source.originId );
2458 }
2459
2460 raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
2461 raw_devices[0].usUsage = HID_USAGE_GENERIC_MOUSE;
2462 raw_devices[0].dwFlags = RIDEV_INPUTSINK;
2463 raw_devices[0].hwndTarget = hwnd;
2464 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE( raw_devices ), sizeof(RAWINPUTDEVICE) ) );
2465
2466 /* check basic error cases */
2467
2468 SetLastError( 0xdeadbeef );
2469 ok_ret( (UINT)-1, GetRawInputBuffer( NULL, NULL, sizeof(RAWINPUTHEADER) ) );
2471 SetLastError( 0xdeadbeef );
2472 size = sizeof(buffer);
2473 ok_ret( (UINT)-1, GetRawInputBuffer( rawbuffer, &size, 0 ) );
2475
2476 /* valid calls, but no input */
2477 t1 = GetMessageTime();
2478 pos1 = GetMessagePos();
2479 extra_info1 = GetMessageExtraInfo();
2480 now = GetTickCount();
2481 ok( t1 <= now, "got %lu, %lu.\n", t1, now );
2482
2483 size = sizeof(buffer);
2484 ok_ret( 0, GetRawInputBuffer( NULL, &size, sizeof(RAWINPUTHEADER) ) );
2485 ok_eq( 0, size, UINT, "%u" );
2486 size = 0;
2487 ok_ret( 0, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) );
2488 ok_eq( 0, size, UINT, "%u" );
2489 size = sizeof(buffer);
2490 ok_ret( 0, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) );
2491 ok_eq( 0, size, UINT, "%u" );
2492
2493
2494 Sleep( 20 );
2495 mouse_event( MOUSEEVENTF_MOVE, 5, 0, 0, 0xdeadbeef );
2496 t2 = GetMessageTime();
2497 ok( t2 == t1, "got %lu, %lu.\n", t1, t2 );
2498 /* invalid calls with input */
2499
2500 SetLastError( 0xdeadbeef );
2501 size = 0;
2502 ok_ret( (UINT)-1, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) );
2503 ok_eq( rawinput_size, size, UINT, "%u" );
2505 t2 = GetMessageTime();
2506 ok( t2 == t1, "got %lu, %lu.\n", t1, t2 );
2507
2508 SetLastError( 0xdeadbeef );
2509 size = sizeof(buffer);
2510 ok_ret( (UINT)-1, GetRawInputBuffer( rawbuffer, &size, 0 ) );
2512 SetLastError( 0xdeadbeef );
2513 size = sizeof(buffer);
2514 ok_ret( (UINT)-1, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) + 1 ) );
2516
2517 /* the function returns 64-bit RAWINPUT structures on WoW64, but still
2518 * forbids sizeof(RAWINPUTHEADER) from the wrong architecture */
2519 SetLastError( 0xdeadbeef );
2520 size = sizeof(buffer);
2521 header_size = (sizeof(void *) == 8 ? sizeof(RAWINPUTHEADER32) : sizeof(RAWINPUTHEADER64));
2522 ok_ret( (UINT)-1, GetRawInputBuffer( rawbuffer, &size, header_size ) );
2524
2525
2526 /* NOTE: calling with size == rawinput_size returns an error, */
2527 /* BUT it fills the buffer nonetheless and empties the internal buffer (!!) */
2528
2529 Sleep( 20 );
2530 t2 = GetTickCount();
2531 size = 0;
2532 ok_ret( 0, GetRawInputBuffer( NULL, &size, sizeof(RAWINPUTHEADER) ) );
2533 ok_eq( rawinput_size, size, UINT, "%u" );
2534
2535 SetLastError( 0xdeadbeef );
2536 size = rawinput_size;
2537 memset( buffer, 0, sizeof(buffer) );
2538 ok_ret( (UINT)-1, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) );
2540 if (is_wow64) ok_eq( 5, rawbuffer64->data.mouse.lLastX, UINT, "%u" );
2541 else ok_eq( 5, rawbuffer->data.mouse.lLastX, UINT, "%u" );
2542
2543 t3 = GetMessageTime();
2544 pos2 = GetMessagePos();
2545 extra_info2 = GetMessageExtraInfo();
2546 ok( extra_info2 == extra_info1, "got %#Ix, %#Ix.\n", extra_info1, extra_info2 );
2547 GetCursorPos( &pt );
2548 ok( t3 > t1, "got %lu, %lu.\n", t1, t3 );
2549 ok( t3 < t2, "got %lu, %lu.\n", t2, t3 );
2550 ok( pos1 == pos2, "got pos1 (%ld, %ld), pos2 (%ld, %ld), pt (%ld %ld).\n",
2551 pos1 & 0xffff, pos1 >> 16, pos2 & 0xffff, pos2 >> 16, pt.x, pt.y );
2552 if (pGetCurrentInputMessageSource)
2553 {
2554 ret = pGetCurrentInputMessageSource( &source );
2555 ok( ret, "got error %lu.\n", GetLastError() );
2556 ok( !source.deviceType, "got %#x.\n", source.deviceType );
2557 ok( !source.originId, "got %#x.\n", source.originId );
2558 }
2559
2560 /* no more data to read */
2561
2562 size = sizeof(buffer);
2563 ok_ret( 0, GetRawInputBuffer( NULL, &size, sizeof(RAWINPUTHEADER) ) );
2564 ok_eq( 0, size, UINT, "%u" );
2565
2566
2567 /* rawinput_size + 1 succeeds */
2568 t1 = GetMessageTime();
2569 pos1 = GetMessagePos();
2570 extra_info1 = GetMessageExtraInfo();
2571 now = GetTickCount();
2572 ok( t1 <= now, "got %lu, %lu.\n", t1, now );
2573
2574 Sleep( 20 );
2575 mouse_event( MOUSEEVENTF_MOVE, 5, 0, 0, 0xfeedcafe );
2576
2577 t2 = GetMessageTime();
2578 ok( t2 == t1, "got %lu, %lu.\n", t1, t2 );
2579
2580 Sleep( 20 );
2581 t2 = GetTickCount();
2582
2583 size = rawinput_size + 1;
2584 memset( buffer, 0, sizeof(buffer) );
2585 ok_ret( 1, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) );
2586 ok_eq( rawinput_size + 1, size, UINT, "%u" );
2587 if (is_wow64)
2588 {
2589 ok_eq( RIM_TYPEMOUSE, rawbuffer64->header.dwType, UINT, "%#x" );
2590 ok_eq( 0, rawbuffer64->header.wParam, WPARAM, "%Iu" );
2591 ok_eq( 5, rawbuffer64->data.mouse.lLastX, UINT, "%u" );
2592 }
2593 else
2594 {
2595 ok_eq( RIM_TYPEMOUSE, rawbuffer->header.dwType, UINT, "%#x" );
2596 ok_eq( 0, rawbuffer->header.wParam, WPARAM, "%Iu" );
2597 ok_eq( 5, rawbuffer->data.mouse.lLastX, UINT, "%u" );
2598 }
2599
2600 size = sizeof(buffer);
2601 ok_ret( 0, GetRawInputBuffer( NULL, &size, sizeof(RAWINPUTHEADER) ) );
2602 ok_eq( 0, size, UINT, "%u" );
2603
2604 t3 = GetMessageTime();
2605 pos2 = GetMessagePos();
2606 extra_info2 = GetMessageExtraInfo();
2607 GetCursorPos(&pt);
2608 ok( extra_info2 == extra_info1, "got %#Ix, %#Ix.\n", extra_info1, extra_info2 );
2609 ok( t3 > t1, "got %lu, %lu.\n", t1, t3 );
2610 ok( t3 < t2, "got %lu, %lu.\n", t2, t3 );
2611 ok( pos1 == pos2, "got pos1 (%ld, %ld), pos2 (%ld, %ld), pt (%ld %ld).\n",
2612 pos1 & 0xffff, pos1 >> 16, pos2 & 0xffff, pos2 >> 16, pt.x, pt.y );
2613
2614 raw_devices[0].dwFlags = RIDEV_REMOVE;
2615 raw_devices[0].hwndTarget = 0;
2616 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE) ) );
2617
2618
2619 /* some keyboard tests to better check fields under wow64 */
2620 raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
2621 raw_devices[0].usUsage = HID_USAGE_GENERIC_KEYBOARD;
2622 raw_devices[0].dwFlags = RIDEV_INPUTSINK;
2623 raw_devices[0].hwndTarget = hwnd;
2624 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE) ) );
2625
2626 keybd_event( 'X', 0x2d, 0, 0 );
2627 keybd_event( 'X', 0x2d, KEYEVENTF_KEYUP, 0 );
2628
2629 if (is_wow64) rawinput_size = sizeof(RAWINPUTHEADER64) + sizeof(RAWKEYBOARD);
2630 else rawinput_size = sizeof(RAWINPUTHEADER) + sizeof(RAWKEYBOARD);
2631
2632 size = 0;
2633 ok_ret( 0, GetRawInputBuffer( NULL, &size, sizeof(RAWINPUTHEADER) ) );
2634 ok_eq( rawinput_size, size, UINT, "%u" );
2635
2636 size = sizeof(buffer);
2637 memset( buffer, 0, sizeof(buffer) );
2638 ok_ret( 2, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) );
2639 ok_eq( sizeof(buffer), size, UINT, "%u" );
2640 if (is_wow64)
2641 {
2642 ok_eq( RIM_TYPEKEYBOARD, rawbuffer64->header.dwType, UINT, "%u" );
2643 ok_eq( 0, rawbuffer64->header.wParam, UINT, "%u" );
2644 ok_eq( 0x2d, rawbuffer64->data.keyboard.MakeCode, UINT, "%#x" );
2645 }
2646 else
2647 {
2648 ok_eq( RIM_TYPEKEYBOARD, rawbuffer->header.dwType, UINT, "%u" );
2649 ok_eq( 0, rawbuffer->header.wParam, UINT, "%u" );
2650 ok_eq( 0x2d, rawbuffer->data.keyboard.MakeCode, UINT, "%#x" );
2651 }
2652
2653
2654 /* test GetRawInputBuffer interaction with WM_INPUT messages */
2655
2657 keybd_event( 'X', 1, 0, 0 );
2658 keybd_event( 'X', 2, KEYEVENTF_KEYUP, 0 );
2659 keybd_event( 'X', 3, 0, 0 );
2660 keybd_event( 'X', 4, KEYEVENTF_KEYUP, 0 );
2661 wait_messages( 100, FALSE );
2663
2664 keybd_event( 'X', 3, 0, 0 );
2665 keybd_event( 'X', 4, KEYEVENTF_KEYUP, 0 );
2666
2667 raw_devices[0].dwFlags = RIDEV_REMOVE;
2668 raw_devices[0].hwndTarget = 0;
2669 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE) ) );
2670
2671
2672 /* rawinput buffer survives registered device changes */
2673
2674 size = rawinput_size + 1;
2675 ok_ret( 1, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) );
2676 ok_eq( rawinput_size + 1, size, UINT, "%u" );
2677
2678 raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
2679 raw_devices[0].usUsage = HID_USAGE_GENERIC_MOUSE;
2680 raw_devices[0].dwFlags = RIDEV_INPUTSINK;
2681 raw_devices[0].hwndTarget = hwnd;
2682 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE) ) );
2683
2684 if (is_wow64) rawinput_size = sizeof(RAWINPUTHEADER64) + sizeof(RAWMOUSE);
2685 else rawinput_size = sizeof(RAWINPUTHEADER) + sizeof(RAWMOUSE);
2686
2687 size = rawinput_size + 1;
2688 ok_ret( 1, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) );
2689 ok_eq( rawinput_size + 1, size, UINT, "%u" );
2690 size = sizeof(buffer);
2691 ok_ret( 0, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) );
2692 ok_eq( 0, size, UINT, "%u" );
2693
2694 raw_devices[0].dwFlags = RIDEV_REMOVE;
2695 raw_devices[0].hwndTarget = 0;
2696 ok_ret( 1, RegisterRawInputDevices( raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE) ) );
2697
2698
2699 ok_ret( 1, DestroyWindow( hwnd ) );
2700}
2701
2705
2707{
2708 UINT ret, raw_size;
2709 RAWINPUT raw;
2710
2711 if (msg == WM_INPUT)
2712 {
2714 ok(!rawinput_test_received_raw, "Unexpected spurious WM_INPUT message.\n");
2715 ok(wparam == RIM_INPUT || wparam == RIM_INPUTSINK, "Unexpected wparam: %Iu\n", wparam);
2716
2718 if (wparam == RIM_INPUT) rawinput_test_received_rawfg = TRUE;
2719
2720 ret = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, NULL, &raw_size, sizeof(RAWINPUTHEADER));
2721 ok(ret == 0, "GetRawInputData failed\n");
2722 ok(raw_size <= sizeof(raw), "Unexpected rawinput data size: %u\n", raw_size);
2723
2724 raw_size = sizeof(raw);
2725 ret = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &raw, &raw_size, sizeof(RAWINPUTHEADER));
2726 ok(ret > 0 && ret != (UINT)-1, "GetRawInputData failed\n");
2727 ok(raw.header.dwType == RIM_TYPEMOUSE, "Unexpected rawinput type: %lu\n", raw.header.dwType);
2728 ok(raw.header.dwSize == raw_size, "Expected size %u, got %lu\n", raw_size, raw.header.dwSize);
2730 ok(raw.header.wParam == wparam, "Expected wparam %Iu, got %Iu\n", wparam, raw.header.wParam);
2731
2732 ok(!(raw.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE), "Unexpected absolute rawinput motion\n");
2733 ok(!(raw.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP), "Unexpected virtual desktop rawinput motion\n");
2734 }
2735
2737
2738 return DefWindowProcA(hwnd, msg, wparam, lparam);
2739}
2740
2742{
2752};
2753
2755{
2756 { FALSE, FALSE, 0, TRUE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
2757 { TRUE, FALSE, 0, TRUE, TRUE, TRUE, /* todos: */ FALSE, FALSE, FALSE },
2758 { TRUE, TRUE, 0, TRUE, TRUE, TRUE, /* todos: */ FALSE, FALSE, FALSE },
2759 { TRUE, TRUE, RIDEV_NOLEGACY, FALSE, TRUE, TRUE, /* todos: */ FALSE, FALSE, FALSE },
2760
2761 /* same-process foreground tests */
2762 { TRUE, FALSE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
2763 { TRUE, TRUE, 0, FALSE, TRUE, TRUE, /* todos: */ FALSE, FALSE, FALSE },
2764
2765 /* cross-process foreground tests */
2766 { TRUE, TRUE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
2767 { TRUE, TRUE, RIDEV_INPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
2768 { TRUE, TRUE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
2769
2770 /* multi-process rawinput tests */
2771 { TRUE, TRUE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
2772 { TRUE, TRUE, RIDEV_INPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
2773 { TRUE, TRUE, RIDEV_INPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
2774
2775 { TRUE, TRUE, RIDEV_EXINPUTSINK, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
2776 { TRUE, TRUE, RIDEV_EXINPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, TRUE, FALSE },
2777
2778 /* cross-desktop foreground tests */
2779 { TRUE, FALSE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
2780 { TRUE, TRUE, 0, FALSE, TRUE, TRUE, /* todos: */ FALSE, FALSE, FALSE },
2781 { TRUE, TRUE, RIDEV_INPUTSINK, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
2782};
2783
2784static void rawinput_test_process(void)
2785{
2786 RAWINPUTDEVICE raw_devices[1];
2787 HANDLE ready, start, done;
2788 DWORD ret;
2789 POINT pt;
2790 HWND hwnd = NULL;
2791 MSG msg;
2792 int i;
2793
2794 ready = OpenEventA(EVENT_ALL_ACCESS, FALSE, "rawinput_test_process_ready");
2795 ok(ready != 0, "OpenEventA failed, error: %lu\n", GetLastError());
2796
2797 start = OpenEventA(EVENT_ALL_ACCESS, FALSE, "rawinput_test_process_start");
2798 ok(start != 0, "OpenEventA failed, error: %lu\n", GetLastError());
2799
2800 done = OpenEventA(EVENT_ALL_ACCESS, FALSE, "rawinput_test_process_done");
2801 ok(done != 0, "OpenEventA failed, error: %lu\n", GetLastError());
2802
2803 for (i = 0; i < ARRAY_SIZE(rawinput_tests); ++i)
2804 {
2806 ResetEvent(ready);
2807
2808 switch (i)
2809 {
2810 case 6:
2811 case 7:
2812 case 8:
2813 case 9:
2814 case 10:
2815 case 11:
2816 case 12:
2817 case 13:
2818 case 16:
2819 GetCursorPos(&pt);
2820
2821 hwnd = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
2822 pt.x - 50, pt.y - 50, 100, 100, 0, NULL, NULL, NULL);
2824 ok(hwnd != 0, "CreateWindow failed\n");
2826
2827 /* FIXME: Try to workaround X11/Win32 focus inconsistencies and
2828 * make the window visible and foreground as hard as possible. */
2834
2835 if (i == 9 || i == 10 || i == 11 || i == 12)
2836 {
2837 raw_devices[0].usUsagePage = 0x01;
2838 raw_devices[0].usUsage = 0x02;
2839 raw_devices[0].dwFlags = i == 11 ? RIDEV_INPUTSINK : 0;
2840 raw_devices[0].hwndTarget = i == 11 ? hwnd : 0;
2841
2842 SetLastError(0xdeadbeef);
2843 ret = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
2844 ok(ret, "%d: RegisterRawInputDevices failed\n", i);
2845 ok(GetLastError() == 0xdeadbeef, "%d: RegisterRawInputDevices returned %08lx\n", i, GetLastError());
2846 }
2847
2851
2852 /* fallthrough */
2853 case 14:
2854 case 15:
2855 if (i != 8) mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0);
2857 break;
2858 }
2859
2860 SetEvent(start);
2861
2863 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
2864
2865 ResetEvent(done);
2866
2867 if (i == 9 || i == 10 || i == 11 || i == 12)
2868 {
2869 raw_devices[0].dwFlags = RIDEV_REMOVE;
2870 raw_devices[0].hwndTarget = 0;
2871
2873 ok(rawinput_test_received_legacy, "%d: foreground process expected WM_MOUSEMOVE message\n", i);
2874 ok(rawinput_test_received_raw, "%d: foreground process expected WM_INPUT message\n", i);
2875 ok(rawinput_test_received_rawfg, "%d: foreground process expected RIM_INPUT message\n", i);
2876
2877 SetLastError(0xdeadbeef);
2878 ret = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
2879 ok(ret, "%d: RegisterRawInputDevices failed\n", i);
2880 ok(GetLastError() == 0xdeadbeef, "%d: RegisterRawInputDevices returned %08lx\n", i, GetLastError());
2881 }
2882
2883 if (hwnd) DestroyWindow(hwnd);
2884 }
2885
2887 CloseHandle(done);
2889 CloseHandle(ready);
2890}
2891
2893{
2894 HDESK desk;
2898};
2899
2901{
2903 RAWINPUTDEVICE raw_devices[1];
2904 DWORD ret;
2905 POINT pt;
2906 HWND hwnd = NULL;
2907 MSG msg;
2908 int i;
2909
2910 ok( SetThreadDesktop( params->desk ), "SetThreadDesktop failed\n" );
2911
2912 for (i = 14; i < ARRAY_SIZE(rawinput_tests); ++i)
2913 {
2915 ResetEvent(params->ready);
2916
2917 switch (i)
2918 {
2919 case 14:
2920 case 15:
2921 case 16:
2922 GetCursorPos(&pt);
2923
2924 hwnd = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
2925 pt.x - 50, pt.y - 50, 100, 100, 0, NULL, NULL, NULL);
2926 ok(hwnd != 0, "CreateWindow failed\n");
2929
2930 /* FIXME: Try to workaround X11/Win32 focus inconsistencies and
2931 * make the window visible and foreground as hard as possible. */
2937
2938 raw_devices[0].usUsagePage = 0x01;
2939 raw_devices[0].usUsage = 0x02;
2940 raw_devices[0].dwFlags = rawinput_tests[i].register_flags;
2941 raw_devices[0].hwndTarget = rawinput_tests[i].register_window ? hwnd : 0;
2942
2946
2947 SetLastError(0xdeadbeef);
2948 ret = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
2949 ok(ret, "%d: RegisterRawInputDevices failed\n", i);
2950 ok(GetLastError() == 0xdeadbeef, "%d: RegisterRawInputDevices returned %08lx\n", i, GetLastError());
2951 break;
2952 }
2953
2954 SetEvent(params->start);
2955
2957 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
2958
2959 ResetEvent(params->done);
2960 if (hwnd) DestroyWindow(hwnd);
2961 }
2962
2963 return 0;
2964}
2965
2967{
2969 HANDLE thread;
2970 POINT pt;
2971 HWND hwnd = NULL;
2972 int i;
2973
2974 for (i = 0; i < 14; ++i)
2975 {
2977 ResetEvent(params->ready);
2978
2979 switch (i)
2980 {
2981 case 4:
2982 case 5:
2983 GetCursorPos(&pt);
2984
2985 hwnd = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
2986 pt.x - 50, pt.y - 50, 100, 100, 0, NULL, NULL, NULL);
2987 ok(hwnd != 0, "CreateWindow failed\n");
2989
2990 /* FIXME: Try to workaround X11/Win32 focus inconsistencies and
2991 * make the window visible and foreground as hard as possible. */
2997
2998 mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0);
3000 break;
3001 }
3002
3003 SetEvent(params->start);
3004
3006 ResetEvent(params->done);
3007 if (hwnd) DestroyWindow(hwnd);
3008 }
3009
3011 ok(thread != NULL, "CreateThread failed\n");
3014
3015 return 0;
3016}
3017
3018static void test_rawinput(const char* argv0)
3019{
3021 PROCESS_INFORMATION process_info;
3022 RAWINPUTDEVICE raw_devices[1];
3023 STARTUPINFOA startup_info;
3024 HANDLE thread, process_ready, process_start, process_done;
3025 DWORD ret;
3026 POINT pt, newpt;
3027 HWND hwnd;
3028 BOOL skipped;
3029 char path[MAX_PATH];
3030 int i;
3031
3032 params.desk = CreateDesktopA( "rawinput_test_desktop", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
3033 ok( params.desk != NULL, "CreateDesktopA failed, last error: %lu\n", GetLastError() );
3034
3035 params.ready = CreateEventA(NULL, FALSE, FALSE, NULL);
3036 ok(params.ready != NULL, "CreateEvent failed\n");
3037
3038 params.start = CreateEventA(NULL, FALSE, FALSE, NULL);
3039 ok(params.start != NULL, "CreateEvent failed\n");
3040
3042 ok(params.done != NULL, "CreateEvent failed\n");
3043
3045 ok(thread != NULL, "CreateThread failed\n");
3046
3047 process_ready = CreateEventA(NULL, FALSE, FALSE, "rawinput_test_process_ready");
3048 ok(process_ready != NULL, "CreateEventA failed\n");
3049
3050 process_start = CreateEventA(NULL, FALSE, FALSE, "rawinput_test_process_start");
3051 ok(process_start != NULL, "CreateEventA failed\n");
3052
3053 process_done = CreateEventA(NULL, FALSE, FALSE, "rawinput_test_process_done");
3054 ok(process_done != NULL, "CreateEventA failed\n");
3055
3056 memset(&startup_info, 0, sizeof(startup_info));
3057 startup_info.cb = sizeof(startup_info);
3058 startup_info.dwFlags = STARTF_USESHOWWINDOW;
3059 startup_info.wShowWindow = SW_SHOWNORMAL;
3060
3061 sprintf(path, "%s input rawinput_test", argv0);
3062 ret = CreateProcessA(NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info );
3063 ok(ret, "CreateProcess \"%s\" failed err %lu.\n", path, GetLastError());
3064
3065 SetCursorPos(100, 100);
3067
3068 for (i = 0; i < ARRAY_SIZE(rawinput_tests); ++i)
3069 {
3070 GetCursorPos(&pt);
3071
3072 hwnd = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
3073 pt.x - 50, pt.y - 50, 100, 100, 0, NULL, NULL, NULL);
3074 ok(hwnd != 0, "CreateWindow failed\n");
3075 if (i != 14 && i != 15 && i != 16)
3078
3079 /* FIXME: Try to workaround X11/Win32 focus inconsistencies and
3080 * make the window visible and foreground as hard as possible. */
3086
3090
3091 raw_devices[0].usUsagePage = 0x01;
3092 raw_devices[0].usUsage = 0x02;
3093 raw_devices[0].dwFlags = rawinput_tests[i].register_flags;
3094 raw_devices[0].hwndTarget = rawinput_tests[i].register_window ? hwnd : 0;
3095
3096 if (!rawinput_tests[i].register_device)
3097 skipped = FALSE;
3098 else
3099 {
3100 SetLastError(0xdeadbeef);
3101 skipped = !RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
3102 if (rawinput_tests[i].register_flags == RIDEV_EXINPUTSINK && skipped)
3103 win_skip("RIDEV_EXINPUTSINK not supported\n");
3104 else
3105 ok(!skipped, "%d: RegisterRawInputDevices failed: %lu\n", i, GetLastError());
3106 }
3107
3108 SetEvent(params.ready);
3110 ResetEvent(params.start);
3111
3112 /* we need the main window to be over the other thread window, as although
3113 * it is in another desktop, it will receive the messages directly otherwise */
3114 switch (i)
3115 {
3116 case 14:
3117 case 15:
3119 hwnd = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
3120 pt.x - 50, pt.y - 50, 100, 100, 0, NULL, NULL, NULL);
3121 ok(hwnd != 0, "CreateWindow failed\n");
3125
3129 break;
3130 }
3131
3132 SetEvent(process_ready);
3133 WaitForSingleObject(process_start, INFINITE);
3134 ResetEvent(process_start);
3135
3136 if (i <= 3 || i == 8) mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0);
3138
3139 SetEvent(process_done);
3140 SetEvent(params.done);
3141
3143 if (!skipped)
3144 {
3145 todo_wine_if(rawinput_tests[i].todo_legacy)
3147 "%d: %sexpected WM_MOUSEMOVE message\n", i, rawinput_tests[i].expect_legacy ? "" : "un");
3148 todo_wine_if(rawinput_tests[i].todo_raw)
3150 "%d: %sexpected WM_INPUT message\n", i, rawinput_tests[i].expect_raw ? "" : "un");
3151 todo_wine_if(rawinput_tests[i].todo_rawfg)
3153 "%d: %sexpected RIM_INPUT message\n", i, rawinput_tests[i].expect_rawfg ? "" : "un");
3154 }
3155
3156 GetCursorPos(&newpt);
3157 ok((newpt.x - pt.x) == 5 || (newpt.x - pt.x) == 4, "%d: Unexpected cursor movement\n", i);
3158
3159 if (rawinput_tests[i].register_device)
3160 {
3161 raw_devices[0].dwFlags = RIDEV_REMOVE;
3162 raw_devices[0].hwndTarget = 0;
3163
3164 SetLastError(0xdeadbeef);
3165 ret = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
3166 ok(ret, "%d: RegisterRawInputDevices failed: %lu\n", i, GetLastError());
3167 }
3168
3170 }
3171
3172 SetEvent(process_ready);
3173 winetest_wait_child_process(process_info.hProcess);
3174 CloseHandle(process_info.hProcess);
3175 CloseHandle(process_info.hThread);
3176 CloseHandle(process_done);
3177 CloseHandle(process_start);
3178 CloseHandle(process_ready);
3179
3181
3182 CloseHandle(params.done);
3183 CloseHandle(params.start);
3184 CloseHandle(params.ready);
3186
3187 CloseDesktop(params.desk);
3188}
3189
3190static void test_DefRawInputProc(void)
3191{
3192 LRESULT ret;
3193
3194 SetLastError(0xdeadbeef);
3195 ret = DefRawInputProc(NULL, 0, sizeof(RAWINPUTHEADER));
3196 ok(!ret, "got %Id\n", ret);
3197 ok(GetLastError() == 0xdeadbeef, "got %ld\n", GetLastError());
3198 ret = DefRawInputProc(LongToPtr(0xcafe), 0xbeef, sizeof(RAWINPUTHEADER));
3199 ok(!ret, "got %Id\n", ret);
3200 ok(GetLastError() == 0xdeadbeef, "got %ld\n", GetLastError());
3201 ret = DefRawInputProc(NULL, 0, sizeof(RAWINPUTHEADER) - 1);
3202 ok(ret == -1, "got %Id\n", ret);
3203 ok(GetLastError() == 0xdeadbeef, "got %ld\n", GetLastError());
3204 ret = DefRawInputProc(NULL, 0, sizeof(RAWINPUTHEADER) + 1);
3205 ok(ret == -1, "got %Id\n", ret);
3206 ok(GetLastError() == 0xdeadbeef, "got %ld\n", GetLastError());
3207}
3208
3209static void test_key_map(void)
3210{
3211 HKL kl = GetKeyboardLayout(0);
3212 UINT kL, kR, s, sL;
3213 int i;
3214 static const UINT numpad_collisions[][2] = {
3215 { VK_NUMPAD0, VK_INSERT },
3216 { VK_NUMPAD1, VK_END },
3217 { VK_NUMPAD2, VK_DOWN },
3218 { VK_NUMPAD3, VK_NEXT },
3219 { VK_NUMPAD4, VK_LEFT },
3220 { VK_NUMPAD6, VK_RIGHT },
3221 { VK_NUMPAD7, VK_HOME },
3222 { VK_NUMPAD8, VK_UP },
3223 { VK_NUMPAD9, VK_PRIOR },
3224 };
3225
3227 ok(s != 0, "MapVirtualKeyEx(VK_SHIFT) should return non-zero\n");
3229 ok(s == sL || broken(sL == 0), /* win9x */
3230 "%x != %x\n", s, sL);
3231
3232 kL = MapVirtualKeyExA(0x2a, MAPVK_VSC_TO_VK, kl);
3233 ok(kL == VK_SHIFT, "Scan code -> vKey = %x (not VK_SHIFT)\n", kL);
3234 kR = MapVirtualKeyExA(0x36, MAPVK_VSC_TO_VK, kl);
3235 ok(kR == VK_SHIFT, "Scan code -> vKey = %x (not VK_SHIFT)\n", kR);
3236
3237 kL = MapVirtualKeyExA(0x2a, MAPVK_VSC_TO_VK_EX, kl);
3238 ok(kL == VK_LSHIFT || broken(kL == 0), /* win9x */
3239 "Scan code -> vKey = %x (not VK_LSHIFT)\n", kL);
3240 kR = MapVirtualKeyExA(0x36, MAPVK_VSC_TO_VK_EX, kl);
3241 ok(kR == VK_RSHIFT || broken(kR == 0), /* win9x */
3242 "Scan code -> vKey = %x (not VK_RSHIFT)\n", kR);
3243
3244 /* test that MAPVK_VSC_TO_VK prefers the non-numpad vkey if there's ambiguity */
3245 for (i = 0; i < ARRAY_SIZE(numpad_collisions); i++)
3246 {
3247 UINT numpad_scan = MapVirtualKeyExA(numpad_collisions[i][0], MAPVK_VK_TO_VSC, kl);
3248 UINT other_scan = MapVirtualKeyExA(numpad_collisions[i][1], MAPVK_VK_TO_VSC, kl);
3249
3250 /* do they really collide for this layout? */
3251 if (numpad_scan && other_scan == numpad_scan)
3252 {
3253 UINT vkey = MapVirtualKeyExA(numpad_scan, MAPVK_VSC_TO_VK, kl);
3254 ok(vkey != numpad_collisions[i][0],
3255 "Got numpad vKey %x for scan code %x when there was another choice\n",
3256 vkey, numpad_scan);
3257 }
3258 }
3259
3260 /* test the scan code prefixes of the right variant of a keys */
3262 ok(s >> 8 == 0x00, "Scan code prefixes should not be returned when not using MAPVK_VK_TO_VSC_EX %#1x\n", s >> 8);
3264 ok(s >> 8 == 0xE0 || broken(s == 0), "Scan code prefix for VK_RCONTROL should be 0xE0 when MAPVK_VK_TO_VSC_EX is set, was %#1x\n", s >> 8);
3266 ok(s >> 8 == 0xE0 || broken(s == 0), "Scan code prefix for VK_RMENU should be 0xE0 when MAPVK_VK_TO_VSC_EX is set, was %#1x\n", s >> 8);
3268 ok(s >> 8 == 0x00 || broken(s == 0), "The scan code shouldn't have a prefix, got %#1x\n", s >> 8);
3269}
3270
3271#define shift 1
3272#define ctrl 2
3273#define menu 4
3274
3275static const struct tounicode_tests
3276{
3279 WCHAR chr; /* if vk is 0, lookup vk using this char */
3282} utests[] =
3283{
3284 { 0, 0, 'a', 1, {'a',0}},
3285 { 0, shift, 'a', 1, {'A',0}},
3286 { 0, menu, 'a', 1, {'a',0}},
3287 { 0, shift|menu, 'a', 1, {'A',0}},
3288#if defined(__REACTOS__) && defined(_MSC_VER)
3289 { 0, shift|ctrl|menu, 'a', 0, {0}},
3290#else
3291 { 0, shift|ctrl|menu, 'a', 0, {}},
3292#endif
3293 { 0, ctrl, 'a', 1, {1, 0}},
3294 { 0, shift|ctrl, 'a', 1, {1, 0}},
3295#if defined(__REACTOS__) && defined(_MSC_VER)
3296 { VK_TAB, ctrl, 0, 0, {0}},
3297 { VK_TAB, shift|ctrl, 0, 0, {0}},
3298#else
3299 { VK_TAB, ctrl, 0, 0, {}},
3300 { VK_TAB, shift|ctrl, 0, 0, {}},
3301#endif
3302 { VK_RETURN, ctrl, 0, 1, {'\n', 0}},
3303#if defined(__REACTOS__) && defined(_MSC_VER)
3304 { VK_RETURN, shift|ctrl, 0, 0, {0}},
3305 { 0, ctrl, '4', 0, {0}},
3306 { 0, shift|ctrl, '4', 0, {0}},
3307 { 0, ctrl, '!', 0, {0}},
3308 { 0, ctrl, '\"', 0, {0}},
3309 { 0, ctrl, '#', 0, {0}},
3310 { 0, ctrl, '$', 0, {0}},
3311 { 0, ctrl, '%', 0, {0}},
3312 { 0, ctrl, '\'', 0, {0}},
3313 { 0, ctrl, '(', 0, {0}},
3314 { 0, ctrl, ')', 0, {0}},
3315 { 0, ctrl, '*', 0, {0}},
3316 { 0, ctrl, '+', 0, {0}},
3317 { 0, ctrl, ',', 0, {0}},
3318 { 0, ctrl, '-', 0, {0}},
3319 { 0, ctrl, '.', 0, {0}},
3320 { 0, ctrl, '/', 0, {0}},
3321 { 0, ctrl, ':', 0, {0}},
3322 { 0, ctrl, ';', 0, {0}},
3323 { 0, ctrl, '<', 0, {0}},
3324 { 0, ctrl, '=', 0, {0}},
3325 { 0, ctrl, '>', 0, {0}},
3326 { 0, ctrl, '?', 0, {0}},
3327#else
3328 { VK_RETURN, shift|ctrl, 0, 0, {}},
3329 { 0, ctrl, '4', 0, {}},
3330 { 0, shift|ctrl, '4', 0, {}},
3331 { 0, ctrl, '!', 0, {}},
3332 { 0, ctrl, '\"', 0, {}},
3333 { 0, ctrl, '#', 0, {}},
3334 { 0, ctrl, '$', 0, {}},
3335 { 0, ctrl, '%', 0, {}},
3336 { 0, ctrl, '\'', 0, {}},
3337 { 0, ctrl, '(', 0, {}},
3338 { 0, ctrl, ')', 0, {}},
3339 { 0, ctrl, '*', 0, {}},
3340 { 0, ctrl, '+', 0, {}},
3341 { 0, ctrl, ',', 0, {}},
3342 { 0, ctrl, '-', 0, {}},
3343 { 0, ctrl, '.', 0, {}},
3344 { 0, ctrl, '/', 0, {}},
3345 { 0, ctrl, ':', 0, {}},
3346 { 0, ctrl, ';', 0, {}},
3347 { 0, ctrl, '<', 0, {}},
3348 { 0, ctrl, '=', 0, {}},
3349 { 0, ctrl, '>', 0, {}},
3350 { 0, ctrl, '?', 0, {}},
3351#endif
3352 { 0, ctrl, '@', 1, {0}},
3353 { 0, ctrl, '[', 1, {0x1b}},
3354 { 0, ctrl, '\\', 1, {0x1c}},
3355 { 0, ctrl, ']', 1, {0x1d}},
3356 { 0, ctrl, '^', 1, {0x1e}},
3357 { 0, ctrl, '_', 1, {0x1f}},
3358#if defined(__REACTOS__) && defined(_MSC_VER)
3359 { 0, ctrl, '`', 0, {0}},
3360#else
3361 { 0, ctrl, '`', 0, {}},
3362#endif
3363 { VK_SPACE, 0, 0, 1, {' ',0}},
3364 { VK_SPACE, shift, 0, 1, {' ',0}},
3365 { VK_SPACE, ctrl, 0, 1, {' ',0}},
3367
3368static void test_ToUnicode(void)
3369{
3370 WCHAR wStr[4];
3371 BYTE state[256];
3372 const BYTE SC_RETURN = 0x1c, SC_TAB = 0x0f, SC_A = 0x1e;
3373 const BYTE HIGHEST_BIT = 0x80;
3374 int i, ret;
3375 BOOL us_kbd = (GetKeyboardLayout(0) == (HKL)(ULONG_PTR)0x04090409);
3376
3377 for(i=0; i<256; i++)
3378 state[i]=0;
3379
3380 wStr[1] = 0xAA;
3381 SetLastError(0xdeadbeef);
3382 ret = ToUnicode(VK_RETURN, SC_RETURN, state, wStr, 4, 0);
3384 {
3385 win_skip("ToUnicode is not implemented\n");
3386 return;
3387 }
3388
3389 ok(ret == 1, "ToUnicode for Return key didn't return 1 (was %i)\n", ret);
3390 if(ret == 1)
3391 {
3392 ok(wStr[0]=='\r', "ToUnicode for CTRL + Return was %i (expected 13)\n", wStr[0]);
3393 ok(wStr[1]==0 || broken(wStr[1]!=0) /* nt4 */,
3394 "ToUnicode didn't null-terminate the buffer when there was room.\n");
3395 }
3396
3397 for (i = 0; i < ARRAY_SIZE(utests); i++)
3398 {
3399 UINT vk = utests[i].vk, mod = utests[i].modifiers, scan;
3400
3401 if(!vk)
3402 {
3403 short vk_ret;
3404
3405 if (!us_kbd) continue;
3406 vk_ret = VkKeyScanW(utests[i].chr);
3407 if (vk_ret == -1) continue;
3408 vk = vk_ret & 0xff;
3409 if (vk_ret & 0x100) mod |= shift;
3410 if (vk_ret & 0x200) mod |= ctrl;
3411 }
3413
3414 state[VK_SHIFT] = state[VK_LSHIFT] = (mod & shift) ? HIGHEST_BIT : 0;
3415 state[VK_CONTROL] = state[VK_LCONTROL] = (mod & ctrl) ? HIGHEST_BIT : 0;
3416 state[VK_MENU] = state[VK_LMENU] = (mod & menu) ? HIGHEST_BIT : 0;
3417
3418 ret = ToUnicode(vk, scan, state, wStr, 4, 0);
3419 ok(ret == utests[i].expect_ret, "%d: got %d expected %d\n", i, ret, utests[i].expect_ret);
3420 if (ret)
3421 ok(!lstrcmpW(wStr, utests[i].expect_buf), "%d: got %s expected %s\n", i, wine_dbgstr_w(wStr),
3422 wine_dbgstr_w(utests[i].expect_buf));
3423
3424 }
3425 state[VK_SHIFT] = state[VK_LSHIFT] = 0;
3427
3428 ret = ToUnicode(VK_TAB, SC_TAB, NULL, wStr, 4, 0);
3429 ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
3430 ret = ToUnicode(VK_RETURN, SC_RETURN, NULL, wStr, 4, 0);
3431 ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
3432 ret = ToUnicode('A', SC_A, NULL, wStr, 4, 0);
3433 ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
3434 ret = ToUnicodeEx(VK_TAB, SC_TAB, NULL, wStr, 4, 0, GetKeyboardLayout(0));
3435 ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
3436 ret = ToUnicodeEx(VK_RETURN, SC_RETURN, NULL, wStr, 4, 0, GetKeyboardLayout(0));
3437 ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
3438 ret = ToUnicodeEx('A', SC_A, NULL, wStr, 4, 0, GetKeyboardLayout(0));
3439 ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
3440}
3441
3442static void test_ToAscii(void)
3443{
3444 WCHAR wstr[16];
3445 char str[16];
3446 WORD character;
3447 BYTE state[256];
3448 const BYTE SC_RETURN = 0x1c, SC_A = 0x1e;
3449 const BYTE HIGHEST_BIT = 0x80;
3450 int ret, len;
3451 DWORD gle;
3452
3453 memset(state, 0, sizeof(state));
3454
3455 character = 0;
3456 ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
3457 ok(ret == 1, "ToAscii for Return key didn't return 1 (was %i)\n", ret);
3458 ok(character == '\r', "ToAscii for Return was %i (expected 13)\n", character);
3459
3460 wstr[0] = 0;
3461 ret = ToUnicode('A', SC_A, state, wstr, ARRAY_SIZE(wstr), 0);
3462 ok(ret == 1, "ToUnicode(A) returned %i, expected 1\n", ret);
3463
3464 str[0] = '\0';
3465 len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, sizeof(str), NULL, NULL);
3466 gle = GetLastError();
3467 ok(len > 0, "Could not convert %s (gle %lu)\n", wine_dbgstr_w(wstr), gle);
3468
3469 character = 0;
3470 ret = ToAscii('A', SC_A, state, &character, 0);
3471 if (len == 1 || len == 2)
3472 ok(ret == 1, "ToAscii(A) returned %i, expected 1\n", ret);
3473 else
3474 /* ToAscii() can only return 2 chars => it fails if len > 2 */
3475 ok(ret == 0, "ToAscii(A) returned %i, expected 0\n", ret);
3476 switch ((ULONG_PTR)GetKeyboardLayout(0))
3477 {
3478 case 0x04090409: /* Qwerty */
3479 case 0x04070407: /* Qwertz */
3480 case 0x040c040c: /* Azerty */
3481 ok(lstrcmpW(wstr, L"a") == 0, "ToUnicode(A) returned %s\n", wine_dbgstr_w(wstr));
3482 ok(character == 'a', "ToAscii(A) returned char=%i, expected %i\n", character, 'a');
3483 break;
3484 /* Other keyboard layouts may or may not return 'a' */
3485 }
3486
3487 state[VK_CONTROL] |= HIGHEST_BIT;
3488 state[VK_LCONTROL] |= HIGHEST_BIT;
3489 character = 0;
3490 ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
3491 ok(ret == 1, "ToAscii for CTRL + Return key didn't return 1 (was %i)\n", ret);
3492 ok(character == '\n', "ToAscii for CTRL + Return was %i (expected 10)\n", character);
3493
3494 character = 0;
3495 ret = ToAscii('A', SC_A, state, &character, 0);
3496 ok(ret == 1, "ToAscii for CTRL + character 'A' didn't return 1 (was %i)\n", ret);
3497 ok(character == 1, "ToAscii for CTRL + character 'A' was %i (expected 1)\n", character);
3498
3499 state[VK_SHIFT] |= HIGHEST_BIT;
3500 state[VK_LSHIFT] |= HIGHEST_BIT;
3501 ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
3502 ok(ret == 0, "ToAscii for CTRL + Shift + Return key didn't return 0 (was %i)\n", ret);
3503
3504 ret = ToAscii(VK_RETURN, SC_RETURN, NULL, &character, 0);
3505 ok(ret == 0, "ToAscii for NULL keystate didn't return 0 (was %i)\n", ret);
3506 ret = ToAscii('A', SC_A, NULL, &character, 0);
3507 ok(ret == 0, "ToAscii for NULL keystate didn't return 0 (was %i)\n", ret);
3508 ret = ToAsciiEx(VK_RETURN, SC_RETURN, NULL, &character, 0, GetKeyboardLayout(0));
3509 ok(ret == 0, "ToAsciiEx for NULL keystate didn't return 0 (was %i)\n", ret);
3510 ret = ToAsciiEx('A', SC_A, NULL, &character, 0, GetKeyboardLayout(0));
3511 ok(ret == 0, "ToAsciiEx for NULL keystate didn't return 0 (was %i)\n", ret);
3512}
3513
3515{
3516 /* input value sanity checks */
3517 ok(0 == GetAsyncKeyState(1000000), "GetAsyncKeyState did not return 0\n");
3518 ok(0 == GetAsyncKeyState(-1000000), "GetAsyncKeyState did not return 0\n");
3519}
3520
3522{
3523 HKL *layouts;
3524
3526 ok_ne( 0, *count, UINT, "%u" );
3527 layouts = malloc( *count * sizeof(HKL) );
3528 ok_ne( NULL, layouts, void *, "%p" );
3529 *count = GetKeyboardLayoutList( *count, layouts );
3530 ok_ne( 0, *count, UINT, "%u" );
3531
3532 return layouts;
3533}
3534
3536{
3537 WCHAR klid[KL_NAMELENGTH], tmpklid[KL_NAMELENGTH], layout_path[MAX_PATH], value[5];
3538 HKL layout, tmplayout, *layouts, *layouts_preload;
3539 DWORD status, value_size, klid_size, type, id;
3540 int i, j;
3541 HKEY hkey;
3542 UINT len;
3543 BOOL ret;
3544
3545 if (0) /* crashes on native system */
3547
3548 SetLastError(0xdeadbeef);
3550 ok(!ret, "got %d\n", ret);
3551 ok(GetLastError() == ERROR_NOACCESS, "got %ld\n", GetLastError());
3552
3554 if (broken( layout == (HKL)0x040a0c0a ))
3555 {
3556 /* The testbot w7u_es has a broken layout configuration, its active layout is 040a:0c0a,
3557 * with 0c0a its user locale and 040a its layout langid. Its layout preload list contains
3558 * a 00000c0a layout but the system layouts OTOH only contains the standard 0000040a layout.
3559 * Later, after activating 0409:0409 layout, GetKeyboardLayoutNameW returns 00000c0a.
3560 */
3561 win_skip( "broken keyboard layout, skipping tests\n" );
3562 return;
3563 }
3564
3565 layouts = get_keyboard_layouts( &len );
3566 ok(layouts != NULL, "Could not allocate memory\n");
3567
3568 layouts_preload = calloc(1, sizeof(HKL));
3569 ok(layouts_preload != NULL, "Could not allocate memory\n");
3570
3571 if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Keyboard Layout\\Preload", &hkey ))
3572 {
3573 i = 0;
3574 type = REG_SZ;
3575 klid_size = sizeof(klid);
3576 value_size = ARRAY_SIZE(value);
3577 while (!RegEnumValueW( hkey, i++, value, &value_size, NULL, &type, (void *)&klid, &klid_size ))
3578 {
3579 klid_size = sizeof(klid);
3580 value_size = ARRAY_SIZE(value);
3581 layouts_preload = realloc( layouts_preload, (i + 1) * sizeof(*layouts_preload) );
3582 ok(layouts_preload != NULL, "Could not allocate memory\n");
3583 layouts_preload[i - 1] = UlongToHandle( wcstoul( klid, NULL, 16 ) );
3584 layouts_preload[i] = 0;
3585
3586 id = (DWORD_PTR)layouts_preload[i - 1];
3587 if (id & 0x80000000) todo_wine_if(HIWORD(id) == 0xe001) ok((id & 0xf0000000) == 0xd0000000, "Unexpected preloaded keyboard layout high bits %#lx\n", id);
3588 else ok(!(id & 0xf0000000), "Unexpected preloaded keyboard layout high bits %#lx\n", id);
3589 }
3590
3591 RegCloseKey( hkey );
3592 }
3593
3594 if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Keyboard Layout\\Substitutes", &hkey ))
3595 {
3596 for (i = 0; layouts_preload[i]; ++i)
3597 {
3598 type = REG_SZ;
3599 klid_size = sizeof(klid);
3600 swprintf( tmpklid, KL_NAMELENGTH, L"%08x", HandleToUlong( layouts_preload[i] ) );
3601 if (!RegQueryValueExW( hkey, tmpklid, NULL, &type, (void *)&klid, &klid_size ))
3602 {
3603 layouts_preload[i] = UlongToHandle( wcstoul( klid, NULL, 16 ) );
3604
3605 /* Substitute should contain the keyboard layout id, not the HKL high word */
3606 id = (DWORD_PTR)layouts_preload[i];
3607 ok(!(id & 0xf0000000), "Unexpected substitute keyboard layout high bits %#lx\n", id);
3608 }
3609 else
3610 {
3611 id = (DWORD_PTR)layouts_preload[i];
3612 ok(!(id & 0xf0000000), "Unexpected preloaded keyboard layout high bits %#lx\n", id);
3613 }
3614 }
3615
3616 RegCloseKey( hkey );
3617 }
3618
3619 for (i = len - 1; i >= 0; --i)
3620 {
3621 id = (DWORD_PTR)layouts[i];
3622
3623 winetest_push_context( "%08lx", id );
3624
3625 ActivateKeyboardLayout(layouts[i], 0);
3626
3627 tmplayout = GetKeyboardLayout(0);
3628 todo_wine_if(tmplayout != layouts[i])
3629 ok( tmplayout == layouts[i], "Failed to activate keyboard layout\n");
3630 if (tmplayout != layouts[i])
3631 {
3633 continue;
3634 }
3635
3637
3638 for (j = 0; layouts_preload[j]; ++j)
3639 {
3640 swprintf( tmpklid, KL_NAMELENGTH, L"%08X", layouts_preload[j] );
3641 if (!wcscmp( tmpklid, klid )) break;
3642 }
3643 ok(j < len, "Could not find keyboard layout %s in preload list\n", wine_dbgstr_w(klid));
3644
3645 if (id & 0x80000000)
3646 {
3647 todo_wine ok((id >> 28) == 0xf, "hkl high bits %#lx, expected 0xf\n", id >> 28);
3648
3649 value_size = sizeof(value);
3650 wcscpy(layout_path, L"System\\CurrentControlSet\\Control\\Keyboard Layouts\\");
3651 wcscat(layout_path, klid);
3652 status = RegGetValueW(HKEY_LOCAL_MACHINE, layout_path, L"Layout Id", RRF_RT_REG_SZ, NULL, (void *)&value, &value_size);
3653 todo_wine ok(!status, "RegGetValueW returned %lx\n", status);
3654 ok(value_size == 5 * sizeof(WCHAR), "RegGetValueW returned size %ld\n", value_size);
3655
3656 swprintf(tmpklid, KL_NAMELENGTH, L"%04X", (id >> 16) & 0x0fff);
3657 todo_wine ok(!wcsicmp(value, tmpklid), "RegGetValueW returned %s, expected %s\n", debugstr_w(value), debugstr_w(tmpklid));
3658 }
3659 else
3660 {
3661 swprintf(tmpklid, KL_NAMELENGTH, L"%08X", id >> 16);
3662 ok(!wcsicmp(klid, tmpklid), "GetKeyboardLayoutNameW returned %s, expected %s\n", debugstr_w(klid), debugstr_w(tmpklid));
3663 }
3664
3666 tmplayout = LoadKeyboardLayoutW(klid, KLF_ACTIVATE);
3667
3668 /* The low word of HKL is the selected user lang and may be different as LoadKeyboardLayoutW also selects the default lang from the layout */
3669 ok(((UINT_PTR)tmplayout & ~0xffff) == ((UINT_PTR)layouts[i] & ~0xffff), "LoadKeyboardLayoutW returned %p, expected %p\n", tmplayout, layouts[i]);
3670
3671 /* The layout name only depends on the keyboard layout: the high word of HKL. */
3672 GetKeyboardLayoutNameW(tmpklid);
3673 ok(!wcsicmp(klid, tmpklid), "GetKeyboardLayoutNameW returned %s, expected %s\n", debugstr_w(tmpklid), debugstr_w(klid));
3674
3676 }
3677
3679
3680 free(layouts);
3681 free(layouts_preload);
3682}
3683
3686static int got_setfocus;
3687
3689{
3690 ok( msg != WM_INPUTLANGCHANGEREQUEST, "got WM_INPUTLANGCHANGEREQUEST\n" );
3691
3692 if (msg == WM_SETFOCUS) got_setfocus = 1;
3693 if (msg == WM_INPUTLANGCHANGE)
3694 {
3697 WCHAR klidW[64];
3698 UINT codepage;
3699 LCID lcid;
3700
3701 /* get keyboard layout lcid from its name, as the HKL might be aliased */
3702 GetKeyboardLayoutNameW( klidW );
3703 swscanf( klidW, L"%x", &lcid );
3704 lcid = LOWORD(lcid);
3705
3706 if (!(HIWORD(layout) & 0x8000)) ok( lcid == HIWORD(layout), "got lcid %#lx\n", lcid );
3707
3708 GetLocaleInfoA( lcid, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
3709 (char *)&codepage, sizeof(codepage) );
3711
3712 ok( !got_setfocus, "got WM_SETFOCUS before WM_INPUTLANGCHANGE\n" );
3713 ok( layout == expect_hkl, "got layout %p\n", layout );
3714 ok( wparam == info.ciCharset || broken(wparam == 0 && (HIWORD(layout) & 0x8000)),
3715 "got wparam %#Ix\n", wparam );
3716 ok( lparam == (LPARAM)expect_hkl, "got lparam %#Ix\n", lparam );
3718 }
3719
3720 return DefWindowProcW( hwnd, msg, wparam, lparam );
3721}
3722
3724{
3726 return 0;
3727}
3728
3730{
3731 HKL layout, tmp_layout, *layouts;
3732 HWND hwnd1, hwnd2;
3733 HANDLE thread;
3734 UINT i, count;
3735 DWORD ret;
3736
3738 if (broken( layout == (HKL)0x040a0c0a ))
3739 {
3740 /* The testbot w7u_es has a broken layout configuration, see test_keyboard_layout_name above. */
3741 win_skip( "broken keyboard layout, skipping tests\n" );
3742 return;
3743 }
3744
3746 ok( count > 0, "GetKeyboardLayoutList returned %d\n", count );
3747 layouts = malloc( count * sizeof(HKL) );
3748 ok( layouts != NULL, "Could not allocate memory\n" );
3749 count = GetKeyboardLayoutList( count, layouts );
3750 ok( count > 0, "GetKeyboardLayoutList returned %d\n", count );
3751
3752 hwnd1 = CreateWindowA( "static", "static", WS_VISIBLE | WS_POPUP,
3753 100, 100, 100, 100, 0, NULL, NULL, NULL );
3754 ok( !!hwnd1, "CreateWindow failed, error %lu\n", GetLastError() );
3756
3758
3759 for (i = 0; i < count; ++i)
3760 {
3761 BOOL broken_focus_activate = FALSE;
3762 HKL other_layout = layouts[i];
3763
3764 winetest_push_context( "%08x / %08x", (UINT)(UINT_PTR)layout, (UINT)(UINT_PTR)other_layout );
3765
3766 /* test WM_INPUTLANGCHANGE message */
3767
3768 change_hkl = 0;
3769 expect_hkl = other_layout;
3770 got_setfocus = 0;
3771 ActivateKeyboardLayout( other_layout, 0 );
3772 if (other_layout == layout) ok( change_hkl == 0, "got change_hkl %p\n", change_hkl );
3773 else todo_wine ok( change_hkl == other_layout, "got change_hkl %p\n", change_hkl );
3774 change_hkl = expect_hkl = 0;
3775
3776 tmp_layout = GetKeyboardLayout( 0 );
3777 todo_wine_if(layout != other_layout)
3778 ok( tmp_layout == other_layout, "got tmp_layout %p\n", tmp_layout );
3779
3780 /* changing the layout from another thread doesn't send the message */
3781
3783 ret = WaitForSingleObject( thread, 1000 );
3784 ok( !ret, "WaitForSingleObject returned %#lx\n", ret );
3786
3787 /* and has no immediate effect */
3788
3790 tmp_layout = GetKeyboardLayout( 0 );
3791 todo_wine_if(layout != other_layout)
3792 ok( tmp_layout == other_layout, "got tmp_layout %p\n", tmp_layout );
3793
3794 /* but the change only takes effect after focus changes */
3795
3796 hwnd2 = CreateWindowA( "static", "static", WS_VISIBLE | WS_POPUP,
3797 100, 100, 100, 100, 0, NULL, NULL, NULL );
3798 ok( !!hwnd2, "CreateWindow failed, error %lu\n", GetLastError() );
3799
3800 tmp_layout = GetKeyboardLayout( 0 );
3801 todo_wine_if(layout != other_layout)
3802 ok( tmp_layout == layout || broken(layout != other_layout && tmp_layout == other_layout) /* w7u */,
3803 "got tmp_layout %p\n", tmp_layout );
3804 if (broken(layout != other_layout && tmp_layout == other_layout))
3805 {
3806 win_skip( "Broken layout activation on focus change, skipping some tests\n" );
3807 broken_focus_activate = TRUE;
3808 }
3810
3811 /* only the focused window receives the WM_INPUTLANGCHANGE message */
3812
3813 ActivateKeyboardLayout( other_layout, 0 );
3814 ok( change_hkl == 0, "got change_hkl %p\n", change_hkl );
3815
3816 tmp_layout = GetKeyboardLayout( 0 );
3817 todo_wine_if(layout != other_layout)
3818 ok( tmp_layout == other_layout, "got tmp_layout %p\n", tmp_layout );
3819
3821 ret = WaitForSingleObject( thread, 1000 );
3822 ok( !ret, "WaitForSingleObject returned %#lx\n", ret );
3824
3825 tmp_layout = GetKeyboardLayout( 0 );
3826 todo_wine_if(layout != other_layout)
3827 ok( tmp_layout == other_layout, "got tmp_layout %p\n", tmp_layout );
3828
3829 /* changing focus is enough for the layout change to take effect */
3830
3831 change_hkl = 0;
3833 got_setfocus = 0;
3834 SetFocus( hwnd1 );
3835
3836 if (broken_focus_activate)
3837 {
3838 ok( got_setfocus == 1, "got got_setfocus %d\n", got_setfocus );
3839 ok( change_hkl == 0, "got change_hkl %p\n", change_hkl );
3840 got_setfocus = 0;
3842 }
3843
3844 if (other_layout == layout) ok( change_hkl == 0, "got change_hkl %p\n", change_hkl );
3845 else todo_wine ok( change_hkl == layout, "got change_hkl %p\n", change_hkl );
3846 change_hkl = expect_hkl = 0;
3847
3848 tmp_layout = GetKeyboardLayout( 0 );
3849 todo_wine_if(layout != other_layout)
3850 ok( tmp_layout == layout, "got tmp_layout %p\n", tmp_layout );
3851
3852 DestroyWindow( hwnd2 );
3854
3856 }
3857
3858 DestroyWindow( hwnd1 );
3859
3860 free( layouts );
3861}
3862
3863static void test_key_names(void)
3864{
3865 char buffer[40];
3866 WCHAR bufferW[40];
3867 int ret, prev;
3868 LONG lparam = 0x1d << 16;
3869
3870 memset( buffer, 0xcc, sizeof(buffer) );
3871 ret = GetKeyNameTextA( lparam, buffer, sizeof(buffer) );
3872 ok( ret > 0, "wrong len %u for '%s'\n", ret, buffer );
3873 ok( ret == strlen(buffer), "wrong len %u for '%s'\n", ret, buffer );
3874
3875 memset( buffer, 0xcc, sizeof(buffer) );
3876 prev = ret;
3877 ret = GetKeyNameTextA( lparam, buffer, prev );
3878 ok( ret == prev - 1, "wrong len %u for '%s'\n", ret, buffer );
3879 ok( ret == strlen(buffer), "wrong len %u for '%s'\n", ret, buffer );
3880
3881 memset( buffer, 0xcc, sizeof(buffer) );
3883 ok( ret == 0, "wrong len %u for '%s'\n", ret, buffer );
3884 ok( buffer[0] == 0, "wrong string '%s'\n", buffer );
3885
3886 memset( bufferW, 0xcc, sizeof(bufferW) );
3887 ret = GetKeyNameTextW( lparam, bufferW, ARRAY_SIZE(bufferW));
3888 ok( ret > 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
3889 ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
3890
3891 memset( bufferW, 0xcc, sizeof(bufferW) );
3892 prev = ret;
3893 ret = GetKeyNameTextW( lparam, bufferW, prev );
3894 ok( ret == prev - 1, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
3895 ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
3896
3897 memset( bufferW, 0xcc, sizeof(bufferW) );
3898 ret = GetKeyNameTextW( lparam, bufferW, 0 );
3899 ok( ret == 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
3900 ok( bufferW[0] == 0xcccc, "wrong string %s\n", wine_dbgstr_w(bufferW) );
3901}
3902
3903static void simulate_click(BOOL left, int x, int y)
3904{
3905 INPUT input[2];
3906 UINT events_no;
3907
3908 SetCursorPos(x, y);
3909 memset(input, 0, sizeof(input));
3910 input[0].type = INPUT_MOUSE;
3911 input[0].mi.dx = x;
3912 input[0].mi.dy = y;
3914 input[1].type = INPUT_MOUSE;
3915 input[1].mi.dx = x;
3916 input[1].mi.dy = y;
3918 events_no = SendInput(2, input, sizeof(input[0]));
3919 ok(events_no == 2, "SendInput returned %d\n", events_no);
3920}
3921
3923{
3924 DWORD end_time = GetTickCount() + timeout;
3925 MSG msg;
3926
3927 do {
3929 return TRUE;
3930 while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
3932 timeout = end_time - GetTickCount();
3933 }while(timeout > 0);
3934
3935 return FALSE;
3936}
3937
3939{
3941 if (msg == WM_NCHITTEST) return HTTRANSPARENT;
3942 return DefWindowProcW( hwnd, msg, wparam, lparam );
3943}
3944
3946{
3950};
3951
3953{
3956
3957 params->hwnd = CreateWindowW( L"static", NULL, WS_VISIBLE | WS_POPUP, 0, 0, 100, 100, NULL, NULL, NULL, NULL );
3958 ok_ne( NULL, params->hwnd, HWND, "%p" );
3959 wait_messages( 100, FALSE );
3961 ok_ne( 0, old_proc, LONG_PTR, "%#Ix" );
3962
3963 ok_ret( 1, SetEvent( params->start_event ) );
3964 wait_for_event( params->end_event, 5000 );
3965
3966 ok_ret( 1, DestroyWindow( params->hwnd ) );
3967 wait_messages( 100, FALSE );
3968 return 0;
3969}
3970
3972{
3973 static DWORD last_x = 50, expect_x = 60;
3974
3975 if (msg == WM_MOUSEMOVE)
3976 {
3978 MapWindowPoints(hwnd, NULL, &pt, 1);
3979
3980 flaky
3981 if (pt.x != last_x) ok( pt.x == expect_x, "got unexpected WM_MOUSEMOVE x %ld, expected %ld\n", pt.x, expect_x );
3982
3983 expect_x = pt.x == 50 ? 60 : 50;
3984 last_x = pt.x;
3985 }
3986
3987 return DefWindowProcW(hwnd, msg, wparam, lparam);
3988}
3989
3991{
3993
3994 if (msg == WM_PAINT)
3995 {
3996 HBRUSH brush = CreateSolidBrush( RGB(50, 100, 255) );
3997 PAINTSTRUCT paint;
3998 RECT client_rect;
3999
4000 HDC hdc = BeginPaint( hwnd, &paint );
4001 GetClientRect( hwnd, &client_rect );
4002 FillRect( hdc, &client_rect, brush );
4003 EndPaint( hwnd, &paint );
4004
4005 DeleteObject( brush );
4006 return 0;
4007 }
4008
4009 return DefWindowProcW( hwnd, msg, wparam, lparam );
4010}
4011
4013{
4022};
4023
4025{
4026 MSLLHOOKSTRUCT *hook_info = (MSLLHOOKSTRUCT *)lparam;
4027 if (code == HC_ACTION) append_ll_hook_ms( wparam, hook_info );
4028 return CallNextHookEx( 0, code, wparam, lparam );
4029}
4030
4032{
4033 if (code == HC_ACTION)
4034 {
4035 MSLLHOOKSTRUCT *hook_info = (MSLLHOOKSTRUCT *)lparam;
4036 POINT pos, hook_pos = {40, 40};
4037
4038 ok( abs( hook_info->pt.x - 51 ) <= 1, "got x %ld\n", hook_info->pt.x );
4039 ok( abs( hook_info->pt.y - 49 ) <= 1, "got y %ld\n", hook_info->pt.y );
4040
4041 /* spuriously moves by 0 or 1 pixels on Windows */
4042 ok_ret( 1, GetCursorPos( &pos ) );
4043 ok( abs( pos.x - 51 ) <= 1, "got x %ld\n", pos.x );
4044 ok( abs( pos.y - 49 ) <= 1, "got y %ld\n", pos.y );
4045
4046 ok_ret( 1, SetCursorPos( 60, 60 ) );
4047 hook_info->pt = hook_pos;
4048 }
4049
4050 return CallNextHookEx( 0, code, wparam, lparam );
4051}
4052
4054{
4055 if (code == HC_ACTION)
4056 {
4057 MSLLHOOKSTRUCT *hook_info = (MSLLHOOKSTRUCT *)lparam;
4058 POINT pos, expect_pos = {60, 60}, hook_pos = {40, 40};
4059 ok_point( hook_pos, hook_info->pt );
4060 ok_ret( 1, GetCursorPos( &pos ) );
4061 ok_point( expect_pos, pos );
4062 }
4063
4064 return CallNextHookEx( 0, code, wparam, lparam );
4065}
4066
4068{
4069 return is_mouse_message( msg ) && msg != WM_MOUSEMOVE;
4070}
4071
4073{
4074#define WIN_MSG(m, h, w, l, ...) {.func = MSG_TEST_WIN, .message = {.msg = m, .hwnd = h, .wparam = w, .lparam = l}, ## __VA_ARGS__}
4075#define MS_HOOK(m, x, y, ...) {.func = LL_HOOK_MOUSE, .ll_hook_ms = {.msg = m, .point = {x, y}, .flags = 1}, ## __VA_ARGS__}
4076 struct user_call mouse_move[] =
4077 {
4078 MS_HOOK(WM_MOUSEMOVE, 40, 40),
4079 {0},
4080 };
4081 struct user_call button_down_hwnd[] =
4082 {
4083 MS_HOOK(WM_LBUTTONDOWN, 50, 50),
4084 WIN_MSG(WM_LBUTTONDOWN, (HWND)-1/*hwnd*/, 0x1, MAKELONG(50, 50)),
4085 {0},
4086 };
4087 struct user_call button_down_hwnd_todo[] =
4088 {
4089 MS_HOOK(WM_LBUTTONDOWN, 50, 50),
4090 WIN_MSG(WM_LBUTTONDOWN, (HWND)-1/*hwnd*/, 0x1, MAKELONG(50, 50), .todo = TRUE),
4091 {0/* placeholder for Wine spurious messages */},
4092 {0},
4093 };
4094 struct user_call button_up_hwnd[] =
4095 {
4096 MS_HOOK(WM_LBUTTONUP, 50, 50),
4097 WIN_MSG(WM_LBUTTONUP, (HWND)-1/*hwnd*/, 0, MAKELONG(50, 50)),
4098 {0},
4099 };
4100 struct user_call button_up_hwnd_todo[] =
4101 {
4102 MS_HOOK(WM_LBUTTONUP, 50, 50),
4103 WIN_MSG(WM_LBUTTONUP, (HWND)-1/*hwnd*/, 0, MAKELONG(50, 50), .todo = TRUE),
4104 {0/* placeholder for Wine spurious messages */},
4105 {0},
4106 };
4107 struct user_call button_down_no_message[] =
4108 {
4109 MS_HOOK(WM_LBUTTONDOWN, 50, 50),
4110 {.todo = TRUE /* spurious message on Wine */},
4111 {0},
4112 };
4113 struct user_call button_up_no_message[] =
4114 {
4115 MS_HOOK(WM_LBUTTONUP, 50, 50),
4116 {.todo = TRUE /* spurious message on Wine */},
4117 {0},
4118 };
4119#undef WIN_MSG
4120#undef MS_HOOK
4121 static const POINT expect_60x50 = {60, 50}, expect_50x50 = {50, 50};
4122
4123 static const struct layered_test
4124 {
4125 UINT color;
4126 UINT alpha;
4127 UINT flags;
4128 BOOL expect_click;
4129 }
4130 layered_tests[] =
4131 {
4132 {.flags = LWA_ALPHA, .expect_click = FALSE},
4133 {.alpha = 1, .flags = LWA_ALPHA, .expect_click = TRUE},
4134 {.color = RGB(0, 255, 0), .flags = LWA_COLORKEY, .expect_click = TRUE},
4135 {.color = RGB(50, 100, 255), .flags = LWA_COLORKEY, .expect_click = TRUE},
4136 {.color = RGB(0, 255, 0), .flags = LWA_COLORKEY | LWA_ALPHA, .expect_click = FALSE},
4137 {.color = RGB(0, 255, 0), .alpha = 1, .flags = LWA_COLORKEY | LWA_ALPHA, .expect_click = TRUE},
4138 {.color = RGB(50, 100, 255), .alpha = 1, .flags = LWA_COLORKEY | LWA_ALPHA, .expect_click = TRUE},
4139 };
4140
4142 ULONG_PTR old_proc, old_other_proc;
4143 RECT clip_rect = {55, 55, 55, 55};
4144 UINT dblclk_time, i;
4145 HWND hwnd, other;
4147 HANDLE thread;
4148 HHOOK hook, hook_setpos, hook_getpos;
4149 HRGN hregion;
4150 RECT region;
4151 POINT pt;
4152
4153 params.start_event = CreateEventA( NULL, FALSE, FALSE, NULL );
4154 ok( !!params.start_event, "CreateEvent failed\n" );
4155 params.end_event = CreateEventA( NULL, FALSE, FALSE, NULL );
4156 ok( !!params.end_event, "CreateEvent failed\n" );
4157
4158
4159 dblclk_time = GetDoubleClickTime();
4160 ok_eq( 500, dblclk_time, UINT, "%u" );
4161
4162 ok_ret( 1, SetCursorPos( 50, 50 ) );
4163 ok_ret( 1, SetDoubleClickTime( 1 ) );
4164
4165 hwnd = CreateWindowW( L"static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL );
4166 ok_ne( NULL, hwnd, HWND, "%p" );
4167 wait_messages( 100, FALSE );
4168 trace( "hwnd %p\n", hwnd );
4169
4171 ok_ne( NULL, hook, HHOOK, "%p" );
4172
4173 /* test hooks only, WM_MOUSEMOVE messages are very brittle */
4176
4177 /* SetCursorPos or ClipCursor don't call mouse ll hooks */
4178 ok_ret( 1, SetCursorPos( 60, 60 ) );
4179 wait_messages( 5, FALSE );
4180 ok_ret( 1, ClipCursor( &clip_rect ) );
4181 wait_messages( 5, FALSE );
4182 ok_ret( 1, ClipCursor( NULL ) );
4183 wait_messages( 5, FALSE );
4184 ok_ret( 1, SetCursorPos( 50, 50 ) );
4185 wait_messages( 100, FALSE );
4187
4189 ok_ne( NULL, hook_getpos, HHOOK, "%p" );
4191 ok_ne( NULL, hook_setpos, HHOOK, "%p" );
4192
4193 mouse_event( MOUSEEVENTF_MOVE, 0, 0, 0, 0 );
4194 /* recent Windows versions don't call the hooks with no movement */
4196 {
4197 ok_seq( mouse_move );
4198 ok_ret( 1, SetCursorPos( 50, 50 ) );
4199 }
4201
4202 /* WH_MOUSE_LL hook is called even with 1 pixel moves */
4203 mouse_event( MOUSEEVENTF_MOVE, +1, -1, 0, 0 );
4204 ok_seq( mouse_move );
4205
4206 ok_ret( 1, UnhookWindowsHookEx( hook_getpos ) );
4207 ok_ret( 1, UnhookWindowsHookEx( hook_setpos ) );
4208
4209
4213
4214
4215 /* basic button messages */
4216
4218 ok_ne( 0, old_proc, LONG_PTR, "%#Ix" );
4219
4220 ok_ret( 1, SetCursorPos( 50, 50 ) );
4221 wait_messages( 100, FALSE );
4223
4224 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4225 wait_messages( 5, FALSE );
4226 button_down_hwnd[1].message.hwnd = hwnd;
4227 ok_seq( button_down_hwnd );
4228
4229 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4230 wait_messages( 5, FALSE );
4231 button_up_hwnd[1].message.hwnd = hwnd;
4232 ok_seq( button_up_hwnd );
4233 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4234 wait_messages( 5, FALSE );
4235 button_up_hwnd[1].message.hwnd = hwnd;
4236 ok_seq( button_up_hwnd );
4237
4238
4239 /* click through top-level window */
4240
4241 other = CreateWindowW( L"static", NULL, WS_VISIBLE | WS_POPUP, 0, 0, 100, 100, NULL, NULL, NULL, NULL );
4242 ok_ne( NULL, hwnd, HWND, "%p" );
4243 wait_messages( 100, FALSE );
4245
4247 ok_ne( 0, old_other_proc, LONG_PTR, "%#Ix" );
4248
4249 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4250 wait_messages( 5, FALSE );
4251 button_down_hwnd[1].message.hwnd = other;
4252 ok_seq( button_down_hwnd );
4253 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4254 wait_messages( 5, FALSE );
4255 button_up_hwnd[1].message.hwnd = other;
4256 ok_seq( button_up_hwnd );
4257
4258 ok_ret( 1, DestroyWindow( other ) );
4259 wait_messages( 0, FALSE );
4260
4261
4262 /* click through child window */
4263
4264 other = CreateWindowW( L"static", NULL, WS_VISIBLE | WS_CHILD, 0, 0, 100, 100, hwnd, NULL, NULL, NULL );
4265 ok_ne( NULL, hwnd, HWND, "%p" );
4266 wait_messages( 100, FALSE );
4268
4270 ok_ne( 0, old_other_proc, LONG_PTR, "%#Ix" );
4271
4272 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4273 wait_messages( 5, FALSE );
4274 button_down_hwnd[1].message.hwnd = other;
4275 ok_seq( button_down_hwnd );
4276 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4277 wait_messages( 5, FALSE );
4278 button_up_hwnd[1].message.hwnd = other;
4279 ok_seq( button_up_hwnd );
4280
4281 ok_ret( 1, DestroyWindow( other ) );
4282 wait_messages( 0, FALSE );
4283
4284
4285 /* click through HTTRANSPARENT top-level window */
4286
4287 other = CreateWindowW( L"static", NULL, WS_VISIBLE | WS_POPUP, 0, 0, 100, 100, NULL, NULL, NULL, NULL );
4288 ok_ne( NULL, hwnd, HWND, "%p" );
4289 wait_messages( 100, FALSE );
4291
4293 ok_ne( 0, old_other_proc, LONG_PTR, "%#Ix" );
4294
4295 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4296 wait_messages( 5, FALSE );
4297 button_down_hwnd_todo[1].message.hwnd = hwnd;
4298 ok_seq( button_down_hwnd_todo );
4299 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4300 wait_messages( 5, FALSE );
4301 button_up_hwnd_todo[1].message.hwnd = hwnd;
4302 ok_seq( button_up_hwnd_todo );
4303
4304 ok_ret( 1, DestroyWindow( other ) );
4305 wait_messages( 0, FALSE );
4306
4307
4308 /* click through HTTRANSPARENT child window */
4309
4310 other = CreateWindowW( L"static", NULL, WS_VISIBLE | WS_CHILD, 0, 0, 100, 100, hwnd, NULL, NULL, NULL );
4311 ok_ne( NULL, hwnd, HWND, "%p" );
4312 wait_messages( 100, FALSE );
4314
4316 ok_ne( 0, old_other_proc, LONG_PTR, "%#Ix" );
4317
4318 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4319 wait_messages( 5, FALSE );
4320 button_down_hwnd[1].message.hwnd = hwnd;
4321 ok_seq( button_down_hwnd );
4322 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4323 wait_messages( 5, FALSE );
4324 button_up_hwnd[1].message.hwnd = hwnd;
4325 ok_seq( button_up_hwnd );
4326
4327 ok_ret( 1, DestroyWindow( other ) );
4328 wait_messages( 0, FALSE );
4329
4330
4331 /* click on HTTRANSPARENT top-level window that belongs to other thread */
4332
4334 ok_ne( NULL, thread, HANDLE, "%p" );
4335
4336 ok_ret( 0, WaitForSingleObject( params.start_event, 5000 ) );
4337 ok_ret( 0, SendMessageW( params.hwnd, WM_USER, 0, 0 ) );
4338
4339 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4340 wait_messages( 5, FALSE );
4341 ok_seq( button_down_no_message );
4342 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4343 wait_messages( 5, FALSE );
4344 ok_seq( button_up_no_message );
4345
4346 ok_ret( 1, SetEvent( params.end_event ) );
4347 ok_ret( 0, WaitForSingleObject( thread, 5000 ) );
4348 ok_ret( 1, CloseHandle( thread ) );
4349 ResetEvent( params.start_event );
4350 ResetEvent( params.end_event );
4351
4352
4353 /* click on HTTRANSPARENT top-level window that belongs to other thread,
4354 * thread input queues are attached */
4355
4357 ok_ne( NULL, thread, HANDLE, "%p" );
4358
4359 ok_ret( 0, WaitForSingleObject( params.start_event, 5000 ) );
4361 ok_ret( 0, SendMessageW( params.hwnd, WM_USER, 0, 0 ) );
4362
4363 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4364 wait_messages( 5, FALSE );
4365 button_down_hwnd_todo[1].message.hwnd = hwnd;
4366 ok_seq( button_down_hwnd_todo );
4367 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4368 wait_messages( 5, FALSE );
4369 button_up_hwnd[1].message.hwnd = hwnd;
4370 ok_seq( button_up_hwnd );
4371
4373 ok_ret( 1, SetEvent( params.end_event ) );
4374 ok_ret( 0, WaitForSingleObject( thread, 5000 ) );
4375 ok_ret( 1, CloseHandle( thread ) );
4376 ResetEvent( params.start_event );
4377 ResetEvent( params.end_event );
4378
4379
4380 /* click on top-level window with SetCapture called for the underlying window */
4381
4382 other = CreateWindowW( L"static", NULL, WS_VISIBLE | WS_POPUP, 0, 0, 100, 100, NULL, NULL, NULL, NULL );
4383 ok_ne( NULL, hwnd, HWND, "%p" );
4384 wait_messages( 100, FALSE );
4386
4388 ok_ne( 0, old_other_proc, LONG_PTR, "%#Ix" );
4389
4390 SetCapture( hwnd );
4391
4392 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4393 wait_messages( 5, FALSE );
4394 button_down_hwnd[1].message.hwnd = hwnd;
4395 ok_seq( button_down_hwnd );
4396 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4397 wait_messages( 5, FALSE );
4398 button_up_hwnd[1].message.hwnd = hwnd;
4399 ok_seq( button_up_hwnd );
4400
4401 ok_ret( 1, DestroyWindow( other ) );
4402 wait_messages( 0, FALSE );
4403
4404 SetCapture( 0 );
4405
4406
4407 /* click through child window with SetCapture called for the underlying window */
4408
4409 other = CreateWindowW( L"static", NULL, WS_VISIBLE | WS_CHILD, 0, 0, 100, 100, hwnd, NULL, NULL, NULL );
4410 ok_ne( NULL, hwnd, HWND, "%p" );
4411 wait_messages( 100, FALSE );
4413
4415 ok_ne( 0, old_other_proc, LONG_PTR, "%#Ix" );
4416
4417 SetCapture( hwnd );
4418
4419 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4420 wait_messages( 5, FALSE );
4421 button_down_hwnd[1].message.hwnd = hwnd;
4422 ok_seq( button_down_hwnd );
4423 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4424 wait_messages( 5, FALSE );
4425 button_up_hwnd[1].message.hwnd = hwnd;
4426 ok_seq( button_up_hwnd );
4427
4428 ok_ret( 1, DestroyWindow( other ) );
4429 wait_messages( 0, FALSE );
4430
4431 SetCapture( 0 );
4432
4433
4434
4435 /* click through layered window with alpha channel / color key */
4436
4437 for (i = 0; i < ARRAY_SIZE(layered_tests); i++)
4438 {
4439 const struct layered_test *test = layered_tests + i;
4440 BOOL ret;
4441
4442 winetest_push_context( "layered %u", i );
4443
4444 other = CreateWindowW( L"static", NULL, WS_VISIBLE | WS_POPUP, 0, 0, 100, 100, NULL, NULL, NULL, NULL );
4445 ok_ne( NULL, other, HWND, "%p" );
4447 ok_ne( 0, old_other_proc, LONG_PTR, "%#Ix" );
4448 wait_messages( 100, FALSE );
4449
4450 ok_ret( ERROR, GetWindowRgnBox( other, &region ) );
4451
4452
4454 ret = SetLayeredWindowAttributes( other, test->color, test->alpha, test->flags );
4455 if (broken(!ret)) /* broken on Win7 probably because of the separate desktop */
4456 {
4457 win_skip("Skipping broken SetLayeredWindowAttributes tests\n");
4460 break;
4461 }
4462
4464 wait_messages( 5, FALSE );
4466
4467 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4468 wait_messages( 5, FALSE );
4469 button_down_hwnd_todo[1].message.hwnd = test->expect_click ? other : hwnd;
4470 button_down_hwnd_todo[1].todo = !test->expect_click;
4471 button_down_hwnd_todo[2].todo = !test->alpha && (test->flags & LWA_ALPHA);
4472 ok_seq( button_down_hwnd_todo );
4473 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4474 wait_messages( 5, FALSE );
4475 button_up_hwnd_todo[1].message.hwnd = test->expect_click ? other : hwnd;
4476 button_up_hwnd_todo[1].todo = !test->expect_click;
4477 button_up_hwnd_todo[2].todo = !test->alpha && (test->flags & LWA_ALPHA);
4478 ok_seq( button_up_hwnd_todo );
4479
4480
4481 /* removing the attribute isn't enough to get mouse input again? */
4482
4485 wait_messages( 5, FALSE );
4486
4487 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4488 wait_messages( 5, FALSE );
4489 button_down_hwnd_todo[1].message.hwnd = test->expect_click ? other : hwnd;
4490 button_down_hwnd_todo[1].todo = !test->expect_click;
4491 button_down_hwnd_todo[2].todo = !test->alpha && (test->flags & LWA_ALPHA);
4492 ok_seq( button_down_hwnd_todo );
4493 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4494 wait_messages( 5, FALSE );
4495 button_up_hwnd_todo[1].message.hwnd = test->expect_click ? other : hwnd;
4496 button_up_hwnd_todo[1].todo = !test->expect_click;
4497 button_up_hwnd_todo[2].todo = !test->alpha && (test->flags & LWA_ALPHA);
4498 ok_seq( button_up_hwnd_todo );
4499
4500 ok_ret( 1, DestroyWindow( other ) );
4501
4503 }
4504
4505
4506 /* click on top-level window with SetWindowRgn called */
4507
4508 other = CreateWindowW( L"static", NULL, WS_VISIBLE | WS_POPUP, 0, 0, 100, 100, NULL, NULL, NULL, NULL );
4509 ok_ne( NULL, hwnd, HWND, "%p" );
4510 wait_messages( 100, FALSE );
4512
4514 ok_ne( 0, old_other_proc, LONG_PTR, "%#Ix" );
4515
4516 hregion = CreateRectRgn( 0, 0, 10, 10 );
4517 ok_ne( NULL, hregion, HRGN, "%p" );
4518 ok_ret( 1, SetWindowRgn( other, hregion, TRUE ) );
4519 DeleteObject( hregion );
4520 ok_ret( SIMPLEREGION, GetWindowRgnBox( other, &region ) );
4521
4522 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
4523 wait_messages( 5, FALSE );
4524 button_down_hwnd[1].message.hwnd = hwnd;
4525 ok_seq( button_down_hwnd );
4526 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
4527 wait_messages( 5, FALSE );
4528 button_up_hwnd[1].message.hwnd = hwnd;
4529 ok_seq( button_up_hwnd );
4530
4531 ok_ret( 1, DestroyWindow( other ) );
4532 wait_messages( 0, FALSE );
4533
4534
4535 /* warm up test case by moving cursor and window a bit first */
4536 ok_ret( 1, SetCursorPos( 60, 50 ) );
4537 ok_ret( 1, SetWindowPos( hwnd, NULL, 10, 0, 0, 0, SWP_NOSIZE ) );
4538 wait_messages( 5, FALSE );
4539 ok_ret( 1, SetCursorPos( 50, 50 ) );
4540 ok_ret( 1, SetWindowPos( hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE ) );
4541 wait_messages( 5, FALSE );
4543
4544 ok_ret( 1, SetCursorPos( 60, 50 ) );
4545 ok_ret( 1, SetWindowPos( hwnd, NULL, 10, 0, 0, 0, SWP_NOSIZE ) );
4546 wait_messages( 5, FALSE );
4547 ok_ret( 1, GetCursorPos( &pt ) );
4548 ok_point( expect_60x50, pt );
4549
4550 ok_ret( 1, SetCursorPos( 50, 50 ) );
4551 ok_ret( 1, SetWindowPos( hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE ) );
4552 wait_messages( 5, FALSE );
4553 ok_ret( 1, GetCursorPos( &pt ) );
4554 ok_point( expect_50x50, pt );
4555
4556
4558
4559 wait_messages( 100, FALSE );
4563
4564
4565 ok_ret( 1, DestroyWindow( hwnd ) );
4566
4567 CloseHandle( params.start_event );
4568 CloseHandle( params.end_event );
4569
4570
4571 ok_ret( 1, SetDoubleClickTime( dblclk_time ) );
4572}
4573
4574
4576{
4577 if (message == WM_USER+1)
4578 {
4579 HWND hwnd = (HWND)lParam;
4580 ok(GetFocus() == hwnd, "thread expected focus %p, got %p\n", hwnd, GetFocus());
4581 ok(GetActiveWindow() == hwnd, "thread expected active %p, got %p\n", hwnd, GetActiveWindow());
4582 }
4584}
4585
4587{
4594};
4595
4597{
4598 MSG msg;
4599 struct wnd_event *wnd_event = param;
4600 BOOL ret;
4601
4602 if (wnd_event->wait_event)
4603 {
4605 "WaitForSingleObject failed\n");
4607 }
4608
4610 {
4612 ok(ret, "AttachThreadInput error %ld\n", GetLastError());
4613 }
4614
4615 if (wnd_event->attach_to)
4616 {
4618 ok(ret, "AttachThreadInput error %ld\n", GetLastError());
4619 }
4620
4621 wnd_event->hwnd = CreateWindowExA(0, "TestWindowClass", "window caption text", WS_OVERLAPPEDWINDOW,
4622 100, 100, 200, 200, 0, 0, 0, NULL);
4623 ok(wnd_event->hwnd != 0, "Failed to create overlapped window\n");
4624
4625 if (wnd_event->setWindows)
4626 {
4629 }
4630
4632
4633 while (GetMessageA(&msg, 0, 0, 0))
4634 {
4637 }
4638
4639 return 0;
4640}
4641
4642static void test_attach_input(void)
4643{
4645 HWND ourWnd, Wnd2;
4646 DWORD ret, tid;
4647 struct wnd_event wnd_event;
4648 WNDCLASSA cls;
4649
4650 cls.style = 0;
4651 cls.lpfnWndProc = MsgCheckProcA;
4652 cls.cbClsExtra = 0;
4653 cls.cbWndExtra = 0;
4654 cls.hInstance = GetModuleHandleA(0);
4655 cls.hIcon = 0;
4656 cls.hCursor = LoadCursorW( NULL, (LPCWSTR)IDC_ARROW);
4657 cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
4658 cls.lpszMenuName = NULL;
4659 cls.lpszClassName = "TestWindowClass";
4660 if(!RegisterClassA(&cls)) return;
4661
4665 wnd_event.attach_to = 0;
4668 {
4669 win_skip("skipping interthread message test under win9x\n");
4670 return;
4671 }
4672
4674 ok(hThread != NULL, "CreateThread failed, error %ld\n", GetLastError());
4675
4676 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
4678
4679 ourWnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
4680 0, 0, 0, 0, 0, 0, 0, NULL);
4681 ok(ourWnd!= 0, "failed to create ourWnd window\n");
4682
4683 Wnd2 = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
4684 0, 0, 0, 0, 0, 0, 0, NULL);
4685 ok(Wnd2!= 0, "failed to create Wnd2 window\n");
4686
4687 SetFocus(ourWnd);
4688 SetActiveWindow(ourWnd);
4689
4691 ok(ret, "AttachThreadInput error %ld\n", GetLastError());
4692
4693 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
4694 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
4695
4696 SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
4697
4699 ok(ret, "AttachThreadInput error %ld\n", GetLastError());
4700 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
4701 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
4702
4704
4706 ok(ret, "AttachThreadInput error %ld\n", GetLastError());
4707
4708 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
4709 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
4710 SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
4711
4712 SetActiveWindow(Wnd2);
4713 SetFocus(Wnd2);
4714 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
4715 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
4716
4718
4720 ok(ret, "AttachThreadInput error %ld\n", GetLastError());
4721 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
4722 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
4723
4725
4727 ok(ret, "PostMessageA(WM_QUIT) error %ld\n", GetLastError());
4728
4729 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
4731
4735 wnd_event.attach_to = 0;
4737
4739 ok(hThread != NULL, "CreateThread failed, error %ld\n", GetLastError());
4740
4741 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
4743
4744 SetFocus(ourWnd);
4745 SetActiveWindow(ourWnd);
4746
4748 ok(ret, "AttachThreadInput error %ld\n", GetLastError());
4749
4750 ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
4751 ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
4752
4754
4756 ok(ret, "AttachThreadInput error %ld\n", GetLastError());
4757
4758 ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
4759 ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
4760
4762
4764 ok(ret, "AttachThreadInput error %ld\n", GetLastError());
4765
4766 ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
4767 ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
4768
4770
4771 SetFocus(Wnd2);
4772 SetActiveWindow(Wnd2);
4773 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
4774 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
4775
4777
4779 ok(ret, "AttachThreadInput error %ld\n", GetLastError());
4780
4781 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
4782 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
4783
4785
4787 ok(ret, "PostMessageA(WM_QUIT) error %ld\n", GetLastError());
4788
4789 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
4791
4795 wnd_event.attach_to = 0;
4797
4799 ok(hThread != NULL, "CreateThread failed, error %ld\n", GetLastError());
4800
4801 SetLastError(0xdeadbeef);
4803 ok(!ret, "AttachThreadInput succeeded\n");
4804 ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef) /* <= Win XP */,
4805 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
4806
4807 SetLastError(0xdeadbeef);
4809 ok(!ret, "AttachThreadInput succeeded\n");
4810 ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef) /* <= Win XP */,
4811 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
4812
4814
4815 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
4817
4819 ok(ret, "PostMessageA(WM_QUIT) error %ld\n", GetLastError());
4820
4821 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
4823
4827 wnd_event.attach_to = 0;
4829
4830 SetFocus(ourWnd);
4831 SetActiveWindow(ourWnd);
4832
4834 ok(hThread != NULL, "CreateThread failed, error %ld\n", GetLastError());
4835
4836 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
4838
4839 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
4840 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
4841
4843 ok(ret, "PostMessageA(WM_QUIT) error %ld\n", GetLastError());
4844
4845 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
4847
4853
4854 SetFocus(ourWnd);
4855 SetActiveWindow(ourWnd);
4856
4858 ok(hThread != NULL, "CreateThread failed, error %ld\n", GetLastError());
4859
4860 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
4862
4863 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
4864 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
4865
4867 ok(ret, "PostMessageA(WM_QUIT) error %ld\n", GetLastError());
4868
4869 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
4871 DestroyWindow(ourWnd);
4872 DestroyWindow(Wnd2);
4873}
4874
4876{
4881};
4882
4884{
4885 /* 0: not peeking in thread, no msg queue: GetKeyState / GetKeyboardState miss key press */
4886 {FALSE, TRUE, FALSE, FALSE},
4887 /* 1: peeking on thread init, not in main: GetKeyState / GetKeyboardState catch key press */
4888 /* - GetKeyboardState misses key press if called before GetKeyState */
4889 /* - GetKeyboardState catches key press, if called after GetKeyState */
4890 { TRUE, FALSE, FALSE, FALSE},
4891 /* 2: peeking on thread init, and in main: GetKeyState / GetKeyboardState catch key press */
4892 { TRUE, TRUE, FALSE, FALSE},
4893
4894 /* same tests but with SetKeyboardState called in main thread */
4895 /* 3: not peeking in thread, no msg queue: GetKeyState / GetKeyboardState miss key press */
4896 {FALSE, TRUE, TRUE, FALSE},
4897 /* 4: peeking on thread init, not in main: GetKeyState / GetKeyboardState catch key press */
4898 /* - GetKeyboardState misses key press if called before GetKeyState */
4899 /* - GetKeyboardState catches key press, if called after GetKeyState */
4900 { TRUE, FALSE, TRUE, FALSE},
4901 /* 5: peeking on thread init, and in main: GetKeyState / GetKeyboardState catch key press */
4902 { TRUE, TRUE, TRUE, FALSE},
4903
4904 /* same tests but with SetKeyboardState called in other thread */
4905 /* 6: not peeking in thread, no msg queue: GetKeyState / GetKeyboardState miss key press */
4906 {FALSE, TRUE, TRUE, TRUE},
4907 /* 7: peeking on thread init, not in main: GetKeyState / GetKeyboardState catch key press */
4908 /* - GetKeyboardState misses key press if called before GetKeyState */
4909 /* - GetKeyboardState catches key press, if called after GetKeyState */
4910 { TRUE, FALSE, TRUE, TRUE},
4911 /* 8: peeking on thread init, and in main: GetKeyState / GetKeyboardState catch key press */
4912 { TRUE, TRUE, TRUE, TRUE},
4913};
4914
4916{
4919};
4920
4921#define check_get_keyboard_state(i, j, c, x) check_get_keyboard_state_(i, j, c, x, __LINE__)
4922static void check_get_keyboard_state_(int i, int j, int c, int x, int line)
4923{
4924 unsigned char keystate[256];
4925 BOOL ret;
4926
4927 memset(keystate, 0, sizeof(keystate));
4929 ok_(__FILE__, line)(ret, "GetKeyboardState failed, %lu\n", GetLastError());
4930 ok_(__FILE__, line)(!(keystate['X'] & 0x80) == !x, "%d:%d: expected that X keystate is %s\n", i, j, x ? "set" : "unset");
4931 ok_(__FILE__, line)(!(keystate['C'] & 0x80) == !c, "%d:%d: expected that C keystate is %s\n", i, j, c ? "set" : "unset");
4932
4933 /* calling it twice shouldn't change */
4934 memset(keystate, 0, sizeof(keystate));
4936 ok_(__FILE__, line)(ret, "GetKeyboardState failed, %lu\n", GetLastError());
4937 ok_(__FILE__, line)(!(keystate['X'] & 0x80) == !x, "%d:%d: expected that X keystate is %s\n", i, j, x ? "set" : "unset");
4938 ok_(__FILE__, line)(!(keystate['C'] & 0x80) == !c, "%d:%d: expected that C keystate is %s\n", i, j, c ? "set" : "unset");
4939}
4940
4941#define check_get_key_state(i, j, c, x) check_get_key_state_(i, j, c, x, __LINE__)
4942static void check_get_key_state_(int i, int j, int c, int x, int line)
4943{
4944 SHORT state;
4945
4946 state = GetKeyState('X');
4947 ok_(__FILE__, line)(!(state & 0x8000) == !x, "%d:%d: expected that X highest bit is %s, got %#x\n", i, j, x ? "set" : "unset", state);
4948 ok_(__FILE__, line)(!(state & 0x007e), "%d:%d: expected that X undefined bits are unset, got %#x\n", i, j, state);
4949
4950 state = GetKeyState('C');
4951 ok_(__FILE__, line)(!(state & 0x8000) == !c, "%d:%d: expected that C highest bit is %s, got %#x\n", i, j, c ? "set" : "unset", state);
4952 ok_(__FILE__, line)(!(state & 0x007e), "%d:%d: expected that C undefined bits are unset, got %#x\n", i, j, state);
4953}
4954
4956{
4959 HANDLE *semaphores = params->semaphores;
4960 DWORD result;
4961 BYTE keystate[256] = {0};
4962 BOOL has_queue;
4963 BOOL expect_x, expect_c;
4964 MSG msg;
4965 int i = params->index, j;
4966
4968 has_queue = test->peek_message || test->set_keyboard_state;
4969
4970 if (test->peek_message)
4971 {
4972 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
4973 ok(!is_keyboard_message(msg.message), "%d: PeekMessageA got keyboard message.\n", i);
4974 }
4975
4976 for (j = 0; j < 4; ++j)
4977 {
4978 /* initialization */
4979 ReleaseSemaphore(semaphores[0], 1, NULL);
4980 result = WaitForSingleObject(semaphores[1], 1000);
4981 ok(result == WAIT_OBJECT_0, "%d:%d: WaitForSingleObject returned %lu\n", i, j, result);
4982
4983 if (test->set_keyboard_state)
4984 {
4985 keystate['C'] = 0xff;
4987 }
4988
4989 /* key pressed */
4990 ReleaseSemaphore(semaphores[0], 1, NULL);
4991 result = WaitForSingleObject(semaphores[1], 1000);
4992 ok(result == WAIT_OBJECT_0, "%d:%d: WaitForSingleObject returned %lu\n", i, j, result);
4993
4994 if (test->set_keyboard_state) expect_x = TRUE;
4995 else if (!has_queue && j == 0) expect_x = FALSE;
4996 else expect_x = TRUE;
4997
4998 if (test->set_keyboard_state) expect_c = TRUE;
4999 else expect_c = FALSE;
5000
5001 check_get_keyboard_state(i, j, expect_c, FALSE);
5002 check_get_key_state(i, j, expect_c, expect_x);
5003 check_get_keyboard_state(i, j, expect_c, expect_x);
5004
5005 /* key released */
5006 ReleaseSemaphore(semaphores[0], 1, NULL);
5007 result = WaitForSingleObject(semaphores[1], 1000);
5008 ok(result == WAIT_OBJECT_0, "%d: WaitForSingleObject returned %lu\n", i, result);
5009
5010 check_get_keyboard_state(i, j, expect_c, expect_x);
5011 check_get_key_state(i, j, expect_c, FALSE);
5012 check_get_keyboard_state(i, j, expect_c, FALSE);
5013 }
5014
5015 return 0;
5016}
5017
5018static void test_GetKeyState(void)
5019{
5021 HANDLE thread;
5022 DWORD result;
5023 BYTE keystate[256] = {0};
5024 BOOL expect_x, expect_c;
5025 HWND hwnd;
5026 MSG msg;
5027 int i, j;
5028
5029 BOOL us_kbd = (GetKeyboardLayout(0) == (HKL)(ULONG_PTR)0x04090409);
5030 if (!us_kbd)
5031 {
5032 skip("skipping test with inconsistent results on non-us keyboard\n");
5033 return;
5034 }
5035
5036 params.semaphores[0] = CreateSemaphoreA(NULL, 0, 1, NULL);
5037 ok(params.semaphores[0] != NULL, "CreateSemaphoreA failed %lu\n", GetLastError());
5038 params.semaphores[1] = CreateSemaphoreA(NULL, 0, 1, NULL);
5039 ok(params.semaphores[1] != NULL, "CreateSemaphoreA failed %lu\n", GetLastError());
5040
5041 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5042 10, 10, 200, 200, NULL, NULL, NULL, NULL);
5043 ok(hwnd != NULL, "CreateWindowA failed %lu\n", GetLastError());
5045
5046 for (i = 0; i < ARRAY_SIZE(get_key_state_tests); ++i)
5047 {
5049
5050 params.index = i;
5052 ok(thread != NULL, "CreateThread failed %lu\n", GetLastError());
5053
5054 for (j = 0; j < 4; ++j)
5055 {
5056 /* initialization */
5057 result = WaitForSingleObject(params.semaphores[0], 1000);
5058 ok(result == WAIT_OBJECT_0, "%d:%d: WaitForSingleObject returned %lu\n", i, j, result);
5059
5061 SetFocus(hwnd);
5063
5064 ReleaseSemaphore(params.semaphores[1], 1, NULL);
5065
5066 /* key pressed */
5067 result = WaitForSingleObject(params.semaphores[0], 1000);
5068 ok(result == WAIT_OBJECT_0, "%d:%d: WaitForSingleObject returned %lu\n", i, j, result);
5069
5070 keybd_event('X', 0, 0, 0);
5071 if (test->set_keyboard_state_main)
5072 {
5073 expect_c = TRUE;
5074 keystate['C'] = 0xff;
5076 }
5077 else expect_c = FALSE;
5078
5079 check_get_keyboard_state(i, j, expect_c, FALSE);
5080 check_get_key_state(i, j, expect_c, FALSE);
5081 check_get_keyboard_state(i, j, expect_c, FALSE);
5082
5083 if (test->peek_message_main) while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
5084
5085 if (test->peek_message_main) expect_x = TRUE;
5086 else expect_x = FALSE;
5087
5088 check_get_keyboard_state(i, j, expect_c, expect_x);
5089 check_get_key_state(i, j, expect_c, expect_x);
5090 check_get_keyboard_state(i, j, expect_c, expect_x);
5091
5092 ReleaseSemaphore(params.semaphores[1], 1, NULL);
5093
5094 /* key released */
5095 result = WaitForSingleObject(params.semaphores[0], 1000);
5096 ok(result == WAIT_OBJECT_0, "%d:%d: WaitForSingleObject returned %lu\n", i, j, result);
5097
5098 keybd_event('X', 0, KEYEVENTF_KEYUP, 0);
5099 if (test->set_keyboard_state_main)
5100 {
5101 expect_x = FALSE;
5102 keystate['C'] = 0x00;
5104 }
5105
5106 check_get_keyboard_state(i, j, FALSE, expect_x);
5107 check_get_key_state(i, j, FALSE, expect_x);
5108 check_get_keyboard_state(i, j, FALSE, expect_x);
5109
5110 if (test->peek_message_main) while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
5111
5115
5116 ReleaseSemaphore(params.semaphores[1], 1, NULL);
5117 }
5118
5120 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result);
5122 }
5123
5125 CloseHandle(params.semaphores[0]);
5126 CloseHandle(params.semaphores[1]);
5127}
5128
5129static void test_OemKeyScan(void)
5130{
5131 DWORD ret, expect, vkey, scan;
5132 WCHAR oem, wchr;
5133 char oem_char;
5134
5135 BOOL us_kbd = (GetKeyboardLayout(0) == (HKL)(ULONG_PTR)0x04090409);
5136 if (!us_kbd)
5137 {
5138 skip("skipping test with inconsistent results on non-us keyboard\n");
5139 return;
5140 }
5141
5142 for (oem = 0; oem < 0x200; oem++)
5143 {
5144 ret = OemKeyScan( oem );
5145
5146 oem_char = LOBYTE( oem );
5147 /* OemKeyScan returns -1 for any character that cannot be mapped,
5148 * whereas OemToCharBuff changes unmappable characters to question
5149 * marks. The ASCII characters 0-127, including the real question mark
5150 * character, are all mappable and are the same in all OEM codepages. */
5151 if (!OemToCharBuffW( &oem_char, &wchr, 1 ) || (wchr == '?' && oem_char < 0))
5152 expect = -1;
5153 else
5154 {
5155 vkey = VkKeyScanW( wchr );
5156 scan = MapVirtualKeyW( LOBYTE( vkey ), MAPVK_VK_TO_VSC );
5157 if (!scan)
5158 expect = -1;
5159 else
5160 {
5161 vkey &= 0xff00;
5162 vkey <<= 8;
5163 expect = vkey | scan;
5164 }
5165 }
5166 ok( ret == expect, "%04x: got %08lx expected %08lx\n", oem, ret, expect );
5167 }
5168}
5169
5170static INPUT_MESSAGE_SOURCE expect_src;
5171
5173{
5174 INPUT_MESSAGE_SOURCE source;
5175 MSG msg;
5176
5177 ok( pGetCurrentInputMessageSource( &source ), "GetCurrentInputMessageSource failed\n" );
5178 switch (message)
5179 {
5180 case WM_KEYDOWN:
5181 case WM_KEYUP:
5182 case WM_SYSKEYDOWN:
5183 case WM_SYSKEYUP:
5184 case WM_MOUSEMOVE:
5185 case WM_LBUTTONDOWN:
5186 case WM_LBUTTONUP:
5187 case WM_RBUTTONDOWN:
5188 case WM_RBUTTONUP:
5189 ok( source.deviceType == expect_src.deviceType || /* also accept system-generated WM_MOUSEMOVE */
5190 (message == WM_MOUSEMOVE && source.deviceType == IMDT_UNAVAILABLE),
5191 "%x: wrong deviceType %x/%x\n", message, source.deviceType, expect_src.deviceType );
5192 ok( source.originId == expect_src.originId ||
5193 (message == WM_MOUSEMOVE && source.originId == IMO_SYSTEM),
5194 "%x: wrong originId %x/%x\n", message, source.originId, expect_src.originId );
5195 SendMessageA( hwnd, WM_USER, 0, 0 );
5196 PostMessageA( hwnd, WM_USER, 0, 0 );
5198 ok( source.deviceType == expect_src.deviceType || /* also accept system-generated WM_MOUSEMOVE */
5199 (message == WM_MOUSEMOVE && source.deviceType == IMDT_UNAVAILABLE),
5200 "%x: wrong deviceType %x/%x\n", message, source.deviceType, expect_src.deviceType );
5201 ok( source.originId == expect_src.originId ||
5202 (message == WM_MOUSEMOVE && source.originId == IMO_SYSTEM),
5203 "%x: wrong originId %x/%x\n", message, source.originId, expect_src.originId );
5204 break;
5205 default:
5206 ok( source.deviceType == IMDT_UNAVAILABLE, "%x: wrong deviceType %x\n",
5207 message, source.deviceType );
5208 ok( source.originId == 0, "%x: wrong originId %x\n", message, source.originId );
5209 break;
5210 }
5211
5212 return DefWindowProcA( hwnd, message, wp, lp );
5213}
5214
5216{
5217 WNDCLASSA cls;
5218 INPUT inputs[2];
5219 HWND hwnd;
5220 RECT rc;
5221 MSG msg;
5222
5223 cls.style = 0;
5225 cls.cbClsExtra = 0;
5226 cls.cbWndExtra = 0;
5227 cls.hInstance = GetModuleHandleA(0);
5228 cls.hIcon = 0;
5230 cls.hbrBackground = 0;
5231 cls.lpszMenuName = NULL;
5232 cls.lpszClassName = "message source class";
5233 RegisterClassA(&cls);
5234 hwnd = CreateWindowA( cls.lpszClassName, "test", WS_OVERLAPPED, 0, 0, 100, 100,
5235 0, 0, 0, 0 );
5237 UpdateWindow( hwnd );
5239 SetFocus( hwnd );
5240
5241 inputs[0].type = INPUT_KEYBOARD;
5242 inputs[0].ki.dwExtraInfo = 0;
5243 inputs[0].ki.time = 0;
5244 inputs[0].ki.wVk = 0;
5245 inputs[0].ki.wScan = 0x3c0;
5246 inputs[0].ki.dwFlags = KEYEVENTF_UNICODE;
5247 inputs[1] = inputs[0];
5248 inputs[1].ki.dwFlags |= KEYEVENTF_KEYUP;
5249
5250 expect_src.deviceType = IMDT_UNAVAILABLE;
5251 expect_src.originId = IMO_UNAVAILABLE;
5252 SendMessageA( hwnd, WM_KEYDOWN, 0, 0 );
5253 SendMessageA( hwnd, WM_MOUSEMOVE, 0, 0 );
5254
5255 SendInput( 2, inputs, sizeof(INPUT) );
5256 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
5257 {
5258 expect_src.deviceType = IMDT_KEYBOARD;
5259 expect_src.originId = IMO_INJECTED;
5262 }
5263 GetWindowRect( hwnd, &rc );
5264 simulate_click( TRUE, (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2 );
5265 simulate_click( FALSE, (rc.left + rc.right) / 2 + 1, (rc.top + rc.bottom) / 2 + 1 );
5266 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
5267 {
5268 expect_src.deviceType = IMDT_MOUSE;
5269 expect_src.originId = IMO_INJECTED;
5272 }
5273
5274 expect_src.deviceType = IMDT_UNAVAILABLE;
5275 expect_src.originId = IMO_UNAVAILABLE;
5276 SendMessageA( hwnd, WM_KEYDOWN, 0, 0 );
5278 PostMessageA( hwnd, WM_KEYUP, 0, 0 );
5279 PostMessageA( hwnd, WM_LBUTTONUP, 0, 0 );
5280 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
5281 {
5284 }
5285
5286 expect_src.deviceType = IMDT_UNAVAILABLE;
5287 expect_src.originId = IMO_SYSTEM;
5288 SetCursorPos( (rc.left + rc.right) / 2 - 1, (rc.top + rc.bottom) / 2 - 1 );
5289 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
5290 {
5293 }
5294
5297}
5298
5300{
5302 ok(ret == FALSE, "Unregistering NULL Device Notification returned: %d\n", ret);
5303}
5304
5305static void test_SendInput( WORD vkey, WCHAR wch, HKL hkl )
5306{
5307 const struct user_call broken_sequence[] =
5308 {
5309 {.func = MSG_TEST_WIN, .message = {.msg = WM_KEYDOWN, .wparam = vkey, .lparam = MAKELONG(1, 0)}},
5310 {.func = MSG_TEST_WIN, .message = {.msg = WM_CHAR, .wparam = wch, .lparam = MAKELONG(1, 0)}},
5311 {.func = MSG_TEST_WIN, .message = {.msg = WM_KEYUP, .wparam = vkey, .lparam = MAKELONG(1, KF_UP | KF_REPEAT)}},
5312 {0}
5313 };
5314
5315 INPUT input[16];
5316 UINT res, i;
5317 HWND hwnd;
5318
5319 hwnd = CreateWindowW( L"static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL );
5320 ok_ne( NULL, hwnd, HWND, "%p" );
5321 wait_messages( 100, FALSE );
5322
5323 /* If we have had a spurious layout change, wch may be incorrect. */
5324 if (GetKeyboardLayout( 0 ) != hkl)
5325 {
5326 win_skip( "Spurious keyboard layout changed detected (expected: %p got: %p)\n",
5327 hkl, GetKeyboardLayout( 0 ) );
5328 ok_ret( 1, DestroyWindow( hwnd ) );
5329 wait_messages( 100, FALSE );
5331 return;
5332 }
5333
5334 SetLastError( 0xdeadbeef );
5335 ok_ret( 0, SendInput( 0, NULL, 0 ) );
5337 SetLastError( 0xdeadbeef );
5338 ok_ret( 0, SendInput( 1, NULL, 0 ) );
5340 SetLastError( 0xdeadbeef );
5341 ok_ret( 0, SendInput( 1, NULL, sizeof(*input) ) );
5343 "GetLastError returned %#lx\n", GetLastError() );
5344 SetLastError( 0xdeadbeef );
5345 ok_ret( 0, SendInput( 0, input, sizeof(*input) ) );
5347 SetLastError( 0xdeadbeef );
5348 ok_ret( 0, SendInput( 0, NULL, sizeof(*input) ) );
5350
5351 memset( input, 0, sizeof(input) );
5352 SetLastError( 0xdeadbeef );
5353 ok_ret( 1, SendInput( 1, input, sizeof(*input) ) );
5354 ok_ret( 0xdeadbeef, GetLastError() );
5355 SetLastError( 0xdeadbeef );
5356 ok_ret( 16, SendInput( 16, input, sizeof(*input) ) );
5357 ok_ret( 0xdeadbeef, GetLastError() );
5358
5359 SetLastError( 0xdeadbeef );
5360 ok_ret( 0, SendInput( 1, input, 0 ) );
5362 SetLastError( 0xdeadbeef );
5363 ok_ret( 0, SendInput( 1, input, sizeof(*input) + 1 ) );
5365 SetLastError( 0xdeadbeef );
5366 ok_ret( 0, SendInput( 1, input, sizeof(*input) - 1 ) );
5368
5369 for (i = 0; i < ARRAY_SIZE(input); ++i) input[i].type = INPUT_KEYBOARD;
5370 SetLastError( 0xdeadbeef );
5371 ok_ret( 0, SendInput( 16, input, offsetof( INPUT, ki ) + sizeof(KEYBDINPUT) ) );
5373 SetLastError( 0xdeadbeef );
5374 ok_ret( 16, SendInput( 16, input, sizeof(*input) ) );
5375 ok_ret( 0xdeadbeef, GetLastError() );
5376
5377 for (i = 0; i < ARRAY_SIZE(input); ++i) input[i].type = INPUT_HARDWARE;
5378 SetLastError( 0xdeadbeef );
5379 ok_ret( 0, SendInput( 16, input, offsetof( INPUT, hi ) + sizeof(HARDWAREINPUT) ) );
5381
5382 wait_messages( 100, FALSE );
5385
5386 input[0].hi.uMsg = WM_KEYDOWN;
5387 input[0].hi.wParamL = 0;
5388 input[0].hi.wParamH = 'A';
5389 input[1].hi.uMsg = WM_KEYUP;
5390 input[1].hi.wParamL = 0;
5391 input[1].hi.wParamH = 'A' | 0xc000;
5392 SetLastError( 0xdeadbeef );
5393 res = SendInput( 16, input, sizeof(*input) );
5395 broken(res == 16 && GetLastError() == 0xdeadbeef) /* 32bit */,
5396 "SendInput returned %u, error %#lx\n", res, GetLastError() );
5397 wait_messages( 100, TRUE );
5399
5400 memset( input, 0, sizeof(input) );
5401 input[0].type = INPUT_HARDWARE;
5402 input[1].type = INPUT_KEYBOARD;
5403 input[1].ki.wVk = vkey;
5404 input[1].ki.dwFlags = 0;
5405 input[2].type = INPUT_KEYBOARD;
5406 input[2].ki.wVk = vkey;
5407 input[2].ki.dwFlags = KEYEVENTF_KEYUP;
5408 SetLastError( 0xdeadbeef );
5409 res = SendInput( 16, input, sizeof(*input) );
5411 broken(res == 16 && GetLastError() == 0xdeadbeef),
5412 "SendInput returned %u, error %#lx\n", res, GetLastError() );
5413 wait_messages( 100, TRUE );
5414 if (broken(res == 16)) ok_seq( broken_sequence );
5415 else ok_seq( empty_sequence );
5416
5417 for (i = 0; i < ARRAY_SIZE(input); ++i) input[i].type = INPUT_HARDWARE + 1;
5418 SetLastError( 0xdeadbeef );
5419 ok_ret( 16, SendInput( 16, input, sizeof(*input) ) );
5420 ok_ret( 0xdeadbeef, GetLastError() );
5421 wait_messages( 100, TRUE );
5423
5424 ok_ret( 1, DestroyWindow( hwnd ) );
5425 wait_messages( 100, FALSE );
5428}
5429
5430#define check_pointer_info( a, b ) check_pointer_info_( __LINE__, a, b )
5431static void check_pointer_info_( int line, const POINTER_INFO *actual, const POINTER_INFO *expected )
5432{
5433 check_member( *actual, *expected, "%#lx", pointerType );
5434 check_member( *actual, *expected, "%#x", pointerId );
5435 check_member( *actual, *expected, "%#x", frameId );
5436 check_member( *actual, *expected, "%#x", pointerFlags );
5437 check_member( *actual, *expected, "%p", sourceDevice );
5438 check_member( *actual, *expected, "%p", hwndTarget );
5439 check_member( *actual, *expected, "%+ld", ptPixelLocation.x );
5440 check_member( *actual, *expected, "%+ld", ptPixelLocation.y );
5441 check_member( *actual, *expected, "%+ld", ptHimetricLocation.x );
5442 check_member( *actual, *expected, "%+ld", ptHimetricLocation.y );
5443 check_member( *actual, *expected, "%+ld", ptPixelLocationRaw.x );
5444 check_member( *actual, *expected, "%+ld", ptPixelLocationRaw.y );
5445 check_member( *actual, *expected, "%+ld", ptHimetricLocationRaw.x );
5446 check_member( *actual, *expected, "%+ld", ptHimetricLocationRaw.y );
5447 check_member( *actual, *expected, "%lu", dwTime );
5448 check_member( *actual, *expected, "%u", historyCount );
5449 check_member( *actual, *expected, "%#x", InputData );
5450 check_member( *actual, *expected, "%#lx", dwKeyStates );
5451 check_member( *actual, *expected, "%I64u", PerformanceCount );
5452 check_member( *actual, *expected, "%#x", ButtonChangeType );
5453}
5454
5456{
5457 POINTER_INFO pointer_info;
5458 HWND hwnd;
5459 BOOL ret;
5460
5461 hwnd = CreateWindowW( L"test", L"test name", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 200,
5462 200, 0, 0, NULL, 0 );
5463
5464 memset( &pointer_info, 0xcd, sizeof(pointer_info) );
5465 ret = pGetPointerInfo( 1, &pointer_info );
5466 ok( !ret, "GetPointerInfo succeeded\n" );
5467 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() );
5468
5470
5471 return 0;
5472}
5473
5474static void test_GetPointerInfo( BOOL mouse_in_pointer_enabled )
5475{
5476 POINTER_INFO pointer_info[4], expect_pointer;
5477 void *invalid_ptr = (void *)0xdeadbeef;
5478 UINT32 entry_count, pointer_count;
5479 POINTER_INPUT_TYPE type;
5480 WNDCLASSW cls =
5481 {
5483 .hInstance = GetModuleHandleW( NULL ),
5484 .hbrBackground = GetStockObject( WHITE_BRUSH ),
5485 .lpszClassName = L"test",
5486 };
5487 HANDLE thread;
5488 ATOM class;
5489 DWORD res;
5490 HWND hwnd;
5491 BOOL ret;
5492
5493 if (!pGetPointerType)
5494 {
5495 todo_wine
5496 win_skip( "GetPointerType not found, skipping tests\n" );
5497 return;
5498 }
5499
5500 SetLastError( 0xdeadbeef );
5501 ret = pGetPointerType( 1, NULL );
5502 ok( !ret, "GetPointerType succeeded\n" );
5503 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() );
5504 SetLastError( 0xdeadbeef );
5505 ret = pGetPointerType( 0xdead, &type );
5506 todo_wine
5507 ok( !ret, "GetPointerType succeeded\n" );
5508 todo_wine
5509 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() );
5510 ret = pGetPointerType( 1, &type );
5511 ok( ret, "GetPointerType failed, error %lu\n", GetLastError() );
5512 ok( type == PT_MOUSE, " type %ld\n", type );
5513
5514 if (!pGetPointerInfo)
5515 {
5516 todo_wine
5517 win_skip( "GetPointerInfo not found, skipping tests\n" );
5518 return;
5519 }
5520
5521 class = RegisterClassW( &cls );
5522 ok( class, "RegisterClassW failed: %lu\n", GetLastError() );
5523
5524 ret = pGetPointerInfo( 1, invalid_ptr );
5525 ok( !ret, "GetPointerInfo succeeded\n" );
5526 todo_wine
5528 "got error %lu\n", GetLastError() );
5529
5530 memset( pointer_info, 0xcd, sizeof(pointer_info) );
5531 ret = pGetPointerInfo( 1, pointer_info );
5532 ok( !ret, "GetPointerInfo succeeded\n" );
5533 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() );
5534
5535 SetCursorPos( 500, 500 ); /* avoid generating mouse message on window creation */
5536
5537 hwnd = CreateWindowW( L"test", L"test name", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 200,
5538 200, 0, 0, NULL, 0 );
5540
5541 memset( pointer_info, 0xcd, sizeof(pointer_info) );
5542 ret = pGetPointerInfo( 1, pointer_info );
5543 ok( !ret, "GetPointerInfo succeeded\n" );
5544 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() );
5545
5546 SetCursorPos( 200, 200 );
5548 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
5550 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
5552 mouse_event( MOUSEEVENTF_MOVE, 10, 10, 0, 0 );
5554
5555 memset( pointer_info, 0xcd, sizeof(pointer_info) );
5556 ret = pGetPointerInfo( 0xdead, pointer_info );
5557 ok( !ret, "GetPointerInfo succeeded\n" );
5558 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() );
5559
5560 memset( pointer_info, 0xcd, sizeof(pointer_info) );
5561 ret = pGetPointerInfo( 1, pointer_info );
5562 todo_wine_if(mouse_in_pointer_enabled)
5563 ok( ret == mouse_in_pointer_enabled, "GetPointerInfo failed, error %lu\n", GetLastError() );
5564 if (!mouse_in_pointer_enabled)
5565 {
5566 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() );
5567 return;
5568 }
5569
5570 todo_wine
5571 ok( pointer_info[0].pointerType == PT_MOUSE, "got pointerType %lu\n", pointer_info[0].pointerType );
5572 todo_wine
5573 ok( pointer_info[0].pointerId == 1, "got pointerId %u\n", pointer_info[0].pointerId );
5574 ok( !!pointer_info[0].frameId, "got frameId %u\n", pointer_info[0].frameId );
5575 todo_wine
5576 ok( pointer_info[0].pointerFlags == (0x20000 | POINTER_MESSAGE_FLAG_INRANGE | POINTER_MESSAGE_FLAG_PRIMARY),
5577 "got pointerFlags %#x\n", pointer_info[0].pointerFlags );
5578 todo_wine
5579 ok( pointer_info[0].sourceDevice == INVALID_HANDLE_VALUE || broken(!!pointer_info[0].sourceDevice) /* < w10 & 32bit */,
5580 "got sourceDevice %p\n", pointer_info[0].sourceDevice );
5581 todo_wine
5582 ok( pointer_info[0].hwndTarget == hwnd, "got hwndTarget %p\n", pointer_info[0].hwndTarget );
5583 ok( !!pointer_info[0].ptPixelLocation.x, "got ptPixelLocation %s\n", wine_dbgstr_point( &pointer_info[0].ptPixelLocation ) );
5584 ok( !!pointer_info[0].ptPixelLocation.y, "got ptPixelLocation %s\n", wine_dbgstr_point( &pointer_info[0].ptPixelLocation ) );
5585 ok( !!pointer_info[0].ptHimetricLocation.x, "got ptHimetricLocation %s\n", wine_dbgstr_point( &pointer_info[0].ptHimetricLocation ) );
5586 ok( !!pointer_info[0].ptHimetricLocation.y, "got ptHimetricLocation %s\n", wine_dbgstr_point( &pointer_info[0].ptHimetricLocation ) );
5587 ok( !!pointer_info[0].ptPixelLocationRaw.x, "got ptPixelLocationRaw %s\n", wine_dbgstr_point( &pointer_info[0].ptPixelLocationRaw ) );
5588 ok( !!pointer_info[0].ptPixelLocationRaw.y, "got ptPixelLocationRaw %s\n", wine_dbgstr_point( &pointer_info[0].ptPixelLocationRaw ) );
5589 ok( !!pointer_info[0].ptHimetricLocationRaw.x, "got ptHimetricLocationRaw %s\n", wine_dbgstr_point( &pointer_info[0].ptHimetricLocationRaw ) );
5590 ok( !!pointer_info[0].ptHimetricLocationRaw.y, "got ptHimetricLocationRaw %s\n", wine_dbgstr_point( &pointer_info[0].ptHimetricLocationRaw ) );
5591 ok( !!pointer_info[0].dwTime, "got dwTime %lu\n", pointer_info[0].dwTime );
5592 todo_wine
5593 ok( pointer_info[0].historyCount == 1, "got historyCount %u\n", pointer_info[0].historyCount );
5594 todo_wine
5595 ok( pointer_info[0].InputData == 0, "got InputData %u\n", pointer_info[0].InputData );
5596 todo_wine
5597 ok( pointer_info[0].dwKeyStates == 0, "got dwKeyStates %lu\n", pointer_info[0].dwKeyStates );
5598 ok( !!pointer_info[0].PerformanceCount, "got PerformanceCount %I64u\n", pointer_info[0].PerformanceCount );
5599 todo_wine
5600 ok( pointer_info[0].ButtonChangeType == 0, "got ButtonChangeType %u\n", pointer_info[0].ButtonChangeType );
5601
5603 res = WaitForSingleObject( thread, 5000 );
5604 ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() );
5605
5606 expect_pointer = pointer_info[0];
5607
5608 memset( pointer_info, 0xa5, sizeof(pointer_info) );
5609 entry_count = pointer_count = 2;
5610 if (!pGetPointerFrameInfo) ret = FALSE;
5611 else ret = pGetPointerFrameInfo( 1, &pointer_count, pointer_info );
5612 todo_wine_if(!pGetPointerFrameInfo)
5613 ok( ret, "GetPointerFrameInfo failed, error %lu\n", GetLastError() );
5614 todo_wine_if(!pGetPointerFrameInfo)
5615 ok( pointer_count == 1, "got pointer_count %u\n", pointer_count );
5616 todo_wine_if(!pGetPointerFrameInfo)
5617 check_pointer_info( &pointer_info[0], &expect_pointer );
5618 memset( pointer_info, 0xa5, sizeof(pointer_info) );
5619 entry_count = pointer_count = 2;
5620 if (!pGetPointerInfoHistory) ret = FALSE;
5621 else ret = pGetPointerInfoHistory( 1, &entry_count, pointer_info );
5622 todo_wine_if(!pGetPointerInfoHistory)
5623 ok( ret, "GetPointerInfoHistory failed, error %lu\n", GetLastError() );
5624 todo_wine_if(!pGetPointerInfoHistory)
5625 ok( entry_count == 1, "got entry_count %u\n", entry_count );
5626 todo_wine_if(!pGetPointerInfoHistory)
5627 check_pointer_info( &pointer_info[0], &expect_pointer );
5628 memset( pointer_info, 0xa5, sizeof(pointer_info) );
5629 entry_count = pointer_count = 2;
5630 if (!pGetPointerFrameInfoHistory) ret = FALSE;
5631 else ret = pGetPointerFrameInfoHistory( 1, &entry_count, &pointer_count, pointer_info );
5632 todo_wine_if(!pGetPointerFrameInfoHistory)
5633 ok( ret, "GetPointerFrameInfoHistory failed, error %lu\n", GetLastError() );
5634 todo_wine_if(!pGetPointerFrameInfoHistory)
5635 ok( entry_count == 1, "got pointer_count %u\n", pointer_count );
5636 todo_wine_if(!pGetPointerFrameInfoHistory)
5637 ok( pointer_count == 1, "got pointer_count %u\n", pointer_count );
5638 todo_wine_if(!pGetPointerFrameInfoHistory)
5639 check_pointer_info( &pointer_info[0], &expect_pointer );
5640
5642
5644 ok( ret, "UnregisterClassW failed: %lu\n", GetLastError() );
5645}
5646
5647static void test_EnableMouseInPointer( const char *arg )
5648{
5649 DWORD enable = strtoul( arg, 0, 10 );
5650 BOOL ret;
5651
5652 winetest_push_context( "enable %lu", enable );
5653
5654 ret = pEnableMouseInPointer( enable );
5655 todo_wine
5656 ok( ret, "EnableMouseInPointer failed, error %lu\n", GetLastError() );
5657
5658 SetLastError( 0xdeadbeef );
5659 ret = pEnableMouseInPointer( !enable );
5660 ok( !ret, "EnableMouseInPointer succeeded\n" );
5661 todo_wine
5662 ok( GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError() );
5663 ret = pIsMouseInPointerEnabled();
5665 ok( ret == enable, "IsMouseInPointerEnabled returned %u, error %lu\n", ret, GetLastError() );
5666
5667 ret = pEnableMouseInPointer( enable );
5668 todo_wine
5669 ok( ret, "EnableMouseInPointer failed, error %lu\n", GetLastError() );
5670 ret = pIsMouseInPointerEnabled();
5672 ok( ret == enable, "IsMouseInPointerEnabled returned %u, error %lu\n", ret, GetLastError() );
5673
5675
5677}
5678
5680{
5681 RECT *virtual_rect = (RECT *)lp;
5682 UnionRect( virtual_rect, virtual_rect, rect );
5683 return TRUE;
5684}
5685
5687{
5688 RECT rect = {0};
5690 return rect;
5691}
5692
5693static void test_ClipCursor_dirty( const char *arg )
5694{
5695 RECT rect, expect_rect = {1, 2, 3, 4};
5696
5697 /* check leaked clip rect from another desktop or process */
5698 ok_ret( 1, GetClipCursor( &rect ) );
5699 todo_wine_if( !strcmp( arg, "desktop" ) )
5701
5702 /* intentionally leaking clipping rect */
5703}
5704
5706{
5707 RECT rect, clip_rect, virtual_rect = get_virtual_screen_rect();
5708 HWND hwnd;
5709
5710 clip_rect.left = clip_rect.right = (virtual_rect.left + virtual_rect.right) / 2;
5711 clip_rect.top = clip_rect.bottom = (virtual_rect.top + virtual_rect.bottom) / 2;
5712
5713 /* creating a window doesn't reset clipping rect */
5714 hwnd = CreateWindowW( L"static", NULL, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0,
5715 NULL, NULL, NULL, NULL );
5716 ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() );
5717 ok_ret( 1, GetClipCursor( &rect ) );
5718 ok_rect( clip_rect, rect );
5719
5720 /* setting a window foreground does, even from the same process */
5722 ok_ret( 1, GetClipCursor( &rect ) );
5723 ok_rect( virtual_rect, rect );
5724
5725 /* destroying the window doesn't reset the clipping rect */
5726 InflateRect( &clip_rect, +1, +1 );
5727 ok_ret( 1, ClipCursor( &clip_rect ) );
5728 ok_ret( 1, DestroyWindow( hwnd ) );
5729 ok_ret( 1, GetClipCursor( &rect ) );
5730 ok_rect( clip_rect, rect );
5731
5732 /* intentionally leaking clipping rect */
5733 return 0;
5734}
5735
5737{
5738 RECT rect, clip_rect, virtual_rect = get_virtual_screen_rect();
5739 HWND hwnd, tmp_hwnd;
5740 HANDLE thread;
5741
5742 clip_rect.left = clip_rect.right = (virtual_rect.left + virtual_rect.right) / 2;
5743 clip_rect.top = clip_rect.bottom = (virtual_rect.top + virtual_rect.bottom) / 2;
5744
5745 ok_ret( 1, GetClipCursor( &rect ) );
5746 ok_rect( clip_rect, rect );
5747
5748 /* creating an invisible window doesn't reset clip cursor */
5749 hwnd = CreateWindowW( L"static", NULL, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0,
5750 NULL, NULL, NULL, NULL );
5751 ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() );
5752 ok_ret( 1, DestroyWindow( hwnd ) );
5753 ok_ret( 1, GetClipCursor( &rect ) );
5754 ok_rect( clip_rect, rect );
5755
5756 /* setting a window foreground, even invisible, resets it */
5757 hwnd = CreateWindowW( L"static", NULL, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0,
5758 NULL, NULL, NULL, NULL );
5759 ok( !!hwnd, "CreateWindowW failed, error %lu\n", GetLastError() );
5761 ok_ret( 1, GetClipCursor( &rect ) );
5762 ok_rect( virtual_rect, rect );
5763
5764 ok_ret( 1, ClipCursor( &clip_rect ) );
5765
5766 /* creating and setting another window foreground doesn't reset it */
5767 tmp_hwnd = CreateWindowW( L"static", NULL, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0,
5768 NULL, NULL, NULL, NULL );
5769 ok( !!tmp_hwnd, "CreateWindowW failed, error %lu\n", GetLastError() );
5770 ok_ret( 1, SetForegroundWindow( tmp_hwnd ) );
5771 ok_ret( 1, DestroyWindow( tmp_hwnd ) );
5772 ok_ret( 1, GetClipCursor( &rect ) );
5773 ok_rect( clip_rect, rect );
5774
5775 /* but changing foreground to another thread in the same process reset it */
5777 ok( !!thread, "CreateThread failed, error %lu\n", GetLastError() );
5778 msg_wait_for_events( 1, &thread, 5000 );
5779
5780 /* thread exit and foreground window destruction doesn't reset the clipping rect */
5781 InflateRect( &clip_rect, +1, +1 );
5782 ok_ret( 1, DestroyWindow( hwnd ) );
5783 ok_ret( 1, GetClipCursor( &rect ) );
5784 ok_rect( clip_rect, rect );
5785
5786 /* intentionally leaking clipping rect */
5787}
5788
5789static void test_ClipCursor_desktop( char **argv )
5790{
5791 RECT rect, clip_rect, virtual_rect = get_virtual_screen_rect();
5792
5793 ok_ret( 1, GetClipCursor( &rect ) );
5794 ok_rect( virtual_rect, rect );
5795
5796 /* ClipCursor clips rectangle to the virtual screen rect */
5797 clip_rect = virtual_rect;
5798 InflateRect( &clip_rect, +1, +1 );
5799 ok_ret( 1, ClipCursor( &clip_rect ) );
5800 ok_ret( 1, GetClipCursor( &rect ) );
5801 ok_rect( virtual_rect, rect );
5802
5803 clip_rect = virtual_rect;
5804 InflateRect( &clip_rect, -1, -1 );
5805 ok_ret( 1, ClipCursor( &clip_rect ) );
5806 ok_ret( 1, GetClipCursor( &rect ) );
5807 ok_rect( clip_rect, rect );
5808
5809 /* ClipCursor(NULL) resets to the virtual screen rect */
5810 ok_ret( 1, ClipCursor( NULL ) );
5811 ok_ret( 1, GetClipCursor( &rect ) );
5812 ok_rect( virtual_rect, rect );
5813
5814 clip_rect.left = clip_rect.right = (virtual_rect.left + virtual_rect.right) / 2;
5815 clip_rect.top = clip_rect.bottom = (virtual_rect.top + virtual_rect.bottom) / 2;
5816 ok_ret( 1, ClipCursor( &clip_rect ) );
5817 ok_ret( 1, GetClipCursor( &rect ) );
5818 ok_rect( clip_rect, rect );
5819
5820 /* ClipCursor rejects invalid rectangles */
5821 clip_rect.right -= 1;
5822 clip_rect.bottom -= 1;
5823 SetLastError( 0xdeadbeef );
5824 ok_ret( 0, ClipCursor( &clip_rect ) );
5825 todo_wine
5827
5828 /* which doesn't reset the previous clip rect */
5829 clip_rect.right += 1;
5830 clip_rect.bottom += 1;
5831 ok_ret( 1, GetClipCursor( &rect ) );
5832 ok_rect( clip_rect, rect );
5833
5834 /* running a process causes it to leak until foreground actually changes */
5835 run_in_process( argv, "test_ClipCursor_process" );
5836
5837 /* as foreground window is now transient, cursor clipping isn't reset */
5838 InflateRect( &clip_rect, +1, +1 );
5839 ok_ret( 1, GetClipCursor( &rect ) );
5840 ok_rect( clip_rect, rect );
5841
5842 /* intentionally leaking clipping rect */
5843}
5844
5845static void test_ClipCursor( char **argv )
5846{
5847 RECT rect, clip_rect = {1, 2, 3, 4}, virtual_rect = get_virtual_screen_rect();
5848
5849 ok_ret( 1, ClipCursor( &clip_rect ) );
5850
5851 /* running a new process doesn't reset clipping rectangle */
5852 run_in_process( argv, "test_ClipCursor_dirty process" );
5853
5854 /* running in a separate desktop, without switching desktop as well */
5855 run_in_desktop( argv, "test_ClipCursor_dirty desktop", 0 );
5856
5857 ok_ret( 1, GetClipCursor( &rect ) );
5858 ok_rect( clip_rect, rect );
5859
5860 /* running in a desktop and switching input resets the clipping rect */
5861 run_in_desktop( argv, "test_ClipCursor_desktop", 1 );
5862
5863 ok_ret( 1, GetClipCursor( &rect ) );
5864 todo_wine
5865 ok_rect( virtual_rect, rect );
5866 if (!EqualRect( &rect, &virtual_rect )) ok_ret( 1, ClipCursor( NULL ) );
5867}
5868
5869static void test_SetCursorPos(void)
5870{
5871 RECT clip_rect = {50, 50, 51, 51};
5872 POINT pos, expect_pos = {50, 50};
5873
5874 ok_ret( 0, GetCursorPos( NULL ) );
5876
5877 /* immediate cursor position updates */
5878 ok_ret( 1, SetCursorPos( 50, 50 ) );
5879 ok_ret( 1, GetCursorPos( &pos ) );
5880 ok_point( expect_pos, pos );
5881
5882 /* without MOUSEEVENTF_MOVE cursor doesn't move */
5883 mouse_event( MOUSEEVENTF_LEFTUP, 123, 456, 0, 0 );
5885 mouse_event( MOUSEEVENTF_RIGHTUP, 456, 123, 0, 0 );
5887 ok_ret( 1, GetCursorPos( &pos ) );
5888 ok_point( expect_pos, pos );
5889
5890 /* need to move by at least 3 pixels to update, but not consistent */
5891 mouse_event( MOUSEEVENTF_MOVE, -1, 0, 0, 0 );
5892 ok_ret( 1, GetCursorPos( &pos ) );
5893#ifdef __REACTOS__
5894 ok( abs( expect_pos.x - pos.x ) <= 2, "got pos %ld\n", pos.x );
5895 ok( abs( expect_pos.y - pos.y ) <= 2, "got pos %ld\n", pos.y );
5896#else
5897 todo_wine ok_point( expect_pos, pos );
5898#endif
5899 mouse_event( MOUSEEVENTF_MOVE, +1, 0, 0, 0 );
5900 ok_ret( 1, GetCursorPos( &pos ) );
5901#ifdef __REACTOS__
5902 ok( abs( expect_pos.x - pos.x ) <= 2, "got pos %ld\n", pos.x );
5903 ok( abs( expect_pos.y - pos.y ) <= 2, "got pos %ld\n", pos.y );
5904#else
5905 ok_point( expect_pos, pos );
5906#endif
5907
5908 /* spuriously moves by 1 or 2 pixels on Windows */
5909 expect_pos.x -= 2;
5910 mouse_event( MOUSEEVENTF_MOVE, -4, 0, 0, 0 );
5911 ok_ret( 1, GetCursorPos( &pos ) );
5912#ifdef __REACTOS__
5913 todo_wine ok( abs( expect_pos.x - pos.x ) <= 2, "got pos %ld\n", pos.x );
5914#else
5915 todo_wine ok( abs( expect_pos.x - pos.x ) <= 1, "got pos %ld\n", pos.x );
5916#endif
5917 expect_pos.x += 2;
5918 mouse_event( MOUSEEVENTF_MOVE, +4, 0, 0, 0 );
5919 ok_ret( 1, GetCursorPos( &pos ) );
5920#ifdef __REACTOS__
5921 ok( abs( expect_pos.x - pos.x ) <= 2, "got pos %ld\n", pos.x );
5922#else
5923 ok( abs( expect_pos.x - pos.x ) <= 1, "got pos %ld\n", pos.x );
5924#endif
5925
5926 /* test ClipCursor holding the cursor in place */
5927 expect_pos.x = expect_pos.y = 50;
5928 ok_ret( 1, SetCursorPos( 49, 51 ) );
5929 ok_ret( 1, ClipCursor( &clip_rect ) );
5930 ok_ret( 1, GetCursorPos( &pos ) );
5931 ok_point( expect_pos, pos );
5932 ok_ret( 1, SetCursorPos( 49, 49 ) );
5933 ok_ret( 1, GetCursorPos( &pos ) );
5934 ok_point( expect_pos, pos );
5935 ok_ret( 1, SetCursorPos( 50, 50 ) );
5936 ok_ret( 1, GetCursorPos( &pos ) );
5937 ok_point( expect_pos, pos );
5938 ok_ret( 1, SetCursorPos( 48, 48 ) );
5939 ok_ret( 1, GetCursorPos( &pos ) );
5940 ok_point( expect_pos, pos );
5941 ok_ret( 1, SetCursorPos( 51, 51 ) );
5942 ok_ret( 1, GetCursorPos( &pos ) );
5943 ok_point( expect_pos, pos );
5944 ok_ret( 1, SetCursorPos( 52, 52 ) );
5945 ok_ret( 1, GetCursorPos( &pos ) );
5946 ok_point( expect_pos, pos );
5947 ok_ret( 1, SetCursorPos( 49, 51 ) );
5948 ok_ret( 1, GetCursorPos( &pos ) );
5949 ok_point( expect_pos, pos );
5950 ok_ret( 1, SetCursorPos( 51, 49 ) );
5951 ok_ret( 1, GetCursorPos( &pos ) );
5952 ok_point( expect_pos, pos );
5953
5954 mouse_event( MOUSEEVENTF_MOVE, -1, 0, 0, 0 );
5955 ok_ret( 1, GetCursorPos( &pos ) );
5956 ok_point( expect_pos, pos );
5957 mouse_event( MOUSEEVENTF_MOVE, 0, +1, 0, 0 );
5958 ok_ret( 1, GetCursorPos( &pos ) );
5959 ok_point( expect_pos, pos );
5960 mouse_event( MOUSEEVENTF_MOVE, +1, 0, 0, 0 );
5961 ok_ret( 1, GetCursorPos( &pos ) );
5962 ok_point( expect_pos, pos );
5963 mouse_event( MOUSEEVENTF_MOVE, 0, -1, 0, 0 );
5964 ok_ret( 1, GetCursorPos( &pos ) );
5965 ok_point( expect_pos, pos );
5966
5967 /* weird behavior when ClipCursor rect is empty */
5968 clip_rect.right = clip_rect.bottom = 50;
5969 ok_ret( 1, SetCursorPos( 50, 50 ) );
5970 expect_pos.x = expect_pos.y = 49;
5971 ok_ret( 1, ClipCursor( &clip_rect ) );
5972 ok_ret( 1, GetCursorPos( &pos ) );
5973 todo_wine ok_point( expect_pos, pos );
5974 expect_pos.x = expect_pos.y = 50;
5975 ok_ret( 1, SetCursorPos( 49, 49 ) );
5976 ok_ret( 1, GetCursorPos( &pos ) );
5977 ok_point( expect_pos, pos );
5978 expect_pos.x = expect_pos.y = 49;
5979 ok_ret( 1, SetCursorPos( 50, 50 ) );
5980 ok_ret( 1, GetCursorPos( &pos ) );
5981 todo_wine ok_point( expect_pos, pos );
5982 expect_pos.x = expect_pos.y = 50;
5983 ok_ret( 1, SetCursorPos( 48, 48 ) );
5984 ok_ret( 1, GetCursorPos( &pos ) );
5985 ok_point( expect_pos, pos );
5986 expect_pos.x = expect_pos.y = 49;
5987 ok_ret( 1, SetCursorPos( 51, 51 ) );
5988 ok_ret( 1, GetCursorPos( &pos ) );
5989 todo_wine ok_point( expect_pos, pos );
5990 ok_ret( 1, SetCursorPos( 52, 52 ) );
5991 ok_ret( 1, GetCursorPos( &pos ) );
5992 todo_wine ok_point( expect_pos, pos );
5993 expect_pos.x = 50;
5994 expect_pos.y = 49;
5995 ok_ret( 1, SetCursorPos( 49, 51 ) );
5996 ok_ret( 1, GetCursorPos( &pos ) );
5997 todo_wine ok_point( expect_pos, pos );
5998 expect_pos.x = 49;
5999 expect_pos.y = 50;
6000 ok_ret( 1, SetCursorPos( 51, 49 ) );
6001 ok_ret( 1, GetCursorPos( &pos ) );
6002 todo_wine ok_point( expect_pos, pos );
6003
6004 expect_pos.x = 50;
6005 expect_pos.y = 49;
6006 mouse_event( MOUSEEVENTF_MOVE, -10, 0, 0, 0 );
6007 ok_ret( 1, GetCursorPos( &pos ) );
6008 todo_wine ok_point( expect_pos, pos );
6009 expect_pos.x = 49;
6010 expect_pos.y = 49;
6011 mouse_event( MOUSEEVENTF_MOVE, 0, +10, 0, 0 );
6012 ok_ret( 1, GetCursorPos( &pos ) );
6013 todo_wine ok_point( expect_pos, pos );
6014 expect_pos.x = 49;
6015 expect_pos.y = 50;
6016 mouse_event( MOUSEEVENTF_MOVE, +10, 0, 0, 0 );
6017 ok_ret( 1, GetCursorPos( &pos ) );
6018 todo_wine ok_point( expect_pos, pos );
6019 expect_pos.x = 50;
6020 expect_pos.y = 50;
6021 mouse_event( MOUSEEVENTF_MOVE, 0, -10, 0, 0 );
6022 ok_ret( 1, GetCursorPos( &pos ) );
6023 ok_point( expect_pos, pos );
6024
6025 ok_ret( 1, ClipCursor( NULL ) );
6026}
6027
6029
6031{
6032 if (code == HC_ACTION)
6033 {
6035 return -123;
6036 }
6037
6038 return CallNextHookEx( 0, code, wparam, lparam );
6039}
6040
6042{
6043 INPUT input = {.type = INPUT_KEYBOARD, .ki = {.wVk = VK_RETURN}};
6044 HHOOK hook;
6045 HWND hwnd;
6046
6047 hwnd = CreateWindowW( L"static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL );
6048 ok_ne( NULL, hwnd, HWND, "%p" );
6049 wait_messages( 100, FALSE );
6051 ok_ne( NULL, hook, HHOOK, "%p" );
6054
6055 ok_ret( 1, SendInput( 1, &input, sizeof(input) ) );
6056 input.ki.dwFlags = KEYEVENTF_KEYUP;
6057 ok_ret( 1, SendInput( 1, &input, sizeof(input) ) );
6059
6062 ok_ret( 1, DestroyWindow( hwnd ) );
6063}
6064
6065static void test_LoadKeyboardLayoutEx( HKL orig_hkl )
6066{
6067 static const WCHAR test_layout_name[] = L"00000429";
6068 static const HKL test_hkl = (HKL)0x04290429;
6069
6070 HKL *new_layouts, *layouts, old_hkl, hkl;
6071 UINT i, j, len, new_len;
6072 WCHAR layout_name[64];
6073
6074 old_hkl = GetKeyboardLayout( 0 );
6075 ok_ne( 0, old_hkl, HKL, "%p" );
6076
6077 /* If we are dealing with a testbot setup that is prone to spurious
6078 * layout changes, layout activations in this test are likely to
6079 * not have the expected effect, invalidating the test assumptions. */
6080 if (orig_hkl != old_hkl)
6081 {
6082 win_skip( "Spurious keyboard layout changed detected (expected: %p got: %p)\n",
6083 orig_hkl, old_hkl );
6084 return;
6085 }
6086
6087 hkl = pLoadKeyboardLayoutEx( NULL, test_layout_name, 0 );
6088 ok_eq( 0, hkl, HKL, "%p" );
6089
6090 layouts = get_keyboard_layouts( &len );
6091 for (i = 0; i < len; i++) if (layouts[i] == test_hkl) break;
6092 if (i != len)
6093 {
6094 skip( "Test HKL is already loaded, skipping tests\n" );
6095 free( layouts );
6096 return;
6097 }
6098
6099 /* LoadKeyboardLayoutEx replaces loaded layouts, but will lose mixed layout / locale */
6100 for (i = 0, j = len; i < len; i++)
6101 {
6102 if (HIWORD(layouts[i]) != LOWORD(layouts[i])) continue;
6103 if (j == len) j = i;
6104 else break;
6105 }
6106 if (i == len) i = j;
6107 if (i == len)
6108 {
6109 skip( "Failed to find appropriate layouts, skipping tests\n" );
6110 free( layouts );
6111 return;
6112 }
6113
6114 trace( "using layouts %p / %p\n", layouts[i], layouts[j] );
6115
6116 ActivateKeyboardLayout( layouts[i], 0 );
6117 ok_eq( layouts[i], GetKeyboardLayout( 0 ), HKL, "%p" );
6118 ok_ret( 1, GetKeyboardLayoutNameW( layout_name ) );
6119
6120 /* LoadKeyboardLayoutEx replaces a currently loaded layout */
6121 hkl = pLoadKeyboardLayoutEx( layouts[i], test_layout_name, 0 );
6122 todo_wine
6123 ok_eq( test_hkl, hkl, HKL, "%p" );
6124 new_layouts = get_keyboard_layouts( &new_len );
6125 ok_eq( len, new_len, UINT, "%u" );
6126 todo_wine
6127 ok_eq( test_hkl, new_layouts[i], HKL, "%p" );
6128 new_layouts[i] = layouts[i];
6129 ok( !memcmp( new_layouts, layouts, len * sizeof(*layouts) ), "keyboard layouts changed\n" );
6130 free( new_layouts );
6131
6132 hkl = pLoadKeyboardLayoutEx( test_hkl, layout_name, 0 );
6133 ok_eq( layouts[i], hkl, HKL, "%p" );
6134 new_layouts = get_keyboard_layouts( &new_len );
6135 ok_eq( len, new_len, UINT, "%u" );
6136 ok( !memcmp( new_layouts, layouts, len * sizeof(*layouts) ), "keyboard layouts changed\n" );
6137 free( new_layouts );
6138
6139 if (j == i) skip( "Only one layout found, skipping tests\n" );
6140 else
6141 {
6142 /* it also works if a different layout is active */
6143 ActivateKeyboardLayout( layouts[j], 0 );
6144 ok_eq( layouts[j], GetKeyboardLayout( 0 ), HKL, "%p" );
6145
6146 hkl = pLoadKeyboardLayoutEx( layouts[i], test_layout_name, 0 );
6147 todo_wine
6148 ok_eq( test_hkl, hkl, HKL, "%p" );
6149 new_layouts = get_keyboard_layouts( &new_len );
6150 ok_eq( len, new_len, UINT, "%u" );
6151 todo_wine
6152 ok_eq( test_hkl, new_layouts[i], HKL, "%p" );
6153 new_layouts[i] = layouts[i];
6154 ok( !memcmp( new_layouts, layouts, len * sizeof(*layouts) ), "keyboard layouts changed\n" );
6155 free( new_layouts );
6156
6157 hkl = pLoadKeyboardLayoutEx( test_hkl, layout_name, 0 );
6158 ok_eq( layouts[i], hkl, HKL, "%p" );
6159 new_layouts = get_keyboard_layouts( &new_len );
6160 ok_eq( len, new_len, UINT, "%u" );
6161 ok( !memcmp( new_layouts, layouts, len * sizeof(*layouts) ), "keyboard layouts changed\n" );
6162 free( new_layouts );
6163 }
6164
6165 free( layouts );
6166 ActivateKeyboardLayout( old_hkl, 0 );
6167 ok_eq( old_hkl, GetKeyboardLayout( 0 ), HKL, "%p" );
6168}
6169
6170/* run the tests in a separate desktop to avoid interaction with other
6171 * tests, current desktop state, or user actions. */
6172static void test_input_desktop( char **argv )
6173{
6174 HKL hkl = GetKeyboardLayout( 0 );
6175 WCHAR wch, wch_shift;
6176 POINT pos;
6177 WORD scan;
6178
6179 trace( "hkl %p\n", hkl );
6180 ok_ret( 1, GetCursorPos( &pos ) );
6182
6183 get_test_scan( 'F', &scan, &wch, &wch_shift );
6184 test_SendInput( 'F', wch, hkl );
6185 test_SendInput_keyboard_messages( 'F', scan, wch, wch_shift, '\x06', hkl );
6187
6189
6194
6196
6197 ok_ret( 1, SetCursorPos( pos.x, pos.y ) );
6198}
6199
6200static void test_keyboard_layout(void)
6201{
6202 const CHAR *layout_name;
6203 LANGID lang_id;
6204 HKL hkl;
6205
6206 /* Test that the high word of the keyboard layout in CJK locale is the same as the low word,
6207 * even when IME is on */
6208 lang_id = PRIMARYLANGID(GetUserDefaultLCID());
6209 if (lang_id == LANG_CHINESE || lang_id == LANG_JAPANESE || lang_id == LANG_KOREAN)
6210 {
6212 ok(HIWORD(hkl) == LOWORD(hkl), "Got unexpected hkl %p.\n", hkl);
6213
6214 if (lang_id == LANG_CHINESE)
6215 layout_name = "00000804";
6216 else if (lang_id == LANG_JAPANESE)
6217 layout_name = "00000411";
6218 else if (lang_id == LANG_KOREAN)
6219 layout_name = "00000412";
6220 hkl = LoadKeyboardLayoutA(layout_name, 0);
6221 ok(HIWORD(hkl) == LOWORD(hkl), "Got unexpected hkl %p.\n", hkl);
6222 }
6223}
6224
6226{
6227 char **argv;
6228 int argc;
6229 POINT pos;
6230
6232 GetCursorPos( &pos );
6233
6234#ifdef __REACTOS__
6235 if (GetNTVersion() < _WIN32_WINNT_VISTA && !is_reactos()) {
6236 skip("The user32:input tests causes persistent input issues on WS03!\n");
6237 return;
6238 }
6239#endif
6241 if (argc >= 3 && !strcmp( argv[2], "rawinput_test" ))
6242 return rawinput_test_process();
6243 if (argc >= 3 && !strcmp( argv[2], "test_GetMouseMovePointsEx_process" ))
6245 if (argc >= 4 && !strcmp( argv[2], "test_EnableMouseInPointer" ))
6246 return test_EnableMouseInPointer( argv[3] );
6247 if (argc >= 4 && !strcmp( argv[2], "test_ClipCursor_dirty" ))
6248 return test_ClipCursor_dirty( argv[3] );
6249 if (argc >= 3 && !strcmp( argv[2], "test_ClipCursor_process" ))
6250 return test_ClipCursor_process();
6251 if (argc >= 3 && !strcmp( argv[2], "test_ClipCursor_desktop" ))
6252 return test_ClipCursor_desktop( argv );
6253 if (argc >= 3 && !strcmp( argv[2], "test_input_desktop" ))
6254 return test_input_desktop( argv );
6255
6256 run_in_desktop( argv, "test_input_desktop", 1 );
6257 test_keynames();
6258 test_key_map();
6260 test_ToAscii();
6269 test_rawinput(argv[0]);
6271
6272 if(pGetMouseMovePointsEx)
6274 else
6275 win_skip("GetMouseMovePointsEx is not available\n");
6276
6277 if(pGetRawInputDeviceList)
6279 else
6280 win_skip("GetRawInputDeviceList is not available\n");
6281
6282 if (pGetCurrentInputMessageSource)
6284 else
6285 win_skip("GetCurrentInputMessageSource is not available\n");
6286
6287 SetCursorPos( pos.x, pos.y );
6288
6289 if (pGetPointerType)
6291 else
6292 win_skip( "GetPointerType is not available\n" );
6293
6295
6296 if (!pEnableMouseInPointer)
6297 win_skip( "EnableMouseInPointer not found, skipping tests\n" );
6298 else
6299 {
6300 run_in_process( argv, "test_EnableMouseInPointer 0" );
6301 run_in_process( argv, "test_EnableMouseInPointer 1" );
6302 }
6303
6305}
BOOL fullscreen
Definition: 3dtext.c:43
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:66
static int iteration
Definition: StackOverflow.c:18
@ lparam
Definition: SystemMenu.c:31
@ hook
Definition: SystemMenu.c:35
@ wparam
Definition: SystemMenu.c:30
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
unsigned char BOOLEAN
Definition: actypes.h:127
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
static void startup(void)
#define GetNTVersion()
Definition: apitest.h:17
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
static const char * wine_dbgstr_point(const POINT *ppt)
Definition: atltest.h:138
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define msg(x)
Definition: auth_time.c:54
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
#define U(x)
Definition: wordpad.c:45
static INT max_size
Definition: history.c:51
static HANDLE thread
Definition: service.c:33
#define UlongToHandle(ul)
Definition: basetsd.h:91
#define HandleToUlong(h)
Definition: basetsd.h:73
#define LongToPtr(l)
Definition: basetsd.h:85
#define RegCloseKey(hKey)
Definition: registry.h:49
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
WORD ATOM
Definition: dimm.idl:113
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2830
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
#define CDECL
Definition: compat.h:29
#define CloseHandle
Definition: compat.h:739
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FreeLibrary(x)
Definition: compat.h:748
#define GetCurrentProcess()
Definition: compat.h:759
HANDLE HWND
Definition: compat.h:19
#define IsWow64Process
Definition: compat.h:760
#define MAX_PATH
Definition: compat.h:34
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define LoadLibraryW(x)
Definition: compat.h:747
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define FILE_SHARE_READ
Definition: compat.h:136
#define wcsicmp
Definition: compat.h:15
#define lstrlenW
Definition: compat.h:750
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
INT WINAPI GetLocaleInfoA(LCID lcid, LCTYPE lctype, LPSTR buffer, INT len)
Definition: locale.c:1609
LCID WINAPI GetUserDefaultLCID(void)
Definition: locale.c:1216
LCID lcid
Definition: locale.c:5656
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(const char *app_name, char *cmd_line, SECURITY_ATTRIBUTES *process_attr, SECURITY_ATTRIBUTES *thread_attr, BOOL inherit, DWORD flags, void *env, const char *cur_dir, STARTUPINFOA *startup_info, PROCESS_INFORMATION *info)
Definition: process.c:686
ULONG WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
Definition: sync.c:182
MonoAssembly int argc
Definition: metahost.c:107
unsigned short vk
Definition: console.c:118
_ACRTIMP int __cdecl swscanf(const wchar_t *, const wchar_t *,...)
Definition: scanf.c:438
_ACRTIMP __msvcrt_ulong __cdecl wcstoul(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2912
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1972
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
_ACRTIMP __msvcrt_ulong __cdecl strtoul(const char *, char **, int)
Definition: string.c:1859
_ACRTIMP char *__cdecl strchr(const char *, int)
Definition: string.c:3286
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP size_t __cdecl strcspn(const char *, const char *)
Definition: string.c:3493
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
char * va_list
Definition: vadefs.h:50
#define swprintf
Definition: precomp.h:40
#define pt(x, y)
Definition: drawing.c:79
#define RGB(r, g, b)
Definition: precomp.h:67
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
r received
Definition: btrfs.c:3005
struct nls_table * tables
Definition: nls_base.c:22
#define INFINITE
Definition: serial.h:102
#define UlongToPtr(u)
Definition: config.h:106
static struct all_devices * devices
Definition: dsm_ctrl.c:48
POINTL point
Definition: edittest.c:50
#define ERROR(name)
Definition: error_private.h:53
static unsigned char buff[32768]
Definition: fatten.c:17
#define abs(i)
Definition: fconv.c:206
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
time_t now
Definition: finger.c:65
pKey DeleteObject()
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
GLdouble s
Definition: gl.h:2039
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct _cl_event * event
Definition: glext.h:7739
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLuint color
Definition: glext.h:6243
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLenum const GLfloat * params
Definition: glext.h:5645
GLuint in
Definition: glext.h:9616
GLint left
Definition: glext.h:7726
GLbitfield flags
Definition: glext.h:7161
GLuint64EXT * result
Definition: glext.h:11304
GLboolean enable
Definition: glext.h:11120
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
HIDAPI BOOLEAN WINAPI HidD_GetPreparsedData(IN HANDLE HidDeviceObject, OUT PHIDP_PREPARSED_DATA *PreparsedData)
Definition: hid.c:290
HIDAPI BOOLEAN WINAPI HidD_FreePreparsedData(IN PHIDP_PREPARSED_DATA PreparsedData)
Definition: hid.c:139
struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA
Definition: hidpi.h:39
#define HID_USAGE_GENERIC_GAMEPAD
Definition: hidusage.h:35
#define HID_USAGE_GENERIC_MOUSE
Definition: hidusage.h:33
#define HID_USAGE_PAGE_GENERIC
Definition: hidusage.h:176
#define HID_USAGE_GENERIC_KEYBOARD
Definition: hidusage.h:36
#define HID_USAGE_GENERIC_JOYSTICK
Definition: hidusage.h:34
static TfClientId tid
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define LOBYTE(W)
Definition: jmemdos.c:487
#define KLLF_ALTGR
Definition: kbd.h:91
#define c
Definition: ke_i.h:80
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
#define REG_SZ
Definition: layer.c:22
USHORT LANGID
Definition: mui.h:9
const char * winetest_platform
int winetest_debug
#define win_skip
Definition: minitest.h:67
#define todo_wine_if(is_todo)
Definition: minitest.h:81
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
#define todo_wine
Definition: minitest.h:80
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
__u16 time
Definition: mkdosfs.c:8
#define sprintf
Definition: sprintf.c:45
HDC hdc
Definition: main.c:9
HANDLE events[2]
Definition: event.c:4
#define expect_rect(r, _left, _top, _right, _bottom)
Definition: combo.c:42
static HDC
Definition: imagelist.c:88
BOOL todo
Definition: filedlg.c:313
BOOL expected
Definition: store.c:2000
static DWORD layout
Definition: bitmap.c:46
static va_list valist
Definition: printf.c:46
static DWORD thread_id
Definition: protocol.c:159
static WNDPROC old_proc
Definition: clipboard.c:236
#define KEY_MSG_(m, s, v, f,...)
static void test_key_names(void)
Definition: input.c:3863
static const char * debugstr_vk(UINT vkey)
Definition: input.c:202
static void test_keynames(void)
Definition: input.c:1465
#define ok_rect(e, r)
Definition: input.c:113
static void test_ClipCursor(char **argv)
Definition: input.c:5845
HWND create_foreground_window_(const char *file, int line, BOOL fullscreen, UINT retries)
Definition: input.c:583
static int ok_call_(const char *file, int line, const struct user_call *expected, const struct user_call *received)
Definition: input.c:223
static void test_UnregisterDeviceNotification(void)
Definition: input.c:5299
static void check_keyboard_async_(int line, const BYTE expect_state[256], const BOOL todo_state[256])
Definition: input.c:693
#define check_get_key_state(i, j, c, x)
Definition: input.c:4941
#define MS_HOOK(m, x, y,...)
static LRESULT CALLBACK mouse_layered_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: input.c:3990
static void test_ActivateKeyboardLayout(char **argv)
Definition: input.c:3729
static POINTER_INPUT_TYPE *static POINTER_INFO *static UINT32 POINTER_INFO *static UINT32 POINTER_INFO *static UINT32 UINT32 POINTER_INFO *static int
Definition: input.c:445
static const char * debugstr_ok(const char *cond)
Definition: input.c:87
static LRESULT WINAPI msg_source_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
Definition: input.c:5172
static HANDLE ll_keyboard_event
Definition: input.c:6028
static LRESULT CALLBACK ll_keyboard_event_wait(int code, WPARAM wparam, LPARAM lparam)
Definition: input.c:6030
static const struct tounicode_tests utests[]
static int got_setfocus
Definition: input.c:3686
static BOOL rawinput_test_received_raw
Definition: input.c:2703
static DWORD CALLBACK test_GetPointerInfo_thread(void *arg)
Definition: input.c:5455
static void append_ll_hook_ms(UINT msg, const MSLLHOOKSTRUCT *info)
Definition: input.c:375
#define ok_seq(a)
Definition: input.c:326
user_function
Definition: input.c:128
@ LL_HOOK_MOUSE
Definition: input.c:131
@ LL_HOOK_KEYBD
Definition: input.c:130
@ RAW_INPUT_KEYBOARD
Definition: input.c:132
@ MSG_TEST_WIN
Definition: input.c:129
static void append_ll_hook_kbd(UINT msg, const KBDLLHOOKSTRUCT *info)
Definition: input.c:357
static BOOL accept_keyboard_messages_raw(UINT msg)
Definition: input.c:1478
#define KEY_HOOK(m, s, v,...)
static void empty_message_queue(void)
Definition: input.c:619
static DWORD WINAPI get_key_state_thread(void *arg)
Definition: input.c:4955
static DWORD WINAPI rawinput_test_thread(void *arg)
Definition: input.c:2966
#define create_foreground_window(a)
Definition: input.c:582
static BOOL wait_for_event(HANDLE event, int timeout)
Definition: input.c:3922
static const char * debugstr_wm(UINT msg)
Definition: input.c:182
static BOOL accept_mouse_messages_nomove(UINT msg)
Definition: input.c:4067
static PUINT
Definition: input.c:446
#define ok_ret(e, r)
Definition: input.c:125
static void rawinput_test_process(void)
Definition: input.c:2784
static LRESULT CALLBACK ll_hook_kbd_proc(int code, WPARAM wparam, LPARAM lparam)
Definition: input.c:654
static LRESULT CALLBACK httransparent_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: input.c:3938
static LRESULT CALLBACK rawinput_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: input.c:2706
static BOOL is_mouse_message(UINT message)
Definition: input.c:577
static BOOL is_keyboard_message(UINT message)
Definition: input.c:572
static LRESULT CALLBACK append_message_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: input.c:428
struct rawinput_test rawinput_tests[]
Definition: input.c:2754
static void test_SendInput_raw_key_messages(WORD vkey, WORD wch, HKL hkl)
Definition: input.c:1483
static void check_get_key_state_(int i, int j, int c, int x, int line)
Definition: input.c:4942
static void test_keyboard_layout_name(void)
Definition: input.c:3535
static DWORD WINAPI thread_proc(void *param)
Definition: input.c:4596
static void test_ClipCursor_desktop(char **argv)
Definition: input.c:5789
static void init_function_pointers(void)
Definition: input.c:456
static LRESULT CALLBACK mouse_move_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: input.c:3971
#define check_keyboard_async(a, b)
Definition: input.c:692
#define MYERROR
static BOOL(* p_accept_message)(UINT msg)
Definition: input.c:355
static HKL expect_hkl
Definition: input.c:3684
static void run_in_desktop_(const char *file, int line, char **argv, const char *args, BOOL input)
Definition: input.c:505
static void test_input_message_source(void)
Definition: input.c:5215
static void test_attach_input(void)
Definition: input.c:4642
static void test_ClipCursor_dirty(const char *arg)
Definition: input.c:5693
static void check_get_keyboard_state_(int i, int j, int c, int x, int line)
Definition: input.c:4922
#define menu
Definition: input.c:3273
static void test_SetCursorPos(void)
Definition: input.c:5869
static BOOL is_wow64
Definition: input.c:454
#define check_keyboard_state(a, b)
Definition: input.c:677
static void test_GetRawInputBuffer(void)
Definition: input.c:2432
static void test_GetKeyState(void)
Definition: input.c:5018
static BOOL rawinput_test_received_legacy
Definition: input.c:2702
static void UINT *static void UINT *static PBOOL
Definition: input.c:449
struct get_key_state_test_desc get_key_state_tests[]
Definition: input.c:4883
static DWORD CALLBACK test_ActivateKeyboardLayout_thread_proc(void *arg)
Definition: input.c:3723
#define check_send_input_keyboard_test(a, b)
Definition: input.c:732
static void test_RegisterRawInputDevices(void)
Definition: input.c:2121
static BOOL append_message_hwnd
Definition: input.c:354
#define run_in_process(a, b)
Definition: input.c:486
static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: input.c:4575
static INPUT_MESSAGE_SOURCE expect_src
Definition: input.c:5170
static void test_keyboard_ll_hook_blocking(void)
Definition: input.c:6041
static DWORD WINAPI create_transparent_window_thread(void *arg)
Definition: input.c:3952
static void test_LoadKeyboardLayoutEx(HKL orig_hkl)
Definition: input.c:6065
#define ok_point(e, r)
Definition: input.c:119
static void test_SendInput_keyboard_messages(WORD vkey, WORD scan, WCHAR wch, WCHAR wch_shift, WCHAR wch_control, HKL hkl)
Definition: input.c:824
static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: input.c:2290
#define check_get_keyboard_state(i, j, c, x)
Definition: input.c:4921
static LRESULT CALLBACK ll_hook_setpos_proc(int code, WPARAM wparam, LPARAM lparam)
Definition: input.c:4031
static void test_GetRawInputDeviceList(void)
Definition: input.c:1933
static void clear_keyboard_state(void)
Definition: input.c:708
#define shift
Definition: input.c:3271
static void get_test_scan(WORD vkey, WORD *scan, WCHAR *wch, WCHAR *wch_shift)
Definition: input.c:812
static void test_SendInput(WORD vkey, WCHAR wch, HKL hkl)
Definition: input.c:5305
static HKL * get_keyboard_layouts(UINT *count)
Definition: input.c:3521
static LRESULT CALLBACK ll_hook_ms_proc(int code, WPARAM wparam, LPARAM lparam)
Definition: input.c:4024
static void test_keyboard_layout(void)
Definition: input.c:6200
static void test_EnableMouseInPointer(const char *arg)
Definition: input.c:5647
static BOOL rawinput_test_received_rawfg
Definition: input.c:2704
static void test_OemKeyScan(void)
Definition: input.c:5129
#define GET_PROC(func)
#define DESKTOP_ALL_ACCESS
Definition: input.c:435
#define KEY_HOOK_(m, s, v, f,...)
static void test_SendInput_mouse_messages(void)
Definition: input.c:4072
static BOOL CALLBACK get_virtual_screen_proc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lp)
Definition: input.c:5679
static void check_pointer_info_(int line, const POINTER_INFO *actual, const POINTER_INFO *expected)
Definition: input.c:5431
static HKL change_hkl
Definition: input.c:3685
static void ok_seq_(const char *file, int line, const struct user_call *expected, const char *context)
Definition: input.c:327
static void simulate_click(BOOL left, int x, int y)
Definition: input.c:3903
static LRESULT CALLBACK ll_hook_getpos_proc(int code, WPARAM wparam, LPARAM lparam)
Definition: input.c:4053
static void test_ClipCursor_process(void)
Definition: input.c:5736
#define wait_messages(a, b)
Definition: input.c:546
#define msg_wait_for_events(a, b, c)
Definition: input.c:547
static BOOL keyboard_layout_has_altgr(void)
Definition: input.c:767
static void test_GetRawInputData(void)
Definition: input.c:2111
static void check_keyboard_state_(int line, const BYTE expect_state[256], const BOOL todo_state[256])
Definition: input.c:678
#define ok_ne(e, r, t, f,...)
Definition: input.c:107
static BOOL accept_keyboard_messages_syscommand(UINT msg)
Definition: input.c:762
static void test_get_async_key_state(void)
Definition: input.c:3514
static LONG current_sequence_len
Definition: input.c:180
static struct user_call current_sequence[1024]
Definition: input.c:179
static int rawinputbuffer_wndproc_count
Definition: input.c:2257
static void run_in_process_(const char *file, int line, char **argv, const char *args)
Definition: input.c:487
#define check_pointer_info(a, b)
Definition: input.c:5430
#define check_member(val, exp, fmt, member)
Definition: input.c:84
static const struct user_call empty_sequence[]
Definition: input.c:178
static void append_rawinput_message(HWND hwnd, WPARAM wparam, HRAWINPUT handle)
Definition: input.c:393
#define ok_eq(e, r, t, f,...)
Definition: input.c:101
static DWORD WINAPI rawinput_test_desk_thread(void *arg)
Definition: input.c:2900
static void test_key_map(void)
Definition: input.c:3209
RECT get_virtual_screen_rect(void)
Definition: input.c:5686
static void test_ToAscii(void)
Definition: input.c:3442
static void test_ToUnicode(void)
Definition: input.c:3368
static LRESULT CALLBACK test_ActivateKeyboardLayout_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: input.c:3688
#define run_in_desktop(a, b, c)
Definition: input.c:504
static DWORD CALLBACK test_ClipCursor_thread(void *arg)
Definition: input.c:5705
static void test_DefRawInputProc(void)
Definition: input.c:3190
static POINTER_INPUT_TYPE *static POINTER_INFO *static UINT32 POINTER_INFO *static UINT32 POINTER_INFO *static UINT32 UINT32 POINTER_INFO *static LPMOUSEMOVEPOINT
Definition: input.c:445
static void test_rawinput(const char *argv0)
Definition: input.c:3018
#define WIN_MSG(m, w, l,...)
#define KEY_MSG(m, s, v,...)
static void test_input_desktop(char **argv)
Definition: input.c:6172
static void check_send_input_keyboard_test_(const struct send_input_keyboard_test *test, const char *context, BOOL peeked)
Definition: input.c:733
#define ctrl
Definition: input.c:3272
static void test_GetPointerInfo(BOOL mouse_in_pointer_enabled)
Definition: input.c:5474
static void append_message(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: input.c:415
static DWORD msg_wait_for_events_(const char *file, int line, DWORD count, HANDLE *events, DWORD timeout, BOOL append_peeked)
Definition: input.c:548
static void test_GetMouseMovePointsEx(char **argv)
Definition: input.c:1621
#define RAW_KEY(s, f, v, m,...)
static void test_GetMouseMovePointsEx_process(void)
Definition: input.c:1847
#define BUFLIM
static POINTER_INPUT_TYPE *static POINTER_INFO *static UINT32 POINTER_INFO *static UINT32 POINTER_INFO *static UINT32 UINT32 POINTER_INFO *static DWORD
Definition: input.c:445
static MONITORINFO mi
Definition: win.c:9400
#define min(a, b)
Definition: monoChain.cc:55
#define argv
Definition: mplay32.c:18
int other
Definition: msacm.c:1376
HKL hkl
Definition: msctf.idl:632
UINT_PTR HKL
Definition: msctf.idl:125
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
HMONITOR WINAPI MonitorFromWindow(HWND, DWORD)
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:28
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define BOOL
Definition: nt_native.h:43
#define MOUSE_MOVE_ABSOLUTE
Definition: ntddmou.h:68
#define MOUSE_VIRTUAL_DESKTOP
Definition: ntddmou.h:69
#define LOWORD(l)
Definition: pedump.c:82
#define WS_CHILD
Definition: pedump.c:617
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define WS_OVERLAPPED
Definition: pedump.c:615
#define WS_POPUP
Definition: pedump.c:616
#define WS_VISIBLE
Definition: pedump.c:620
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
struct _STARTUPINFOA STARTUPINFOA
#define err(...)
#define calloc
Definition: rosglue.h:14
#define test
Definition: rosglue.h:37
const WCHAR * str
#define offsetof(TYPE, MEMBER)
#define LANG_CHINESE
Definition: nls.h:42
DWORD LCID
Definition: nls.h:13
#define LANG_JAPANESE
Definition: nls.h:76
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define LANG_KOREAN
Definition: nls.h:84
wcscat
wcscpy
strcpy
Definition: string.h:131
#define flaky_wine
Definition: test.h:165
int winetest_get_mainargs(char ***pargv)
void winetest_wait_child_process(HANDLE process)
#define flaky
Definition: test.h:164
#define wait_child_process
Definition: test.h:159
#define memset(x, y, z)
Definition: compat.h:39
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
static PVOID hdll
Definition: shimdbg.c:126
static char argv0[MAX_PATH]
Definition: shlexec.c:49
DWORD dwTime
Definition: solitaire.cpp:27
& rect
Definition: startmenu.cpp:1413
TCHAR * cmdline
Definition: stretchblt.cpp:32
RAWMOUSE mouse
Definition: input.c:2283
union RAWINPUT64::@1862 data
RAWKEYBOARD keyboard
Definition: input.c:2284
RAWINPUTHEADER64 header
Definition: input.c:2281
RAWHID hid
Definition: input.c:2285
ULONG hDevice
Definition: input.c:2263
ULONG wParam
Definition: input.c:2264
DWORD dwType
Definition: input.c:2261
DWORD dwSize
Definition: input.c:2262
DWORD dwType
Definition: input.c:2273
ULONGLONG hDevice
Definition: input.c:2275
ULONGLONG wParam
Definition: input.c:2276
DWORD dwSize
Definition: input.c:2274
Definition: kbd.h:95
LONG y
Definition: windef.h:130
LONG x
Definition: windef.h:129
HBRUSH hbrBackground
Definition: winuser.h:3278
HICON hIcon
Definition: winuser.h:3276
HINSTANCE hInstance
Definition: winuser.h:3275
HCURSOR hCursor
Definition: winuser.h:3277
int cbWndExtra
Definition: winuser.h:3274
UINT style
Definition: winuser.h:3271
LPCSTR lpszMenuName
Definition: winuser.h:3279
LPCSTR lpszClassName
Definition: winuser.h:3280
WNDPROC lpfnWndProc
Definition: winuser.h:3272
int cbClsExtra
Definition: winuser.h:3273
WNDPROC lpfnWndProc
Definition: winuser.h:3285
Definition: match.c:390
Definition: inflate.c:139
Definition: http.c:7252
Definition: dialog.c:52
Definition: fci.c:127
Definition: format.c:58
BOOL set_keyboard_state_main
Definition: input.c:4879
Definition: parser.c:49
Definition: tftpd.h:60
Definition: name.c:39
BOOL register_window
Definition: input.c:2744
BOOL todo_raw
Definition: input.c:2750
BOOL todo_legacy
Definition: input.c:2749
BOOL expect_raw
Definition: input.c:2747
BOOL todo_rawfg
Definition: input.c:2751
BOOL expect_legacy
Definition: input.c:2746
BOOL expect_rawfg
Definition: input.c:2748
DWORD register_flags
Definition: input.c:2745
BOOL register_device
Definition: input.c:2743
BOOL todo_state[256]
Definition: input.c:648
struct user_call expect[8]
Definition: input.c:646
BOOL todo_async[256]
Definition: input.c:651
BYTE expect_async[256]
Definition: input.c:650
BYTE expect_state[256]
Definition: input.c:647
struct user_call expect[8]
Definition: input.c:4019
BOOL todo_state[256]
Definition: input.c:4021
BYTE expect_state[256]
Definition: input.c:4020
ULONG_PTR extra
Definition: input.c:4018
Definition: ps.c:97
KEYBDINPUT ki
Definition: winable.h:62
DWORD type
Definition: winable.h:59
ULONG_PTR dwExtraInfo
Definition: winuser.h:3920
DWORD dwFlags
Definition: winable.h:49
WORD wVk
Definition: winable.h:47
WORD wScan
Definition: winable.h:48
ULONG_PTR dwExtraInfo
Definition: winable.h:51
DWORD time
Definition: winable.h:50
RECT rcMonitor
Definition: winuser.h:3893
DWORD cbSize
Definition: winuser.h:3892
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
Definition: dhcpd.h:248
WCHAR expect_buf[4]
Definition: input.c:3281
DWORD modifiers
Definition: input.c:3278
int expect_ret
Definition: input.c:3280
struct user_call::@1856::@1861 raw_input
UINT vkey
Definition: input.c:152
UINT data
Definition: input.c:160
UINT scan
Definition: input.c:151
HWND hwnd
Definition: input.c:143
UINT flags
Definition: input.c:153
BOOL broken
Definition: input.c:175
UINT_PTR extra
Definition: input.c:154
LPARAM lparam
Definition: input.c:146
struct user_call::@1856::@1860 ll_hook_ms
UINT time
Definition: input.c:162
POINT point
Definition: input.c:159
UINT msg
Definition: input.c:144
struct user_call::@1856::@1859 ll_hook_kbd
struct user_call::@1856::@1858 message
WPARAM wparam
Definition: input.c:145
BOOL todo_value
Definition: input.c:174
BYTE code
Definition: input.c:168
BOOL todo
Definition: input.c:173
enum user_function func
Definition: input.c:137
RAWKEYBOARD kbd
Definition: input.c:169
DWORD attach_from
Definition: input.c:4591
HANDLE wait_event
Definition: input.c:4589
HWND hwnd
Definition: input.c:4588
HANDLE start_event
Definition: input.c:4590
BOOL setWindows
Definition: input.c:4593
DWORD attach_to
Definition: input.c:4592
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:573
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventA(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCSTR lpName)
Definition: synch.c:605
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:650
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseSemaphore(IN HANDLE hSemaphore, IN LONG lReleaseCount, IN LPLONG lpPreviousCount)
Definition: synch.c:491
HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL, IN LONG lInitialCount, IN LONG lMaximumCount, IN LPCSTR lpName OPTIONAL)
Definition: synchansi.c:44
#define vsnprintf
Definition: tif_win32.c:406
#define GWLP_WNDPROC
Definition: treelist.c:66
#define DWORD_PTR
Definition: treelist.c:76
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
PVOID HANDLE
Definition: typedefs.h:73
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
uint32_t UINT32
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define HIWORD(l)
Definition: typedefs.h:247
Definition: pdh_main.c:96
static BOOL keystate[LAST_MODIFIER - FIRST_MODIFIER]
Definition: vnc.c:133
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
int retval
Definition: wcstombs.cpp:91
HDESK WINAPI CreateDesktopA(LPCSTR lpszDesktop, LPCSTR lpszDevice, LPDEVMODEA pDevmode, DWORD dwFlags, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa)
Definition: desktop.c:431
BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY Handle)
Definition: resources.c:162
UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader)
Definition: stubs.c:299
UINT WINAPI DECLSPEC_HOTPATCH GetRegisteredRawInputDevices(PRAWINPUTDEVICE pRawInputDevices, PUINT puiNumDevices, UINT cbSize)
Definition: stubs.c:349
BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(PCRAWINPUTDEVICE pRawInputDevices, UINT uiNumDevices, UINT cbSize)
Definition: stubs.c:364
UINT WINAPI GetRawInputDeviceInfoA(HANDLE hDevice, UINT uiCommand, LPVOID pData, PUINT pcbSize)
Definition: stubs.c:257
UINT WINAPI GetRawInputDeviceInfoW(HANDLE hDevice, UINT uiCommand, LPVOID pData, PUINT pcbSize)
Definition: stubs.c:225
UINT WINAPI GetRawInputData(HRAWINPUT hRawInput, UINT uiCommand, LPVOID pData, PUINT pcbSize, UINT cbSizeHeader)
Definition: stubs.c:313
LRESULT WINAPI DefRawInputProc(PRAWINPUT *paRawInput, INT nInput, UINT cbSizeHeader)
Definition: stubs.c:283
UINT WINAPI GetRawInputDeviceList(PRAWINPUTDEVICELIST pRawInputDeviceList, PUINT puiNumDevices, UINT cbSize)
Definition: stubs.c:329
HKL WINAPI LoadKeyboardLayoutEx(HKL hklUnload, LPCWSTR pwszKLID, UINT Flags)
Definition: input.c:837
int WINAPI GetWindowRgnBox(HWND hWnd, LPRECT lprc)
Definition: paint.c:299
BOOL WINAPI GetPointerType(UINT32 id, POINTER_INPUT_TYPE *type)
Definition: misc.c:608
BOOL WINAPI GetPointerInfo(UINT32 id, POINTER_INFO *info)
Definition: misc.c:622
int codepage
Definition: win_iconv.c:156
#define INPUT_HARDWARE
Definition: winable.h:11
UINT WINAPI SendInput(UINT, LPINPUT, int)
Definition: ntwrapper.h:344
#define INPUT_KEYBOARD
Definition: winable.h:10
#define INPUT_MOUSE
Definition: winable.h:9
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define STARTF_USESHOWWINDOW
Definition: winbase.h:468
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
HWINSTA WINAPI GetProcessWindowStation(void)
Definition: ntwrapper.h:124
#define WAIT_OBJECT_0
Definition: winbase.h:383
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define ERROR_POINT_NOT_FOUND
Definition: winerror.h:1017
#define ERROR_NOACCESS
Definition: winerror.h:902
HGDIOBJ WINAPI GetStockObject(_In_ int)
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
#define WHITE_BRUSH
Definition: wingdi.h:902
#define SIMPLEREGION
Definition: wingdi.h:362
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
BOOL WINAPI TranslateCharsetInfo(_Inout_ PDWORD, _Out_ LPCHARSETINFO, _In_ DWORD)
#define TCI_SRCCODEPAGE
Definition: wingdi.h:962
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:45
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RRF_RT_REG_SZ
Definition: winreg.h:58
#define SW_SHOWNORMAL
Definition: winuser.h:781
#define WM_PAINT
Definition: winuser.h:1648
HWND WINAPI GetFocus(void)
Definition: window.c:1863
HWND WINAPI SetCapture(_In_ HWND hWnd)
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
BOOL WINAPI GetKeyboardLayoutNameW(_Out_writes_(KL_NAMELENGTH) LPWSTR)
#define MOUSEEVENTF_ABSOLUTE
Definition: winuser.h:1205
#define SetWindowLongPtrA
Definition: winuser.h:5511
HWND WINAPI GetActiveWindow(void)
Definition: winpos.c:138
BOOL WINAPI SetDoubleClickTime(_In_ UINT)
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define VK_NUMPAD3
Definition: winuser.h:2278
#define WM_INPUT_DEVICE_CHANGE
Definition: winuser.h:1739
#define WM_SYSCOMMAND
Definition: winuser.h:1769
BOOL WINAPI RedrawWindow(_In_opt_ HWND, _In_opt_ LPCRECT, _In_opt_ HRGN, _In_ UINT)
void WINAPI mouse_event(_In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ ULONG_PTR)
#define SC_KEYMENU
Definition: winuser.h:2632
#define VK_TAB
Definition: winuser.h:2235
#define WM_MOUSEFIRST
Definition: winuser.h:1802
#define SWP_FRAMECHANGED
Definition: winuser.h:1251
#define WM_QUIT
Definition: winuser.h:1651
BOOL WINAPI GetKeyboardLayoutNameA(_Out_writes_(KL_NAMELENGTH) LPSTR)
BOOL WINAPI SetKeyboardState(_In_reads_(256) LPBYTE)
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define WM_KEYUP
Definition: winuser.h:1744
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define COLOR_WINDOW
Definition: winuser.h:929
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define WM_MOUSELAST
Definition: winuser.h:1829
#define LLKHF_EXTENDED
Definition: winuser.h:2687
UINT WINAPI MapVirtualKeyExA(_In_ UINT, _In_ UINT, _In_opt_ HKL)
DWORD WINAPI GetMessagePos(void)
Definition: message.c:1351
BOOL WINAPI UnregisterClassA(_In_ LPCSTR, HINSTANCE)
BOOL WINAPI GetClipCursor(_Out_ LPRECT)
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI SwitchDesktop(_In_ HDESK)
#define MOUSEEVENTF_LEFTUP
Definition: winuser.h:1196
#define HWND_TOPMOST
Definition: winuser.h:1219
BOOL WINAPI AttachThreadInput(_In_ DWORD, _In_ DWORD, _In_ BOOL)
#define KL_NAMELENGTH
Definition: winuser.h:122
#define VK_NUMPAD1
Definition: winuser.h:2276
int WINAPI GetKeyNameTextA(_In_ LONG lParam, _Out_writes_(cchSize) LPSTR lpString, _In_ int cchSize)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI SetThreadDesktop(_In_ HDESK)
#define GET_RAWINPUT_CODE_WPARAM(wParam)
Definition: winuser.h:2877
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4469
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
HHOOK WINAPI SetWindowsHookExW(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define VK_NUMPAD2
Definition: winuser.h:2277
UINT WINAPI MapVirtualKeyExW(_In_ UINT, _In_ UINT, _In_opt_ HKL)
#define VK_SPACE
Definition: winuser.h:2255
#define KLF_ACTIVATE
Definition: winuser.h:111
int WINAPI SetWindowRgn(_In_ HWND, _In_opt_ HRGN, _In_ BOOL)
HDESK WINAPI OpenInputDesktop(_In_ DWORD, _In_ BOOL, _In_ DWORD)
LONG WINAPI SetWindowLongW(_In_ HWND, _In_ int, _In_ LONG)
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define VK_CAPITAL
Definition: winuser.h:2242
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1806
int WINAPI ToAscii(_In_ UINT, _In_ UINT, _In_reads_opt_(256) CONST BYTE *, _Out_ LPWORD, _In_ UINT)
BOOL WINAPI ClipCursor(_In_opt_ LPCRECT)
#define SWP_NOMOVE
Definition: winuser.h:1255
#define MAPVK_VSC_TO_VK_EX
Definition: winuser.h:2394
#define VK_NUMPAD4
Definition: winuser.h:2279
#define KF_ALTDOWN
Definition: winuser.h:2485
#define VK_SCROLL
Definition: winuser.h:2316
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define RIDEV_NOLEGACY
Definition: winuser.h:2963
#define KF_EXTENDED
Definition: winuser.h:2482
#define IDC_ARROW
Definition: winuser.h:695
#define WM_KEYFIRST
Definition: winuser.h:1742
#define VK_CONTROL
Definition: winuser.h:2239
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:3064
#define HC_ACTION
Definition: winuser.h:48
#define WM_NCHITTEST
Definition: winuser.h:1714
#define WM_RBUTTONUP
Definition: winuser.h:1808
#define VK_RSHIFT
Definition: winuser.h:2319
#define VK_UP
Definition: winuser.h:2261
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_SETFOCUS
Definition: winuser.h:1641
#define QS_ALLINPUT
Definition: winuser.h:914
BOOL WINAPI EnumDisplayMonitors(_In_opt_ HDC, _In_opt_ LPCRECT, _In_ MONITORENUMPROC, _In_ LPARAM)
int WINAPI ToUnicode(_In_ UINT wVirtKey, _In_ UINT wScanCode, _In_reads_bytes_opt_(256) CONST BYTE *lpKeyState, _Out_writes_(cchBuff) LPWSTR pwszBuff, _In_ int cchBuff, _In_ UINT wFlags)
HWINSTA WINAPI CreateWindowStationA(_In_opt_ LPCSTR lpwinsta, _In_ DWORD dwFlags, _In_ ACCESS_MASK dwDesiredAccess, _In_opt_ LPSECURITY_ATTRIBUTES lpsa)
#define SWP_NOSIZE
Definition: winuser.h:1256
BOOL WINAPI CloseWindowStation(_In_ HWINSTA)
#define WM_MOUSEMOVE
Definition: winuser.h:1803
#define MOUSEEVENTF_RIGHTUP
Definition: winuser.h:1198
#define WM_INPUT
Definition: winuser.h:1740
#define RDW_ERASE
Definition: winuser.h:1222
_Check_return_ BOOL WINAPI GetKeyboardState(_Out_writes_(256) PBYTE lpKeyState)
#define VK_LSHIFT
Definition: winuser.h:2318
#define WM_LBUTTONDOWN
Definition: winuser.h:1804
BOOL WINAPI SetCursorPos(_In_ int, _In_ int)
Definition: cursoricon.c:3056
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2474
#define VK_LCONTROL
Definition: winuser.h:2320
#define VK_NUMPAD0
Definition: winuser.h:2275
#define LLKHF_ALTDOWN
Definition: winuser.h:2689
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
BOOL WINAPI SetProcessWindowStation(_In_ HWINSTA)
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
UINT WINAPI GetDoubleClickTime(void)
Definition: ntwrapper.h:314
#define VK_NUMPAD6
Definition: winuser.h:2281
#define MAPVK_VSC_TO_VK
Definition: winuser.h:2392
#define VK_NEXT
Definition: winuser.h:2257
#define VK_RCONTROL
Definition: winuser.h:2321
#define WM_RBUTTONDOWN
Definition: winuser.h:1807
#define MOUSEEVENTF_MOVE
Definition: winuser.h:1194
#define KF_UP
Definition: winuser.h:2487
UINT WINAPI MapVirtualKeyW(_In_ UINT, _In_ UINT)
#define WINSTA_ALL_ACCESS
Definition: winuser.h:417
#define WH_MOUSE_LL
Definition: winuser.h:44
#define MOUSEEVENTF_LEFTDOWN
Definition: winuser.h:1195
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define WM_SYSCHAR
Definition: winuser.h:1749
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
BOOL WINAPI OemToCharBuffW(_In_ LPCSTR lpszSrc, _Out_writes_(cchDstLength) LPWSTR lpszDst, _In_ DWORD cchDstLength)
#define VK_RETURN
Definition: winuser.h:2237
HWND WINAPI SetFocus(_In_opt_ HWND)
HKL WINAPI LoadKeyboardLayoutW(_In_ LPCWSTR, _In_ UINT)
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
HWND WINAPI SetActiveWindow(_In_ HWND)
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
int WINAPI GetKeyNameTextW(_In_ LONG lParam, _Out_writes_(cchSize) LPWSTR lpString, _In_ int cchSize)
UINT WINAPI GetKeyboardLayoutList(_In_ int nBuff, _Out_writes_to_opt_(nBuff, return) HKL FAR *lpList)
#define VK_RMENU
Definition: winuser.h:2323
#define VK_NUMPAD9
Definition: winuser.h:2284
#define RDW_ALLCHILDREN
Definition: winuser.h:1232
#define VK_END
Definition: winuser.h:2258
#define VK_HOME
Definition: winuser.h:2259
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define PM_REMOVE
Definition: winuser.h:1207
#define RDW_FRAME
Definition: winuser.h:1223
BOOL WINAPI UpdateWindow(_In_ HWND)
#define SWP_SHOWWINDOW
Definition: winuser.h:1259
#define WM_SYSKEYUP
Definition: winuser.h:1748
#define RIDEV_INPUTSINK
Definition: winuser.h:2964
HKL WINAPI LoadKeyboardLayoutA(_In_ LPCSTR, _In_ UINT)
#define WH_KEYBOARD_LL
Definition: winuser.h:43
#define WS_EX_LAYERED
Definition: winuser.h:389
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4470
VOID WINAPI keybd_event(_In_ BYTE, _In_ BYTE, _In_ DWORD, _In_ ULONG_PTR)
#define WM_LBUTTONUP
Definition: winuser.h:1805
LONG WINAPI GetMessageTime(void)
Definition: message.c:1361
#define WM_CHAR
Definition: winuser.h:1745
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
#define VK_LEFT
Definition: winuser.h:2260
#define KEYEVENTF_EXTENDEDKEY
Definition: winuser.h:1112
#define VK_NUMPAD7
Definition: winuser.h:2282
#define VK_RIGHT
Definition: winuser.h:2262
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define VK_DOWN
Definition: winuser.h:2263
#define MOUSEEVENTF_RIGHTDOWN
Definition: winuser.h:1197
#define HTTRANSPARENT
Definition: winuser.h:2509
int WINAPI ToUnicodeEx(_In_ UINT wVirtKey, _In_ UINT wScanCode, _In_reads_bytes_(256) CONST BYTE *lpKeyState, _Out_writes_(cchBuff) LPWSTR pwszBuff, _In_ int cchBuff, _In_ UINT wFlags, _In_opt_ HKL dwhkl)
#define VK_NUMLOCK
Definition: winuser.h:2315
struct tagMONITORINFO MONITORINFO
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define KF_REPEAT
Definition: winuser.h:2486
#define WM_USER
Definition: winuser.h:1923
#define VK_SHIFT
Definition: winuser.h:2238
#define SW_SHOW
Definition: winuser.h:786
#define VK_PRIOR
Definition: winuser.h:2256
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
#define MAPVK_VK_TO_VSC
Definition: winuser.h:2391
SHORT WINAPI GetAsyncKeyState(_In_ int)
#define WM_KEYDOWN
Definition: winuser.h:1743
BOOL WINAPI GetMonitorInfoW(_In_ HMONITOR, _Inout_ LPMONITORINFO)
#define VK_NUMPAD8
Definition: winuser.h:2283
BOOL WINAPI CloseDesktop(_In_ HDESK)
HKL WINAPI ActivateKeyboardLayout(_In_ HKL, _In_ UINT)
#define MAPVK_VK_TO_VSC_EX
Definition: winuser.h:2395
DWORD WINAPI OemKeyScan(_In_ WORD)
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
#define RIDEV_REMOVE
Definition: winuser.h:2960
BOOL WINAPI UnionRect(_Out_ LPRECT, _In_ LPCRECT, _In_ LPCRECT)
#define SetWindowLongPtrW
Definition: winuser.h:5512
BOOL WINAPI InflateRect(_Inout_ LPRECT, _In_ int, _In_ int)
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#define WM_KEYLAST
Definition: winuser.h:1756
int WINAPI ToAsciiEx(_In_ UINT, _In_ UINT, _In_reads_opt_(256) CONST BYTE *, _Out_ LPWORD, _In_ UINT, _In_opt_ HKL)
SHORT WINAPI VkKeyScanW(_In_ WCHAR)
LPARAM WINAPI GetMessageExtraInfo(void)
Definition: message.c:1340
BOOL WINAPI DestroyWindow(_In_ HWND)
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
#define KEYEVENTF_KEYUP
Definition: winuser.h:1113
#define WM_SYSKEYDOWN
Definition: winuser.h:1747
#define VK_INSERT
Definition: winuser.h:2268
#define RDW_INVALIDATE
Definition: winuser.h:1225
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2459
SHORT WINAPI GetKeyState(_In_ int)
#define VK_LMENU
Definition: winuser.h:2322
#define VK_MENU
Definition: winuser.h:2240
#define GWL_EXSTYLE
Definition: winuser.h:862
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193