ReactOS  0.4.13-dev-544-gede3fdd
input.c
Go to the documentation of this file.
1 /* Test Key event to Key message translation
2  *
3  * Copyright 2003 Rein Klazes
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 /* test whether the right type of messages:
21  * WM_KEYUP/DOWN vs WM_SYSKEYUP/DOWN are sent in case of combined
22  * keystrokes.
23  *
24  * For instance <ALT>-X can be accomplished by
25  * the sequence ALT-KEY-DOWN, X-KEY-DOWN, ALT-KEY-UP, X-KEY-UP
26  * but also X-KEY-DOWN, ALT-KEY-DOWN, X-KEY-UP, ALT-KEY-UP
27  * Whether a KEY or a SYSKEY message is sent is not always clear, it is
28  * also not the same in WINNT as in WIN9X */
29 
30 /* NOTE that there will be test failures under WIN9X
31  * No applications are known to me that rely on this
32  * so I don't fix it */
33 
34 /* TODO:
35  * 1. extend it to the wm_command and wm_syscommand notifications
36  * 2. add some more tests with special cases like dead keys or right (alt) key
37  * 3. there is some adapted code from input.c in here. Should really
38  * make that code exactly the same.
39  * 4. resolve the win9x case when there is a need or the testing frame work
40  * offers a nice way.
41  * 5. The test app creates a window, the user should not take the focus
42  * away during its short existence. I could do something to prevent that
43  * if it is a problem.
44  *
45  */
46 
47 #ifndef __REACTOS__
48 #define _WIN32_WINNT 0x401
49 #define _WIN32_IE 0x0500
50 #endif
51 
52 #include <stdarg.h>
53 #include <assert.h>
54 
55 #include "windef.h"
56 #include "winbase.h"
57 #include "winuser.h"
58 #include "wingdi.h"
59 #include "winnls.h"
60 
61 #include "wine/test.h"
62 
63 #ifdef __REACTOS__
64 #include <reactos/undocuser.h>
65 #endif
66 
67 /* globals */
68 static HWND hWndTest;
69 static LONG timetag = 0x10000000;
70 
71 static struct {
84 } key_status;
85 
86 static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t);
87 static int (WINAPI *pGetMouseMovePointsEx) (UINT, LPMOUSEMOVEPOINT, LPMOUSEMOVEPOINT, int, DWORD);
88 static UINT (WINAPI *pGetRawInputDeviceList) (PRAWINPUTDEVICELIST, PUINT, UINT);
89 static int (WINAPI *pGetWindowRgnBox)(HWND, LPRECT);
90 
91 #define MAXKEYEVENTS 12
92 #define MAXKEYMESSAGES MAXKEYEVENTS /* assuming a key event generates one
93  and only one message */
94 
95 /* keyboard message names, sorted as their value */
96 static const char *MSGNAME[]={"WM_KEYDOWN", "WM_KEYUP", "WM_CHAR","WM_DEADCHAR",
97  "WM_SYSKEYDOWN", "WM_SYSKEYUP", "WM_SYSCHAR", "WM_SYSDEADCHAR" ,"WM_KEYLAST"};
98 
99 /* keyevents, add more as needed */
100 typedef enum KEVtag
102 /* matching VK's */
103 static const int GETVKEY[]={0, VK_MENU, VK_MENU, 'X', 'X', VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL};
104 /* matching scan codes */
105 static const int GETSCAN[]={0, 0x38, 0x38, 0x2D, 0x2D, 0x2A, 0x2A, 0x1D, 0x1D };
106 /* matching updown events */
108 /* matching descriptions */
109 static const char *getdesc[]={"", "+alt","-alt","+X","-X","+shift","-shift","+ctrl","-ctrl"};
110 
111 /* The MSVC headers ignore our NONAMELESSUNION requests so we have to define our own type */
112 typedef struct
113 {
114  DWORD type;
115  union
116  {
117  MOUSEINPUT mi;
118  KEYBDINPUT ki;
119  HARDWAREINPUT hi;
120  } u;
121 } TEST_INPUT;
122 
123 #define ADDTOINPUTS(kev) \
124 inputs[evtctr].type = INPUT_KEYBOARD; \
125  ((TEST_INPUT*)inputs)[evtctr].u.ki.wVk = GETVKEY[ kev]; \
126  ((TEST_INPUT*)inputs)[evtctr].u.ki.wScan = GETSCAN[ kev]; \
127  ((TEST_INPUT*)inputs)[evtctr].u.ki.dwFlags = GETFLAGS[ kev]; \
128  ((TEST_INPUT*)inputs)[evtctr].u.ki.dwExtraInfo = 0; \
129  ((TEST_INPUT*)inputs)[evtctr].u.ki.time = ++timetag; \
130  if( kev) evtctr++;
131 
132 typedef struct {
136 } KMSG;
137 
138 /*******************************************
139  * add new test sets here
140  * the software will make all combinations of the
141  * keyevent defined here
142  */
143 static const struct {
144  int nrkev;
147 } testkeyset[]= {
148  { 2, { ALTDOWN, XDOWN }, { ALTUP, XUP}},
149  { 3, { ALTDOWN, XDOWN , SHIFTDOWN}, { ALTUP, XUP, SHIFTUP}},
150  { 3, { ALTDOWN, XDOWN , CTRLDOWN}, { ALTUP, XUP, CTRLUP}},
151  { 3, { SHIFTDOWN, XDOWN , CTRLDOWN}, { SHIFTUP, XUP, CTRLUP}},
152  { 0 } /* mark the end */
153 };
154 
155 /**********************adapted from input.c **********************************/
156 
159 static BYTE TrackSysKey = 0; /* determine whether ALT key up will cause a WM_SYSKEYUP
160  or a WM_KEYUP message */
161 
162 static void init_function_pointers(void)
163 {
164  HMODULE hdll = GetModuleHandleA("user32");
165 
166 #define GET_PROC(func) \
167  p ## func = (void*)GetProcAddress(hdll, #func); \
168  if(!p ## func) \
169  trace("GetProcAddress(%s) failed\n", #func);
170 
172  GET_PROC(GetMouseMovePointsEx)
175 
176 #undef GET_PROC
177 }
178 
179 static int KbdMessage( KEV kev, WPARAM *pwParam, LPARAM *plParam )
180 {
181  UINT message;
182  int VKey = GETVKEY[kev];
183  WORD flags;
184 
185  flags = LOBYTE(GETSCAN[kev]);
187 
188  if (GETFLAGS[kev] & KEYEVENTF_KEYUP )
189  {
190  message = WM_KEYUP;
191  if( (InputKeyStateTable[VK_MENU] & 0x80) && (
192  (VKey == VK_MENU) || (VKey == VK_CONTROL) ||
193  !(InputKeyStateTable[VK_CONTROL] & 0x80))) {
194  if( TrackSysKey == VK_MENU || /* <ALT>-down/<ALT>-up sequence */
195  (VKey != VK_MENU)) /* <ALT>-down...<something else>-up */
197  TrackSysKey = 0;
198  }
199  InputKeyStateTable[VKey] &= ~0x80;
200  flags |= KF_REPEAT | KF_UP;
201  }
202  else
203  {
204  if (InputKeyStateTable[VKey] & 0x80) flags |= KF_REPEAT;
205  if (!(InputKeyStateTable[VKey] & 0x80)) InputKeyStateTable[VKey] ^= 0x01;
206  InputKeyStateTable[VKey] |= 0x80;
207  AsyncKeyStateTable[VKey] |= 0x80;
208 
210  if( (InputKeyStateTable[VK_MENU] & 0x80) &&
211  !(InputKeyStateTable[VK_CONTROL] & 0x80)) {
213  TrackSysKey = VKey;
214  }
215  }
216 
217  if (InputKeyStateTable[VK_MENU] & 0x80) flags |= KF_ALTDOWN;
218 
219  if( plParam) *plParam = MAKELPARAM( 1, flags );
220  if( pwParam) *pwParam = VKey;
221  return message;
222 }
223 
224 /****************************** end copy input.c ****************************/
225 
226 /*
227  * . prepare the keyevents for SendInputs
228  * . calculate the "expected" messages
229  * . Send the events to our window
230  * . retrieve the messages from the input queue
231  * . verify
232  */
233 static BOOL do_test( HWND hwnd, int seqnr, const KEV td[] )
234 {
235  INPUT inputs[MAXKEYEVENTS];
236  KMSG expmsg[MAXKEYEVENTS];
237  MSG msg;
238  char buf[100];
239  UINT evtctr=0;
240  int kmctr, i;
241 
242  buf[0]='\0';
243  TrackSysKey=0; /* see input.c */
244  for( i = 0; i < MAXKEYEVENTS; i++) {
245  ADDTOINPUTS(td[i])
246  strcat(buf, getdesc[td[i]]);
247  if(td[i])
248  expmsg[i].message = KbdMessage(td[i], &(expmsg[i].wParam), &(expmsg[i].lParam));
249  else
250  expmsg[i].message = 0;
251  }
252  for( kmctr = 0; kmctr < MAXKEYEVENTS && expmsg[kmctr].message; kmctr++)
253  ;
254  ok( evtctr <= MAXKEYEVENTS, "evtctr is above MAXKEYEVENTS\n" );
255  if( evtctr != pSendInput(evtctr, &inputs[0], sizeof(INPUT)))
256  ok (FALSE, "SendInput failed to send some events\n");
257  i = 0;
258  if (winetest_debug > 1)
259  trace("======== key stroke sequence #%d: %s =============\n",
260  seqnr + 1, buf);
262  if (winetest_debug > 1)
263  trace("message[%d] %-15s wParam %04lx lParam %08lx time %x\n", i,
264  MSGNAME[msg.message - WM_KEYFIRST], msg.wParam, msg.lParam, msg.time);
265  if( i < kmctr ) {
266  ok( msg.message == expmsg[i].message &&
267  msg.wParam == expmsg[i].wParam &&
268  msg.lParam == expmsg[i].lParam,
269  "%u/%u: wrong message %x/%08lx/%08lx expected %s/%08lx/%08lx\n",
270  seqnr, i, msg.message, msg.wParam, msg.lParam,
271  MSGNAME[(expmsg[i]).message - WM_KEYFIRST], expmsg[i].wParam, expmsg[i].lParam );
272  }
273  i++;
274  }
275  if (winetest_debug > 1)
276  trace("%d messages retrieved\n", i);
277  if (!i && kmctr)
278  {
279  skip( "simulated keyboard input doesn't work\n" );
280  return FALSE;
281  }
282  ok( i == kmctr, "message count is wrong: got %d expected: %d\n", i, kmctr);
283  return TRUE;
284 }
285 
286 /* test all combinations of the specified key events */
287 static BOOL TestASet( HWND hWnd, int nrkev, const KEV kevdwn[], const KEV kevup[] )
288 {
289  int i,j,k,l,m,n;
290  static int count=0;
291  KEV kbuf[MAXKEYEVENTS];
292  assert( nrkev==2 || nrkev==3);
293  for(i=0;i<MAXKEYEVENTS;i++) kbuf[i]=0;
294  /* two keys involved gives 4 test cases */
295  if(nrkev==2) {
296  for(i=0;i<nrkev;i++) {
297  for(j=0;j<nrkev;j++) {
298  kbuf[0] = kevdwn[i];
299  kbuf[1] = kevdwn[1-i];
300  kbuf[2] = kevup[j];
301  kbuf[3] = kevup[1-j];
302  if (!do_test( hWnd, count++, kbuf)) return FALSE;
303  }
304  }
305  }
306  /* three keys involved gives 36 test cases */
307  if(nrkev==3){
308  for(i=0;i<nrkev;i++){
309  for(j=0;j<nrkev;j++){
310  if(j==i) continue;
311  for(k=0;k<nrkev;k++){
312  if(k==i || k==j) continue;
313  for(l=0;l<nrkev;l++){
314  for(m=0;m<nrkev;m++){
315  if(m==l) continue;
316  for(n=0;n<nrkev;n++){
317  if(n==l ||n==m) continue;
318  kbuf[0] = kevdwn[i];
319  kbuf[1] = kevdwn[j];
320  kbuf[2] = kevdwn[k];
321  kbuf[3] = kevup[l];
322  kbuf[4] = kevup[m];
323  kbuf[5] = kevup[n];
324  if (!do_test( hWnd, count++, kbuf)) return FALSE;
325  }
326  }
327  }
328  }
329  }
330  }
331  }
332  return TRUE;
333 }
334 
335 /* test each set specified in the global testkeyset array */
336 static void TestSysKeys( HWND hWnd)
337 {
338  int i;
339  for(i=0; testkeyset[i].nrkev;i++)
341 }
342 
344  LPARAM lParam )
345 {
346  return DefWindowProcA( hWnd, msg, wParam, lParam );
347 }
348 
349 static void test_Input_whitebox(void)
350 {
351  MSG msg;
352  WNDCLASSA wclass;
354 
355  wclass.lpszClassName = "InputSysKeyTestClass";
356  wclass.style = CS_HREDRAW | CS_VREDRAW;
357  wclass.lpfnWndProc = WndProc;
358  wclass.hInstance = hInstance;
359  wclass.hIcon = LoadIconA( 0, (LPCSTR)IDI_APPLICATION );
360  wclass.hCursor = LoadCursorA( NULL, (LPCSTR)IDC_ARROW );
361  wclass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
362  wclass.lpszMenuName = 0;
363  wclass.cbClsExtra = 0;
364  wclass.cbWndExtra = 0;
365  RegisterClassA( &wclass );
366  /* create the test window that will receive the keystrokes */
367  hWndTest = CreateWindowA( wclass.lpszClassName, "InputSysKeyTest",
368  WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100,
369  NULL, NULL, hInstance, NULL);
370  assert( hWndTest );
375 
376  /* flush pending messages */
377  while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
378 
379  SetFocus( hWndTest );
382 }
383 
385 {
386  return (message >= WM_KEYFIRST && message <= WM_KEYLAST);
387 }
388 
390 {
391  return (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST);
392 }
393 
394 /* try to make sure pending X events have been processed before continuing */
395 static void empty_message_queue(void)
396 {
397  MSG msg;
398  int diff = 200;
399  int min_timeout = 50;
400  DWORD time = GetTickCount() + diff;
401 
402  while (diff > 0)
403  {
404  if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT) break;
405  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
406  {
407  if (is_keyboard_message(msg.message) || is_mouse_message(msg.message))
408  ok(msg.time != 0, "message %#x has time set to 0\n", msg.message);
409 
412  }
413  diff = time - GetTickCount();
414  }
415 }
416 
417 struct transition_s {
421 };
422 
423 typedef enum {
424  sent=0x1,
425  posted=0x2,
426  parent=0x4,
427  wparam=0x8,
428  lparam=0x10,
431  optional=0x80,
432  hook=0x100,
434 } msg_flags_t;
435 
436 struct message {
437  UINT message; /* the WM_* code */
438  msg_flags_t flags; /* message props */
439  WPARAM wParam; /* expected value of wParam */
440  LPARAM lParam; /* expected value of lParam */
441 };
442 
443 static const struct sendinput_test_s {
449 } sendinput_test[] = {
450  /* test ALT+F */
451  /* 0 */
452  {VK_LMENU, 0, FALSE, {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}},
454  {'F', 0, FALSE, {{'F', 0x00}, {0}},
456  {WM_SYSCHAR},
457  {WM_SYSCOMMAND}, {0}}},
458  {'F', KEYEVENTF_KEYUP, FALSE, {{'F', 0x80}, {0}},
459  {{WM_SYSKEYUP, hook}, {WM_SYSKEYUP}, {0}}},
460  {VK_LMENU, KEYEVENTF_KEYUP, FALSE, {{VK_MENU, 0x80}, {VK_LMENU, 0x80}, {0}},
461  {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
462 
463  /* test CTRL+O */
464  /* 4 */
465  {VK_LCONTROL, 0, FALSE, {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
466  {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}},
467  {'O', 0, FALSE, {{'O', 0x00}, {0}},
468  {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {WM_CHAR}, {0}}},
469  {'O', KEYEVENTF_KEYUP, FALSE, {{'O', 0x80}, {0}},
470  {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
471  {VK_LCONTROL, KEYEVENTF_KEYUP, FALSE, {{VK_CONTROL, 0x80}, {VK_LCONTROL, 0x80}, {0}},
472  {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
473 
474  /* test ALT+CTRL+X */
475  /* 8 */
476  {VK_LMENU, 0, FALSE, {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}},
477  {{WM_SYSKEYDOWN, hook}, {WM_SYSKEYDOWN}, {0}}},
478  {VK_LCONTROL, 0, FALSE, {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
479  {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}},
480  {'X', 0, FALSE, {{'X', 0x00}, {0}},
481  {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}},
482  {'X', KEYEVENTF_KEYUP, FALSE, {{'X', 0x80}, {0}},
483  {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
484  {VK_LCONTROL, KEYEVENTF_KEYUP, FALSE, {{VK_CONTROL, 0x80}, {VK_LCONTROL, 0x80}, {0}},
485  {{WM_SYSKEYUP, hook}, {WM_SYSKEYUP}, {0}}},
486  {VK_LMENU, KEYEVENTF_KEYUP, FALSE, {{VK_MENU, 0x80}, {VK_LMENU, 0x80}, {0}},
487  {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
488 
489  /* test SHIFT+A */
490  /* 14 */
491  {VK_LSHIFT, 0, FALSE, {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}},
492  {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}},
493  {'A', 0, FALSE, {{'A', 0x00}, {0}},
494  {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {WM_CHAR}, {0}}},
495  {'A', KEYEVENTF_KEYUP, FALSE, {{'A', 0x80}, {0}},
496  {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
497  {VK_LSHIFT, KEYEVENTF_KEYUP, FALSE, {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80}, {0}},
498  {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
499  /* test L-SHIFT & R-SHIFT: */
500  /* RSHIFT == LSHIFT */
501  /* 18 */
502  {VK_RSHIFT, 0, FALSE,
503  /* recent windows versions (>= w2k3) correctly report an RSHIFT transition */
504  {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00, TRUE}, {VK_RSHIFT, 0x00, TRUE}, {0}},
506  {WM_KEYDOWN}, {0}}},
508  {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80, TRUE}, {VK_RSHIFT, 0x80, TRUE}, {0}},
510  {WM_KEYUP}, {0}}},
511 
512  /* LSHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */
513  /* 20 */
515  {{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}},
517  {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
519  {{VK_SHIFT, 0x80}, {VK_RSHIFT, 0x80}, {0}},
521  {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
522  /* RSHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */
523  /* 22 */
525  {{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}},
527  {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
529  {{VK_SHIFT, 0x80}, {VK_RSHIFT, 0x80}, {0}},
531  {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
532 
533  /* Note about wparam for hook with generic key (VK_SHIFT, VK_CONTROL, VK_MENU):
534  win2k - sends to hook whatever we generated here
535  winXP+ - Attempts to convert key to L/R key but not always correct
536  */
537  /* SHIFT == LSHIFT */
538  /* 24 */
539  {VK_SHIFT, 0, FALSE,
540  {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}},
541  {{WM_KEYDOWN, hook/* |wparam */|lparam, VK_SHIFT, 0},
542  {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
544  {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80}, {0}},
545  {{WM_KEYUP, hook/*|wparam*/|lparam, VK_SHIFT, LLKHF_UP},
546  {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
547  /* SHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */
548  /* 26 */
550  {{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}},
551  {{WM_KEYDOWN, hook/*|wparam*/|lparam, VK_SHIFT, LLKHF_EXTENDED},
552  {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
554  {{VK_SHIFT, 0x80}, {VK_RSHIFT, 0x80}, {0}},
556  {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
557 
558  /* test L-CONTROL & R-CONTROL: */
559  /* RCONTROL == LCONTROL */
560  /* 28 */
561  {VK_RCONTROL, 0, FALSE,
562  {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
564  {WM_KEYDOWN, wparam|lparam, VK_CONTROL, 0}, {0}}},
566  {{VK_CONTROL, 0x80}, {VK_LCONTROL, 0x80}, {0}},
568  {WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP}, {0}}},
569  /* LCONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */
570  /* 30 */
572  {{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}},
576  {{VK_CONTROL, 0x80}, {VK_RCONTROL, 0x80}, {0}},
579  /* RCONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */
580  /* 32 */
582  {{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}},
586  {{VK_CONTROL, 0x80}, {VK_RCONTROL, 0x80}, {0}},
589  /* CONTROL == LCONTROL */
590  /* 34 */
591  {VK_CONTROL, 0, FALSE,
592  {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
593  {{WM_KEYDOWN, hook/*|wparam, VK_CONTROL*/},
594  {WM_KEYDOWN, wparam|lparam, VK_CONTROL, 0}, {0}}},
596  {{VK_CONTROL, 0x80}, {VK_LCONTROL, 0x80}, {0}},
597  {{WM_KEYUP, hook/*|wparam, VK_CONTROL*/},
598  {WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP}, {0}}},
599  /* CONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */
600  /* 36 */
602  {{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}},
606  {{VK_CONTROL, 0x80}, {VK_RCONTROL, 0x80}, {0}},
609 
610  /* test L-MENU & R-MENU: */
611  /* RMENU == LMENU */
612  /* 38 */
613  {VK_RMENU, 0, FALSE,
614  {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {VK_CONTROL, 0x00, 1}, {VK_LCONTROL, 0x01, 1}, {0}},
618  {WM_SYSKEYDOWN, wparam|lparam, VK_MENU, 0}, {0}}},
620  {{VK_MENU, 0x80}, {VK_LMENU, 0x80}, {VK_CONTROL, 0x81, 1}, {VK_LCONTROL, 0x80, 1}, {0}},
625  {WM_SYSCOMMAND, optional}, {0}}},
626  /* LMENU | KEYEVENTF_EXTENDEDKEY == RMENU */
627  /* 40 */
629  {{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {0}},
633  {{VK_MENU, 0x80}, {VK_RMENU, 0x80}, {0}},
636  {WM_SYSCOMMAND}, {0}}},
637  /* RMENU | KEYEVENTF_EXTENDEDKEY == RMENU */
638  /* 42 */
640  {{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {VK_CONTROL, 0x00, 1}, {VK_LCONTROL, 0x01, 1}, {0}},
646  {{VK_MENU, 0x80}, {VK_RMENU, 0x80}, {VK_CONTROL, 0x81, 1}, {VK_LCONTROL, 0x80, 1}, {0}},
651  {WM_SYSCOMMAND, optional}, {0}}},
652  /* MENU == LMENU */
653  /* 44 */
654  {VK_MENU, 0, FALSE,
655  {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}},
656  {{WM_SYSKEYDOWN, hook/*|wparam, VK_MENU*/},
657  {WM_SYSKEYDOWN, wparam|lparam, VK_MENU, 0}, {0}}},
659  {{VK_MENU, 0x80}, {VK_LMENU, 0x80}, {0}},
660  {{WM_KEYUP, hook/*|wparam, VK_MENU*/},
662  {WM_SYSCOMMAND}, {0}}},
663  /* MENU | KEYEVENTF_EXTENDEDKEY == RMENU */
664  /* 46 */
666  {{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {VK_CONTROL, 0x00, 1}, {VK_LCONTROL, 0x01, 1}, {0}},
671  {{VK_MENU, 0x80}, {VK_RMENU, 0x80}, {VK_CONTROL, 0x81, 1}, {VK_LCONTROL, 0x80, 1}, {0}},
675  {WM_SYSCOMMAND}, {0}}},
676 
677  /* test LSHIFT & RSHIFT */
678  /* 48 */
679  {VK_LSHIFT, 0, FALSE,
680  {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}},
682  {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
684  {{VK_RSHIFT, 0x00}, {0}},
686  {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
688  {{VK_RSHIFT, 0x80}, {0}},
690  {WM_KEYUP, optional}, {0}}},
692  {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80}, {0}},
694  {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
695 
696  {0, 0, FALSE, {{0}}, {{0}}} /* end */
697 };
698 
701 
702 /* Verify that only specified key state transitions occur */
703 static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, const struct sendinput_test_s *test)
704 {
705  int i, failcount = 0;
706  const struct transition_s *t = test->expected_transitions;
707  UINT actual_cnt = 0;
708  const struct message *expected = test->expected_messages;
709 
710  while (t->wVk) {
711  BOOL matched = ((ks1[t->wVk]&0x80) == (t->before_state&0x80)
712  && (ks2[t->wVk]&0x80) == (~t->before_state&0x80));
713 
714  if (!matched && !t->optional && test->_todo_wine)
715  {
716  failcount++;
717  todo_wine {
718  ok(matched, "%2d (%x/%x): %02x from %02x -> %02x "
719  "instead of %02x -> %02x\n", id, test->wVk, test->dwFlags,
720  t->wVk, ks1[t->wVk]&0x80, ks2[t->wVk]&0x80, t->before_state,
721  ~t->before_state&0x80);
722  }
723  } else {
724  ok(matched || t->optional, "%2d (%x/%x): %02x from %02x -> %02x "
725  "instead of %02x -> %02x\n", id, test->wVk, test->dwFlags,
726  t->wVk, ks1[t->wVk]&0x80, ks2[t->wVk]&0x80, t->before_state,
727  ~t->before_state&0x80);
728  }
729  ks2[t->wVk] = ks1[t->wVk]; /* clear the match */
730  t++;
731  }
732  for (i = 0; i < 256; i++)
733  if (ks2[i] != ks1[i] && test->_todo_wine)
734  {
735  failcount++;
736  todo_wine
737  ok(FALSE, "%2d (%x/%x): %02x from %02x -> %02x unexpected\n",
738  id, test->wVk, test->dwFlags, i, ks1[i], ks2[i]);
739  }
740  else
741  ok(ks2[i] == ks1[i], "%2d (%x/%x): %02x from %02x -> %02x unexpected\n",
742  id, test->wVk, test->dwFlags, i, ks1[i], ks2[i]);
743 
744  while (expected->message && actual_cnt < sent_messages_cnt)
745  {
746  const struct message *actual = &sent_messages[actual_cnt];
747 
748  if (expected->message == actual->message)
749  {
750  if (expected->flags & wparam)
751  {
752  if ((expected->flags & optional) && (expected->wParam != actual->wParam))
753  {
754  expected++;
755  continue;
756  }
757  if (expected->wParam != actual->wParam && test->_todo_wine)
758  {
759  failcount++;
760  todo_wine
761  ok(FALSE, "%2d (%x/%x): in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
762  id, test->wVk, test->dwFlags, expected->message, expected->wParam, actual->wParam);
763  }
764  else
765  ok(expected->wParam == actual->wParam,
766  "%2d (%x/%x): in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
767  id, test->wVk, test->dwFlags, expected->message, expected->wParam, actual->wParam);
768  }
769  if (expected->flags & lparam)
770  {
771  if (expected->lParam != actual->lParam && test->_todo_wine)
772  {
773  failcount++;
774  todo_wine
775  ok(FALSE, "%2d (%x/%x): in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
776  id, test->wVk, test->dwFlags, expected->message, expected->lParam, actual->lParam);
777  }
778  else
779  ok(expected->lParam == actual->lParam,
780  "%2d (%x/%x): in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
781  id, test->wVk, test->dwFlags, expected->message, expected->lParam, actual->lParam);
782  }
783  ok((expected->flags & hook) == (actual->flags & hook),
784  "%2d (%x/%x): the msg 0x%04x should have been sent by a hook\n",
785  id, test->wVk, test->dwFlags, expected->message);
786 
787  }
788  else if (expected->flags & optional)
789  {
790  expected++;
791  continue;
792  }
793  /* NT4 doesn't send SYSKEYDOWN/UP to hooks, only KEYDOWN/UP */
794  else if ((expected->flags & hook) &&
795  (expected->message == WM_SYSKEYDOWN || expected->message == WM_SYSKEYUP) &&
796  (actual->message == expected->message - 4))
797  {
798  ok((expected->flags & hook) == (actual->flags & hook),
799  "%2d (%x/%x): the msg 0x%04x should have been sent by a hook\n",
800  id, test->wVk, test->dwFlags, expected->message);
801  }
802  /* For VK_RMENU, at least localized Win2k/XP sends KEYDOWN/UP
803  * instead of SYSKEYDOWN/UP to the WNDPROC */
804  else if (test->wVk == VK_RMENU && !(expected->flags & hook) &&
805  (expected->message == WM_SYSKEYDOWN || expected->message == WM_SYSKEYUP) &&
806  (actual->message == expected->message - 4))
807  {
808  ok(expected->wParam == actual->wParam && expected->lParam == actual->lParam,
809  "%2d (%x/%x): the msg 0x%04x was expected, but got msg 0x%04x instead\n",
810  id, test->wVk, test->dwFlags, expected->message, actual->message);
811  }
812  else if (test->_todo_wine)
813  {
814  failcount++;
815  todo_wine
816  ok(FALSE,
817  "%2d (%x/%x): the msg 0x%04x was expected, but got msg 0x%04x instead\n",
818  id, test->wVk, test->dwFlags, expected->message, actual->message);
819  }
820  else
821  ok(FALSE,
822  "%2d (%x/%x): the msg 0x%04x was expected, but got msg 0x%04x instead\n",
823  id, test->wVk, test->dwFlags, expected->message, actual->message);
824 
825  actual_cnt++;
826  expected++;
827  }
828  /* skip all optional trailing messages */
829  while (expected->message && (expected->flags & optional))
830  expected++;
831 
832 
833  if (expected->message || actual_cnt < sent_messages_cnt)
834  {
835  if (test->_todo_wine)
836  {
837  failcount++;
838  todo_wine
839  ok(FALSE, "%2d (%x/%x): the msg sequence is not complete: expected %04x - actual %04x\n",
840  id, test->wVk, test->dwFlags, expected->message, sent_messages[actual_cnt].message);
841  }
842  else
843  ok(FALSE, "%2d (%x/%x): the msg sequence is not complete: expected %04x - actual %04x\n",
844  id, test->wVk, test->dwFlags, expected->message, sent_messages[actual_cnt].message);
845  }
846 
847  if( test->_todo_wine && !failcount) /* succeeded yet marked todo */
848  todo_wine
849  ok(TRUE, "%2d (%x/%x): marked \"todo_wine\" but succeeds\n", id, test->wVk, test->dwFlags);
850 
851  sent_messages_cnt = 0;
852 }
853 
854 /* WndProc2 checks that we get at least the messages specified */
856  LPARAM lParam)
857 {
858  if (winetest_debug > 1) trace("MSG: %8x W:%8lx L:%8lx\n", Msg, wParam, lParam);
859 
860  if (Msg != WM_PAINT &&
861  Msg != WM_NCPAINT &&
862  Msg != WM_SYNCPAINT &&
863  Msg != WM_ERASEBKGND &&
864  Msg != WM_NCHITTEST &&
865  Msg != WM_GETTEXT &&
866  Msg != WM_GETICON &&
867  Msg != WM_IME_SELECT &&
868  Msg != WM_DEVICECHANGE &&
869  Msg != WM_TIMECHANGE)
870  {
871  ok(sent_messages_cnt < MAXKEYMESSAGES, "Too many messages\n");
873  {
875  sent_messages[sent_messages_cnt].flags = 0;
878  }
879  }
880  return DefWindowProcA(hWnd, Msg, wParam, lParam);
881 }
882 
884 {
885  KBDLLHOOKSTRUCT *hook_info = (KBDLLHOOKSTRUCT *)lparam;
886 
887  if (code == HC_ACTION)
888  {
889  ok(sent_messages_cnt < MAXKEYMESSAGES, "Too many messages\n");
891  {
894  sent_messages[sent_messages_cnt].wParam = hook_info->vkCode;
895  sent_messages[sent_messages_cnt++].lParam = hook_info->flags & (LLKHF_UP|LLKHF_EXTENDED);
896  }
897 
898 if(0) /* For some reason not stable on Wine */
899 {
900  if (wparam == WM_KEYDOWN || wparam == WM_SYSKEYDOWN)
901  ok(!(GetAsyncKeyState(hook_info->vkCode) & 0x8000), "key %x should be up\n", hook_info->vkCode);
902  else if (wparam == WM_KEYUP || wparam == WM_SYSKEYUP)
903  ok(GetAsyncKeyState(hook_info->vkCode) & 0x8000, "key %x should be down\n", hook_info->vkCode);
904 }
905 
906  if (winetest_debug > 1)
907  trace("Hook: w=%lx vk:%8x sc:%8x fl:%8x %lx\n", wparam,
908  hook_info->vkCode, hook_info->scanCode, hook_info->flags, hook_info->dwExtraInfo);
909  }
910  return CallNextHookEx( 0, code, wparam, lparam );
911 }
912 static void test_Input_blackbox(void)
913 {
914  TEST_INPUT i;
915  int ii;
916  BYTE ks1[256], ks2[256];
917  LONG_PTR prevWndProc;
918  HWND window;
919  HHOOK hook;
920 
921  if (GetKeyboardLayout(0) != (HKL)(ULONG_PTR)0x04090409)
922  {
923  skip("Skipping Input_blackbox test on non-US keyboard\n");
924  return;
925  }
927  |WS_VISIBLE, 0, 0, 200, 60, NULL, NULL,
928  NULL, NULL);
929  ok(window != NULL, "error: %d\n", (int) GetLastError());
932 
934  {
936  win_skip("WH_KEYBOARD_LL is not supported\n");
937  return;
938  }
939 
940  /* must process all initial messages, otherwise X11DRV_KeymapNotify unsets
941  * key state set by SendInput(). */
943 
945  ok(prevWndProc != 0 || GetLastError() == 0, "error: %d\n", (int) GetLastError());
946 
947  i.type = INPUT_KEYBOARD;
948  i.u.ki.time = 0;
949  i.u.ki.dwExtraInfo = 0;
950 
951  for (ii = 0; ii < sizeof(sendinput_test)/sizeof(struct sendinput_test_s)-1;
952  ii++) {
953  GetKeyboardState(ks1);
954  i.u.ki.wScan = ii+1 /* useful for debugging */;
955  i.u.ki.dwFlags = sendinput_test[ii].dwFlags;
956  i.u.ki.wVk = sendinput_test[ii].wVk;
957  pSendInput(1, (INPUT*)&i, sizeof(TEST_INPUT));
959  GetKeyboardState(ks2);
960  if (!ii && sent_messages_cnt <= 1 && !memcmp( ks1, ks2, sizeof(ks1) ))
961  {
962  win_skip( "window doesn't receive the queued input\n" );
963  /* release the key */
964  i.u.ki.dwFlags |= KEYEVENTF_KEYUP;
965  pSendInput(1, (INPUT*)&i, sizeof(TEST_INPUT));
966  break;
967  }
968  compare_and_check(ii, ks1, ks2, &sendinput_test[ii]);
969  }
970 
974 }
975 
976 static void reset_key_status(void)
977 {
978  key_status.last_key_down = -1;
979  key_status.last_key_up = -1;
980  key_status.last_syskey_down = -1;
981  key_status.last_syskey_up = -1;
982  key_status.last_char = -1;
983  key_status.last_syschar = -1;
984  key_status.last_hook_down = -1;
985  key_status.last_hook_up = -1;
986  key_status.last_hook_syskey_down = -1;
987  key_status.last_hook_syskey_up = -1;
988  key_status.expect_alt = FALSE;
989  key_status.sendinput_broken = FALSE;
990 }
991 
992 static void test_unicode_keys(HWND hwnd, HHOOK hook)
993 {
994  TEST_INPUT inputs[2];
995  MSG msg;
996 
997  /* init input data that never changes */
998  inputs[1].type = inputs[0].type = INPUT_KEYBOARD;
999  inputs[1].u.ki.dwExtraInfo = inputs[0].u.ki.dwExtraInfo = 0;
1000  inputs[1].u.ki.time = inputs[0].u.ki.time = 0;
1001 
1002  /* pressing & releasing a single unicode character */
1003  inputs[0].u.ki.wVk = 0;
1004  inputs[0].u.ki.wScan = 0x3c0;
1005  inputs[0].u.ki.dwFlags = KEYEVENTF_UNICODE;
1006 
1007  reset_key_status();
1008  pSendInput(1, (INPUT*)inputs, sizeof(INPUT));
1009  while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1010  if(msg.message == WM_KEYDOWN && msg.wParam == VK_PACKET){
1012  }
1014  }
1015  if(!key_status.sendinput_broken){
1016  ok(key_status.last_key_down == VK_PACKET,
1017  "Last keydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_down);
1018  ok(key_status.last_char == 0x3c0,
1019  "Last char msg wparam should have been 0x3c0 (was: 0x%x)\n", key_status.last_char);
1020  if(hook)
1021  ok(key_status.last_hook_down == 0x3c0,
1022  "Last hookdown msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_down);
1023  }
1024 
1025  inputs[1].u.ki.wVk = 0;
1026  inputs[1].u.ki.wScan = 0x3c0;
1027  inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
1028 
1029  reset_key_status();
1030  pSendInput(1, (INPUT*)(inputs+1), sizeof(INPUT));
1031  while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1032  if(msg.message == WM_KEYDOWN && msg.wParam == VK_PACKET){
1034  }
1036  }
1037  if(!key_status.sendinput_broken){
1038  ok(key_status.last_key_up == VK_PACKET,
1039  "Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up);
1040  if(hook)
1041  ok(key_status.last_hook_up == 0x3c0,
1042  "Last hookup msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_up);
1043  }
1044 
1045  /* holding alt, pressing & releasing a unicode character, releasing alt */
1046  inputs[0].u.ki.wVk = VK_LMENU;
1047  inputs[0].u.ki.wScan = 0;
1048  inputs[0].u.ki.dwFlags = 0;
1049 
1050  inputs[1].u.ki.wVk = 0;
1051  inputs[1].u.ki.wScan = 0x3041;
1052  inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE;
1053 
1054  reset_key_status();
1055  key_status.expect_alt = TRUE;
1056  pSendInput(2, (INPUT*)inputs, sizeof(INPUT));
1057  while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1058  if(msg.message == WM_SYSKEYDOWN && msg.wParam == VK_PACKET){
1060  }
1062  }
1063  if(!key_status.sendinput_broken){
1064  ok(key_status.last_syskey_down == VK_PACKET,
1065  "Last syskeydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_syskey_down);
1066  ok(key_status.last_syschar == 0x3041,
1067  "Last syschar msg should have been 0x3041 (was: 0x%x)\n", key_status.last_syschar);
1068  if(hook)
1069  ok(key_status.last_hook_syskey_down == 0x3041,
1070  "Last hooksysdown msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_syskey_down);
1071  }
1072 
1073  inputs[1].u.ki.wVk = 0;
1074  inputs[1].u.ki.wScan = 0x3041;
1075  inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
1076 
1077  inputs[0].u.ki.wVk = VK_LMENU;
1078  inputs[0].u.ki.wScan = 0;
1079  inputs[0].u.ki.dwFlags = KEYEVENTF_KEYUP;
1080 
1081  reset_key_status();
1082  key_status.expect_alt = TRUE;
1083  pSendInput(2, (INPUT*)inputs, sizeof(INPUT));
1084  while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1085  if(msg.message == WM_SYSKEYDOWN && msg.wParam == VK_PACKET){
1087  }
1089  }
1090  if(!key_status.sendinput_broken){
1091  ok(key_status.last_key_up == VK_PACKET,
1092  "Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up);
1093  if(hook)
1094  ok(key_status.last_hook_up == 0x3041,
1095  "Last hook up msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_up);
1096  }
1097 }
1098 
1100  LPARAM lParam )
1101 {
1102  switch(msg){
1103  case WM_KEYDOWN:
1104  key_status.last_key_down = wParam;
1105  break;
1106  case WM_SYSKEYDOWN:
1107  key_status.last_syskey_down = wParam;
1108  break;
1109  case WM_KEYUP:
1110  key_status.last_key_up = wParam;
1111  break;
1112  case WM_SYSKEYUP:
1113  key_status.last_syskey_up = wParam;
1114  break;
1115  case WM_CHAR:
1116  key_status.last_char = wParam;
1117  break;
1118  case WM_SYSCHAR:
1119  key_status.last_syschar = wParam;
1120  break;
1121  }
1122  return DefWindowProcW(hWnd, msg, wParam, lParam);
1123 }
1124 
1126 {
1127  if(nCode == HC_ACTION){
1129  if(!info->vkCode){
1130  key_status.sendinput_broken = TRUE;
1131  win_skip("SendInput doesn't support unicode on this platform\n");
1132  }else{
1133  if(key_status.expect_alt){
1134  ok(info->vkCode == VK_LMENU, "vkCode should have been VK_LMENU[0x%04x], was: 0x%x\n", VK_LMENU, info->vkCode);
1135  key_status.expect_alt = FALSE;
1136  }else
1137  ok(info->vkCode == VK_PACKET, "vkCode should have been VK_PACKET[0x%04x], was: 0x%x\n", VK_PACKET, info->vkCode);
1138  }
1139  switch(wParam){
1140  case WM_KEYDOWN:
1141  key_status.last_hook_down = info->scanCode;
1142  break;
1143  case WM_KEYUP:
1144  key_status.last_hook_up = info->scanCode;
1145  break;
1146  case WM_SYSKEYDOWN:
1147  key_status.last_hook_syskey_down = info->scanCode;
1148  break;
1149  case WM_SYSKEYUP:
1150  key_status.last_hook_syskey_up = info->scanCode;
1151  break;
1152  }
1153  }
1154  return CallNextHookEx(NULL, nCode, wParam, lParam);
1155 }
1156 
1157 static void test_Input_unicode(void)
1158 {
1159  WCHAR classNameW[] = {'I','n','p','u','t','U','n','i','c','o','d','e',
1160  'K','e','y','T','e','s','t','C','l','a','s','s',0};
1161  WCHAR windowNameW[] = {'I','n','p','u','t','U','n','i','c','o','d','e',
1162  'K','e','y','T','e','s','t',0};
1163  MSG msg;
1164  WNDCLASSW wclass;
1166  HHOOK hook;
1167  HMODULE hModuleImm32;
1168  BOOL (WINAPI *pImmDisableIME)(DWORD);
1169 
1170  wclass.lpszClassName = classNameW;
1171  wclass.style = CS_HREDRAW | CS_VREDRAW;
1172  wclass.lpfnWndProc = unicode_wnd_proc;
1173  wclass.hInstance = hInstance;
1174  wclass.hIcon = LoadIconW(0, (LPCWSTR)IDI_APPLICATION);
1175  wclass.hCursor = LoadCursorW( NULL, (LPCWSTR)IDC_ARROW);
1176  wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1177  wclass.lpszMenuName = 0;
1178  wclass.cbClsExtra = 0;
1179  wclass.cbWndExtra = 0;
1180  if(!RegisterClassW(&wclass)){
1181  win_skip("Unicode functions not supported\n");
1182  return;
1183  }
1184 
1185  hModuleImm32 = LoadLibraryA("imm32.dll");
1186  if (hModuleImm32) {
1187  pImmDisableIME = (void *)GetProcAddress(hModuleImm32, "ImmDisableIME");
1188  if (pImmDisableIME)
1189  pImmDisableIME(0);
1190  }
1191  pImmDisableIME = NULL;
1192  FreeLibrary(hModuleImm32);
1193 
1194  /* create the test window that will receive the keystrokes */
1195  hWndTest = CreateWindowW(wclass.lpszClassName, windowNameW,
1196  WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100,
1197  NULL, NULL, hInstance, NULL);
1198 
1199  assert(hWndTest);
1201 
1203  if(!hook)
1204  win_skip("unable to set WH_KEYBOARD_LL hook\n");
1205 
1210 
1211  /* flush pending messages */
1212  while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageW(&msg);
1213 
1214  SetFocus(hWndTest);
1215 
1217 
1218  if(hook)
1221 }
1222 
1223 static void test_keynames(void)
1224 {
1225  int i, len;
1226  char buff[256];
1227 
1228  for (i = 0; i < 512; i++)
1229  {
1230  strcpy(buff, "----");
1231  len = GetKeyNameTextA(i << 16, buff, sizeof(buff));
1232  ok(len || !buff[0], "%d: Buffer is not zeroed\n", i);
1233  }
1234 }
1235 
1237 static BOOL clipped;
1238 #define STEP 3
1239 
1241 {
1243  POINT pt, pt1;
1244 
1245  if (code == HC_ACTION)
1246  {
1247  /* This is our new cursor position */
1248  pt_new = hook->pt;
1249  /* Should return previous position */
1250  GetCursorPos(&pt);
1251  ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1252 
1253  /* Should set new position until hook chain is finished. */
1254  pt.x = pt_old.x + STEP;
1255  pt.y = pt_old.y + STEP;
1256  SetCursorPos(pt.x, pt.y);
1257  GetCursorPos(&pt1);
1258  if (clipped)
1259  ok(pt1.x == pt_old.x && pt1.y == pt_old.y, "Wrong set pos: (%d,%d)\n", pt1.x, pt1.y);
1260  else
1261  ok(pt1.x == pt.x && pt1.y == pt.y, "Wrong set pos: (%d,%d)\n", pt1.x, pt1.y);
1262  }
1263  return CallNextHookEx( 0, code, wparam, lparam );
1264 }
1265 
1267 {
1269  POINT pt;
1270 
1271  if (code == HC_ACTION)
1272  {
1273  ok(hook->pt.x == pt_new.x && hook->pt.y == pt_new.y,
1274  "Wrong hook coords: (%d %d) != (%d,%d)\n", hook->pt.x, hook->pt.y, pt_new.x, pt_new.y);
1275 
1276  /* Should match position set above */
1277  GetCursorPos(&pt);
1278  if (clipped)
1279  ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1280  else
1281  ok(pt.x == pt_old.x +STEP && pt.y == pt_old.y +STEP, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1282  }
1283  return CallNextHookEx( 0, code, wparam, lparam );
1284 }
1285 
1287 {
1288  POINT pt;
1289 
1290  if (code == HC_ACTION)
1291  {
1292  /* MSLLHOOKSTRUCT does not seem to be reliable and contains different data on each run. */
1293  GetCursorPos(&pt);
1294  ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1295  }
1296  return CallNextHookEx( 0, code, wparam, lparam );
1297 }
1298 
1299 static void test_mouse_ll_hook(void)
1300 {
1301  HWND hwnd;
1302  HHOOK hook1, hook2;
1303  POINT pt_org, pt;
1304  RECT rc;
1305 
1306  GetCursorPos(&pt_org);
1307  hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1308  10, 10, 200, 200, NULL, NULL, NULL, NULL);
1309  SetCursorPos(100, 100);
1310 
1311  if (!(hook2 = SetWindowsHookExA(WH_MOUSE_LL, hook_proc2, GetModuleHandleA(0), 0)))
1312  {
1313  win_skip( "cannot set MOUSE_LL hook\n" );
1314  goto done;
1315  }
1317 
1318  GetCursorPos(&pt_old);
1319  mouse_event(MOUSEEVENTF_MOVE, -STEP, 0, 0, 0);
1320  GetCursorPos(&pt_old);
1321  ok(pt_old.x == pt_new.x && pt_old.y == pt_new.y, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1322  mouse_event(MOUSEEVENTF_MOVE, +STEP, 0, 0, 0);
1323  GetCursorPos(&pt_old);
1324  ok(pt_old.x == pt_new.x && pt_old.y == pt_new.y, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1325  mouse_event(MOUSEEVENTF_MOVE, 0, -STEP, 0, 0);
1326  GetCursorPos(&pt_old);
1327  ok(pt_old.x == pt_new.x && pt_old.y == pt_new.y, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1328  mouse_event(MOUSEEVENTF_MOVE, 0, +STEP, 0, 0);
1329  GetCursorPos(&pt_old);
1330  ok(pt_old.x == pt_new.x && pt_old.y == pt_new.y, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1331 
1332  SetRect(&rc, 50, 50, 151, 151);
1333  ClipCursor(&rc);
1334  clipped = TRUE;
1335 
1336  SetCursorPos(40, 40);
1337  GetCursorPos(&pt_old);
1338  ok(pt_old.x == 50 && pt_old.y == 50, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
1339  SetCursorPos(160, 160);
1340  GetCursorPos(&pt_old);
1341  ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
1343  GetCursorPos(&pt_old);
1344  ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
1345 
1346  clipped = FALSE;
1347  pt_new.x = pt_new.y = 150;
1348  ClipCursor(NULL);
1349  UnhookWindowsHookEx(hook1);
1350 
1351  /* Now check that mouse buttons do not change mouse position
1352  if we don't have MOUSEEVENTF_MOVE flag specified. */
1353 
1354  /* We reusing the same hook callback, so make it happy */
1355  pt_old.x = pt_new.x - STEP;
1356  pt_old.y = pt_new.y - STEP;
1357  mouse_event(MOUSEEVENTF_LEFTUP, 123, 456, 0, 0);
1358  GetCursorPos(&pt);
1359  ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1360  mouse_event(MOUSEEVENTF_RIGHTUP, 456, 123, 0, 0);
1361  GetCursorPos(&pt);
1362  ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1363 
1365  GetCursorPos(&pt);
1366  ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1368  GetCursorPos(&pt);
1369  ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1370 
1371  UnhookWindowsHookEx(hook2);
1373 
1374  SetRect(&rc, 150, 150, 150, 150);
1375  ClipCursor(&rc);
1376  clipped = TRUE;
1377 
1378  SetCursorPos(140, 140);
1379  GetCursorPos(&pt_old);
1380  ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1381  SetCursorPos(160, 160);
1382  GetCursorPos(&pt_old);
1383  todo_wine
1384  ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1386  GetCursorPos(&pt_old);
1387  ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1389  GetCursorPos(&pt_old);
1390  todo_wine
1391  ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1392  mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0);
1393  GetCursorPos(&pt_old);
1394  ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1395  mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0);
1396  GetCursorPos(&pt_old);
1397  todo_wine
1398  ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1399 
1400  clipped = FALSE;
1401  ClipCursor(NULL);
1402 
1403  SetCursorPos(140, 140);
1404  SetRect(&rc, 150, 150, 150, 150);
1405  ClipCursor(&rc);
1406  GetCursorPos(&pt_old);
1407  ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1408  ClipCursor(NULL);
1409 
1410  SetCursorPos(160, 160);
1411  SetRect(&rc, 150, 150, 150, 150);
1412  ClipCursor(&rc);
1413  GetCursorPos(&pt_old);
1414  todo_wine
1415  ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1416  ClipCursor(NULL);
1417 
1418  SetCursorPos(150, 150);
1419  SetRect(&rc, 150, 150, 150, 150);
1420  ClipCursor(&rc);
1421  GetCursorPos(&pt_old);
1422  todo_wine
1423  ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1424  ClipCursor(NULL);
1425 
1426  UnhookWindowsHookEx(hook1);
1427 
1428 done:
1430  SetCursorPos(pt_org.x, pt_org.y);
1431 }
1432 
1433 static void test_GetMouseMovePointsEx(void)
1434 {
1435 #define BUFLIM 64
1436 #define MYERROR 0xdeadbeef
1437  int count, retval;
1438  MOUSEMOVEPOINT in;
1439  MOUSEMOVEPOINT out[200];
1440  POINT point;
1441 
1442  /* Get a valid content for the input struct */
1443  if(!GetCursorPos(&point)) {
1444  win_skip("GetCursorPos() failed with error %u\n", GetLastError());
1445  return;
1446  }
1447  memset(&in, 0, sizeof(MOUSEMOVEPOINT));
1448  in.x = point.x;
1449  in.y = point.y;
1450 
1451  /* test first parameter
1452  * everything different than sizeof(MOUSEMOVEPOINT)
1453  * is expected to fail with ERROR_INVALID_PARAMETER
1454  */
1456  retval = pGetMouseMovePointsEx(0, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1457  if (retval == ERROR_INVALID_PARAMETER)
1458  {
1459  win_skip( "GetMouseMovePointsEx broken on WinME\n" );
1460  return;
1461  }
1462  ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1464  "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1465 
1467  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1468  ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1470  "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1471 
1473  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)+1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1474  ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1476  "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1477 
1478  /* test second and third parameter
1479  */
1481  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1482  ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1484  "expected error ERROR_NOACCESS, got %u\n", GetLastError());
1485 
1487  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1488  ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1490  "expected error ERROR_NOACCESS, got %u\n", GetLastError());
1491 
1493  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1494  ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1496  "expected error ERROR_NOACCESS, got %u\n", GetLastError());
1497 
1499  count = 0;
1500  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, count, GMMP_USE_DISPLAY_POINTS);
1501  if (retval == -1)
1502  ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %u\n", GetLastError());
1503  else
1504  ok(retval == count, "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1505 
1506  /* test fourth parameter
1507  * a value higher than 64 is expected to fail with ERROR_INVALID_PARAMETER
1508  */
1510  count = -1;
1511  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1512  ok(retval == count, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1514  "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1515 
1517  count = 0;
1518  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1519  if (retval == -1)
1520  ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %u\n", GetLastError());
1521  else
1522  ok(retval == count, "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1523 
1525  count = BUFLIM;
1526  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1527  if (retval == -1)
1528  ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %u\n", GetLastError());
1529  else
1530  ok((0 <= retval) && (retval <= count), "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1531 
1533  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1534  ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1536  "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1537 
1538  /* it was not possible to force an error with the fifth parameter on win2k */
1539 
1540  /* test combinations of wrong parameters to see which error wins */
1542  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1543  ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1545  "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1546 
1548  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1549  ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1551  "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1552 
1554  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1555  ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1557  "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1558 
1560  retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1561  ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1563  "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1564 
1565 #undef BUFLIM
1566 #undef MYERROR
1567 }
1568 
1570 {
1571  RAWINPUTDEVICELIST devices[32];
1572  UINT ret, oret, devcount, odevcount;
1573  DWORD err;
1574 
1575  SetLastError(0xdeadbeef);
1576  ret = pGetRawInputDeviceList(NULL, NULL, 0);
1577  err = GetLastError();
1578  ok(ret == -1, "expected -1, got %d\n", ret);
1579  ok(err == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", err);
1580 
1581  SetLastError(0xdeadbeef);
1582  ret = pGetRawInputDeviceList(NULL, NULL, sizeof(devices[0]));
1583  err = GetLastError();
1584  ok(ret == -1, "expected -1, got %d\n", ret);
1585  ok(err == ERROR_NOACCESS, "expected 998, got %d\n", err);
1586 
1587  devcount = 0;
1588  ret = pGetRawInputDeviceList(NULL, &devcount, sizeof(devices[0]));
1589  ok(ret == 0, "expected 0, got %d\n", ret);
1590  ok(devcount > 0, "expected non-zero\n");
1591 
1592  SetLastError(0xdeadbeef);
1593  devcount = 0;
1594  ret = pGetRawInputDeviceList(devices, &devcount, sizeof(devices[0]));
1595  err = GetLastError();
1596  ok(ret == -1, "expected -1, got %d\n", ret);
1597  ok(err == ERROR_INSUFFICIENT_BUFFER, "expected 122, got %d\n", err);
1598  ok(devcount > 0, "expected non-zero\n");
1599 
1600  /* devcount contains now the correct number of devices */
1601  ret = pGetRawInputDeviceList(devices, &devcount, sizeof(devices[0]));
1602  ok(ret > 0, "expected non-zero\n");
1603 
1604  /* check if variable changes from larger to smaller value */
1605  devcount = odevcount = sizeof(devices) / sizeof(devices[0]);
1606  oret = ret = pGetRawInputDeviceList(devices, &odevcount, sizeof(devices[0]));
1607  ok(ret > 0, "expected non-zero\n");
1608  ok(devcount == odevcount, "expected %d, got %d\n", devcount, odevcount);
1609  devcount = odevcount;
1610  odevcount = sizeof(devices) / sizeof(devices[0]);
1611  ret = pGetRawInputDeviceList(NULL, &odevcount, sizeof(devices[0]));
1612  ok(ret == 0, "expected 0, got %d\n", ret);
1613  ok(odevcount == oret, "expected %d, got %d\n", oret, odevcount);
1614 }
1615 
1616 static void test_key_map(void)
1617 {
1618  HKL kl = GetKeyboardLayout(0);
1619  UINT kL, kR, s, sL;
1620  int i;
1621  static const UINT numpad_collisions[][2] = {
1622  { VK_NUMPAD0, VK_INSERT },
1623  { VK_NUMPAD1, VK_END },
1624  { VK_NUMPAD2, VK_DOWN },
1625  { VK_NUMPAD3, VK_NEXT },
1626  { VK_NUMPAD4, VK_LEFT },
1627  { VK_NUMPAD6, VK_RIGHT },
1628  { VK_NUMPAD7, VK_HOME },
1629  { VK_NUMPAD8, VK_UP },
1630  { VK_NUMPAD9, VK_PRIOR },
1631  };
1632 
1634  ok(s != 0, "MapVirtualKeyEx(VK_SHIFT) should return non-zero\n");
1636  ok(s == sL || broken(sL == 0), /* win9x */
1637  "%x != %x\n", s, sL);
1638 
1639  kL = MapVirtualKeyExA(0x2a, MAPVK_VSC_TO_VK, kl);
1640  ok(kL == VK_SHIFT, "Scan code -> vKey = %x (not VK_SHIFT)\n", kL);
1641  kR = MapVirtualKeyExA(0x36, MAPVK_VSC_TO_VK, kl);
1642  ok(kR == VK_SHIFT, "Scan code -> vKey = %x (not VK_SHIFT)\n", kR);
1643 
1644  kL = MapVirtualKeyExA(0x2a, MAPVK_VSC_TO_VK_EX, kl);
1645  ok(kL == VK_LSHIFT || broken(kL == 0), /* win9x */
1646  "Scan code -> vKey = %x (not VK_LSHIFT)\n", kL);
1647  kR = MapVirtualKeyExA(0x36, MAPVK_VSC_TO_VK_EX, kl);
1648  ok(kR == VK_RSHIFT || broken(kR == 0), /* win9x */
1649  "Scan code -> vKey = %x (not VK_RSHIFT)\n", kR);
1650 
1651  /* test that MAPVK_VSC_TO_VK prefers the non-numpad vkey if there's ambiguity */
1652  for (i = 0; i < sizeof(numpad_collisions)/sizeof(numpad_collisions[0]); i++)
1653  {
1654  UINT numpad_scan = MapVirtualKeyExA(numpad_collisions[i][0], MAPVK_VK_TO_VSC, kl);
1655  UINT other_scan = MapVirtualKeyExA(numpad_collisions[i][1], MAPVK_VK_TO_VSC, kl);
1656 
1657  /* do they really collide for this layout? */
1658  if (numpad_scan && other_scan == numpad_scan)
1659  {
1660  UINT vkey = MapVirtualKeyExA(numpad_scan, MAPVK_VSC_TO_VK, kl);
1661  ok(vkey != numpad_collisions[i][0],
1662  "Got numpad vKey %x for scan code %x when there was another choice\n",
1663  vkey, numpad_scan);
1664  }
1665  }
1666 }
1667 
1668 #define shift 1
1669 #define ctrl 2
1670 
1671 static const struct tounicode_tests
1672 {
1675  WCHAR chr; /* if vk is 0, lookup vk using this char */
1678 } utests[] =
1679 {
1680  { 'A', 0, 0, 1, {'a',0}},
1681  { 'A', ctrl, 0, 1, {1, 0}},
1682  { 'A', shift|ctrl, 0, 1, {1, 0}},
1683  { VK_TAB, ctrl, 0, 0, {0}},
1684  { VK_TAB, shift|ctrl, 0, 0, {0}},
1685  { VK_RETURN, ctrl, 0, 1, {'\n', 0}},
1686  { VK_RETURN, shift|ctrl, 0, 0, {0}},
1687  { '4', ctrl, 0, 0, {0}},
1688  { '4', shift|ctrl, 0, 0, {0}},
1689  { 0, ctrl, '!', 0, {0}},
1690  { 0, ctrl, '\"', 0, {0}},
1691  { 0, ctrl, '#', 0, {0}},
1692  { 0, ctrl, '$', 0, {0}},
1693  { 0, ctrl, '%', 0, {0}},
1694  { 0, ctrl, '\'', 0, {0}},
1695  { 0, ctrl, '(', 0, {0}},
1696  { 0, ctrl, ')', 0, {0}},
1697  { 0, ctrl, '*', 0, {0}},
1698  { 0, ctrl, '+', 0, {0}},
1699  { 0, ctrl, ',', 0, {0}},
1700  { 0, ctrl, '-', 0, {0}},
1701  { 0, ctrl, '.', 0, {0}},
1702  { 0, ctrl, '/', 0, {0}},
1703  { 0, ctrl, ':', 0, {0}},
1704  { 0, ctrl, ';', 0, {0}},
1705  { 0, ctrl, '<', 0, {0}},
1706  { 0, ctrl, '=', 0, {0}},
1707  { 0, ctrl, '>', 0, {0}},
1708  { 0, ctrl, '?', 0, {0}},
1709  { 0, ctrl, '@', 1, {0}},
1710  { 0, ctrl, '[', 1, {0x1b}},
1711  { 0, ctrl, '\\', 1, {0x1c}},
1712  { 0, ctrl, ']', 1, {0x1d}},
1713  { 0, ctrl, '^', 1, {0x1e}},
1714  { 0, ctrl, '_', 1, {0x1f}},
1715  { 0, ctrl, '`', 0, {0}},
1716  { VK_SPACE, 0, 0, 1, {' ',0}},
1717  { VK_SPACE, shift, 0, 1, {' ',0}},
1718  { VK_SPACE, ctrl, 0, 1, {' ',0}},
1719 };
1720 
1721 static void test_ToUnicode(void)
1722 {
1723  WCHAR wStr[4];
1724  BYTE state[256];
1725  const BYTE SC_RETURN = 0x1c, SC_TAB = 0x0f, SC_A = 0x1e;
1726  const BYTE HIGHEST_BIT = 0x80;
1727  int i, ret;
1728  BOOL us_kbd = (GetKeyboardLayout(0) == (HKL)(ULONG_PTR)0x04090409);
1729 
1730  for(i=0; i<256; i++)
1731  state[i]=0;
1732 
1733  wStr[1] = 0xAA;
1734  SetLastError(0xdeadbeef);
1735  ret = ToUnicode(VK_RETURN, SC_RETURN, state, wStr, 4, 0);
1737  {
1738  win_skip("ToUnicode is not implemented\n");
1739  return;
1740  }
1741 
1742  ok(ret == 1, "ToUnicode for Return key didn't return 1 (was %i)\n", ret);
1743  if(ret == 1)
1744  {
1745  ok(wStr[0]=='\r', "ToUnicode for CTRL + Return was %i (expected 13)\n", wStr[0]);
1746  ok(wStr[1]==0 || broken(wStr[1]!=0) /* nt4 */,
1747  "ToUnicode didn't null-terminate the buffer when there was room.\n");
1748  }
1749 
1750  for (i = 0; i < sizeof(utests) / sizeof(utests[0]); i++)
1751  {
1752  UINT vk = utests[i].vk, mod = utests[i].modifiers, scan;
1753 
1754  if(!vk)
1755  {
1756  short vk_ret;
1757 
1758  if (!us_kbd) continue;
1759  vk_ret = VkKeyScanW(utests[i].chr);
1760  if (vk_ret == -1) continue;
1761  vk = vk_ret & 0xff;
1762  if (vk_ret & 0x100) mod |= shift;
1763  if (vk_ret & 0x200) mod |= ctrl;
1764  }
1765  scan = MapVirtualKeyW(vk, MAPVK_VK_TO_VSC);
1766 
1767  state[VK_SHIFT] = state[VK_LSHIFT] = (mod & shift) ? HIGHEST_BIT : 0;
1768  state[VK_CONTROL] = state[VK_LCONTROL] = (mod & ctrl) ? HIGHEST_BIT : 0;
1769 
1770  ret = ToUnicode(vk, scan, state, wStr, 4, 0);
1771  ok(ret == utests[i].expect_ret, "%d: got %d expected %d\n", i, ret, utests[i].expect_ret);
1772  if (ret)
1773  ok(!lstrcmpW(wStr, utests[i].expect_buf), "%d: got %s expected %s\n", i, wine_dbgstr_w(wStr),
1774  wine_dbgstr_w(utests[i].expect_buf));
1775 
1776  }
1777  state[VK_SHIFT] = state[VK_LSHIFT] = 0;
1779 
1780  ret = ToUnicode(VK_TAB, SC_TAB, NULL, wStr, 4, 0);
1781  ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
1782  ret = ToUnicode(VK_RETURN, SC_RETURN, NULL, wStr, 4, 0);
1783  ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
1784  ret = ToUnicode('A', SC_A, NULL, wStr, 4, 0);
1785  ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
1786  ret = ToUnicodeEx(VK_TAB, SC_TAB, NULL, wStr, 4, 0, GetKeyboardLayout(0));
1787  ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
1788  ret = ToUnicodeEx(VK_RETURN, SC_RETURN, NULL, wStr, 4, 0, GetKeyboardLayout(0));
1789  ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
1790  ret = ToUnicodeEx('A', SC_A, NULL, wStr, 4, 0, GetKeyboardLayout(0));
1791  ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
1792 }
1793 
1794 static void test_ToAscii(void)
1795 {
1796  WORD character;
1797  BYTE state[256];
1798  const BYTE SC_RETURN = 0x1c, SC_A = 0x1e;
1799  const BYTE HIGHEST_BIT = 0x80;
1800  int ret;
1801 
1802  memset(state, 0, sizeof(state));
1803 
1804  character = 0;
1805  ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
1806  ok(ret == 1, "ToAscii for Return key didn't return 1 (was %i)\n", ret);
1807  ok(character == '\r', "ToAscii for Return was %i (expected 13)\n", character);
1808 
1809  character = 0;
1810  ret = ToAscii('A', SC_A, state, &character, 0);
1811  ok(ret == 1, "ToAscii for character 'A' didn't return 1 (was %i)\n", ret);
1812  ok(character == 'a', "ToAscii for character 'A' was %i (expected %i)\n", character, 'a');
1813 
1814  state[VK_CONTROL] |= HIGHEST_BIT;
1815  state[VK_LCONTROL] |= HIGHEST_BIT;
1816  character = 0;
1817  ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
1818  ok(ret == 1, "ToAscii for CTRL + Return key didn't return 1 (was %i)\n", ret);
1819  ok(character == '\n', "ToAscii for CTRL + Return was %i (expected 10)\n", character);
1820 
1821  character = 0;
1822  ret = ToAscii('A', SC_A, state, &character, 0);
1823  ok(ret == 1, "ToAscii for CTRL + character 'A' didn't return 1 (was %i)\n", ret);
1824  ok(character == 1, "ToAscii for CTRL + character 'A' was %i (expected 1)\n", character);
1825 
1826  state[VK_SHIFT] |= HIGHEST_BIT;
1827  state[VK_LSHIFT] |= HIGHEST_BIT;
1828  ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
1829  ok(ret == 0, "ToAscii for CTRL + Shift + Return key didn't return 0 (was %i)\n", ret);
1830 
1831  ret = ToAscii(VK_RETURN, SC_RETURN, NULL, &character, 0);
1832  ok(ret == 0, "ToAscii for NULL keystate didn't return 0 (was %i)\n", ret);
1833  ret = ToAscii('A', SC_A, NULL, &character, 0);
1834  ok(ret == 0, "ToAscii for NULL keystate didn't return 0 (was %i)\n", ret);
1835  ret = ToAsciiEx(VK_RETURN, SC_RETURN, NULL, &character, 0, GetKeyboardLayout(0));
1836  ok(ret == 0, "ToAsciiEx for NULL keystate didn't return 0 (was %i)\n", ret);
1837  ret = ToAsciiEx('A', SC_A, NULL, &character, 0, GetKeyboardLayout(0));
1838  ok(ret == 0, "ToAsciiEx for NULL keystate didn't return 0 (was %i)\n", ret);
1839 }
1840 
1841 static void test_get_async_key_state(void)
1842 {
1843  /* input value sanity checks */
1844  ok(0 == GetAsyncKeyState(1000000), "GetAsyncKeyState did not return 0\n");
1845  ok(0 == GetAsyncKeyState(-1000000), "GetAsyncKeyState did not return 0\n");
1846 }
1847 
1848 static void test_keyboard_layout_name(void)
1849 {
1850  BOOL ret;
1851  char klid[KL_NAMELENGTH];
1852 
1853  if (0) /* crashes on native system */
1855 
1856  SetLastError(0xdeadbeef);
1858  ok(!ret, "got %d\n", ret);
1859  ok(GetLastError() == ERROR_NOACCESS, "got %d\n", GetLastError());
1860 
1861  if (GetKeyboardLayout(0) != (HKL)(ULONG_PTR)0x04090409) return;
1862 
1863  klid[0] = 0;
1864  ret = GetKeyboardLayoutNameA(klid);
1865  ok(ret, "GetKeyboardLayoutNameA failed %u\n", GetLastError());
1866  ok(!strcmp(klid, "00000409"), "expected 00000409, got %s\n", klid);
1867 }
1868 
1869 static void test_key_names(void)
1870 {
1871  char buffer[40];
1872  WCHAR bufferW[40];
1873  int ret, prev;
1874  LONG lparam = 0x1d << 16;
1875 
1876  memset( buffer, 0xcc, sizeof(buffer) );
1877  ret = GetKeyNameTextA( lparam, buffer, sizeof(buffer) );
1878  ok( ret > 0, "wrong len %u for '%s'\n", ret, buffer );
1879  ok( ret == strlen(buffer), "wrong len %u for '%s'\n", ret, buffer );
1880 
1881  memset( buffer, 0xcc, sizeof(buffer) );
1882  prev = ret;
1883  ret = GetKeyNameTextA( lparam, buffer, prev );
1884  ok( ret == prev - 1, "wrong len %u for '%s'\n", ret, buffer );
1885  ok( ret == strlen(buffer), "wrong len %u for '%s'\n", ret, buffer );
1886 
1887  memset( buffer, 0xcc, sizeof(buffer) );
1888  ret = GetKeyNameTextA( lparam, buffer, 0 );
1889  ok( ret == 0, "wrong len %u for '%s'\n", ret, buffer );
1890  ok( buffer[0] == 0, "wrong string '%s'\n", buffer );
1891 
1892  memset( bufferW, 0xcc, sizeof(bufferW) );
1893  ret = GetKeyNameTextW( lparam, bufferW, sizeof(bufferW)/sizeof(WCHAR) );
1894  ok( ret > 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1895  ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1896 
1897  memset( bufferW, 0xcc, sizeof(bufferW) );
1898  prev = ret;
1899  ret = GetKeyNameTextW( lparam, bufferW, prev );
1900  ok( ret == prev - 1, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1901  ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1902 
1903  memset( bufferW, 0xcc, sizeof(bufferW) );
1904  ret = GetKeyNameTextW( lparam, bufferW, 0 );
1905  ok( ret == 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1906  ok( bufferW[0] == 0xcccc, "wrong string %s\n", wine_dbgstr_w(bufferW) );
1907 }
1908 
1909 static void simulate_click(BOOL left, int x, int y)
1910 {
1911  INPUT input[2];
1912  UINT events_no;
1913 
1914  SetCursorPos(x, y);
1915  memset(input, 0, sizeof(input));
1916  input[0].type = INPUT_MOUSE;
1917  U(input[0]).mi.dx = x;
1918  U(input[0]).mi.dy = y;
1919  U(input[0]).mi.dwFlags = left ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN;
1920  input[1].type = INPUT_MOUSE;
1921  U(input[1]).mi.dx = x;
1922  U(input[1]).mi.dy = y;
1923  U(input[1]).mi.dwFlags = left ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP;
1924  events_no = SendInput(2, input, sizeof(input[0]));
1925  ok(events_no == 2, "SendInput returned %d\n", events_no);
1926 }
1927 
1929 {
1930  BOOL ret;
1931 
1932  for (;;)
1933  {
1934  ret = PeekMessageA(msg, 0, 0, 0, PM_REMOVE);
1935  if (ret)
1936  {
1937  if (msg->message == WM_PAINT) DispatchMessageA(msg);
1938  else break;
1939  }
1940  else if (MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLINPUT) == WAIT_TIMEOUT) break;
1941  }
1942  if (!ret) msg->message = 0;
1943  return ret;
1944 }
1945 
1947 {
1948  DWORD end_time = GetTickCount() + timeout;
1949  MSG msg;
1950 
1951  do {
1953  return TRUE;
1954  while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
1956  timeout = end_time - GetTickCount();
1957  }while(timeout > 0);
1958 
1959  return FALSE;
1960 }
1961 
1965 {
1966  if (msg == WM_NCHITTEST)
1967  {
1968  /* break infinite hittest loop */
1969  if(hittest_no > 50) return HTCLIENT;
1970  hittest_no++;
1971  }
1972 
1973  return def_static_proc(hwnd, msg, wp, lp);
1974 }
1975 
1977 {
1981 };
1982 
1984 {
1985  struct thread_data *thread_data = arg;
1986  HWND win;
1987 
1988  win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
1989  100, 100, 100, 100, 0, NULL, NULL, NULL);
1990  ok(win != 0, "CreateWindow failed\n");
1993  thread_data->win = win;
1994 
1997  return 0;
1998 }
1999 
2000 static void get_dc_region(RECT *region, HWND hwnd, DWORD flags)
2001 {
2002  int region_type;
2003  HRGN hregion;
2004  HDC hdc;
2005 
2006  hdc = GetDCEx(hwnd, 0, flags);
2007  ok(hdc != NULL, "GetDCEx failed\n");
2008  hregion = CreateRectRgn(40, 40, 60, 60);
2009  ok(hregion != NULL, "CreateRectRgn failed\n");
2010  GetRandomRgn(hdc, hregion, SYSRGN);
2011  region_type = GetRgnBox(hregion, region);
2012  ok(region_type == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", region_type);
2013  DeleteObject(hregion);
2014  ReleaseDC(hwnd, hdc);
2015 }
2016 
2017 static void test_Input_mouse(void)
2018 {
2019  BOOL got_button_down, got_button_up;
2020  HWND hwnd, button_win, static_win;
2021  struct thread_data thread_data;
2022  HANDLE thread;
2023  DWORD thread_id;
2024  WNDCLASSA wclass;
2025  POINT pt, pt_org;
2026  int region_type;
2027  HRGN hregion;
2028  RECT region;
2029  MSG msg;
2030  BOOL ret;
2031 
2032  SetLastError(0xdeadbeef);
2033  ret = GetCursorPos(NULL);
2034  ok(!ret, "GetCursorPos succeed\n");
2035  ok(GetLastError() == 0xdeadbeef || GetLastError() == ERROR_NOACCESS, "error %u\n", GetLastError());
2036 
2037  SetLastError(0xdeadbeef);
2038  ret = GetCursorPos(&pt_org);
2039  ok(ret, "GetCursorPos failed\n");
2040  ok(GetLastError() == 0xdeadbeef, "error %u\n", GetLastError());
2041 
2042  button_win = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP,
2043  100, 100, 100, 100, 0, NULL, NULL, NULL);
2044  ok(button_win != 0, "CreateWindow failed\n");
2045 
2046  pt.x = pt.y = 150;
2047  hwnd = WindowFromPoint(pt);
2048  if (hwnd != button_win)
2049  {
2050  skip("there's another window covering test window\n");
2051  DestroyWindow(button_win);
2052  return;
2053  }
2054 
2055  /* simple button click test */
2056  simulate_click(TRUE, 150, 150);
2057  got_button_down = got_button_up = FALSE;
2058  while (wait_for_message(&msg))
2059  {
2061 
2062  if (msg.message == WM_LBUTTONDOWN)
2063  {
2064  got_button_down = TRUE;
2065  }
2066  else if (msg.message == WM_LBUTTONUP)
2067  {
2068  got_button_up = TRUE;
2069  break;
2070  }
2071  }
2072  ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2073  ok(got_button_up, "expected WM_LBUTTONUP message\n");
2074 
2075  /* click through HTTRANSPARENT child window */
2076  static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_CHILD,
2077  0, 0, 100, 100, button_win, NULL, NULL, NULL);
2078  ok(static_win != 0, "CreateWindow failed\n");
2079  def_static_proc = (void*)SetWindowLongPtrA(static_win,
2081  simulate_click(FALSE, 150, 150);
2082  hittest_no = 0;
2083  got_button_down = got_button_up = FALSE;
2084  while (wait_for_message(&msg))
2085  {
2087 
2088  if (msg.message == WM_RBUTTONDOWN)
2089  {
2090  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2091  got_button_down = TRUE;
2092  }
2093  else if (msg.message == WM_RBUTTONUP)
2094  {
2095  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2096  got_button_up = TRUE;
2097  break;
2098  }
2099  }
2100  ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
2101  ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
2102  ok(got_button_up, "expected WM_RBUTTONUP message\n");
2103  DestroyWindow(static_win);
2104 
2105  /* click through HTTRANSPARENT top-level window */
2106  static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
2107  100, 100, 100, 100, 0, NULL, NULL, NULL);
2108  ok(static_win != 0, "CreateWindow failed\n");
2109  def_static_proc = (void*)SetWindowLongPtrA(static_win,
2111  simulate_click(TRUE, 150, 150);
2112  hittest_no = 0;
2113  got_button_down = got_button_up = FALSE;
2114  while (wait_for_message(&msg))
2115  {
2117 
2118  if (msg.message == WM_LBUTTONDOWN)
2119  {
2120  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2121  got_button_down = TRUE;
2122  }
2123  else if (msg.message == WM_LBUTTONUP)
2124  {
2125  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2126  got_button_up = TRUE;
2127  break;
2128  }
2129  }
2130  ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
2131  ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2132  ok(got_button_up, "expected WM_LBUTTONUP message\n");
2133  DestroyWindow(static_win);
2134 
2135  /* click on HTTRANSPARENT top-level window that belongs to other thread */
2137  ok(thread_data.start_event != NULL, "CreateEvent failed\n");
2139  ok(thread_data.end_event != NULL, "CreateEvent failed\n");
2141  ok(thread != NULL, "CreateThread failed\n");
2142  hittest_no = 0;
2143  got_button_down = got_button_up = FALSE;
2145  simulate_click(FALSE, 150, 150);
2146  while (wait_for_message(&msg))
2147  {
2149 
2150  if (msg.message == WM_RBUTTONDOWN)
2151  got_button_down = TRUE;
2152  else if (msg.message == WM_RBUTTONUP)
2153  got_button_up = TRUE;
2154  }
2158  ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
2159  ok(!got_button_down, "unexpected WM_RBUTTONDOWN message\n");
2160  ok(!got_button_up, "unexpected WM_RBUTTONUP message\n");
2161 
2162  /* click on HTTRANSPARENT top-level window that belongs to other thread,
2163  * thread input queues are attached */
2165  ok(thread != NULL, "CreateThread failed\n");
2166  hittest_no = 0;
2167  got_button_down = got_button_up = FALSE;
2170  "AttachThreadInput failed\n");
2172  SetWindowPos(thread_data.win, button_win, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
2173  simulate_click(TRUE, 150, 150);
2174  while (wait_for_message(&msg))
2175  {
2177 
2178  if (msg.message == WM_LBUTTONDOWN)
2179  got_button_down = TRUE;
2180  else if (msg.message == WM_LBUTTONUP)
2181  got_button_up = TRUE;
2182  }
2185  todo_wine ok(hittest_no > 50, "expected loop with WM_NCHITTEST messages\n");
2186  ok(!got_button_down, "unexpected WM_LBUTTONDOWN message\n");
2187  ok(!got_button_up, "unexpected WM_LBUTTONUP message\n");
2188 
2189  /* click after SetCapture call */
2190  hwnd = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP,
2191  0, 0, 100, 100, 0, NULL, NULL, NULL);
2192  ok(hwnd != 0, "CreateWindow failed\n");
2193  SetCapture(button_win);
2194  got_button_down = got_button_up = FALSE;
2195  simulate_click(FALSE, 50, 50);
2196  while (wait_for_message(&msg))
2197  {
2199 
2200  if (msg.message == WM_RBUTTONDOWN)
2201  {
2202  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2203  got_button_down = TRUE;
2204  }
2205  else if (msg.message == WM_RBUTTONUP)
2206  {
2207  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2208  got_button_up = TRUE;
2209  break;
2210  }
2211  }
2212  ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
2213  ok(got_button_up, "expected WM_RBUTTONUP message\n");
2215 
2216  /* click on child window after SetCapture call */
2217  hwnd = CreateWindowA("button", "button2", WS_VISIBLE | WS_CHILD,
2218  0, 0, 100, 100, button_win, NULL, NULL, NULL);
2219  ok(hwnd != 0, "CreateWindow failed\n");
2220  got_button_down = got_button_up = FALSE;
2221  simulate_click(TRUE, 150, 150);
2222  while (wait_for_message(&msg))
2223  {
2225 
2226  if (msg.message == WM_LBUTTONDOWN)
2227  {
2228  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2229  got_button_down = TRUE;
2230  }
2231  else if (msg.message == WM_LBUTTONUP)
2232  {
2233  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2234  got_button_up = TRUE;
2235  break;
2236  }
2237  }
2238  ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2239  ok(got_button_up, "expected WM_LBUTTONUP message\n");
2241  ok(ReleaseCapture(), "ReleaseCapture failed\n");
2242 
2243  wclass.style = 0;
2244  wclass.lpfnWndProc = WndProc;
2245  wclass.cbClsExtra = 0;
2246  wclass.cbWndExtra = 0;
2247  wclass.hInstance = GetModuleHandleA(NULL);
2248  wclass.hIcon = LoadIconA(0, (LPCSTR)IDI_APPLICATION);
2249  wclass.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
2250  wclass.hbrBackground = CreateSolidBrush(RGB(128, 128, 128));
2251  wclass.lpszMenuName = NULL;
2252  wclass.lpszClassName = "InputLayeredTestClass";
2253  RegisterClassA( &wclass );
2254 
2255  /* click through layered window with alpha channel / color key */
2256  hwnd = CreateWindowA(wclass.lpszClassName, "InputLayeredTest",
2257  WS_VISIBLE | WS_POPUP, 100, 100, 100, 100, button_win, NULL, NULL, NULL);
2258  ok(hwnd != NULL, "CreateWindowEx failed\n");
2259 
2260  static_win = CreateWindowA("static", "Title", WS_VISIBLE | WS_CHILD,
2261  10, 10, 20, 20, hwnd, NULL, NULL, NULL);
2262  ok(static_win != NULL, "CreateWindowA failed %u\n", GetLastError());
2263 
2266  ret = SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA);
2267  ok(ret, "SetLayeredWindowAttributes failed\n");
2269  Sleep(100);
2270 
2271  if (pGetWindowRgnBox)
2272  {
2273  region_type = pGetWindowRgnBox(hwnd, &region);
2274  ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2275  }
2276 
2277  got_button_down = got_button_up = FALSE;
2278  simulate_click(TRUE, 150, 150);
2279  while (wait_for_message(&msg))
2280  {
2282 
2283  if (msg.message == WM_LBUTTONDOWN)
2284  {
2285  ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2286  got_button_down = TRUE;
2287  }
2288  else if (msg.message == WM_LBUTTONUP)
2289  {
2290  ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2291  got_button_up = TRUE;
2292  break;
2293  }
2294  }
2295  ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2296  ok(got_button_up, "expected WM_LBUTTONUP message\n");
2297 
2298  ret = SetLayeredWindowAttributes(hwnd, 0, 0, LWA_ALPHA);
2299  ok(ret, "SetLayeredWindowAttributes failed\n");
2301  Sleep(100);
2302 
2303  if (pGetWindowRgnBox)
2304  {
2305  region_type = pGetWindowRgnBox(hwnd, &region);
2306  ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2307  }
2308 
2309  got_button_down = got_button_up = FALSE;
2310  simulate_click(TRUE, 150, 150);
2311  while (wait_for_message(&msg))
2312  {
2314 
2315  if (msg.message == WM_LBUTTONDOWN)
2316  {
2317  todo_wine
2318  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2319  got_button_down = TRUE;
2320  }
2321  else if (msg.message == WM_LBUTTONUP)
2322  {
2323  todo_wine
2324  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2325  got_button_up = TRUE;
2326  break;
2327  }
2328  }
2329  ok(got_button_down || broken(!got_button_down), "expected WM_LBUTTONDOWN message\n");
2330  ok(got_button_up, "expected WM_LBUTTONUP message\n");
2331 
2332  ret = SetLayeredWindowAttributes(hwnd, RGB(0, 255, 0), 255, LWA_ALPHA | LWA_COLORKEY);
2333  ok(ret, "SetLayeredWindowAttributes failed\n");
2335  Sleep(100);
2336 
2337  if (pGetWindowRgnBox)
2338  {
2339  region_type = pGetWindowRgnBox(hwnd, &region);
2340  ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2341  }
2342 
2343  got_button_down = got_button_up = FALSE;
2344  simulate_click(TRUE, 150, 150);
2345  while (wait_for_message(&msg))
2346  {
2348 
2349  if (msg.message == WM_LBUTTONDOWN)
2350  {
2351  ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2352  got_button_down = TRUE;
2353  }
2354  else if (msg.message == WM_LBUTTONUP)
2355  {
2356  ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2357  got_button_up = TRUE;
2358  break;
2359  }
2360  }
2361  ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2362  ok(got_button_up, "expected WM_LBUTTONUP message\n");
2363 
2364  ret = SetLayeredWindowAttributes(hwnd, RGB(128, 128, 128), 0, LWA_COLORKEY);
2365  ok(ret, "SetLayeredWindowAttributes failed\n");
2367  Sleep(100);
2368 
2369  if (pGetWindowRgnBox)
2370  {
2371  region_type = pGetWindowRgnBox(hwnd, &region);
2372  ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2373  }
2374 
2375  get_dc_region(&region, hwnd, DCX_PARENTCLIP);
2376  ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2377  "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2379  ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2380  "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2381  get_dc_region(&region, hwnd, DCX_USESTYLE);
2382  ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2383  "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2384  get_dc_region(&region, static_win, DCX_PARENTCLIP);
2385  ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2386  "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2387  get_dc_region(&region, static_win, DCX_WINDOW | DCX_USESTYLE);
2388  ok(region.left == 110 && region.top == 110 && region.right == 130 && region.bottom == 130,
2389  "expected region (110,110)-(130,130), got %s\n", wine_dbgstr_rect(&region));
2390  get_dc_region(&region, static_win, DCX_USESTYLE);
2391  ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2392  "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2393 
2394  got_button_down = got_button_up = FALSE;
2395  simulate_click(TRUE, 150, 150);
2396  while (wait_for_message(&msg))
2397  {
2399 
2400  if (msg.message == WM_LBUTTONDOWN)
2401  {
2402  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2403  got_button_down = TRUE;
2404  }
2405  else if (msg.message == WM_LBUTTONUP)
2406  {
2407  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2408  got_button_up = TRUE;
2409  break;
2410  }
2411  }
2412  ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2413  ok(got_button_up, "expected WM_LBUTTONUP message\n");
2414 
2417  Sleep(100);
2418 
2419  if (pGetWindowRgnBox)
2420  {
2421  region_type = pGetWindowRgnBox(hwnd, &region);
2422  ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2423  }
2424 
2425  got_button_down = got_button_up = FALSE;
2426  simulate_click(TRUE, 150, 150);
2427  while (wait_for_message(&msg))
2428  {
2430 
2431  if (msg.message == WM_LBUTTONDOWN)
2432  {
2433  ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2434  got_button_down = TRUE;
2435  }
2436  else if (msg.message == WM_LBUTTONUP)
2437  {
2438  ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2439  got_button_up = TRUE;
2440  break;
2441  }
2442  }
2443  ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2444  ok(got_button_up, "expected WM_LBUTTONUP message\n");
2445 
2446  hregion = CreateRectRgn(0, 0, 10, 10);
2447  ok(hregion != NULL, "CreateRectRgn failed\n");
2448  ret = SetWindowRgn(hwnd, hregion, TRUE);
2449  ok(ret, "SetWindowRgn failed\n");
2450  DeleteObject(hregion);
2452  Sleep(1000);
2453 
2454  if (pGetWindowRgnBox)
2455  {
2456  region_type = pGetWindowRgnBox(hwnd, &region);
2457  ok(region_type == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", region_type);
2458  }
2459 
2460  got_button_down = got_button_up = FALSE;
2461  simulate_click(TRUE, 150, 150);
2462  while (wait_for_message(&msg))
2463  {
2465 
2466  if (msg.message == WM_LBUTTONDOWN)
2467  {
2468  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2469  got_button_down = TRUE;
2470  }
2471  else if (msg.message == WM_LBUTTONUP)
2472  {
2473  ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2474  got_button_up = TRUE;
2475  break;
2476  }
2477  }
2478  ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2479  ok(got_button_up, "expected WM_LBUTTONUP message\n");
2480 
2481  DestroyWindow(static_win);
2483  SetCursorPos(pt_org.x, pt_org.y);
2484 
2487  DestroyWindow(button_win);
2488 }
2489 
2490 
2492 {
2493  if (message == WM_USER+1)
2494  {
2495  HWND hwnd = (HWND)lParam;
2496  ok(GetFocus() == hwnd, "thread expected focus %p, got %p\n", hwnd, GetFocus());
2497  ok(GetActiveWindow() == hwnd, "thread expected active %p, got %p\n", hwnd, GetActiveWindow());
2498  }
2500 }
2501 
2503 {
2510 };
2511 
2513 {
2514  MSG msg;
2515  struct wnd_event *wnd_event = param;
2516  BOOL ret;
2517 
2518  if (wnd_event->wait_event)
2519  {
2521  "WaitForSingleObject failed\n");
2523  }
2524 
2525  if (wnd_event->attach_from)
2526  {
2528  ok(ret, "AttachThreadInput error %d\n", GetLastError());
2529  }
2530 
2531  if (wnd_event->attach_to)
2532  {
2534  ok(ret, "AttachThreadInput error %d\n", GetLastError());
2535  }
2536 
2537  wnd_event->hwnd = CreateWindowExA(0, "TestWindowClass", "window caption text", WS_OVERLAPPEDWINDOW,
2538  100, 100, 200, 200, 0, 0, 0, NULL);
2539  ok(wnd_event->hwnd != 0, "Failed to create overlapped window\n");
2540 
2541  if (wnd_event->setWindows)
2542  {
2545  }
2546 
2548 
2549  while (GetMessageA(&msg, 0, 0, 0))
2550  {
2553  }
2554 
2555  return 0;
2556 }
2557 
2558 static void test_attach_input(void)
2559 {
2560  HANDLE hThread;
2561  HWND ourWnd, Wnd2;
2562  DWORD ret, tid;
2563  struct wnd_event wnd_event;
2564  WNDCLASSA cls;
2565 
2566  cls.style = 0;
2567  cls.lpfnWndProc = MsgCheckProcA;
2568  cls.cbClsExtra = 0;
2569  cls.cbWndExtra = 0;
2570  cls.hInstance = GetModuleHandleA(0);
2571  cls.hIcon = 0;
2572  cls.hCursor = LoadCursorW( NULL, (LPCWSTR)IDC_ARROW);
2573  cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2574  cls.lpszMenuName = NULL;
2575  cls.lpszClassName = "TestWindowClass";
2576  if(!RegisterClassA(&cls)) return;
2577 
2580  wnd_event.attach_from = 0;
2581  wnd_event.attach_to = 0;
2583  if (!wnd_event.start_event)
2584  {
2585  win_skip("skipping interthread message test under win9x\n");
2586  return;
2587  }
2588 
2590  ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2591 
2592  ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2594 
2595  ourWnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
2596  0, 0, 0, 0, 0, 0, 0, NULL);
2597  ok(ourWnd!= 0, "failed to create ourWnd window\n");
2598 
2599  Wnd2 = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
2600  0, 0, 0, 0, 0, 0, 0, NULL);
2601  ok(Wnd2!= 0, "failed to create Wnd2 window\n");
2602 
2603  SetFocus(ourWnd);
2604  SetActiveWindow(ourWnd);
2605 
2607  ok(ret, "AttachThreadInput error %d\n", GetLastError());
2608 
2609  ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2610  ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2611 
2612  SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
2613 
2615  ok(ret, "AttachThreadInput error %d\n", GetLastError());
2616  ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2617  ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2618 
2619  SendMessageA(wnd_event.hwnd, WM_USER+1, 0, 0);
2620 
2622  ok(ret, "AttachThreadInput error %d\n", GetLastError());
2623 
2624  ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2625  ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2626  SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
2627 
2628  SetActiveWindow(Wnd2);
2629  SetFocus(Wnd2);
2630  ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2631  ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2632 
2633  SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)Wnd2);
2634 
2636  ok(ret, "AttachThreadInput error %d\n", GetLastError());
2637  ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2638  ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2639 
2640  SendMessageA(wnd_event.hwnd, WM_USER+1, 0, 0);
2641 
2643  ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2644 
2645  ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2647 
2650  wnd_event.attach_from = 0;
2651  wnd_event.attach_to = 0;
2653 
2655  ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2656 
2657  ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2659 
2660  SetFocus(ourWnd);
2661  SetActiveWindow(ourWnd);
2662 
2664  ok(ret, "AttachThreadInput error %d\n", GetLastError());
2665 
2666  ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
2667  ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
2668 
2670 
2672  ok(ret, "AttachThreadInput error %d\n", GetLastError());
2673 
2674  ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
2675  ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
2676 
2678 
2680  ok(ret, "AttachThreadInput error %d\n", GetLastError());
2681 
2682  ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
2683  ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
2684 
2686 
2687  SetFocus(Wnd2);
2688  SetActiveWindow(Wnd2);
2689  ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2690  ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2691 
2692  SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)Wnd2);
2693 
2695  ok(ret, "AttachThreadInput error %d\n", GetLastError());
2696 
2697  ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2698  ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2699 
2700  SendMessageA(wnd_event.hwnd, WM_USER+1, 0, 0);
2701 
2703  ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2704 
2705  ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2707 
2710  wnd_event.attach_from = 0;
2711  wnd_event.attach_to = 0;
2713 
2715  ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2716 
2717  SetLastError(0xdeadbeef);
2719  ok(!ret, "AttachThreadInput succeeded\n");
2720  ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef) /* <= Win XP */,
2721  "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2722 
2723  SetLastError(0xdeadbeef);
2725  ok(!ret, "AttachThreadInput succeeded\n");
2726  ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef) /* <= Win XP */,
2727  "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2728 
2730 
2731  ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2733 
2735  ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2736 
2737  ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2739 
2743  wnd_event.attach_to = 0;
2745 
2746  SetFocus(ourWnd);
2747  SetActiveWindow(ourWnd);
2748 
2750  ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2751 
2752  ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2754 
2755  ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2756  ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2757 
2759  ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2760 
2761  ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2763 
2766  wnd_event.attach_from = 0;
2769 
2770  SetFocus(ourWnd);
2771  SetActiveWindow(ourWnd);
2772 
2774  ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2775 
2776  ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2778 
2779  ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2780  ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2781 
2783  ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2784 
2785  ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2787  DestroyWindow(ourWnd);
2788  DestroyWindow(Wnd2);
2789 }
2790 
2792 {
2793  HANDLE *semaphores = arg;
2794  DWORD result;
2795 
2796  ReleaseSemaphore(semaphores[0], 1, NULL);
2797  result = WaitForSingleObject(semaphores[1], 1000);
2798  ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2799 
2800  result = GetKeyState('X');
2801  ok((result & 0x8000) || broken(!(result & 0x8000)), /* > Win 2003 */
2802  "expected that highest bit is set, got %x\n", result);
2803 
2804  ReleaseSemaphore(semaphores[0], 1, NULL);
2805  result = WaitForSingleObject(semaphores[1], 1000);
2806  ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2807 
2808  result = GetKeyState('X');
2809  ok(!(result & 0x8000), "expected that highest bit is unset, got %x\n", result);
2810 
2811  return 0;
2812 }
2813 
2814 static void test_GetKeyState(void)
2815 {
2816  HANDLE semaphores[2];
2817  HANDLE thread;
2818  DWORD result;
2819  HWND hwnd;
2820 
2821  semaphores[0] = CreateSemaphoreA(NULL, 0, 1, NULL);
2822  ok(semaphores[0] != NULL, "CreateSemaphoreA failed %u\n", GetLastError());
2823  semaphores[1] = CreateSemaphoreA(NULL, 0, 1, NULL);
2824  ok(semaphores[1] != NULL, "CreateSemaphoreA failed %u\n", GetLastError());
2825 
2826  hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2827  10, 10, 200, 200, NULL, NULL, NULL, NULL);
2828  ok(hwnd != NULL, "CreateWindowA failed %u\n", GetLastError());
2829 
2830  thread = CreateThread(NULL, 0, get_key_state_thread, semaphores, 0, NULL);
2831  ok(thread != NULL, "CreateThread failed %u\n", GetLastError());
2832  result = WaitForSingleObject(semaphores[0], 1000);
2833  ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2834 
2835  SetFocus(hwnd);
2836  keybd_event('X', 0, 0, 0);
2837 
2838  ReleaseSemaphore(semaphores[1], 1, NULL);
2839  result = WaitForSingleObject(semaphores[0], 1000);
2840  ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2841 
2842  keybd_event('X', 0, KEYEVENTF_KEYUP, 0);
2843 
2844  ReleaseSemaphore(semaphores[1], 1, NULL);
2846  ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2848 
2850  CloseHandle(semaphores[0]);
2851  CloseHandle(semaphores[1]);
2852 }
2853 
2854 static void test_OemKeyScan(void)
2855 {
2856  DWORD ret, expect, vkey, scan;
2857  WCHAR oem, wchr;
2858  char oem_char;
2859 
2860  for (oem = 0; oem < 0x200; oem++)
2861  {
2862  ret = OemKeyScan( oem );
2863 
2864  oem_char = LOBYTE( oem );
2865  /* OemKeyScan returns -1 for any character that cannot be mapped,
2866  * whereas OemToCharBuff changes unmappable characters to question
2867  * marks. The ASCII characters 0-127, including the real question mark
2868  * character, are all mappable and are the same in all OEM codepages. */
2869  if (!OemToCharBuffW( &oem_char, &wchr, 1 ) || (wchr == '?' && oem_char < 0))
2870  expect = -1;
2871  else
2872  {
2873  vkey = VkKeyScanW( wchr );
2874  scan = MapVirtualKeyW( LOBYTE( vkey ), MAPVK_VK_TO_VSC );
2875  if (!scan)
2876  expect = -1;
2877  else
2878  {
2879  vkey &= 0xff00;
2880  vkey <<= 8;
2881  expect = vkey | scan;
2882  }
2883  }
2884  ok( ret == expect, "%04x: got %08x expected %08x\n", oem, ret, expect );
2885  }
2886 }
2887 
2889 {
2891 
2892  if (pSendInput)
2893  {
2897  test_Input_mouse();
2898  }
2899  else win_skip("SendInput is not available\n");
2900 
2901  test_keynames();
2903  test_key_map();
2904  test_ToUnicode();
2905  test_ToAscii();
2908  test_key_names();
2910  test_GetKeyState();
2911  test_OemKeyScan();
2912 
2913  if(pGetMouseMovePointsEx)
2915  else
2916  win_skip("GetMouseMovePointsEx is not available\n");
2917 
2918  if(pGetRawInputDeviceList)
2920  else
2921  win_skip("GetRawInputDeviceList is not available\n");
2922 }
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 * u
Definition: glfuncs.h:240
struct transition_s expected_transitions[MAXKEYEVENTS+1]
Definition: input.c:447
#define WM_SYNCPAINT
Definition: winuser.h:1672
static BOOL do_test(HWND hwnd, int seqnr, const KEV td[])
Definition: input.c:233
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
LONG last_key_down
Definition: input.c:72
LONG last_syskey_up
Definition: input.c:75
#define VK_NUMPAD8
Definition: winuser.h:2201
#define MOUSEEVENTF_LEFTDOWN
Definition: winuser.h:1170
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
static DWORD
Definition: input.c:87
static struct message sent_messages[MAXKEYMESSAGES]
Definition: input.c:699
#define trace(...)
Definition: kmt_test.h:217
static BOOL TestASet(HWND hWnd, int nrkev, const KEV kevdwn[], const KEV kevup[])
Definition: input.c:287
#define VK_NUMPAD0
Definition: winuser.h:2193
static void test_keynames(void)
Definition: input.c:1223
UINT message
Definition: msg.h:50
HDC WINAPI GetDCEx(_In_opt_ HWND, _In_opt_ HRGN, _In_ DWORD)
#define ADDTOINPUTS(kev)
Definition: input.c:123
DWORD type
Definition: imm32.c:51
msg_flags_t
Definition: input.c:423
BOOL WINAPI TranslateMessage(_In_ const MSG *)
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
Definition: tftpd.h:59
BOOL WINAPI OemToCharBuffW(_In_ LPCSTR lpszSrc, _Out_writes_(cchDstLength) LPWSTR lpszDst, _In_ DWORD cchDstLength)
static LPRECT
Definition: input.c:89
#define TRUE
Definition: types.h:120
DWORD attach_to
Definition: input.c:2508
#define KL_NAMELENGTH
Definition: winuser.h:122
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
#define shift
Definition: input.c:1668
static void TestSysKeys(HWND hWnd)
Definition: input.c:336
UINT WINAPI MapVirtualKeyExA(UINT uCode, UINT uMapType, HKL dwhkl)
Definition: input.c:347
#define WM_MOUSEFIRST
Definition: winuser.h:1750
#define MOUSEEVENTF_ABSOLUTE
Definition: winuser.h:1180
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
long y
Definition: polytest.cpp:48
static void test_GetMouseMovePointsEx(void)
Definition: input.c:1433
UINT style
Definition: winuser.h:3129
static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: input.c:2491
#define WM_CHAR
Definition: winuser.h:1693
#define WM_LBUTTONDOWN
Definition: winuser.h:1752
static BYTE AsyncKeyStateTable[256]
Definition: input.c:158
LPCWSTR lpszMenuName
Definition: winuser.h:3137
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static void test_get_async_key_state(void)
Definition: input.c:1841
BOOL WINAPI AttachThreadInput(_In_ DWORD, _In_ DWORD, _In_ BOOL)
#define LOBYTE(W)
Definition: jmemdos.c:487
int WINAPI ToAscii(UINT uVirtKey, UINT uScanCode, CONST BYTE *lpKeyState, LPWORD lpChar, UINT uFlags)
Definition: input.c:429
BOOL WINAPI ClipCursor(_In_opt_ LPCRECT)
#define KEYEVENTF_KEYUP
Definition: winuser.h:1092
static LRESULT CALLBACK hook_proc2(int code, WPARAM wparam, LPARAM lparam)
Definition: input.c:1266
long x
Definition: polytest.cpp:48
int expect_ret
Definition: input.c:1676
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define VK_NUMPAD6
Definition: winuser.h:2199
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
DWORD attach_from
Definition: input.c:2507
static const char * getdesc[]
Definition: input.c:109
LPARAM lParam
Definition: input.c:135
#define pt(x, y)
Definition: drawing.c:79
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL, IN LONG lInitialCount, IN LONG lMaximumCount, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:430
static WNDPROC def_static_proc
Definition: input.c:1962
#define VK_RMENU
Definition: winuser.h:2241
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define ERROR(name)
Definition: error_private.h:53
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static struct @1655 key_status
#define VK_LSHIFT
Definition: winuser.h:2236
GLuint GLuint GLsizei count
Definition: gl.h:1545
BOOL sendinput_broken
Definition: input.c:83
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
START_TEST(input)
Definition: input.c:2888
const char * devices
Definition: diskspace.c:793
#define WM_GETTEXT
Definition: winuser.h:1600
static DWORD WINAPI get_key_state_thread(void *arg)
Definition: input.c:2791
#define U(x)
Definition: wordpad.c:44
static int
Definition: input.c:87
#define MAKELPARAM(l, h)
Definition: winuser.h:3915
LONG last_hook_up
Definition: input.c:79
HWND win
Definition: input.c:1980
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glext.h:5579
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:27
#define MAXKEYEVENTS
Definition: input.c:91
BOOL WINAPI UpdateWindow(_In_ HWND)
HWND hWnd
Definition: settings.c:17
#define WM_QUIT
Definition: winuser.h:1605
#define wine_dbgstr_w
Definition: kernel32.h:34
static const struct @1656 testkeyset[]
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
GLdouble n
Definition: glext.h:7729
LONG top
Definition: windef.h:292
GLdouble GLdouble t
Definition: gl.h:2047
#define WM_IME_SELECT
Definition: winuser.h:1809
HANDLE HWND
Definition: compat.h:13
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
DWORD time
Definition: winable.h:50
#define DCX_USESTYLE
Definition: GetDCEx.c:10
#define VK_LEFT
Definition: winuser.h:2178
int cbClsExtra
Definition: winuser.h:3118
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define assert(x)
Definition: debug.h:53
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
#define CS_HREDRAW
Definition: winuser.h:648
LPCSTR lpszMenuName
Definition: winuser.h:3124
#define GWL_EXSTYLE
Definition: winuser.h:845
#define HWND_TOPMOST
Definition: winuser.h:1194
GLuint buffer
Definition: glext.h:5915
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
int cbClsExtra
Definition: winuser.h:3131
HWND WINAPI SetFocus(_In_opt_ HWND)
static MONITORINFO mi
Definition: win.c:7331
void * arg
Definition: msvc.h:12
#define KF_UP
Definition: winuser.h:2405
#define WM_NCHITTEST
Definition: winuser.h:1668
Definition: dhcpd.h:245
#define test
Definition: rosglue.h:37
LONG last_char
Definition: input.c:76
DWORD WINAPI OemKeyScan(WORD wOemChar)
Definition: input.c:382
#define IDI_APPLICATION
Definition: winuser.h:699
UINT_PTR WPARAM
Definition: windef.h:207
#define VK_TAB
Definition: winuser.h:2153
SHORT WINAPI VkKeyScanW(WCHAR ch)
Definition: input.c:543
#define VK_DOWN
Definition: winuser.h:2181
HBRUSH hbrBackground
Definition: winuser.h:3123
#define VK_INSERT
Definition: winuser.h:2186
#define WS_CHILD
Definition: pedump.c:617
#define VK_PRIOR
Definition: winuser.h:2174
#define VK_MENU
Definition: winuser.h:2158
Definition: input.c:101
__u16 time
Definition: mkdosfs.c:366
LONG left
Definition: windef.h:291
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
static void test_mouse_ll_hook(void)
Definition: input.c:1299
static BOOL clipped
Definition: input.c:1237
KEVtag
Definition: input.c:100
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2635
#define VK_NUMPAD9
Definition: winuser.h:2202
LONG right
Definition: windef.h:293
#define lstrlenW
Definition: compat.h:407
#define BOOL
Definition: nt_native.h:43
BOOL WINAPI DestroyWindow(_In_ HWND)
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4185
#define COLOR_WINDOW
Definition: winuser.h:908
#define MAPVK_VSC_TO_VK_EX
Definition: winuser.h:2312
int winetest_debug
static BOOL wait_for_event(HANDLE event, int timeout)
Definition: input.c:1946
VOID WINAPI mouse_event(DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData, ULONG_PTR dwExtraInfo)
Definition: input.c:578
#define VK_RETURN
Definition: winuser.h:2155
GLbitfield GLuint64 timeout
Definition: glext.h:7164
POINTL point
Definition: edittest.c:50
WPARAM wParam
Definition: combotst.c:138
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2029
const GLfloat * m
Definition: glext.h:10848
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:597
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define DCX_WINDOW
Definition: winuser.h:2074
#define VK_NEXT
Definition: winuser.h:2175
WCHAR expect_buf[4]
Definition: input.c:1677
LONG y
Definition: windef.h:315
Definition: input.c:101
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOL _todo_wine
Definition: input.c:446
int WINAPI SetWindowRgn(_In_ HWND, _In_opt_ HRGN, _In_ BOOL)
Definition: input.c:101
#define WM_NCPAINT
Definition: winuser.h:1669
static void reset_key_status(void)
Definition: input.c:976
HHOOK WINAPI SetWindowsHookExA(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define WH_MOUSE_LL
Definition: winuser.h:44
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
Definition: input.c:424
int cbWndExtra
Definition: winuser.h:3119
static INPUT size_t
Definition: input.c:86
static BYTE InputKeyStateTable[256]
Definition: input.c:157
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
HINSTANCE hInstance
Definition: charmap.c:20
#define VK_HOME
Definition: winuser.h:2177
#define ERROR_NOACCESS
Definition: winerror.h:578
static int KbdMessage(KEV kev, WPARAM *pwParam, LPARAM *plParam)
Definition: input.c:179
HKL WINAPI GetKeyboardLayout(DWORD idThread)
Definition: input.c:122
#define INPUT_KEYBOARD
Definition: winable.h:10
#define WM_KEYFIRST
Definition: winuser.h:1690
BYTE before_state
Definition: input.c:419
static const char * MSGNAME[]
Definition: input.c:96
#define VK_UP
Definition: winuser.h:2179
int WINAPI ToUnicode(UINT wVirtKey, UINT wScanCode, CONST BYTE *lpKeyState, LPWSTR pwszBuff, int cchBuff, UINT wFlags)
Definition: input.c:465
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
HWND WINAPI SetActiveWindow(_In_ HWND)
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
static LRESULT CALLBACK WndProc2(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: input.c:855
static DWORD WINAPI thread_proc(void *param)
Definition: input.c:2512
unsigned int BOOL
Definition: ntddk_ex.h:94
#define STEP
Definition: input.c:1238
long LONG
Definition: pedump.c:60
LONG last_hook_syskey_up
Definition: input.c:81
static const int GETFLAGS[]
Definition: input.c:107
static void test_Input_whitebox(void)
Definition: input.c:349
DWORD dwFlags
Definition: input.c:445
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
WNDPROC lpfnWndProc
Definition: winuser.h:3130
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HWND hwnd
Definition: input.c:2504
#define WM_SYSCHAR
Definition: winuser.h:1697
#define ok(value,...)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4184
HCURSOR hCursor
Definition: winuser.h:3122
#define CW_USEDEFAULT
Definition: winuser.h:225
#define LLKHF_UP
Definition: winuser.h:2602
#define MYERROR
#define VK_SHIFT
Definition: winuser.h:2156
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:111
smooth NULL
Definition: ftsmooth.c:416
#define VK_NUMPAD3
Definition: winuser.h:2196
static void test_unicode_keys(HWND hwnd, HHOOK hook)
Definition: input.c:992
msg_flags_t
Definition: msg.h:32
#define WM_KEYDOWN
Definition: winuser.h:1691
LPCWSTR lpszClassName
Definition: winuser.h:3138
SHORT WINAPI DECLSPEC_HOTPATCH GetKeyState(int nVirtKey)
Definition: input.c:183
LONG_PTR LPARAM
Definition: windef.h:208
#define ERROR_POINT_NOT_FOUND
Definition: winerror.h:693
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:583
static LRESULT WINAPI static_hook_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Definition: input.c:1964
static void test_ToAscii(void)
Definition: input.c:1794
const char * LPCSTR
Definition: xmlstorage.h:183
#define GET_PROC(func)
#define SW_SHOW
Definition: winuser.h:769
BOOL WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID)
Definition: input.c:192
BOOL WINAPI IsWindowUnicode(_In_ HWND)
int WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpString, int nSize)
Definition: input.c:170
static DWORD hittest_no
Definition: input.c:1963
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:420
static void test_Input_unicode(void)
Definition: input.c:1157
#define ctrl
Definition: input.c:1669
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
#define WM_RBUTTONDOWN
Definition: winuser.h:1755
static HWND hWndTest
Definition: input.c:68
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
static LRESULT CALLBACK hook_proc3(int code, WPARAM wparam, LPARAM lparam)
Definition: input.c:1286
Definition: input.c:426
r l[0]
Definition: byte_order.h:167
#define KF_EXTENDED
Definition: winuser.h:2400
DWORD dwFlags
Definition: winable.h:49
Definition: input.c:427
#define INPUT_MOUSE
Definition: winable.h:9
#define KF_REPEAT
Definition: winuser.h:2404
#define CS_VREDRAW
Definition: winuser.h:653
#define MAPVK_VSC_TO_VK
Definition: winuser.h:2310
Definition: