ReactOS 0.4.15-dev-7958-gcd0bb1a
input.c File Reference
#include <stdarg.h>
#include <assert.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"
#include "winnls.h"
#include "wine/test.h"
Include dependency graph for input.c:

Go to the source code of this file.

Classes

struct  TEST_INPUT
 
struct  KMSG
 
struct  transition_s
 
struct  message
 
struct  sendinput_test_s
 
struct  tounicode_tests
 
struct  thread_data
 
struct  wnd_event
 

Macros

#define MAXKEYEVENTS   12
 
#define MAXKEYMESSAGES
 
#define GET_PROC(func)
 
#define STEP   3
 
#define BUFLIM   64
 
#define MYERROR   0xdeadbeef
 
#define shift   1
 
#define ctrl   2
 

Typedefs

typedef enum KEVtag KEV
 

Enumerations

enum  KEVtag {
  ALTDOWN = 1 , ALTUP , XDOWN , XUP ,
  SHIFTDOWN , SHIFTUP , CTRLDOWN , CTRLUP
}
 
enum  msg_flags_t {
  sent = 0x1 , posted = 0x2 , parent = 0x4 , wparam = 0x8 ,
  lparam = 0x10 , defwinproc = 0x20 , beginpaint = 0x40 , optional = 0x80 ,
  hook = 0x100 , winevent_hook = 0x200 , kbd_hook = 0x400 , sent = 0x1 ,
  posted = 0x2 , parent = 0x4 , wparam = 0x8 , lparam = 0x10 ,
  defwinproc = 0x20 , beginpaint = 0x40 , optional = 0x80 , hook = 0x100 ,
  winevent_hook =0x200 , id = 0x400 , custdraw = 0x800 , sent = 0x1 ,
  posted = 0x2 , parent = 0x4 , wparam = 0x8 , lparam = 0x10 ,
  defwinproc = 0x20 , beginpaint = 0x40 , optional = 0x80 , hook = 0x100 ,
  winevent_hook =0x200 , id = 0x400 , sent =0x1 , posted =0x2 ,
  parent =0x4 , wparam =0x8 , lparam =0x10 , defwinproc =0x20 ,
  beginpaint =0x40 , optional =0x80 , hook =0x100 , winevent_hook =0x200 ,
  sent =0x1 , posted =0x2 , parent =0x4 , wparam =0x8 ,
  lparam =0x10 , defwinproc =0x20 , beginpaint =0x40 , optional =0x80 ,
  hook =0x100 , winevent_hook =0x200 , kbd_hook =0x400
}
 

Functions

static BOOL (WINAPI *pGetCurrentInputMessageSource)(INPUT_MESSAGE_SOURCE *source)
 
static POINTER_INPUT_TYPE *static int (WINAPI *pGetMouseMovePointsEx)(UINT
 
static UINT (WINAPI *pGetRawInputDeviceList)(PRAWINPUTDEVICELIST
 
static void init_function_pointers (void)
 
static int KbdMessage (KEV kev, WPARAM *pwParam, LPARAM *plParam)
 
static BOOL do_test (HWND hwnd, int seqnr, const KEV td[])
 
static BOOL TestASet (HWND hWnd, int nrkev, const KEV kevdwn[], const KEV kevup[])
 
static void TestSysKeys (HWND hWnd)
 
static LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
static void test_Input_whitebox (void)
 
static BOOL is_keyboard_message (UINT message)
 
static BOOL is_mouse_message (UINT message)
 
static void empty_message_queue (void)
 
static void compare_and_check (int id, BYTE *ks1, BYTE *ks2, const struct sendinput_test_s *test, BOOL foreground)
 
static LRESULT CALLBACK WndProc2 (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 
static LRESULT CALLBACK hook_proc (int code, WPARAM wparam, LPARAM lparam)
 
static void test_Input_blackbox (void)
 
static void reset_key_status (WORD vk)
 
static void test_unicode_keys (HWND hwnd, HHOOK hook)
 
static LRESULT CALLBACK unicode_wnd_proc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
static LRESULT CALLBACK llkbd_unicode_hook (int nCode, WPARAM wParam, LPARAM lParam)
 
static void test_Input_unicode (void)
 
static void test_keynames (void)
 
static LRESULT CALLBACK hook_proc1 (int code, WPARAM wparam, LPARAM lparam)
 
static LRESULT CALLBACK hook_proc2 (int code, WPARAM wparam, LPARAM lparam)
 
static LRESULT CALLBACK hook_proc3 (int code, WPARAM wparam, LPARAM lparam)
 
static void test_mouse_ll_hook (void)
 
static void test_GetMouseMovePointsEx (void)
 
static void test_GetRawInputDeviceList (void)
 
static void test_GetRawInputData (void)
 
static void test_key_map (void)
 
static void test_ToUnicode (void)
 
static void test_ToAscii (void)
 
static void test_get_async_key_state (void)
 
static void test_keyboard_layout_name (void)
 
static void test_key_names (void)
 
static void simulate_click (BOOL left, int x, int y)
 
static BOOL wait_for_message (MSG *msg)
 
static BOOL wait_for_event (HANDLE event, int timeout)
 
static LRESULT WINAPI static_hook_proc (HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
 
static DWORD WINAPI create_static_win (void *arg)
 
static void get_dc_region (RECT *region, HWND hwnd, DWORD flags)
 
static void test_Input_mouse (void)
 
static LRESULT WINAPI MsgCheckProcA (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
static DWORD WINAPI thread_proc (void *param)
 
static void test_attach_input (void)
 
static DWORD WINAPI get_key_state_thread (void *arg)
 
static void test_GetKeyState (void)
 
static void test_OemKeyScan (void)
 
static LRESULT WINAPI msg_source_proc (HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
 
static void test_input_message_source (void)
 
static void test_GetPointerType (void)
 
static void test_GetKeyboardLayoutList (void)
 
 START_TEST (input)
 

Variables

static HWND hWndTest
 
static LONG timetag = 0x10000000
 
struct {
   LONG   last_key_down
 
   LONG   last_key_up
 
   LONG   last_syskey_down
 
   LONG   last_syskey_up
 
   LONG   last_char
 
   LONG   last_syschar
 
   LONG   last_hook_down
 
   LONG   last_hook_up
 
   LONG   last_hook_syskey_down
 
   LONG   last_hook_syskey_up
 
   WORD   vk
 
   BOOL   expect_alt
 
   BOOL   sendinput_broken
 
key_status
 
static POINTER_INPUT_TYPE *static LPMOUSEMOVEPOINT
 
static POINTER_INPUT_TYPE *static int
 
static POINTER_INPUT_TYPE *static DWORD
 
static PUINT
 
static UINT
 
static void UINT *static void UINT *static LPRECT
 
static const charMSGNAME []
 
static const int GETVKEY [] ={0, VK_MENU, VK_MENU, 'X', 'X', VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL}
 
static const int GETSCAN [] ={0, 0x38, 0x38, 0x2D, 0x2D, 0x2A, 0x2A, 0x1D, 0x1D }
 
static const int GETFLAGS [] ={0, 0, KEYEVENTF_KEYUP, 0, KEYEVENTF_KEYUP, 0, KEYEVENTF_KEYUP, 0, KEYEVENTF_KEYUP}
 
static const chargetdesc [] ={"", "+alt","-alt","+X","-X","+shift","-shift","+ctrl","-ctrl"}
 
struct {
   int   nrkev
 
   KEV   keydwn [MAXKEYEVENTS]
 
   KEV   keyup [MAXKEYEVENTS]
 
testkeyset []
 
static BYTE InputKeyStateTable [256]
 
static BYTE AsyncKeyStateTable [256]
 
static BYTE TrackSysKey = 0
 
static const struct sendinput_test_s sendinput_test []
 
static struct message sent_messages [MAXKEYMESSAGES]
 
static UINT sent_messages_cnt
 
static POINT pt_old
 
static POINT pt_new
 
static BOOL clipped
 
static const struct tounicode_tests utests []
 
static WNDPROC def_static_proc
 
static DWORD hittest_no
 
static INPUT_MESSAGE_SOURCE expect_src
 

Macro Definition Documentation

◆ BUFLIM

#define BUFLIM   64

◆ ctrl

#define ctrl   2

Definition at line 1756 of file input.c.

◆ GET_PROC

#define GET_PROC (   func)
Value:
if (!(p ## func = (void*)GetProcAddress(hdll, #func))) \
trace("GetProcAddress(%s) failed\n", #func)
#define GetProcAddress(x, y)
Definition: compat.h:753
GLenum func
Definition: glext.h:6028
GLfloat GLfloat p
Definition: glext.h:8902
static PVOID hdll
Definition: shimdbg.c:126

◆ MAXKEYEVENTS

#define MAXKEYEVENTS   12

Definition at line 90 of file input.c.

◆ MAXKEYMESSAGES

#define MAXKEYMESSAGES
Value:
MAXKEYEVENTS /* assuming a key event generates one
and only one message */
#define MAXKEYEVENTS
Definition: input.c:90

Definition at line 91 of file input.c.

◆ MYERROR

#define MYERROR   0xdeadbeef

◆ shift

#define shift   1

Definition at line 1755 of file input.c.

◆ STEP

#define STEP   3

Definition at line 1259 of file input.c.

Typedef Documentation

◆ KEV

typedef enum KEVtag KEV

Enumeration Type Documentation

◆ KEVtag

Enumerator
ALTDOWN 
ALTUP 
XDOWN 
XUP 
SHIFTDOWN 
SHIFTUP 
CTRLDOWN 
CTRLUP 

Definition at line 98 of file input.c.

103/* matching scan codes */
104static const int GETSCAN[]={0, 0x38, 0x38, 0x2D, 0x2D, 0x2A, 0x2A, 0x1D, 0x1D };
105/* matching updown events */
106static const int GETFLAGS[]={0, 0, KEYEVENTF_KEYUP, 0, KEYEVENTF_KEYUP, 0, KEYEVENTF_KEYUP, 0, KEYEVENTF_KEYUP};
107/* matching descriptions */
108static const char *getdesc[]={"", "+alt","-alt","+X","-X","+shift","-shift","+ctrl","-ctrl"};
109
110/* The MSVC headers ignore our NONAMELESSUNION requests so we have to define our own type */
111typedef struct
112{
113 DWORD type;
114 union
115 {
117 KEYBDINPUT ki;
118 HARDWAREINPUT hi;
119 } u;
120} TEST_INPUT;
121
122typedef struct {
126} KMSG;
127
128/*******************************************
129 * add new test sets here
130 * the software will make all combinations of the
131 * keyevent defined here
132 */
133static const struct {
134 int nrkev;
137} testkeyset[]= {
138 { 2, { ALTDOWN, XDOWN }, { ALTUP, XUP}},
139 { 3, { ALTDOWN, XDOWN , SHIFTDOWN}, { ALTUP, XUP, SHIFTUP}},
140 { 3, { ALTDOWN, XDOWN , CTRLDOWN}, { ALTUP, XUP, CTRLUP}},
141 { 3, { SHIFTDOWN, XDOWN , CTRLDOWN}, { SHIFTUP, XUP, CTRLUP}},
142 { 0 } /* mark the end */
143};
144
145/**********************adapted from input.c **********************************/
146
147static BYTE InputKeyStateTable[256];
148static BYTE AsyncKeyStateTable[256];
149static BYTE TrackSysKey = 0; /* determine whether ALT key up will cause a WM_SYSKEYUP
150 or a WM_KEYUP message */
151
152static void init_function_pointers(void)
153{
154 HMODULE hdll = GetModuleHandleA("user32");
155
156#define GET_PROC(func) \
157 if (!(p ## func = (void*)GetProcAddress(hdll, #func))) \
158 trace("GetProcAddress(%s) failed\n", #func)
159
160 GET_PROC(GetCurrentInputMessageSource);
161 GET_PROC(GetMouseMovePointsEx);
162 GET_PROC(GetPointerType);
167#undef GET_PROC
168}
169
170static int KbdMessage( KEV kev, WPARAM *pwParam, LPARAM *plParam )
171{
173 int VKey = GETVKEY[kev];
174 WORD flags;
175
176 flags = LOBYTE(GETSCAN[kev]);
178
179 if (GETFLAGS[kev] & KEYEVENTF_KEYUP )
180 {
182 if( (InputKeyStateTable[VK_MENU] & 0x80) && (
183 (VKey == VK_MENU) || (VKey == VK_CONTROL) ||
184 !(InputKeyStateTable[VK_CONTROL] & 0x80))) {
185 if( TrackSysKey == VK_MENU || /* <ALT>-down/<ALT>-up sequence */
186 (VKey != VK_MENU)) /* <ALT>-down...<something else>-up */
188 TrackSysKey = 0;
189 }
190 InputKeyStateTable[VKey] &= ~0x80;
191 flags |= KF_REPEAT | KF_UP;
192 }
193 else
194 {
195 if (InputKeyStateTable[VKey] & 0x80) flags |= KF_REPEAT;
196 if (!(InputKeyStateTable[VKey] & 0x80)) InputKeyStateTable[VKey] ^= 0x01;
197 InputKeyStateTable[VKey] |= 0x80;
198 AsyncKeyStateTable[VKey] |= 0x80;
199
201 if( (InputKeyStateTable[VK_MENU] & 0x80) &&
202 !(InputKeyStateTable[VK_CONTROL] & 0x80)) {
204 TrackSysKey = VKey;
205 }
206 }
207
209
210 if( plParam) *plParam = MAKELPARAM( 1, flags );
211 if( pwParam) *pwParam = VKey;
212 return message;
213}
214
215/****************************** end copy input.c ****************************/
216
217/*
218 * . prepare the keyevents for SendInputs
219 * . calculate the "expected" messages
220 * . Send the events to our window
221 * . retrieve the messages from the input queue
222 * . verify
223 */
224static BOOL do_test( HWND hwnd, int seqnr, const KEV td[] )
225{
226 TEST_INPUT inputs[MAXKEYEVENTS];
227 KMSG expmsg[MAXKEYEVENTS];
228 MSG msg;
229 char buf[100];
230 UINT evtctr=0, ret;
231 int kmctr, i;
232
233 buf[0]='\0';
234 TrackSysKey=0; /* see input.c */
235 for (i = 0; i < MAXKEYEVENTS; i++)
236 {
237 inputs[evtctr].type = INPUT_KEYBOARD;
238 inputs[evtctr].u.ki.wVk = GETVKEY[td[i]];
239 inputs[evtctr].u.ki.wScan = GETSCAN[td[i]];
240 inputs[evtctr].u.ki.dwFlags = GETFLAGS[td[i]];
241 inputs[evtctr].u.ki.dwExtraInfo = 0;
242 inputs[evtctr].u.ki.time = ++timetag;
243 if (td[i]) evtctr++;
244
245 strcat(buf, getdesc[td[i]]);
246 if(td[i])
247 expmsg[i].message = KbdMessage(td[i], &(expmsg[i].wParam), &(expmsg[i].lParam));
248 else
249 expmsg[i].message = 0;
250 }
251 for( kmctr = 0; kmctr < MAXKEYEVENTS && expmsg[kmctr].message; kmctr++)
252 ;
253 ok( evtctr <= MAXKEYEVENTS, "evtctr is above MAXKEYEVENTS\n" );
254 ret = SendInput(evtctr, (INPUT *)inputs, sizeof(INPUT));
255 ok(ret == evtctr, "SendInput failed to send some events\n");
256 i = 0;
257 if (winetest_debug > 1)
258 trace("======== key stroke sequence #%d: %s =============\n",
259 seqnr + 1, buf);
261 if (winetest_debug > 1)
262 trace("message[%d] %-15s wParam %04lx lParam %08lx time %x\n", i,
263 MSGNAME[msg.message - WM_KEYFIRST], msg.wParam, msg.lParam, msg.time);
264 if( i < kmctr ) {
265 ok( msg.message == expmsg[i].message &&
266 msg.wParam == expmsg[i].wParam &&
267 msg.lParam == expmsg[i].lParam,
268 "%u/%u: wrong message %x/%08lx/%08lx expected %s/%08lx/%08lx\n",
269 seqnr, i, msg.message, msg.wParam, msg.lParam,
270 MSGNAME[(expmsg[i]).message - WM_KEYFIRST], expmsg[i].wParam, expmsg[i].lParam );
271 }
272 i++;
273 }
274 if (winetest_debug > 1)
275 trace("%d messages retrieved\n", i);
276 if (!i && kmctr)
277 {
278 skip( "simulated keyboard input doesn't work\n" );
279 return FALSE;
280 }
281 ok( i == kmctr, "message count is wrong: got %d expected: %d\n", i, kmctr);
282 return TRUE;
283}
284
285/* test all combinations of the specified key events */
286static BOOL TestASet( HWND hWnd, int nrkev, const KEV kevdwn[], const KEV kevup[] )
287{
288 int i,j,k,l,m,n;
289 static int count=0;
290 KEV kbuf[MAXKEYEVENTS];
291 assert( nrkev==2 || nrkev==3);
292 for(i=0;i<MAXKEYEVENTS;i++) kbuf[i]=0;
293 /* two keys involved gives 4 test cases */
294 if(nrkev==2) {
295 for(i=0;i<nrkev;i++) {
296 for(j=0;j<nrkev;j++) {
297 kbuf[0] = kevdwn[i];
298 kbuf[1] = kevdwn[1-i];
299 kbuf[2] = kevup[j];
300 kbuf[3] = kevup[1-j];
301 if (!do_test( hWnd, count++, kbuf)) return FALSE;
302 }
303 }
304 }
305 /* three keys involved gives 36 test cases */
306 if(nrkev==3){
307 for(i=0;i<nrkev;i++){
308 for(j=0;j<nrkev;j++){
309 if(j==i) continue;
310 for(k=0;k<nrkev;k++){
311 if(k==i || k==j) continue;
312 for(l=0;l<nrkev;l++){
313 for(m=0;m<nrkev;m++){
314 if(m==l) continue;
315 for(n=0;n<nrkev;n++){
316 if(n==l ||n==m) continue;
317 kbuf[0] = kevdwn[i];
318 kbuf[1] = kevdwn[j];
319 kbuf[2] = kevdwn[k];
320 kbuf[3] = kevup[l];
321 kbuf[4] = kevup[m];
322 kbuf[5] = kevup[n];
323 if (!do_test( hWnd, count++, kbuf)) return FALSE;
324 }
325 }
326 }
327 }
328 }
329 }
330 }
331 return TRUE;
332}
333
334/* test each set specified in the global testkeyset array */
335static void TestSysKeys( HWND hWnd)
336{
337 int i;
338 for(i=0; testkeyset[i].nrkev;i++)
340}
341
343 LPARAM lParam )
344{
345 return DefWindowProcA( hWnd, msg, wParam, lParam );
346}
347
348static void test_Input_whitebox(void)
349{
350 MSG msg;
351 WNDCLASSA wclass;
353
354 wclass.lpszClassName = "InputSysKeyTestClass";
355 wclass.style = CS_HREDRAW | CS_VREDRAW;
356 wclass.lpfnWndProc = WndProc;
357 wclass.hInstance = hInstance;
358 wclass.hIcon = LoadIconA( 0, (LPCSTR)IDI_APPLICATION );
360 wclass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
361 wclass.lpszMenuName = 0;
362 wclass.cbClsExtra = 0;
363 wclass.cbWndExtra = 0;
364 RegisterClassA( &wclass );
365 /* create the test window that will receive the keystrokes */
366 hWndTest = CreateWindowA( wclass.lpszClassName, "InputSysKeyTest",
369 assert( hWndTest );
374
375 /* flush pending messages */
376 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
377
381}
382
383static inline BOOL is_keyboard_message( UINT message )
384{
385 return (message >= WM_KEYFIRST && message <= WM_KEYLAST);
386}
387
388static inline BOOL is_mouse_message( UINT message )
389{
390 return (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST);
391}
392
393/* try to make sure pending X events have been processed before continuing */
394static void empty_message_queue(void)
395{
396 MSG msg;
397 int diff = 200;
398 int min_timeout = 50;
399 DWORD time = GetTickCount() + diff;
400
401 while (diff > 0)
402 {
403 if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT) break;
404 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
405 {
406 if (is_keyboard_message(msg.message) || is_mouse_message(msg.message))
407 ok(msg.time != 0, "message %#x has time set to 0\n", msg.message);
408
411 }
412 diff = time - GetTickCount();
413 }
414}
415
416struct transition_s {
417 WORD wVk;
420};
421
422typedef enum {
423 sent=0x1,
424 posted=0x2,
425 parent=0x4,
426 wparam=0x8,
427 lparam=0x10,
428 defwinproc=0x20,
429 beginpaint=0x40,
430 optional=0x80,
431 hook=0x100,
432 winevent_hook=0x200
434
435struct message {
436 UINT message; /* the WM_* code */
437 msg_flags_t flags; /* message props */
438 WPARAM wParam; /* expected value of wParam */
439 LPARAM lParam; /* expected value of lParam */
440};
441
442static const struct sendinput_test_s {
443 WORD wVk;
448} sendinput_test[] = {
449 /* test ALT+F */
450 /* 0 */
451 {VK_LMENU, 0, FALSE, {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}},
453 {'F', 0, FALSE, {{'F', 0x00}, {0}},
455 {WM_SYSCHAR},
456 {WM_SYSCOMMAND}, {0}}},
457 {'F', KEYEVENTF_KEYUP, FALSE, {{'F', 0x80}, {0}},
458 {{WM_SYSKEYUP, hook}, {WM_SYSKEYUP}, {0}}},
459 {VK_LMENU, KEYEVENTF_KEYUP, FALSE, {{VK_MENU, 0x80}, {VK_LMENU, 0x80}, {0}},
460 {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
461
462 /* test CTRL+O */
463 /* 4 */
464 {VK_LCONTROL, 0, FALSE, {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
465 {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}},
466 {'O', 0, FALSE, {{'O', 0x00}, {0}},
467 {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {WM_CHAR}, {0}}},
468 {'O', KEYEVENTF_KEYUP, FALSE, {{'O', 0x80}, {0}},
469 {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
470 {VK_LCONTROL, KEYEVENTF_KEYUP, FALSE, {{VK_CONTROL, 0x80}, {VK_LCONTROL, 0x80}, {0}},
471 {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
472
473 /* test ALT+CTRL+X */
474 /* 8 */
475 {VK_LMENU, 0, FALSE, {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}},
476 {{WM_SYSKEYDOWN, hook}, {WM_SYSKEYDOWN}, {0}}},
477 {VK_LCONTROL, 0, FALSE, {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
478 {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}},
479 {'X', 0, FALSE, {{'X', 0x00}, {0}},
480 {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}},
481 {'X', KEYEVENTF_KEYUP, FALSE, {{'X', 0x80}, {0}},
482 {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
483 {VK_LCONTROL, KEYEVENTF_KEYUP, FALSE, {{VK_CONTROL, 0x80}, {VK_LCONTROL, 0x80}, {0}},
484 {{WM_SYSKEYUP, hook}, {WM_SYSKEYUP}, {0}}},
485 {VK_LMENU, KEYEVENTF_KEYUP, FALSE, {{VK_MENU, 0x80}, {VK_LMENU, 0x80}, {0}},
486 {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
487
488 /* test SHIFT+A */
489 /* 14 */
490 {VK_LSHIFT, 0, FALSE, {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}},
491 {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}},
492 {'A', 0, FALSE, {{'A', 0x00}, {0}},
493 {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {WM_CHAR}, {0}}},
494 {'A', KEYEVENTF_KEYUP, FALSE, {{'A', 0x80}, {0}},
495 {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
496 {VK_LSHIFT, KEYEVENTF_KEYUP, FALSE, {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80}, {0}},
497 {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
498 /* test L-SHIFT & R-SHIFT: */
499 /* RSHIFT == LSHIFT */
500 /* 18 */
501 {VK_RSHIFT, 0, FALSE,
502 /* recent windows versions (>= w2k3) correctly report an RSHIFT transition */
503 {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00, TRUE}, {VK_RSHIFT, 0x00, TRUE}, {0}},
505 {WM_KEYDOWN}, {0}}},
507 {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80, TRUE}, {VK_RSHIFT, 0x80, TRUE}, {0}},
509 {WM_KEYUP}, {0}}},
510
511 /* LSHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */
512 /* 20 */
514 {{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}},
516 {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
518 {{VK_SHIFT, 0x80}, {VK_RSHIFT, 0x80}, {0}},
520 {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
521 /* RSHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */
522 /* 22 */
524 {{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}},
526 {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
528 {{VK_SHIFT, 0x80}, {VK_RSHIFT, 0x80}, {0}},
530 {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
531
532 /* Note about wparam for hook with generic key (VK_SHIFT, VK_CONTROL, VK_MENU):
533 win2k - sends to hook whatever we generated here
534 winXP+ - Attempts to convert key to L/R key but not always correct
535 */
536 /* SHIFT == LSHIFT */
537 /* 24 */
538 {VK_SHIFT, 0, FALSE,
539 {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}},
540 {{WM_KEYDOWN, hook/* |wparam */|lparam, VK_SHIFT, 0},
541 {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
543 {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80}, {0}},
544 {{WM_KEYUP, hook/*|wparam*/|lparam, VK_SHIFT, LLKHF_UP},
545 {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
546 /* SHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */
547 /* 26 */
549 {{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}},
551 {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
553 {{VK_SHIFT, 0x80}, {VK_RSHIFT, 0x80}, {0}},
555 {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
556
557 /* test L-CONTROL & R-CONTROL: */
558 /* RCONTROL == LCONTROL */
559 /* 28 */
560 {VK_RCONTROL, 0, FALSE,
561 {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
563 {WM_KEYDOWN, wparam|lparam, VK_CONTROL, 0}, {0}}},
565 {{VK_CONTROL, 0x80}, {VK_LCONTROL, 0x80}, {0}},
568 /* LCONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */
569 /* 30 */
571 {{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}},
575 {{VK_CONTROL, 0x80}, {VK_RCONTROL, 0x80}, {0}},
578 /* RCONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */
579 /* 32 */
581 {{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}},
585 {{VK_CONTROL, 0x80}, {VK_RCONTROL, 0x80}, {0}},
588 /* CONTROL == LCONTROL */
589 /* 34 */
590 {VK_CONTROL, 0, FALSE,
591 {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
592 {{WM_KEYDOWN, hook/*|wparam, VK_CONTROL*/},
593 {WM_KEYDOWN, wparam|lparam, VK_CONTROL, 0}, {0}}},
595 {{VK_CONTROL, 0x80}, {VK_LCONTROL, 0x80}, {0}},
596 {{WM_KEYUP, hook/*|wparam, VK_CONTROL*/},
598 /* CONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */
599 /* 36 */
601 {{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}},
605 {{VK_CONTROL, 0x80}, {VK_RCONTROL, 0x80}, {0}},
608
609 /* test L-MENU & R-MENU: */
610 /* RMENU == LMENU */
611 /* 38 */
612 {VK_RMENU, 0, FALSE,
613 {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {VK_CONTROL, 0x00, 1}, {VK_LCONTROL, 0x01, 1}, {0}},
617 {WM_SYSKEYDOWN, wparam|lparam, VK_MENU, 0}, {0}}},
619 {{VK_MENU, 0x80}, {VK_LMENU, 0x80}, {VK_CONTROL, 0x81, 1}, {VK_LCONTROL, 0x80, 1}, {0}},
624 {WM_SYSCOMMAND, optional}, {0}}},
625 /* LMENU | KEYEVENTF_EXTENDEDKEY == RMENU */
626 /* 40 */
628 {{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {0}},
632 {{VK_MENU, 0x80}, {VK_RMENU, 0x80}, {0}},
635 {WM_SYSCOMMAND}, {0}}},
636 /* RMENU | KEYEVENTF_EXTENDEDKEY == RMENU */
637 /* 42 */
639 {{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {VK_CONTROL, 0x00, 1}, {VK_LCONTROL, 0x01, 1}, {0}},
645 {{VK_MENU, 0x80}, {VK_RMENU, 0x80}, {VK_CONTROL, 0x81, 1}, {VK_LCONTROL, 0x80, 1}, {0}},
650 {WM_SYSCOMMAND, optional}, {0}}},
651 /* MENU == LMENU */
652 /* 44 */
653 {VK_MENU, 0, FALSE,
654 {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}},
655 {{WM_SYSKEYDOWN, hook/*|wparam, VK_MENU*/},
656 {WM_SYSKEYDOWN, wparam|lparam, VK_MENU, 0}, {0}}},
658 {{VK_MENU, 0x80}, {VK_LMENU, 0x80}, {0}},
659 {{WM_KEYUP, hook/*|wparam, VK_MENU*/},
661 {WM_SYSCOMMAND}, {0}}},
662 /* MENU | KEYEVENTF_EXTENDEDKEY == RMENU */
663 /* 46 */
665 {{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {VK_CONTROL, 0x00, 1}, {VK_LCONTROL, 0x01, 1}, {0}},
670 {{VK_MENU, 0x80}, {VK_RMENU, 0x80}, {VK_CONTROL, 0x81, 1}, {VK_LCONTROL, 0x80, 1}, {0}},
674 {WM_SYSCOMMAND}, {0}}},
675
676 /* test LSHIFT & RSHIFT */
677 /* 48 */
678 {VK_LSHIFT, 0, FALSE,
679 {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}},
681 {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
683 {{VK_RSHIFT, 0x00}, {0}},
685 {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
687 {{VK_RSHIFT, 0x80}, {0}},
689 {WM_KEYUP, optional}, {0}}},
691 {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80}, {0}},
693 {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
694
695 {0, 0, FALSE, {{0}}, {{0}}} /* end */
696};
697
700
701/* Verify that only specified key state transitions occur */
702static void compare_and_check(int id, BYTE *ks1, BYTE *ks2,
703 const struct sendinput_test_s *test, BOOL foreground)
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 && foreground) {
711 /* We won't receive any information from GetKeyboardState() if we're
712 * not the foreground window. */
713 BOOL matched = ((ks1[t->wVk]&0x80) == (t->before_state&0x80)
714 && (ks2[t->wVk]&0x80) == (~t->before_state&0x80));
715
716 if (!matched && !t->optional && test->_todo_wine)
717 {
718 failcount++;
719 todo_wine {
720 ok(matched, "%2d (%x/%x): %02x from %02x -> %02x "
721 "instead of %02x -> %02x\n", id, test->wVk, test->dwFlags,
722 t->wVk, ks1[t->wVk]&0x80, ks2[t->wVk]&0x80, t->before_state,
723 ~t->before_state&0x80);
724 }
725 } else {
726 ok(matched || t->optional, "%2d (%x/%x): %02x from %02x -> %02x "
727 "instead of %02x -> %02x\n", id, test->wVk, test->dwFlags,
728 t->wVk, ks1[t->wVk]&0x80, ks2[t->wVk]&0x80, t->before_state,
729 ~t->before_state&0x80);
730 }
731 ks2[t->wVk] = ks1[t->wVk]; /* clear the match */
732 t++;
733 }
734 for (i = 0; i < 256; i++)
735 if (ks2[i] != ks1[i] && test->_todo_wine)
736 {
737 failcount++;
739 ok(FALSE, "%2d (%x/%x): %02x from %02x -> %02x unexpected\n",
740 id, test->wVk, test->dwFlags, i, ks1[i], ks2[i]);
741 }
742 else
743 ok(ks2[i] == ks1[i], "%2d (%x/%x): %02x from %02x -> %02x unexpected\n",
744 id, test->wVk, test->dwFlags, i, ks1[i], ks2[i]);
745
746 while (expected->message && actual_cnt < sent_messages_cnt)
747 {
748 const struct message *actual = &sent_messages[actual_cnt];
749
750 if (expected->message == actual->message)
751 {
752 if (expected->flags & wparam)
753 {
754 if ((expected->flags & optional) && (expected->wParam != actual->wParam))
755 {
756 expected++;
757 continue;
758 }
759 if (expected->wParam != actual->wParam && test->_todo_wine)
760 {
761 failcount++;
763 ok(FALSE, "%2d (%x/%x): in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
764 id, test->wVk, test->dwFlags, expected->message, expected->wParam, actual->wParam);
765 }
766 else
767 ok(expected->wParam == actual->wParam,
768 "%2d (%x/%x): in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
769 id, test->wVk, test->dwFlags, expected->message, expected->wParam, actual->wParam);
770 }
771 if (expected->flags & lparam)
772 {
773 if (expected->lParam != actual->lParam && test->_todo_wine)
774 {
775 failcount++;
777 ok(FALSE, "%2d (%x/%x): in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
778 id, test->wVk, test->dwFlags, expected->message, expected->lParam, actual->lParam);
779 }
780 else
781 ok(expected->lParam == actual->lParam,
782 "%2d (%x/%x): in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
783 id, test->wVk, test->dwFlags, expected->message, expected->lParam, actual->lParam);
784 }
785 ok((expected->flags & hook) == (actual->flags & hook),
786 "%2d (%x/%x): the msg 0x%04x should have been sent by a hook\n",
787 id, test->wVk, test->dwFlags, expected->message);
788
789 }
790 else if (expected->flags & optional)
791 {
792 expected++;
793 continue;
794 }
795 else if (!(expected->flags & hook) && !foreground)
796 {
797 /* If we weren't able to receive foreground status, we won't get
798 * any window messages. */
799 expected++;
800 continue;
801 }
802 /* NT4 doesn't send SYSKEYDOWN/UP to hooks, only KEYDOWN/UP */
803 else if ((expected->flags & hook) &&
804 (expected->message == WM_SYSKEYDOWN || expected->message == WM_SYSKEYUP) &&
805 (actual->message == expected->message - 4))
806 {
807 ok((expected->flags & hook) == (actual->flags & hook),
808 "%2d (%x/%x): the msg 0x%04x should have been sent by a hook\n",
809 id, test->wVk, test->dwFlags, expected->message);
810 }
811 /* For VK_RMENU, at least localized Win2k/XP sends KEYDOWN/UP
812 * instead of SYSKEYDOWN/UP to the WNDPROC */
813 else if (test->wVk == VK_RMENU && !(expected->flags & hook) &&
814 (expected->message == WM_SYSKEYDOWN || expected->message == WM_SYSKEYUP) &&
815 (actual->message == expected->message - 4))
816 {
817 ok(expected->wParam == actual->wParam && expected->lParam == actual->lParam,
818 "%2d (%x/%x): the msg 0x%04x was expected, but got msg 0x%04x instead\n",
819 id, test->wVk, test->dwFlags, expected->message, actual->message);
820 }
821 else if (test->_todo_wine)
822 {
823 failcount++;
825 ok(FALSE,
826 "%2d (%x/%x): the msg 0x%04x was expected, but got msg 0x%04x instead\n",
827 id, test->wVk, test->dwFlags, expected->message, actual->message);
828 }
829 else
830 ok(FALSE,
831 "%2d (%x/%x): the msg 0x%04x was expected, but got msg 0x%04x instead\n",
832 id, test->wVk, test->dwFlags, expected->message, actual->message);
833
834 actual_cnt++;
835 expected++;
836 }
837 /* skip all optional trailing messages */
838 while (expected->message && ((expected->flags & optional) || (!(expected->flags & hook) && !foreground)))
839 expected++;
840
841
842 if (expected->message || actual_cnt < sent_messages_cnt)
843 {
844 if (test->_todo_wine)
845 {
846 failcount++;
848 ok(FALSE, "%2d (%x/%x): the msg sequence is not complete: expected %04x - actual %04x\n",
849 id, test->wVk, test->dwFlags, expected->message, sent_messages[actual_cnt].message);
850 }
851 else
852 ok(FALSE, "%2d (%x/%x): the msg sequence is not complete: expected %04x - actual %04x\n",
853 id, test->wVk, test->dwFlags, expected->message, sent_messages[actual_cnt].message);
854 }
855
856 if( test->_todo_wine && !failcount) /* succeeded yet marked todo */
858 ok(TRUE, "%2d (%x/%x): marked \"todo_wine\" but succeeds\n", id, test->wVk, test->dwFlags);
859
861}
862
863/* WndProc2 checks that we get at least the messages specified */
866{
867 if (winetest_debug > 1) trace("MSG: %8x W:%8lx L:%8lx\n", Msg, wParam, lParam);
868
869 if ((Msg >= WM_KEYFIRST && Msg <= WM_KEYLAST) || Msg == WM_SYSCOMMAND)
870 {
871 ok(sent_messages_cnt < MAXKEYMESSAGES, "Too many messages\n");
873 {
878 }
879 }
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;
896 }
897
898if(0) /* For some reason not stable on Wine */
899{
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}
912static void test_Input_blackbox(void)
913{
915 int ii;
916 BYTE ks1[256], ks2[256];
917 LONG_PTR prevWndProc;
918 BOOL foreground;
919 HWND window;
920 HHOOK hook;
921
922 if (GetKeyboardLayout(0) != (HKL)(ULONG_PTR)0x04090409)
923 {
924 skip("Skipping Input_blackbox test on non-US keyboard\n");
925 return;
926 }
928 |WS_VISIBLE, 0, 0, 200, 60, NULL, NULL,
929 NULL, NULL);
930 ok(window != NULL, "error: %d\n", (int) GetLastError());
932 foreground = SetForegroundWindow( window );
933 if (!foreground)
934 skip("Failed to set foreground window; some tests will be skipped.\n");
935
937 {
939 win_skip("WH_KEYBOARD_LL is not supported\n");
940 return;
941 }
942
943 /* must process all initial messages, otherwise X11DRV_KeymapNotify unsets
944 * key state set by SendInput(). */
946
948 ok(prevWndProc != 0 || GetLastError() == 0, "error: %d\n", (int) GetLastError());
949
950 i.type = INPUT_KEYBOARD;
951 i.u.ki.time = 0;
952 i.u.ki.dwExtraInfo = 0;
953
954 for (ii = 0; ii < ARRAY_SIZE(sendinput_test)-1; ii++) {
955 GetKeyboardState(ks1);
956 i.u.ki.wScan = ii+1 /* useful for debugging */;
957 i.u.ki.dwFlags = sendinput_test[ii].dwFlags;
958 i.u.ki.wVk = sendinput_test[ii].wVk;
959 SendInput(1, (INPUT*)&i, sizeof(TEST_INPUT));
961 GetKeyboardState(ks2);
962 compare_and_check(ii, ks1, ks2, &sendinput_test[ii], foreground);
963 }
964
968}
969
970static void reset_key_status(WORD vk)
971{
972 key_status.last_key_down = -1;
973 key_status.last_key_up = -1;
974 key_status.last_syskey_down = -1;
975 key_status.last_syskey_up = -1;
976 key_status.last_char = -1;
977 key_status.last_syschar = -1;
978 key_status.last_hook_down = -1;
979 key_status.last_hook_up = -1;
980 key_status.last_hook_syskey_down = -1;
981 key_status.last_hook_syskey_up = -1;
982 key_status.vk = vk;
983 key_status.expect_alt = FALSE;
984 key_status.sendinput_broken = FALSE;
985}
986
987static void test_unicode_keys(HWND hwnd, HHOOK hook)
988{
989 TEST_INPUT inputs[2];
990 MSG msg;
991
992 /* init input data that never changes */
993 inputs[1].type = inputs[0].type = INPUT_KEYBOARD;
994 inputs[1].u.ki.dwExtraInfo = inputs[0].u.ki.dwExtraInfo = 0;
995 inputs[1].u.ki.time = inputs[0].u.ki.time = 0;
996
997 /* pressing & releasing a single unicode character */
998 inputs[0].u.ki.wVk = 0;
999 inputs[0].u.ki.wScan = 0x3c0;
1000 inputs[0].u.ki.dwFlags = KEYEVENTF_UNICODE;
1001
1002 reset_key_status(VK_PACKET);
1003 SendInput(1, (INPUT*)inputs, sizeof(INPUT));
1004 while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1005 if(msg.message == WM_KEYDOWN && msg.wParam == VK_PACKET){
1007 }
1009 }
1010 if(!key_status.sendinput_broken){
1011 ok(key_status.last_key_down == VK_PACKET,
1012 "Last keydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_down);
1013 ok(key_status.last_char == 0x3c0,
1014 "Last char msg wparam should have been 0x3c0 (was: 0x%x)\n", key_status.last_char);
1015 if(hook)
1016 ok(key_status.last_hook_down == 0x3c0,
1017 "Last hookdown msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_down);
1018 }
1019
1020 inputs[1].u.ki.wVk = 0;
1021 inputs[1].u.ki.wScan = 0x3c0;
1022 inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
1023
1024 reset_key_status(VK_PACKET);
1025 SendInput(1, (INPUT*)(inputs+1), sizeof(INPUT));
1026 while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1027 if(msg.message == WM_KEYDOWN && msg.wParam == VK_PACKET){
1029 }
1031 }
1032 if(!key_status.sendinput_broken){
1033 ok(key_status.last_key_up == VK_PACKET,
1034 "Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up);
1035 if(hook)
1036 ok(key_status.last_hook_up == 0x3c0,
1037 "Last hookup msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_up);
1038 }
1039
1040 /* holding alt, pressing & releasing a unicode character, releasing alt */
1041 inputs[0].u.ki.wVk = VK_LMENU;
1042 inputs[0].u.ki.wScan = 0;
1043 inputs[0].u.ki.dwFlags = 0;
1044
1045 inputs[1].u.ki.wVk = 0;
1046 inputs[1].u.ki.wScan = 0x3041;
1047 inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE;
1048
1049 reset_key_status(VK_PACKET);
1050 key_status.expect_alt = TRUE;
1051 SendInput(2, (INPUT*)inputs, sizeof(INPUT));
1052 while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1053 if(msg.message == WM_SYSKEYDOWN && msg.wParam == VK_PACKET){
1055 }
1057 }
1058 if(!key_status.sendinput_broken){
1059 ok(key_status.last_syskey_down == VK_PACKET,
1060 "Last syskeydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_syskey_down);
1061 ok(key_status.last_syschar == 0x3041,
1062 "Last syschar msg should have been 0x3041 (was: 0x%x)\n", key_status.last_syschar);
1063 if(hook)
1064 ok(key_status.last_hook_syskey_down == 0x3041,
1065 "Last hooksysdown msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_syskey_down);
1066 }
1067
1068 inputs[1].u.ki.wVk = 0;
1069 inputs[1].u.ki.wScan = 0x3041;
1070 inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
1071
1072 inputs[0].u.ki.wVk = VK_LMENU;
1073 inputs[0].u.ki.wScan = 0;
1074 inputs[0].u.ki.dwFlags = KEYEVENTF_KEYUP;
1075
1076 reset_key_status(VK_PACKET);
1077 key_status.expect_alt = TRUE;
1078 SendInput(2, (INPUT*)inputs, sizeof(INPUT));
1079 while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1080 if(msg.message == WM_SYSKEYDOWN && msg.wParam == VK_PACKET){
1082 }
1084 }
1085 if(!key_status.sendinput_broken){
1086 ok(key_status.last_key_up == VK_PACKET,
1087 "Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up);
1088 if(hook)
1089 ok(key_status.last_hook_up == 0x3041,
1090 "Last hook up msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_up);
1091 }
1092
1093 /* Press and release, non-zero key code. */
1094 inputs[0].u.ki.wVk = 0x51;
1095 inputs[0].u.ki.wScan = 0x123;
1096 inputs[0].u.ki.dwFlags = KEYEVENTF_UNICODE;
1097
1098 inputs[1].u.ki.wVk = 0x51;
1099 inputs[1].u.ki.wScan = 0x123;
1100 inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
1101
1102 reset_key_status(inputs[0].u.ki.wVk);
1103 SendInput(2, (INPUT*)inputs, sizeof(INPUT));
1104 while (PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE))
1105 {
1108 }
1109
1110 if (!key_status.sendinput_broken)
1111 {
1112 ok(key_status.last_key_down == 0x51, "Unexpected key down %#x.\n", key_status.last_key_down);
1113 ok(key_status.last_key_up == 0x51, "Unexpected key up %#x.\n", key_status.last_key_up);
1114 if (hook)
1115 todo_wine
1116 ok(key_status.last_hook_up == 0x23, "Unexpected hook message %#x.\n", key_status.last_hook_up);
1117 }
1118}
1119
1121 LPARAM lParam )
1122{
1123 switch(msg){
1124 case WM_KEYDOWN:
1125 key_status.last_key_down = wParam;
1126 break;
1127 case WM_SYSKEYDOWN:
1128 key_status.last_syskey_down = wParam;
1129 break;
1130 case WM_KEYUP:
1131 key_status.last_key_up = wParam;
1132 break;
1133 case WM_SYSKEYUP:
1134 key_status.last_syskey_up = wParam;
1135 break;
1136 case WM_CHAR:
1137 key_status.last_char = wParam;
1138 break;
1139 case WM_SYSCHAR:
1140 key_status.last_syschar = wParam;
1141 break;
1142 }
1143 return DefWindowProcW(hWnd, msg, wParam, lParam);
1144}
1145
1147{
1148 if(nCode == HC_ACTION){
1150 if(!info->vkCode){
1151 key_status.sendinput_broken = TRUE;
1152 win_skip("SendInput doesn't support unicode on this platform\n");
1153 }else{
1154 if(key_status.expect_alt){
1155 ok(info->vkCode == VK_LMENU, "vkCode should have been VK_LMENU[0x%04x], was: 0x%x\n", VK_LMENU, info->vkCode);
1156 key_status.expect_alt = FALSE;
1157 }else
1158 todo_wine_if(key_status.vk != VK_PACKET)
1159 ok(info->vkCode == key_status.vk, "Unexpected vkCode %#x, expected %#x.\n", info->vkCode, key_status.vk);
1160 }
1161 switch(wParam){
1162 case WM_KEYDOWN:
1163 key_status.last_hook_down = info->scanCode;
1164 break;
1165 case WM_KEYUP:
1166 key_status.last_hook_up = info->scanCode;
1167 break;
1168 case WM_SYSKEYDOWN:
1169 key_status.last_hook_syskey_down = info->scanCode;
1170 break;
1171 case WM_SYSKEYUP:
1172 key_status.last_hook_syskey_up = info->scanCode;
1173 break;
1174 }
1175 }
1176 return CallNextHookEx(NULL, nCode, wParam, lParam);
1177}
1178
1179static void test_Input_unicode(void)
1180{
1181 WCHAR classNameW[] = {'I','n','p','u','t','U','n','i','c','o','d','e',
1182 'K','e','y','T','e','s','t','C','l','a','s','s',0};
1183 WCHAR windowNameW[] = {'I','n','p','u','t','U','n','i','c','o','d','e',
1184 'K','e','y','T','e','s','t',0};
1185 MSG msg;
1186 WNDCLASSW wclass;
1188 HHOOK hook;
1189 HMODULE hModuleImm32;
1190 BOOL (WINAPI *pImmDisableIME)(DWORD);
1191
1192 wclass.lpszClassName = classNameW;
1193 wclass.style = CS_HREDRAW | CS_VREDRAW;
1195 wclass.hInstance = hInstance;
1196 wclass.hIcon = LoadIconW(0, (LPCWSTR)IDI_APPLICATION);
1198 wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1199 wclass.lpszMenuName = 0;
1200 wclass.cbClsExtra = 0;
1201 wclass.cbWndExtra = 0;
1202 if(!RegisterClassW(&wclass)){
1203 win_skip("Unicode functions not supported\n");
1204 return;
1205 }
1206
1207 hModuleImm32 = LoadLibraryA("imm32.dll");
1208 if (hModuleImm32) {
1209 pImmDisableIME = (void *)GetProcAddress(hModuleImm32, "ImmDisableIME");
1210 if (pImmDisableIME)
1211 pImmDisableIME(0);
1212 }
1213 pImmDisableIME = NULL;
1214 FreeLibrary(hModuleImm32);
1215
1216 /* create the test window that will receive the keystrokes */
1217 hWndTest = CreateWindowW(wclass.lpszClassName, windowNameW,
1218 WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100,
1219 NULL, NULL, hInstance, NULL);
1220
1223
1225 if(!hook)
1226 win_skip("unable to set WH_KEYBOARD_LL hook\n");
1227
1232
1233 /* flush pending messages */
1234 while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageW(&msg);
1235
1237
1239
1240 if(hook)
1243}
1244
1245static void test_keynames(void)
1246{
1247 int i, len;
1248 char buff[256];
1249
1250 for (i = 0; i < 512; i++)
1251 {
1252 strcpy(buff, "----");
1253 len = GetKeyNameTextA(i << 16, buff, sizeof(buff));
1254 ok(len || !buff[0], "%d: Buffer is not zeroed\n", i);
1255 }
1256}
1257
1258static POINT pt_old, pt_new;
1259static BOOL clipped;
1260#define STEP 3
1261
1263{
1265 POINT pt, pt1;
1266
1267 if (code == HC_ACTION)
1268 {
1269 /* This is our new cursor position */
1270 pt_new = hook->pt;
1271 /* Should return previous position */
1272 GetCursorPos(&pt);
1273 ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1274
1275 /* Should set new position until hook chain is finished. */
1276 pt.x = pt_old.x + STEP;
1277 pt.y = pt_old.y + STEP;
1278 SetCursorPos(pt.x, pt.y);
1279 GetCursorPos(&pt1);
1280 if (clipped)
1281 ok(pt1.x == pt_old.x && pt1.y == pt_old.y, "Wrong set pos: (%d,%d)\n", pt1.x, pt1.y);
1282 else
1283 ok(pt1.x == pt.x && pt1.y == pt.y, "Wrong set pos: (%d,%d)\n", pt1.x, pt1.y);
1284 }
1285 return CallNextHookEx( 0, code, wparam, lparam );
1286}
1287
1289{
1291 POINT pt;
1292
1293 if (code == HC_ACTION)
1294 {
1295 ok(hook->pt.x == pt_new.x && hook->pt.y == pt_new.y,
1296 "Wrong hook coords: (%d %d) != (%d,%d)\n", hook->pt.x, hook->pt.y, pt_new.x, pt_new.y);
1297
1298 /* Should match position set above */
1299 GetCursorPos(&pt);
1300 if (clipped)
1301 ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1302 else
1303 ok(pt.x == pt_old.x +STEP && pt.y == pt_old.y +STEP, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1304 }
1305 return CallNextHookEx( 0, code, wparam, lparam );
1306}
1307
1309{
1310 POINT pt;
1311
1312 if (code == HC_ACTION)
1313 {
1314 /* MSLLHOOKSTRUCT does not seem to be reliable and contains different data on each run. */
1315 GetCursorPos(&pt);
1316 ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1317 }
1318 return CallNextHookEx( 0, code, wparam, lparam );
1319}
1320
1321static void test_mouse_ll_hook(void)
1322{
1323 HWND hwnd;
1324 HHOOK hook1, hook2;
1325 POINT pt_org, pt;
1326 RECT rc;
1327
1328 GetCursorPos(&pt_org);
1329 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1330 10, 10, 200, 200, NULL, NULL, NULL, NULL);
1331 SetCursorPos(100, 100);
1332
1334 {
1335 win_skip( "cannot set MOUSE_LL hook\n" );
1336 goto done;
1337 }
1339
1341 mouse_event(MOUSEEVENTF_MOVE, -STEP, 0, 0, 0);
1343 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);
1344 mouse_event(MOUSEEVENTF_MOVE, +STEP, 0, 0, 0);
1346 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);
1347 mouse_event(MOUSEEVENTF_MOVE, 0, -STEP, 0, 0);
1349 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);
1350 mouse_event(MOUSEEVENTF_MOVE, 0, +STEP, 0, 0);
1352 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);
1353
1354 SetRect(&rc, 50, 50, 151, 151);
1355 ClipCursor(&rc);
1356 clipped = TRUE;
1357
1358 SetCursorPos(40, 40);
1360 ok(pt_old.x == 50 && pt_old.y == 50, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
1361 SetCursorPos(160, 160);
1363 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
1366 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
1367
1368 clipped = FALSE;
1369 pt_new.x = pt_new.y = 150;
1371 UnhookWindowsHookEx(hook1);
1372
1373 /* Now check that mouse buttons do not change mouse position
1374 if we don't have MOUSEEVENTF_MOVE flag specified. */
1375
1376 /* We reusing the same hook callback, so make it happy */
1377 pt_old.x = pt_new.x - STEP;
1378 pt_old.y = pt_new.y - STEP;
1379 mouse_event(MOUSEEVENTF_LEFTUP, 123, 456, 0, 0);
1380 GetCursorPos(&pt);
1381 ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1382 mouse_event(MOUSEEVENTF_RIGHTUP, 456, 123, 0, 0);
1383 GetCursorPos(&pt);
1384 ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1385
1387 GetCursorPos(&pt);
1388 ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1390 GetCursorPos(&pt);
1391 ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1392
1393 UnhookWindowsHookEx(hook2);
1395
1396 SetRect(&rc, 150, 150, 150, 150);
1397 ClipCursor(&rc);
1398 clipped = TRUE;
1399
1400 SetCursorPos(140, 140);
1402 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1403 SetCursorPos(160, 160);
1405 todo_wine
1406 ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1409 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1412 todo_wine
1413 ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1414 mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0);
1416 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1417 mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0);
1419 todo_wine
1420 ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1421
1422 clipped = FALSE;
1424
1425 SetCursorPos(140, 140);
1426 SetRect(&rc, 150, 150, 150, 150);
1427 ClipCursor(&rc);
1429 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1431
1432 SetCursorPos(160, 160);
1433 SetRect(&rc, 150, 150, 150, 150);
1434 ClipCursor(&rc);
1436 todo_wine
1437 ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1439
1440 SetCursorPos(150, 150);
1441 SetRect(&rc, 150, 150, 150, 150);
1442 ClipCursor(&rc);
1444 todo_wine
1445 ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1447
1448 UnhookWindowsHookEx(hook1);
1449
1450done:
1452 SetCursorPos(pt_org.x, pt_org.y);
1453}
1454
1455static void test_GetMouseMovePointsEx(void)
1456{
1457#define BUFLIM 64
1458#define MYERROR 0xdeadbeef
1459 int count, retval;
1460 MOUSEMOVEPOINT in;
1461 MOUSEMOVEPOINT out[200];
1462 POINT point;
1463
1464 /* Get a valid content for the input struct */
1465 if(!GetCursorPos(&point)) {
1466 win_skip("GetCursorPos() failed with error %u\n", GetLastError());
1467 return;
1468 }
1469 memset(&in, 0, sizeof(MOUSEMOVEPOINT));
1470 in.x = point.x;
1471 in.y = point.y;
1472
1473 /* test first parameter
1474 * everything different than sizeof(MOUSEMOVEPOINT)
1475 * is expected to fail with ERROR_INVALID_PARAMETER
1476 */
1478 retval = pGetMouseMovePointsEx(0, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1479 if (retval == ERROR_INVALID_PARAMETER)
1480 {
1481 win_skip( "GetMouseMovePointsEx broken on WinME\n" );
1482 return;
1483 }
1484 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1486 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1487
1489 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1490 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1492 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1493
1495 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)+1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1496 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1498 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1499
1500 /* test second and third parameter
1501 */
1503 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1504 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1506 "expected error ERROR_NOACCESS, got %u\n", GetLastError());
1507
1509 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1510 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1512 "expected error ERROR_NOACCESS, got %u\n", GetLastError());
1513
1515 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1516 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1518 "expected error ERROR_NOACCESS, got %u\n", GetLastError());
1519
1521 count = 0;
1522 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, count, GMMP_USE_DISPLAY_POINTS);
1523 if (retval == -1)
1524 ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %u\n", GetLastError());
1525 else
1526 ok(retval == count, "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1527
1528 /* test fourth parameter
1529 * a value higher than 64 is expected to fail with ERROR_INVALID_PARAMETER
1530 */
1532 count = -1;
1533 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1534 ok(retval == count, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1536 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1537
1539 count = 0;
1540 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1541 if (retval == -1)
1542 ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %u\n", GetLastError());
1543 else
1544 ok(retval == count, "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1545
1547 count = BUFLIM;
1548 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1549 if (retval == -1)
1550 ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %u\n", GetLastError());
1551 else
1552 ok((0 <= retval) && (retval <= count), "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1553
1555 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1556 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1558 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1559
1560 /* it was not possible to force an error with the fifth parameter on win2k */
1561
1562 /* test combinations of wrong parameters to see which error wins */
1564 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1565 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1567 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1568
1570 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1571 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1573 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1574
1576 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1577 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1579 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1580
1582 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1583 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1585 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1586
1587#undef BUFLIM
1588#undef MYERROR
1589}
1590
1591static void test_GetRawInputDeviceList(void)
1592{
1593 RAWINPUTDEVICELIST devices[32];
1594 UINT ret, oret, devcount, odevcount, i;
1595 DWORD err;
1596
1597 SetLastError(0xdeadbeef);
1598 ret = pGetRawInputDeviceList(NULL, NULL, 0);
1599 err = GetLastError();
1600 ok(ret == -1, "expected -1, got %d\n", ret);
1601 ok(err == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", err);
1602
1603 SetLastError(0xdeadbeef);
1604 ret = pGetRawInputDeviceList(NULL, NULL, sizeof(devices[0]));
1605 err = GetLastError();
1606 ok(ret == -1, "expected -1, got %d\n", ret);
1607 ok(err == ERROR_NOACCESS, "expected 998, got %d\n", err);
1608
1609 devcount = 0;
1610 ret = pGetRawInputDeviceList(NULL, &devcount, sizeof(devices[0]));
1611 ok(ret == 0, "expected 0, got %d\n", ret);
1612 ok(devcount > 0, "expected non-zero\n");
1613
1614 SetLastError(0xdeadbeef);
1615 devcount = 0;
1616 ret = pGetRawInputDeviceList(devices, &devcount, sizeof(devices[0]));
1617 err = GetLastError();
1618 ok(ret == -1, "expected -1, got %d\n", ret);
1619 ok(err == ERROR_INSUFFICIENT_BUFFER, "expected 122, got %d\n", err);
1620 ok(devcount > 0, "expected non-zero\n");
1621
1622 /* devcount contains now the correct number of devices */
1623 ret = pGetRawInputDeviceList(devices, &devcount, sizeof(devices[0]));
1624 ok(ret > 0, "expected non-zero\n");
1625
1626 for(i = 0; i < devcount; ++i)
1627 {
1628 WCHAR name[128];
1629 char nameA[128];
1630 UINT sz, len;
1631 RID_DEVICE_INFO info;
1632 HANDLE file;
1633
1634 /* get required buffer size */
1635 name[0] = '\0';
1636 sz = 5;
1637 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICENAME, name, &sz);
1638 ok(ret == -1, "GetRawInputDeviceInfo gave wrong failure: %d\n", err);
1639 ok(sz > 5 && sz < ARRAY_SIZE(name), "Size should have been set and not too large (got: %u)\n", sz);
1640
1641 /* buffer size for RIDI_DEVICENAME is in CHARs, not BYTEs */
1642 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICENAME, name, &sz);
1643 ok(ret == sz, "GetRawInputDeviceInfo gave wrong return: %d\n", err);
1644 len = lstrlenW(name);
1645 ok(len + 1 == ret, "GetRawInputDeviceInfo returned wrong length (name: %u, ret: %u)\n", len + 1, ret);
1646
1647 /* test A variant with same size */
1648 ret = pGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, nameA, &sz);
1649 ok(ret == sz, "GetRawInputDeviceInfoA gave wrong return: %d\n", err);
1650 len = strlen(nameA);
1651 ok(len + 1 == ret, "GetRawInputDeviceInfoA returned wrong length (name: %u, ret: %u)\n", len + 1, ret);
1652
1653 /* buffer size for RIDI_DEVICEINFO is in BYTEs */
1654 memset(&info, 0, sizeof(info));
1655 info.cbSize = sizeof(info);
1656 sz = sizeof(info) - 1;
1657 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz);
1658 ok(ret == -1, "GetRawInputDeviceInfo gave wrong failure: %d\n", err);
1659 ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n");
1660
1661 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz);
1662 ok(ret == sizeof(info), "GetRawInputDeviceInfo gave wrong return: %d\n", err);
1663 ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n");
1664 ok(info.dwType == devices[i].dwType, "GetRawInputDeviceInfo set wrong type: 0x%x\n", info.dwType);
1665
1666 memset(&info, 0, sizeof(info));
1667 info.cbSize = sizeof(info);
1668 ret = pGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz);
1669 ok(ret == sizeof(info), "GetRawInputDeviceInfo gave wrong return: %d\n", err);
1670 ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n");
1671 ok(info.dwType == devices[i].dwType, "GetRawInputDeviceInfo set wrong type: 0x%x\n", info.dwType);
1672
1673 /* setupapi returns an NT device path, but CreateFile() < Vista can't
1674 * understand that; so use the \\?\ prefix instead */
1675 name[1] = '\\';
1677 todo_wine_if(info.dwType != RIM_TYPEHID)
1678 ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u\n", wine_dbgstr_w(name), GetLastError());
1680 }
1681
1682 /* check if variable changes from larger to smaller value */
1683 devcount = odevcount = ARRAY_SIZE(devices);
1684 oret = ret = pGetRawInputDeviceList(devices, &odevcount, sizeof(devices[0]));
1685 ok(ret > 0, "expected non-zero\n");
1686 ok(devcount == odevcount, "expected %d, got %d\n", devcount, odevcount);
1687 devcount = odevcount;
1688 odevcount = ARRAY_SIZE(devices);
1689 ret = pGetRawInputDeviceList(NULL, &odevcount, sizeof(devices[0]));
1690 ok(ret == 0, "expected 0, got %d\n", ret);
1691 ok(odevcount == oret, "expected %d, got %d\n", oret, odevcount);
1692}
1693
1694static void test_GetRawInputData(void)
1695{
1696 UINT size;
1697 UINT ret;
1698
1699 /* Null raw input handle */
1700 ret = GetRawInputData(NULL, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
1701 ok(ret == ~0U, "Expect ret %u, got %u\n", ~0U, ret);
1702}
1703
1704static void test_key_map(void)
1705{
1706 HKL kl = GetKeyboardLayout(0);
1707 UINT kL, kR, s, sL;
1708 int i;
1709 static const UINT numpad_collisions[][2] = {
1710 { VK_NUMPAD0, VK_INSERT },
1711 { VK_NUMPAD1, VK_END },
1712 { VK_NUMPAD2, VK_DOWN },
1713 { VK_NUMPAD3, VK_NEXT },
1714 { VK_NUMPAD4, VK_LEFT },
1715 { VK_NUMPAD6, VK_RIGHT },
1716 { VK_NUMPAD7, VK_HOME },
1717 { VK_NUMPAD8, VK_UP },
1718 { VK_NUMPAD9, VK_PRIOR },
1719 };
1720
1722 ok(s != 0, "MapVirtualKeyEx(VK_SHIFT) should return non-zero\n");
1724 ok(s == sL || broken(sL == 0), /* win9x */
1725 "%x != %x\n", s, sL);
1726
1727 kL = MapVirtualKeyExA(0x2a, MAPVK_VSC_TO_VK, kl);
1728 ok(kL == VK_SHIFT, "Scan code -> vKey = %x (not VK_SHIFT)\n", kL);
1729 kR = MapVirtualKeyExA(0x36, MAPVK_VSC_TO_VK, kl);
1730 ok(kR == VK_SHIFT, "Scan code -> vKey = %x (not VK_SHIFT)\n", kR);
1731
1732 kL = MapVirtualKeyExA(0x2a, MAPVK_VSC_TO_VK_EX, kl);
1733 ok(kL == VK_LSHIFT || broken(kL == 0), /* win9x */
1734 "Scan code -> vKey = %x (not VK_LSHIFT)\n", kL);
1735 kR = MapVirtualKeyExA(0x36, MAPVK_VSC_TO_VK_EX, kl);
1736 ok(kR == VK_RSHIFT || broken(kR == 0), /* win9x */
1737 "Scan code -> vKey = %x (not VK_RSHIFT)\n", kR);
1738
1739 /* test that MAPVK_VSC_TO_VK prefers the non-numpad vkey if there's ambiguity */
1740 for (i = 0; i < ARRAY_SIZE(numpad_collisions); i++)
1741 {
1742 UINT numpad_scan = MapVirtualKeyExA(numpad_collisions[i][0], MAPVK_VK_TO_VSC, kl);
1743 UINT other_scan = MapVirtualKeyExA(numpad_collisions[i][1], MAPVK_VK_TO_VSC, kl);
1744
1745 /* do they really collide for this layout? */
1746 if (numpad_scan && other_scan == numpad_scan)
1747 {
1748 UINT vkey = MapVirtualKeyExA(numpad_scan, MAPVK_VSC_TO_VK, kl);
1749 ok(vkey != numpad_collisions[i][0],
1750 "Got numpad vKey %x for scan code %x when there was another choice\n",
1751 vkey, numpad_scan);
1752 }
1753 }
1754}
1755
1756#define shift 1
1757#define ctrl 2
1758
1759static const struct tounicode_tests
1760{
1761 UINT vk;
1763 WCHAR chr; /* if vk is 0, lookup vk using this char */
1764 int expect_ret;
1765 WCHAR expect_buf[4];
1766} utests[] =
1767{
1768 { 'A', 0, 0, 1, {'a',0}},
1769 { 'A', ctrl, 0, 1, {1, 0}},
1770 { 'A', shift|ctrl, 0, 1, {1, 0}},
1771 { VK_TAB, ctrl, 0, 0, {0}},
1772 { VK_TAB, shift|ctrl, 0, 0, {0}},
1773 { VK_RETURN, ctrl, 0, 1, {'\n', 0}},
1774 { VK_RETURN, shift|ctrl, 0, 0, {0}},
1775 { '4', ctrl, 0, 0, {0}},
1776 { '4', shift|ctrl, 0, 0, {0}},
1777 { 0, ctrl, '!', 0, {0}},
1778 { 0, ctrl, '\"', 0, {0}},
1779 { 0, ctrl, '#', 0, {0}},
1780 { 0, ctrl, '$', 0, {0}},
1781 { 0, ctrl, '%', 0, {0}},
1782 { 0, ctrl, '\'', 0, {0}},
1783 { 0, ctrl, '(', 0, {0}},
1784 { 0, ctrl, ')', 0, {0}},
1785 { 0, ctrl, '*', 0, {0}},
1786 { 0, ctrl, '+', 0, {0}},
1787 { 0, ctrl, ',', 0, {0}},
1788 { 0, ctrl, '-', 0, {0}},
1789 { 0, ctrl, '.', 0, {0}},
1790 { 0, ctrl, '/', 0, {0}},
1791 { 0, ctrl, ':', 0, {0}},
1792 { 0, ctrl, ';', 0, {0}},
1793 { 0, ctrl, '<', 0, {0}},
1794 { 0, ctrl, '=', 0, {0}},
1795 { 0, ctrl, '>', 0, {0}},
1796 { 0, ctrl, '?', 0, {0}},
1797 { 0, ctrl, '@', 1, {0}},
1798 { 0, ctrl, '[', 1, {0x1b}},
1799 { 0, ctrl, '\\', 1, {0x1c}},
1800 { 0, ctrl, ']', 1, {0x1d}},
1801 { 0, ctrl, '^', 1, {0x1e}},
1802 { 0, ctrl, '_', 1, {0x1f}},
1803 { 0, ctrl, '`', 0, {0}},
1804 { VK_SPACE, 0, 0, 1, {' ',0}},
1805 { VK_SPACE, shift, 0, 1, {' ',0}},
1806 { VK_SPACE, ctrl, 0, 1, {' ',0}},
1807};
1808
1809static void test_ToUnicode(void)
1810{
1811 WCHAR wStr[4];
1812 BYTE state[256];
1813 const BYTE SC_RETURN = 0x1c, SC_TAB = 0x0f, SC_A = 0x1e;
1814 const BYTE HIGHEST_BIT = 0x80;
1815 int i, ret;
1816 BOOL us_kbd = (GetKeyboardLayout(0) == (HKL)(ULONG_PTR)0x04090409);
1817
1818 for(i=0; i<256; i++)
1819 state[i]=0;
1820
1821 wStr[1] = 0xAA;
1822 SetLastError(0xdeadbeef);
1823 ret = ToUnicode(VK_RETURN, SC_RETURN, state, wStr, 4, 0);
1825 {
1826 win_skip("ToUnicode is not implemented\n");
1827 return;
1828 }
1829
1830 ok(ret == 1, "ToUnicode for Return key didn't return 1 (was %i)\n", ret);
1831 if(ret == 1)
1832 {
1833 ok(wStr[0]=='\r', "ToUnicode for CTRL + Return was %i (expected 13)\n", wStr[0]);
1834 ok(wStr[1]==0 || broken(wStr[1]!=0) /* nt4 */,
1835 "ToUnicode didn't null-terminate the buffer when there was room.\n");
1836 }
1837
1838 for (i = 0; i < ARRAY_SIZE(utests); i++)
1839 {
1840 UINT vk = utests[i].vk, mod = utests[i].modifiers, scan;
1841
1842 if(!vk)
1843 {
1844 short vk_ret;
1845
1846 if (!us_kbd) continue;
1847 vk_ret = VkKeyScanW(utests[i].chr);
1848 if (vk_ret == -1) continue;
1849 vk = vk_ret & 0xff;
1850 if (vk_ret & 0x100) mod |= shift;
1851 if (vk_ret & 0x200) mod |= ctrl;
1852 }
1854
1855 state[VK_SHIFT] = state[VK_LSHIFT] = (mod & shift) ? HIGHEST_BIT : 0;
1856 state[VK_CONTROL] = state[VK_LCONTROL] = (mod & ctrl) ? HIGHEST_BIT : 0;
1857
1858 ret = ToUnicode(vk, scan, state, wStr, 4, 0);
1859 ok(ret == utests[i].expect_ret, "%d: got %d expected %d\n", i, ret, utests[i].expect_ret);
1860 if (ret)
1861 ok(!lstrcmpW(wStr, utests[i].expect_buf), "%d: got %s expected %s\n", i, wine_dbgstr_w(wStr),
1862 wine_dbgstr_w(utests[i].expect_buf));
1863
1864 }
1865 state[VK_SHIFT] = state[VK_LSHIFT] = 0;
1867
1868 ret = ToUnicode(VK_TAB, SC_TAB, NULL, wStr, 4, 0);
1869 ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
1870 ret = ToUnicode(VK_RETURN, SC_RETURN, NULL, wStr, 4, 0);
1871 ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
1872 ret = ToUnicode('A', SC_A, NULL, wStr, 4, 0);
1873 ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
1874 ret = ToUnicodeEx(VK_TAB, SC_TAB, NULL, wStr, 4, 0, GetKeyboardLayout(0));
1875 ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
1876 ret = ToUnicodeEx(VK_RETURN, SC_RETURN, NULL, wStr, 4, 0, GetKeyboardLayout(0));
1877 ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
1878 ret = ToUnicodeEx('A', SC_A, NULL, wStr, 4, 0, GetKeyboardLayout(0));
1879 ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
1880}
1881
1882static void test_ToAscii(void)
1883{
1884 WORD character;
1885 BYTE state[256];
1886 const BYTE SC_RETURN = 0x1c, SC_A = 0x1e;
1887 const BYTE HIGHEST_BIT = 0x80;
1888 int ret;
1889
1890 memset(state, 0, sizeof(state));
1891
1892 character = 0;
1893 ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
1894 ok(ret == 1, "ToAscii for Return key didn't return 1 (was %i)\n", ret);
1895 ok(character == '\r', "ToAscii for Return was %i (expected 13)\n", character);
1896
1897 character = 0;
1898 ret = ToAscii('A', SC_A, state, &character, 0);
1899 ok(ret == 1, "ToAscii for character 'A' didn't return 1 (was %i)\n", ret);
1900 ok(character == 'a', "ToAscii for character 'A' was %i (expected %i)\n", character, 'a');
1901
1902 state[VK_CONTROL] |= HIGHEST_BIT;
1903 state[VK_LCONTROL] |= HIGHEST_BIT;
1904 character = 0;
1905 ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
1906 ok(ret == 1, "ToAscii for CTRL + Return key didn't return 1 (was %i)\n", ret);
1907 ok(character == '\n', "ToAscii for CTRL + Return was %i (expected 10)\n", character);
1908
1909 character = 0;
1910 ret = ToAscii('A', SC_A, state, &character, 0);
1911 ok(ret == 1, "ToAscii for CTRL + character 'A' didn't return 1 (was %i)\n", ret);
1912 ok(character == 1, "ToAscii for CTRL + character 'A' was %i (expected 1)\n", character);
1913
1914 state[VK_SHIFT] |= HIGHEST_BIT;
1915 state[VK_LSHIFT] |= HIGHEST_BIT;
1916 ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
1917 ok(ret == 0, "ToAscii for CTRL + Shift + Return key didn't return 0 (was %i)\n", ret);
1918
1919 ret = ToAscii(VK_RETURN, SC_RETURN, NULL, &character, 0);
1920 ok(ret == 0, "ToAscii for NULL keystate didn't return 0 (was %i)\n", ret);
1921 ret = ToAscii('A', SC_A, NULL, &character, 0);
1922 ok(ret == 0, "ToAscii for NULL keystate didn't return 0 (was %i)\n", ret);
1923 ret = ToAsciiEx(VK_RETURN, SC_RETURN, NULL, &character, 0, GetKeyboardLayout(0));
1924 ok(ret == 0, "ToAsciiEx for NULL keystate didn't return 0 (was %i)\n", ret);
1925 ret = ToAsciiEx('A', SC_A, NULL, &character, 0, GetKeyboardLayout(0));
1926 ok(ret == 0, "ToAsciiEx for NULL keystate didn't return 0 (was %i)\n", ret);
1927}
1928
1929static void test_get_async_key_state(void)
1930{
1931 /* input value sanity checks */
1932 ok(0 == GetAsyncKeyState(1000000), "GetAsyncKeyState did not return 0\n");
1933 ok(0 == GetAsyncKeyState(-1000000), "GetAsyncKeyState did not return 0\n");
1934}
1935
1936static void test_keyboard_layout_name(void)
1937{
1938 BOOL ret;
1939 char klid[KL_NAMELENGTH];
1940
1941 if (0) /* crashes on native system */
1943
1944 SetLastError(0xdeadbeef);
1946 ok(!ret, "got %d\n", ret);
1947 ok(GetLastError() == ERROR_NOACCESS, "got %d\n", GetLastError());
1948
1949 if (GetKeyboardLayout(0) != (HKL)(ULONG_PTR)0x04090409) return;
1950
1951 klid[0] = 0;
1953 ok(ret, "GetKeyboardLayoutNameA failed %u\n", GetLastError());
1954 ok(!strcmp(klid, "00000409"), "expected 00000409, got %s\n", klid);
1955}
1956
1957static void test_key_names(void)
1958{
1959 char buffer[40];
1960 WCHAR bufferW[40];
1961 int ret, prev;
1962 LONG lparam = 0x1d << 16;
1963
1964 memset( buffer, 0xcc, sizeof(buffer) );
1965 ret = GetKeyNameTextA( lparam, buffer, sizeof(buffer) );
1966 ok( ret > 0, "wrong len %u for '%s'\n", ret, buffer );
1967 ok( ret == strlen(buffer), "wrong len %u for '%s'\n", ret, buffer );
1968
1969 memset( buffer, 0xcc, sizeof(buffer) );
1970 prev = ret;
1971 ret = GetKeyNameTextA( lparam, buffer, prev );
1972 ok( ret == prev - 1, "wrong len %u for '%s'\n", ret, buffer );
1973 ok( ret == strlen(buffer), "wrong len %u for '%s'\n", ret, buffer );
1974
1975 memset( buffer, 0xcc, sizeof(buffer) );
1977 ok( ret == 0, "wrong len %u for '%s'\n", ret, buffer );
1978 ok( buffer[0] == 0, "wrong string '%s'\n", buffer );
1979
1980 memset( bufferW, 0xcc, sizeof(bufferW) );
1981 ret = GetKeyNameTextW( lparam, bufferW, ARRAY_SIZE(bufferW));
1982 ok( ret > 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1983 ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1984
1985 memset( bufferW, 0xcc, sizeof(bufferW) );
1986 prev = ret;
1987 ret = GetKeyNameTextW( lparam, bufferW, prev );
1988 ok( ret == prev - 1, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1989 ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1990
1991 memset( bufferW, 0xcc, sizeof(bufferW) );
1992 ret = GetKeyNameTextW( lparam, bufferW, 0 );
1993 ok( ret == 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1994 ok( bufferW[0] == 0xcccc, "wrong string %s\n", wine_dbgstr_w(bufferW) );
1995}
1996
1997static void simulate_click(BOOL left, int x, int y)
1998{
1999 INPUT input[2];
2000 UINT events_no;
2001
2002 SetCursorPos(x, y);
2003 memset(input, 0, sizeof(input));
2004 input[0].type = INPUT_MOUSE;
2005 U(input[0]).mi.dx = x;
2006 U(input[0]).mi.dy = y;
2008 input[1].type = INPUT_MOUSE;
2009 U(input[1]).mi.dx = x;
2010 U(input[1]).mi.dy = y;
2011 U(input[1]).mi.dwFlags = left ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP;
2012 events_no = SendInput(2, input, sizeof(input[0]));
2013 ok(events_no == 2, "SendInput returned %d\n", events_no);
2014}
2015
2016static BOOL wait_for_message( MSG *msg )
2017{
2018 BOOL ret;
2019
2020 for (;;)
2021 {
2022 ret = PeekMessageA(msg, 0, 0, 0, PM_REMOVE);
2023 if (ret)
2024 {
2025 if (msg->message == WM_PAINT) DispatchMessageA(msg);
2026 else break;
2027 }
2028 else if (MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLINPUT) == WAIT_TIMEOUT) break;
2029 }
2030 if (!ret) msg->message = 0;
2031 return ret;
2032}
2033
2035{
2036 DWORD end_time = GetTickCount() + timeout;
2037 MSG msg;
2038
2039 do {
2041 return TRUE;
2042 while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2044 timeout = end_time - GetTickCount();
2045 }while(timeout > 0);
2046
2047 return FALSE;
2048}
2049
2051static DWORD hittest_no;
2053{
2054 if (msg == WM_NCHITTEST)
2055 {
2056 /* break infinite hittest loop */
2057 if(hittest_no > 50) return HTCLIENT;
2058 hittest_no++;
2059 }
2060
2061 return def_static_proc(hwnd, msg, wp, lp);
2062}
2063
2064struct thread_data
2065{
2068 HWND win;
2069};
2070
2071static DWORD WINAPI create_static_win(void *arg)
2072{
2073 struct thread_data *thread_data = arg;
2074 HWND win;
2075
2076 win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
2077 100, 100, 100, 100, 0, NULL, NULL, NULL);
2078 ok(win != 0, "CreateWindow failed\n");
2081 thread_data->win = win;
2082
2085 return 0;
2086}
2087
2088static void get_dc_region(RECT *region, HWND hwnd, DWORD flags)
2089{
2090 int region_type;
2091 HRGN hregion;
2092 HDC hdc;
2093
2094 hdc = GetDCEx(hwnd, 0, flags);
2095 ok(hdc != NULL, "GetDCEx failed\n");
2096 hregion = CreateRectRgn(40, 40, 60, 60);
2097 ok(hregion != NULL, "CreateRectRgn failed\n");
2098 GetRandomRgn(hdc, hregion, SYSRGN);
2099 region_type = GetRgnBox(hregion, region);
2100 ok(region_type == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", region_type);
2101 DeleteObject(hregion);
2102 ReleaseDC(hwnd, hdc);
2103}
2104
2105static void test_Input_mouse(void)
2106{
2107 BOOL got_button_down, got_button_up;
2108 HWND hwnd, button_win, static_win;
2109 struct thread_data thread_data;
2110 HANDLE thread;
2112 WNDCLASSA wclass;
2113 POINT pt, pt_org;
2114 int region_type;
2115 HRGN hregion;
2116 RECT region;
2117 MSG msg;
2118 BOOL ret;
2119
2120 SetLastError(0xdeadbeef);
2122 ok(!ret, "GetCursorPos succeed\n");
2123 ok(GetLastError() == 0xdeadbeef || GetLastError() == ERROR_NOACCESS, "error %u\n", GetLastError());
2124
2125 SetLastError(0xdeadbeef);
2126 ret = GetCursorPos(&pt_org);
2127 ok(ret, "GetCursorPos failed\n");
2128 ok(GetLastError() == 0xdeadbeef, "error %u\n", GetLastError());
2129
2130 button_win = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP,
2131 100, 100, 100, 100, 0, NULL, NULL, NULL);
2132 ok(button_win != 0, "CreateWindow failed\n");
2133
2134 pt.x = pt.y = 150;
2136 if (hwnd != button_win)
2137 {
2138 skip("there's another window covering test window\n");
2139 DestroyWindow(button_win);
2140 return;
2141 }
2142
2143 /* simple button click test */
2144 simulate_click(TRUE, 150, 150);
2145 got_button_down = got_button_up = FALSE;
2146 while (wait_for_message(&msg))
2147 {
2149
2150 if (msg.message == WM_LBUTTONDOWN)
2151 {
2152 got_button_down = TRUE;
2153 }
2154 else if (msg.message == WM_LBUTTONUP)
2155 {
2156 got_button_up = TRUE;
2157 break;
2158 }
2159 }
2160 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2161 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2162
2163 /* click through HTTRANSPARENT child window */
2164 static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_CHILD,
2165 0, 0, 100, 100, button_win, NULL, NULL, NULL);
2166 ok(static_win != 0, "CreateWindow failed\n");
2167 def_static_proc = (void*)SetWindowLongPtrA(static_win,
2169 simulate_click(FALSE, 150, 150);
2170 hittest_no = 0;
2171 got_button_down = got_button_up = FALSE;
2172 while (wait_for_message(&msg))
2173 {
2175
2176 if (msg.message == WM_RBUTTONDOWN)
2177 {
2178 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2179 got_button_down = TRUE;
2180 }
2181 else if (msg.message == WM_RBUTTONUP)
2182 {
2183 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2184 got_button_up = TRUE;
2185 break;
2186 }
2187 }
2188 ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
2189 ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
2190 ok(got_button_up, "expected WM_RBUTTONUP message\n");
2191 DestroyWindow(static_win);
2192
2193 /* click through HTTRANSPARENT top-level window */
2194 static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
2195 100, 100, 100, 100, 0, NULL, NULL, NULL);
2196 ok(static_win != 0, "CreateWindow failed\n");
2197 def_static_proc = (void*)SetWindowLongPtrA(static_win,
2199 simulate_click(TRUE, 150, 150);
2200 hittest_no = 0;
2201 got_button_down = got_button_up = FALSE;
2202 while (wait_for_message(&msg))
2203 {
2205
2206 if (msg.message == WM_LBUTTONDOWN)
2207 {
2208 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2209 got_button_down = TRUE;
2210 }
2211 else if (msg.message == WM_LBUTTONUP)
2212 {
2213 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2214 got_button_up = TRUE;
2215 break;
2216 }
2217 }
2218 ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
2219 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2220 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2221 DestroyWindow(static_win);
2222
2223 /* click on HTTRANSPARENT top-level window that belongs to other thread */
2225 ok(thread_data.start_event != NULL, "CreateEvent failed\n");
2227 ok(thread_data.end_event != NULL, "CreateEvent failed\n");
2229 ok(thread != NULL, "CreateThread failed\n");
2230 hittest_no = 0;
2231 got_button_down = got_button_up = FALSE;
2233 simulate_click(FALSE, 150, 150);
2234 while (wait_for_message(&msg))
2235 {
2237
2238 if (msg.message == WM_RBUTTONDOWN)
2239 got_button_down = TRUE;
2240 else if (msg.message == WM_RBUTTONUP)
2241 got_button_up = TRUE;
2242 }
2246 ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
2247 ok(!got_button_down, "unexpected WM_RBUTTONDOWN message\n");
2248 ok(!got_button_up, "unexpected WM_RBUTTONUP message\n");
2249
2250 /* click on HTTRANSPARENT top-level window that belongs to other thread,
2251 * thread input queues are attached */
2253 ok(thread != NULL, "CreateThread failed\n");
2254 hittest_no = 0;
2255 got_button_down = got_button_up = FALSE;
2258 "AttachThreadInput failed\n");
2260 SetWindowPos(thread_data.win, button_win, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
2261 simulate_click(TRUE, 150, 150);
2262 while (wait_for_message(&msg))
2263 {
2265
2266 if (msg.message == WM_LBUTTONDOWN)
2267 got_button_down = TRUE;
2268 else if (msg.message == WM_LBUTTONUP)
2269 got_button_up = TRUE;
2270 }
2273 todo_wine ok(hittest_no > 50, "expected loop with WM_NCHITTEST messages\n");
2274 ok(!got_button_down, "unexpected WM_LBUTTONDOWN message\n");
2275 ok(!got_button_up, "unexpected WM_LBUTTONUP message\n");
2276
2277 /* click after SetCapture call */
2278 hwnd = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP,
2279 0, 0, 100, 100, 0, NULL, NULL, NULL);
2280 ok(hwnd != 0, "CreateWindow failed\n");
2281 SetCapture(button_win);
2282 got_button_down = got_button_up = FALSE;
2283 simulate_click(FALSE, 50, 50);
2284 while (wait_for_message(&msg))
2285 {
2287
2288 if (msg.message == WM_RBUTTONDOWN)
2289 {
2290 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2291 got_button_down = TRUE;
2292 }
2293 else if (msg.message == WM_RBUTTONUP)
2294 {
2295 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2296 got_button_up = TRUE;
2297 break;
2298 }
2299 }
2300 ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
2301 ok(got_button_up, "expected WM_RBUTTONUP message\n");
2303
2304 /* click on child window after SetCapture call */
2305 hwnd = CreateWindowA("button", "button2", WS_VISIBLE | WS_CHILD,
2306 0, 0, 100, 100, button_win, NULL, NULL, NULL);
2307 ok(hwnd != 0, "CreateWindow failed\n");
2308 got_button_down = got_button_up = FALSE;
2309 simulate_click(TRUE, 150, 150);
2310 while (wait_for_message(&msg))
2311 {
2313
2314 if (msg.message == WM_LBUTTONDOWN)
2315 {
2316 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2317 got_button_down = TRUE;
2318 }
2319 else if (msg.message == WM_LBUTTONUP)
2320 {
2321 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2322 got_button_up = TRUE;
2323 break;
2324 }
2325 }
2326 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2327 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2329 ok(ReleaseCapture(), "ReleaseCapture failed\n");
2330
2331 wclass.style = 0;
2332 wclass.lpfnWndProc = WndProc;
2333 wclass.cbClsExtra = 0;
2334 wclass.cbWndExtra = 0;
2336 wclass.hIcon = LoadIconA(0, (LPCSTR)IDI_APPLICATION);
2338 wclass.hbrBackground = CreateSolidBrush(RGB(128, 128, 128));
2339 wclass.lpszMenuName = NULL;
2340 wclass.lpszClassName = "InputLayeredTestClass";
2341 RegisterClassA( &wclass );
2342
2343 /* click through layered window with alpha channel / color key */
2344 hwnd = CreateWindowA(wclass.lpszClassName, "InputLayeredTest",
2345 WS_VISIBLE | WS_POPUP, 100, 100, 100, 100, button_win, NULL, NULL, NULL);
2346 ok(hwnd != NULL, "CreateWindowEx failed\n");
2347
2348 static_win = CreateWindowA("static", "Title", WS_VISIBLE | WS_CHILD,
2349 10, 10, 20, 20, hwnd, NULL, NULL, NULL);
2350 ok(static_win != NULL, "CreateWindowA failed %u\n", GetLastError());
2351
2354 ret = SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA);
2355 ok(ret, "SetLayeredWindowAttributes failed\n");
2357 Sleep(100);
2358
2359 if (pGetWindowRgnBox)
2360 {
2361 region_type = pGetWindowRgnBox(hwnd, &region);
2362 ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2363 }
2364
2366 ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2367 "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2369 ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2370 "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2371 get_dc_region(&region, hwnd, DCX_USESTYLE);
2372 ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2373 "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2374 get_dc_region(&region, static_win, DCX_PARENTCLIP);
2375 ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2376 "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2377 get_dc_region(&region, static_win, DCX_WINDOW | DCX_USESTYLE);
2378 ok(region.left == 110 && region.top == 110 && region.right == 130 && region.bottom == 130,
2379 "expected region (110,110)-(130,130), got %s\n", wine_dbgstr_rect(&region));
2380 get_dc_region(&region, static_win, DCX_USESTYLE);
2381 ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2382 "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2383
2384 got_button_down = got_button_up = FALSE;
2385 simulate_click(TRUE, 150, 150);
2386 while (wait_for_message(&msg))
2387 {
2389
2390 if (msg.message == WM_LBUTTONDOWN)
2391 {
2392 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2393 got_button_down = TRUE;
2394 }
2395 else if (msg.message == WM_LBUTTONUP)
2396 {
2397 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2398 got_button_up = TRUE;
2399 break;
2400 }
2401 }
2402 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2403 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2404
2405 ret = SetLayeredWindowAttributes(hwnd, 0, 0, LWA_ALPHA);
2406 ok(ret, "SetLayeredWindowAttributes failed\n");
2408 Sleep(100);
2409
2410 if (pGetWindowRgnBox)
2411 {
2412 region_type = pGetWindowRgnBox(hwnd, &region);
2413 ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2414 }
2415
2416 got_button_down = got_button_up = FALSE;
2417 simulate_click(TRUE, 150, 150);
2418 while (wait_for_message(&msg))
2419 {
2421
2422 if (msg.message == WM_LBUTTONDOWN)
2423 {
2424 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2425 got_button_down = TRUE;
2426 }
2427 else if (msg.message == WM_LBUTTONUP)
2428 {
2429 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2430 got_button_up = TRUE;
2431 break;
2432 }
2433 }
2434 ok(got_button_down || broken(!got_button_down), "expected WM_LBUTTONDOWN message\n");
2435 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2436
2437 ret = SetLayeredWindowAttributes(hwnd, RGB(0, 255, 0), 255, LWA_ALPHA | LWA_COLORKEY);
2438 ok(ret, "SetLayeredWindowAttributes failed\n");
2440 Sleep(100);
2441
2442 if (pGetWindowRgnBox)
2443 {
2444 region_type = pGetWindowRgnBox(hwnd, &region);
2445 ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2446 }
2447
2448 got_button_down = got_button_up = FALSE;
2449 simulate_click(TRUE, 150, 150);
2450 while (wait_for_message(&msg))
2451 {
2453
2454 if (msg.message == WM_LBUTTONDOWN)
2455 {
2456 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2457 got_button_down = TRUE;
2458 }
2459 else if (msg.message == WM_LBUTTONUP)
2460 {
2461 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2462 got_button_up = TRUE;
2463 break;
2464 }
2465 }
2466 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2467 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2468
2469 ret = SetLayeredWindowAttributes(hwnd, RGB(128, 128, 128), 0, LWA_COLORKEY);
2470 ok(ret, "SetLayeredWindowAttributes failed\n");
2472 Sleep(100);
2473
2474 if (pGetWindowRgnBox)
2475 {
2476 region_type = pGetWindowRgnBox(hwnd, &region);
2477 ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2478 }
2479
2480 got_button_down = got_button_up = FALSE;
2481 simulate_click(TRUE, 150, 150);
2482 while (wait_for_message(&msg))
2483 {
2485
2486 if (msg.message == WM_LBUTTONDOWN)
2487 {
2488 todo_wine
2489 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2490 got_button_down = TRUE;
2491 }
2492 else if (msg.message == WM_LBUTTONUP)
2493 {
2494 todo_wine
2495 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2496 got_button_up = TRUE;
2497 break;
2498 }
2499 }
2500 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2501 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2502
2505 Sleep(100);
2506
2507 if (pGetWindowRgnBox)
2508 {
2509 region_type = pGetWindowRgnBox(hwnd, &region);
2510 ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2511 }
2512
2513 got_button_down = got_button_up = FALSE;
2514 simulate_click(TRUE, 150, 150);
2515 while (wait_for_message(&msg))
2516 {
2518
2519 if (msg.message == WM_LBUTTONDOWN)
2520 {
2521 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2522 got_button_down = TRUE;
2523 }
2524 else if (msg.message == WM_LBUTTONUP)
2525 {
2526 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2527 got_button_up = TRUE;
2528 break;
2529 }
2530 }
2531 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2532 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2533
2534 hregion = CreateRectRgn(0, 0, 10, 10);
2535 ok(hregion != NULL, "CreateRectRgn failed\n");
2536 ret = SetWindowRgn(hwnd, hregion, TRUE);
2537 ok(ret, "SetWindowRgn failed\n");
2538 DeleteObject(hregion);
2540 Sleep(1000);
2541
2542 if (pGetWindowRgnBox)
2543 {
2544 region_type = pGetWindowRgnBox(hwnd, &region);
2545 ok(region_type == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", region_type);
2546 }
2547
2548 got_button_down = got_button_up = FALSE;
2549 simulate_click(TRUE, 150, 150);
2550 while (wait_for_message(&msg))
2551 {
2553
2554 if (msg.message == WM_LBUTTONDOWN)
2555 {
2556 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2557 got_button_down = TRUE;
2558 }
2559 else if (msg.message == WM_LBUTTONUP)
2560 {
2561 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2562 got_button_up = TRUE;
2563 break;
2564 }
2565 }
2566 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2567 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2568
2569 DestroyWindow(static_win);
2571 SetCursorPos(pt_org.x, pt_org.y);
2572
2575 DestroyWindow(button_win);
2576}
2577
2578
2580{
2581 if (message == WM_USER+1)
2582 {
2583 HWND hwnd = (HWND)lParam;
2584 ok(GetFocus() == hwnd, "thread expected focus %p, got %p\n", hwnd, GetFocus());
2585 ok(GetActiveWindow() == hwnd, "thread expected active %p, got %p\n", hwnd, GetActiveWindow());
2586 }
2588}
2589
2590struct wnd_event
2591{
2592 HWND hwnd;
2598};
2599
2600static DWORD WINAPI thread_proc(void *param)
2601{
2602 MSG msg;
2603 struct wnd_event *wnd_event = param;
2604 BOOL ret;
2605
2606 if (wnd_event->wait_event)
2607 {
2609 "WaitForSingleObject failed\n");
2611 }
2612
2614 {
2616 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2617 }
2618
2619 if (wnd_event->attach_to)
2620 {
2622 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2623 }
2624
2625 wnd_event->hwnd = CreateWindowExA(0, "TestWindowClass", "window caption text", WS_OVERLAPPEDWINDOW,
2626 100, 100, 200, 200, 0, 0, 0, NULL);
2627 ok(wnd_event->hwnd != 0, "Failed to create overlapped window\n");
2628
2629 if (wnd_event->setWindows)
2630 {
2633 }
2634
2636
2637 while (GetMessageA(&msg, 0, 0, 0))
2638 {
2641 }
2642
2643 return 0;
2644}
2645
2646static void test_attach_input(void)
2647{
2649 HWND ourWnd, Wnd2;
2650 DWORD ret, tid;
2651 struct wnd_event wnd_event;
2652 WNDCLASSA cls;
2653
2654 cls.style = 0;
2655 cls.lpfnWndProc = MsgCheckProcA;
2656 cls.cbClsExtra = 0;
2657 cls.cbWndExtra = 0;
2658 cls.hInstance = GetModuleHandleA(0);
2659 cls.hIcon = 0;
2660 cls.hCursor = LoadCursorW( NULL, (LPCWSTR)IDC_ARROW);
2661 cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2662 cls.lpszMenuName = NULL;
2663 cls.lpszClassName = "TestWindowClass";
2664 if(!RegisterClassA(&cls)) return;
2665
2669 wnd_event.attach_to = 0;
2672 {
2673 win_skip("skipping interthread message test under win9x\n");
2674 return;
2675 }
2676
2678 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2679
2680 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2682
2683 ourWnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
2684 0, 0, 0, 0, 0, 0, 0, NULL);
2685 ok(ourWnd!= 0, "failed to create ourWnd window\n");
2686
2687 Wnd2 = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
2688 0, 0, 0, 0, 0, 0, 0, NULL);
2689 ok(Wnd2!= 0, "failed to create Wnd2 window\n");
2690
2691 SetFocus(ourWnd);
2692 SetActiveWindow(ourWnd);
2693
2695 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2696
2697 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2698 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2699
2700 SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
2701
2703 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2704 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2705 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2706
2708
2710 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2711
2712 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2713 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2714 SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
2715
2716 SetActiveWindow(Wnd2);
2717 SetFocus(Wnd2);
2718 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2719 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2720
2722
2724 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2725 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2726 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2727
2729
2731 ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2732
2733 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2735
2739 wnd_event.attach_to = 0;
2741
2743 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2744
2745 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2747
2748 SetFocus(ourWnd);
2749 SetActiveWindow(ourWnd);
2750
2752 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2753
2754 ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
2755 ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
2756
2758
2760 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2761
2762 ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
2763 ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
2764
2766
2768 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2769
2770 ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
2771 ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
2772
2774
2775 SetFocus(Wnd2);
2776 SetActiveWindow(Wnd2);
2777 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2778 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2779
2781
2783 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2784
2785 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2786 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2787
2789
2791 ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2792
2793 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2795
2799 wnd_event.attach_to = 0;
2801
2803 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2804
2805 SetLastError(0xdeadbeef);
2807 ok(!ret, "AttachThreadInput succeeded\n");
2808 ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef) /* <= Win XP */,
2809 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2810
2811 SetLastError(0xdeadbeef);
2813 ok(!ret, "AttachThreadInput succeeded\n");
2814 ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef) /* <= Win XP */,
2815 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2816
2818
2819 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2821
2823 ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2824
2825 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2827
2831 wnd_event.attach_to = 0;
2833
2834 SetFocus(ourWnd);
2835 SetActiveWindow(ourWnd);
2836
2838 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2839
2840 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2842
2843 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2844 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2845
2847 ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2848
2849 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2851
2857
2858 SetFocus(ourWnd);
2859 SetActiveWindow(ourWnd);
2860
2862 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2863
2864 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2866
2867 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2868 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2869
2871 ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2872
2873 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2875 DestroyWindow(ourWnd);
2876 DestroyWindow(Wnd2);
2877}
2878
2880{
2881 HANDLE *semaphores = arg;
2882 DWORD result;
2883
2884 ReleaseSemaphore(semaphores[0], 1, NULL);
2885 result = WaitForSingleObject(semaphores[1], 1000);
2886 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2887
2888 result = GetKeyState('X');
2889 ok((result & 0x8000) || broken(!(result & 0x8000)), /* > Win 2003 */
2890 "expected that highest bit is set, got %x\n", result);
2891
2892 ReleaseSemaphore(semaphores[0], 1, NULL);
2893 result = WaitForSingleObject(semaphores[1], 1000);
2894 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2895
2896 result = GetKeyState('X');
2897 ok(!(result & 0x8000), "expected that highest bit is unset, got %x\n", result);
2898
2899 return 0;
2900}
2901
2902static void test_GetKeyState(void)
2903{
2904 HANDLE semaphores[2];
2905 HANDLE thread;
2906 DWORD result;
2907 HWND hwnd;
2908
2909 semaphores[0] = CreateSemaphoreA(NULL, 0, 1, NULL);
2910 ok(semaphores[0] != NULL, "CreateSemaphoreA failed %u\n", GetLastError());
2911 semaphores[1] = CreateSemaphoreA(NULL, 0, 1, NULL);
2912 ok(semaphores[1] != NULL, "CreateSemaphoreA failed %u\n", GetLastError());
2913
2914 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2915 10, 10, 200, 200, NULL, NULL, NULL, NULL);
2916 ok(hwnd != NULL, "CreateWindowA failed %u\n", GetLastError());
2917
2918 thread = CreateThread(NULL, 0, get_key_state_thread, semaphores, 0, NULL);
2919 ok(thread != NULL, "CreateThread failed %u\n", GetLastError());
2920 result = WaitForSingleObject(semaphores[0], 1000);
2921 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2922
2924 SetFocus(hwnd);
2925 keybd_event('X', 0, 0, 0);
2926
2927 ReleaseSemaphore(semaphores[1], 1, NULL);
2928 result = WaitForSingleObject(semaphores[0], 1000);
2929 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2930
2931 keybd_event('X', 0, KEYEVENTF_KEYUP, 0);
2932
2933 ReleaseSemaphore(semaphores[1], 1, NULL);
2935 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2937
2939 CloseHandle(semaphores[0]);
2940 CloseHandle(semaphores[1]);
2941}
2942
2943static void test_OemKeyScan(void)
2944{
2945 DWORD ret, expect, vkey, scan;
2946 WCHAR oem, wchr;
2947 char oem_char;
2948
2949 for (oem = 0; oem < 0x200; oem++)
2950 {
2951 ret = OemKeyScan( oem );
2952
2953 oem_char = LOBYTE( oem );
2954 /* OemKeyScan returns -1 for any character that cannot be mapped,
2955 * whereas OemToCharBuff changes unmappable characters to question
2956 * marks. The ASCII characters 0-127, including the real question mark
2957 * character, are all mappable and are the same in all OEM codepages. */
2958 if (!OemToCharBuffW( &oem_char, &wchr, 1 ) || (wchr == '?' && oem_char < 0))
2959 expect = -1;
2960 else
2961 {
2962 vkey = VkKeyScanW( wchr );
2963 scan = MapVirtualKeyW( LOBYTE( vkey ), MAPVK_VK_TO_VSC );
2964 if (!scan)
2965 expect = -1;
2966 else
2967 {
2968 vkey &= 0xff00;
2969 vkey <<= 8;
2970 expect = vkey | scan;
2971 }
2972 }
2973 ok( ret == expect, "%04x: got %08x expected %08x\n", oem, ret, expect );
2974 }
2975}
2976
2977static INPUT_MESSAGE_SOURCE expect_src;
2978
2980{
2981 INPUT_MESSAGE_SOURCE source;
2982 MSG msg;
2983
2984 ok( pGetCurrentInputMessageSource( &source ), "GetCurrentInputMessageSource failed\n" );
2985 switch (message)
2986 {
2987 case WM_KEYDOWN:
2988 case WM_KEYUP:
2989 case WM_SYSKEYDOWN:
2990 case WM_SYSKEYUP:
2991 case WM_MOUSEMOVE:
2992 case WM_LBUTTONDOWN:
2993 case WM_LBUTTONUP:
2994 case WM_RBUTTONDOWN:
2995 case WM_RBUTTONUP:
2996 ok( source.deviceType == expect_src.deviceType || /* also accept system-generated WM_MOUSEMOVE */
2997 (message == WM_MOUSEMOVE && source.deviceType == IMDT_UNAVAILABLE),
2998 "%x: wrong deviceType %x/%x\n", message, source.deviceType, expect_src.deviceType );
2999 ok( source.originId == expect_src.originId ||
3000 (message == WM_MOUSEMOVE && source.originId == IMO_SYSTEM),
3001 "%x: wrong originId %x/%x\n", message, source.originId, expect_src.originId );
3002 SendMessageA( hwnd, WM_USER, 0, 0 );
3003 PostMessageA( hwnd, WM_USER, 0, 0 );
3005 ok( source.deviceType == expect_src.deviceType || /* also accept system-generated WM_MOUSEMOVE */
3006 (message == WM_MOUSEMOVE && source.deviceType == IMDT_UNAVAILABLE),
3007 "%x: wrong deviceType %x/%x\n", message, source.deviceType, expect_src.deviceType );
3008 ok( source.originId == expect_src.originId ||
3009 (message == WM_MOUSEMOVE && source.originId == IMO_SYSTEM),
3010 "%x: wrong originId %x/%x\n", message, source.originId, expect_src.originId );
3011 break;
3012 default:
3013 ok( source.deviceType == IMDT_UNAVAILABLE, "%x: wrong deviceType %x\n",
3014 message, source.deviceType );
3015 ok( source.originId == 0, "%x: wrong originId %x\n", message, source.originId );
3016 break;
3017 }
3018
3019 return DefWindowProcA( hwnd, message, wp, lp );
3020}
3021
3022static void test_input_message_source(void)
3023{
3024 WNDCLASSA cls;
3025 TEST_INPUT inputs[2];
3026 HWND hwnd;
3027 RECT rc;
3028 MSG msg;
3029
3030 cls.style = 0;
3032 cls.cbClsExtra = 0;
3033 cls.cbWndExtra = 0;
3034 cls.hInstance = GetModuleHandleA(0);
3035 cls.hIcon = 0;
3037 cls.hbrBackground = 0;
3038 cls.lpszMenuName = NULL;
3039 cls.lpszClassName = "message source class";
3040 RegisterClassA(&cls);
3041 hwnd = CreateWindowA( cls.lpszClassName, "test", WS_OVERLAPPED, 0, 0, 100, 100,
3042 0, 0, 0, 0 );
3044 UpdateWindow( hwnd );
3046 SetFocus( hwnd );
3047
3048 inputs[0].type = INPUT_KEYBOARD;
3049 inputs[0].u.ki.dwExtraInfo = 0;
3050 inputs[0].u.ki.time = 0;
3051 inputs[0].u.ki.wVk = 0;
3052 inputs[0].u.ki.wScan = 0x3c0;
3053 inputs[0].u.ki.dwFlags = KEYEVENTF_UNICODE;
3054 inputs[1] = inputs[0];
3055 inputs[1].u.ki.dwFlags |= KEYEVENTF_KEYUP;
3056
3057 expect_src.deviceType = IMDT_UNAVAILABLE;
3058 expect_src.originId = IMO_UNAVAILABLE;
3059 SendMessageA( hwnd, WM_KEYDOWN, 0, 0 );
3060 SendMessageA( hwnd, WM_MOUSEMOVE, 0, 0 );
3061
3062 SendInput( 2, (INPUT *)inputs, sizeof(INPUT) );
3063 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
3064 {
3065 expect_src.deviceType = IMDT_KEYBOARD;
3066 expect_src.originId = IMO_INJECTED;
3069 }
3070 GetWindowRect( hwnd, &rc );
3071 simulate_click( TRUE, (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2 );
3072 simulate_click( FALSE, (rc.left + rc.right) / 2 + 1, (rc.top + rc.bottom) / 2 + 1 );
3073 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
3074 {
3075 expect_src.deviceType = IMDT_MOUSE;
3076 expect_src.originId = IMO_INJECTED;
3079 }
3080
3081 expect_src.deviceType = IMDT_UNAVAILABLE;
3082 expect_src.originId = IMO_UNAVAILABLE;
3083 SendMessageA( hwnd, WM_KEYDOWN, 0, 0 );
3085 PostMessageA( hwnd, WM_KEYUP, 0, 0 );
3086 PostMessageA( hwnd, WM_LBUTTONUP, 0, 0 );
3087 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
3088 {
3091 }
3092
3093 expect_src.deviceType = IMDT_UNAVAILABLE;
3094 expect_src.originId = IMO_SYSTEM;
3095 SetCursorPos( (rc.left + rc.right) / 2 - 1, (rc.top + rc.bottom) / 2 - 1 );
3096 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
3097 {
3100 }
3101
3104}
3105
3106static void test_GetPointerType(void)
3107{
3108 BOOL ret;
3109 POINTER_INPUT_TYPE type = -1;
3110 UINT id = 0;
3111
3112 SetLastError(0xdeadbeef);
3113 ret = pGetPointerType(id, NULL);
3114 ok(!ret, "GetPointerType should have failed.\n");
3116 "expected error ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
3117
3118 SetLastError(0xdeadbeef);
3119 ret = pGetPointerType(id, &type);
3121 "expected error ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
3122 ok(!ret, "GetPointerType failed, got type %d for %u.\n", type, id );
3123 ok(type == -1, " type %d\n", type );
3124
3125 id = 1;
3126 ret = pGetPointerType(id, &type);
3127 ok(ret, "GetPointerType failed, got type %d for %u.\n", type, id );
3128 ok(type == PT_MOUSE, " type %d\n", type );
3129}
3130
3131static void test_GetKeyboardLayoutList(void)
3132{
3133 int cnt, cnt2;
3134 HKL *layouts;
3135 ULONG_PTR baselayout;
3136 LANGID langid;
3137
3138 baselayout = GetUserDefaultLCID();
3139 langid = PRIMARYLANGID(LANGIDFROMLCID(baselayout));
3141 baselayout = MAKELONG( baselayout, 0xe001 ); /* IME */
3142 else
3143 baselayout |= baselayout << 16;
3144
3145 cnt = GetKeyboardLayoutList(0, NULL);
3146 /* Most users will not have more than a few keyboard layouts installed at a time. */
3147 ok(cnt > 0 && cnt < 10, "Layout count %d\n", cnt);
3148 if (cnt > 0)
3149 {
3150 layouts = HeapAlloc(GetProcessHeap(), 0, sizeof(*layouts) * cnt );
3151
3152 cnt2 = GetKeyboardLayoutList(cnt, layouts);
3153 ok(cnt == cnt2, "wrong value %d!=%d\n", cnt, cnt2);
3154 for(cnt = 0; cnt < cnt2; cnt++)
3155 {
3156 if(layouts[cnt] == (HKL)baselayout)
3157 break;
3158 }
3159 ok(cnt < cnt2, "Didnt find current keyboard\n");
3160
3161 HeapFree(GetProcessHeap(), 0, layouts);
3162 }
3163}
3164
3166{
3167 POINT pos;
3168
3170 GetCursorPos( &pos );
3171
3176 test_keynames();
3178 test_key_map();
3180 test_ToAscii();
3189
3190 if(pGetMouseMovePointsEx)
3192 else
3193 win_skip("GetMouseMovePointsEx is not available\n");
3194
3195 if(pGetRawInputDeviceList)
3197 else
3198 win_skip("GetRawInputDeviceList is not available\n");
3199
3200 if (pGetCurrentInputMessageSource)
3202 else
3203 win_skip("GetCurrentInputMessageSource is not available\n");
3204
3205 SetCursorPos( pos.x, pos.y );
3206
3207 if(pGetPointerType)
3209 else
3210 win_skip("GetPointerType is not available\n");
3211}
#define DCX_USESTYLE
Definition: GetDCEx.c:10
#define SYSRGN
Definition: GetRandomRgn.c:13
msg_flags_t
Definition: SystemMenu.c:26
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
#define broken(x)
Definition: _sntprintf.h:21
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static int state
Definition: maze.c:121
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define ARRAY_SIZE(A)
Definition: main.h:33
#define U(x)
Definition: wordpad.c:45
static HANDLE thread
Definition: service.c:33
r l[0]
Definition: byte_order.h:168
HINSTANCE hInstance
Definition: charmap.c:19
struct @1632 Msg[]
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
HANDLE HWND
Definition: compat.h:19
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define FreeLibrary(x)
Definition: compat.h:748
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define CALLBACK
Definition: compat.h:35
#define FILE_SHARE_READ
Definition: compat.h:136
#define lstrlenW
Definition: compat.h:750
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
#define assert(x)
Definition: debug.h:53
#define pt(x, y)
Definition: drawing.c:79
#define RGB(r, g, b)
Definition: precomp.h:71
#define INFINITE
Definition: serial.h:102
static struct all_devices * devices
Definition: dsm_ctrl.c:48
POINTL point
Definition: edittest.c:50
#define ERROR(name)
Definition: error_private.h:53
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
static void do_test(void)
Definition: ftrandom.c:516
pKey DeleteObject()
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
struct _cl_event * event
Definition: glext.h:7739
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLint left
Definition: glext.h:7726
GLbitfield flags
Definition: glext.h:7161
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLuint64EXT * result
Definition: glext.h:11304
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
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
static int mod
Definition: i386-dis.c:1288
#define LOBYTE(W)
Definition: jmemdos.c:487
#define wine_dbgstr_w
Definition: kernel32.h:34
static real win[4][36]
LCID WINAPI GetUserDefaultLCID(void)
Definition: lang.c:778
USHORT LANGID
Definition: mui.h:9
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
__u16 time
Definition: mkdosfs.c:8
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:92
BOOL expected
Definition: store.c:2063
static TfClientId tid
static IHTMLWindow2 * window
Definition: events.c:77
#define todo_wine_if(is_todo)
Definition: custom.c:76
#define todo_wine
Definition: custom.c:79
static DWORD thread_id
Definition: protocol.c:159
msg_flags_t
Definition: input.c:421
@ sent
Definition: input.c:422
@ beginpaint
Definition: input.c:428
@ defwinproc
Definition: input.c:427
@ parent
Definition: input.c:424
@ posted
Definition: input.c:423
@ lparam
Definition: input.c:426
@ hook
Definition: input.c:430
@ winevent_hook
Definition: input.c:431
@ wparam
Definition: input.c:425
@ optional
Definition: input.c:429
static void test_key_names(void)
Definition: input.c:1956
static void test_keynames(void)
Definition: input.c:1244
static void test_Input_whitebox(void)
Definition: input.c:347
static POINTER_INPUT_TYPE *static DWORD
Definition: input.c:84
static const int GETFLAGS[]
Definition: input.c:105
#define MAXKEYMESSAGES
Definition: input.c:91
static LRESULT WINAPI msg_source_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
Definition: input.c:2978
enum KEVtag KEV
static const struct tounicode_tests utests[]
static DWORD hittest_no
Definition: input.c:2050
static void empty_message_queue(void)
Definition: input.c:393
static DWORD WINAPI get_key_state_thread(void *arg)
Definition: input.c:2878
static BOOL wait_for_event(HANDLE event, int timeout)
Definition: input.c:2033
static LRESULT WINAPI static_hook_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Definition: input.c:2051
static const struct @1723 testkeyset[]
static void test_mouse_ll_hook(void)
Definition: input.c:1320
static LRESULT CALLBACK hook_proc3(int code, WPARAM wparam, LPARAM lparam)
Definition: input.c:1307
static HWND hWndTest
Definition: input.c:63
static BYTE TrackSysKey
Definition: input.c:148
static void get_dc_region(RECT *region, HWND hwnd, DWORD flags)
Definition: input.c:2087
static LRESULT CALLBACK hook_proc1(int code, WPARAM wparam, LPARAM lparam)
Definition: input.c:1261
static BOOL is_mouse_message(UINT message)
Definition: input.c:387
static BOOL is_keyboard_message(UINT message)
Definition: input.c:382
@ SHIFTUP
Definition: input.c:99
@ SHIFTDOWN
Definition: input.c:99
@ ALTDOWN
Definition: input.c:99
@ ALTUP
Definition: input.c:99
@ XUP
Definition: input.c:99
@ CTRLDOWN
Definition: input.c:99
@ CTRLUP
Definition: input.c:99
@ XDOWN
Definition: input.c:99
static void test_unicode_keys(HWND hwnd, HHOOK hook)
Definition: input.c:986
static void test_keyboard_layout_name(void)
Definition: input.c:1935
static DWORD WINAPI thread_proc(void *param)
Definition: input.c:2599
static void init_function_pointers(void)
Definition: input.c:151
#define MYERROR
static void test_Input_unicode(void)
Definition: input.c:1178
static void test_Input_mouse(void)
Definition: input.c:2104
static void test_input_message_source(void)
Definition: input.c:3021
static void test_attach_input(void)
Definition: input.c:2645
static BYTE AsyncKeyStateTable[256]
Definition: input.c:147
static void test_GetKeyState(void)
Definition: input.c:2901
static struct @1722 key_status
static BOOL wait_for_message(MSG *msg)
Definition: input.c:2015
static const int GETSCAN[]
Definition: input.c:103
static LRESULT CALLBACK llkbd_unicode_hook(int nCode, WPARAM wParam, LPARAM lParam)
Definition: input.c:1145
#define STEP
Definition: input.c:1259
static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: input.c:2578
static INPUT_MESSAGE_SOURCE expect_src
Definition: input.c:2976
static void test_GetMouseMovePointsEx(void)
Definition: input.c:1454
static WNDPROC def_static_proc
Definition: input.c:2049
static const struct sendinput_test_s sendinput_test[]
static void TestSysKeys(HWND hWnd)
Definition: input.c:334
int nrkev
Definition: input.c:133
static LRESULT CALLBACK WndProc2(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: input.c:863
static void test_GetRawInputDeviceList(void)
Definition: input.c:1590
#define shift
Definition: input.c:1755
static const char * getdesc[]
Definition: input.c:107
WORD vk
Definition: input.c:77
static void test_OemKeyScan(void)
Definition: input.c:2942
static void test_GetPointerType(void)
Definition: input.c:3105
#define GET_PROC(func)
static POINT pt_old
Definition: input.c:1257
KEV keyup[MAXKEYEVENTS]
Definition: input.c:135
KEV keydwn[MAXKEYEVENTS]
Definition: input.c:134
static void simulate_click(BOOL left, int x, int y)
Definition: input.c:1996
static const char * MSGNAME[]
Definition: input.c:94
static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: input.c:341
static BYTE InputKeyStateTable[256]
Definition: input.c:146
static DWORD WINAPI create_static_win(void *arg)
Definition: input.c:2070
static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, const struct sendinput_test_s *test, BOOL foreground)
Definition: input.c:701
static void test_GetRawInputData(void)
Definition: input.c:1693
static struct message sent_messages[MAXKEYMESSAGES]
Definition: input.c:697
static LONG timetag
Definition: input.c:64
static POINT pt_new
Definition: input.c:1257
static void test_get_async_key_state(void)
Definition: input.c:1928
static LRESULT CALLBACK hook_proc(int code, WPARAM wparam, LPARAM lparam)
Definition: input.c:882
static LRESULT CALLBACK unicode_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: input.c:1119
static BOOL TestASet(HWND hWnd, int nrkev, const KEV kevdwn[], const KEV kevup[])
Definition: input.c:285
static LRESULT CALLBACK hook_proc2(int code, WPARAM wparam, LPARAM lparam)
Definition: input.c:1287
static UINT sent_messages_cnt
Definition: input.c:698
static void test_GetKeyboardLayoutList(void)
Definition: input.c:3130
static BOOL clipped
Definition: input.c:1258
static void test_key_map(void)
Definition: input.c:1703
static void test_ToAscii(void)
Definition: input.c:1881
static void test_ToUnicode(void)
Definition: input.c:1808
static const int GETVKEY[]
Definition: input.c:101
static int KbdMessage(KEV kev, WPARAM *pwParam, LPARAM *plParam)
Definition: input.c:169
static void test_Input_blackbox(void)
Definition: input.c:911
#define ctrl
Definition: input.c:1756
static void reset_key_status(WORD vk)
Definition: input.c:969
#define BUFLIM
int k
Definition: mpi.c:3369
UINT_PTR HKL
Definition: msctf.idl:143
LANGID langid
Definition: msctf.idl:644
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:28
#define BOOL
Definition: nt_native.h:43
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define WS_CHILD
Definition: pedump.c:617
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define WS_OVERLAPPED
Definition: pedump.c:615
#define WS_POPUP
Definition: pedump.c:616
#define WS_VSCROLL
Definition: pedump.c:627
#define WS_VISIBLE
Definition: pedump.c:620
long LONG
Definition: pedump.c:60
#define WS_HSCROLL
Definition: pedump.c:628
#define err(...)
static FILE * out
Definition: regtests2xml.c:44
#define test
Definition: rosglue.h:37
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#define LANG_CHINESE
Definition: nls.h:42
#define LANG_JAPANESE
Definition: nls.h:76
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define LANG_KOREAN
Definition: nls.h:84
int winetest_debug
#define win_skip
Definition: test.h:160
#define memset(x, y, z)
Definition: compat.h:39
Definition: input.c:121
UINT message
Definition: input.c:122
DWORD type
Definition: imm32.c:55
union TEST_INPUT::@1662 u
KEYBDINPUT ki
Definition: imm32.c:59
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
HBRUSH hbrBackground
Definition: winuser.h:3170
HICON hIcon
Definition: winuser.h:3168
HINSTANCE hInstance
Definition: winuser.h:3167
HCURSOR hCursor
Definition: winuser.h:3169
int cbWndExtra
Definition: winuser.h:3166
UINT style
Definition: winuser.h:3163
LPCSTR lpszMenuName
Definition: winuser.h:3171
LPCSTR lpszClassName
Definition: winuser.h:3172
WNDPROC lpfnWndProc
Definition: winuser.h:3164
int cbClsExtra
Definition: winuser.h:3165
LPCWSTR lpszClassName
Definition: winuser.h:3185
LPCWSTR lpszMenuName
Definition: winuser.h:3184
HBRUSH hbrBackground
Definition: winuser.h:3183
HICON hIcon
Definition: winuser.h:3181
HINSTANCE hInstance
Definition: winuser.h:3180
int cbClsExtra
Definition: winuser.h:3178
UINT style
Definition: winuser.h:3176
WNDPROC lpfnWndProc
Definition: winuser.h:3177
int cbWndExtra
Definition: winuser.h:3179
HCURSOR hCursor
Definition: winuser.h:3182
Definition: inflate.c:139
Definition: fci.c:127
Definition: tftpd.h:60
UINT message
Definition: SystemMenu.c:42
msg_flags_t flags
Definition: SystemMenu.c:43
Definition: name.c:39
DWORD dwFlags
Definition: input.c:443
struct transition_s expected_transitions[MAXKEYEVENTS+1]
Definition: input.c:445
struct message expected_messages[MAXKEYMESSAGES+1]
Definition: input.c:446
BOOL _todo_wine
Definition: input.c:444
KEYBDINPUT ki
Definition: winable.h:62
ULONG_PTR dwExtraInfo
Definition: winuser.h:3812
DWORD dwFlags
Definition: winable.h:49
WORD wVk
Definition: winable.h:47
WORD wScan
Definition: winable.h:48
ULONG_PTR dwExtraInfo
Definition: winable.h:51
DWORD time
Definition: winable.h:50
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
HWND win
Definition: input.c:2067
HANDLE start_event
Definition: input.c:2065
HANDLE end_event
Definition: input.c:2066
Definition: dhcpd.h:245
WCHAR expect_buf[4]
Definition: input.c:1764
DWORD modifiers
Definition: input.c:1761
int expect_ret
Definition: input.c:1763
WORD wVk
Definition: input.c:416
BYTE before_state
Definition: input.c:417
BYTE optional
Definition: input.c:418
DWORD attach_from
Definition: input.c:2594
HANDLE wait_event
Definition: input.c:2592
HWND hwnd
Definition: input.c:2591
HANDLE start_event
Definition: input.c:2593
BOOL setWindows
Definition: input.c:2596
DWORD attach_to
Definition: input.c:2595
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL, IN LONG lInitialCount, IN LONG lMaximumCount, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:430
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseSemaphore(IN HANDLE hSemaphore, IN LONG lReleaseCount, IN LPLONG lpPreviousCount)
Definition: synch.c:542
#define GWLP_WNDPROC
Definition: treelist.c:66
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
int ret
UINT WINAPI GetRawInputDeviceInfoA(HANDLE hDevice, UINT uiCommand, LPVOID pData, PUINT pcbSize)
Definition: stubs.c:257
UINT WINAPI GetRawInputDeviceInfoW(HANDLE hDevice, UINT uiCommand, LPVOID pData, PUINT pcbSize)
Definition: stubs.c:225
UINT WINAPI GetRawInputData(HRAWINPUT hRawInput, UINT uiCommand, LPVOID pData, PUINT pcbSize, UINT cbSizeHeader)
Definition: stubs.c:313
UINT WINAPI GetRawInputDeviceList(PRAWINPUTDEVICELIST pRawInputDeviceList, PUINT puiNumDevices, UINT cbSize)
Definition: stubs.c:329
int WINAPI GetWindowRgnBox(HWND hWnd, LPRECT lprc)
Definition: paint.c:299
static MONITORINFO mi
Definition: win.c:7338
UINT WINAPI SendInput(UINT, LPINPUT, int)
Definition: ntwrapper.h:344
#define INPUT_KEYBOARD
Definition: winable.h:10
#define INPUT_MOUSE
Definition: winable.h:9
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define WAIT_OBJECT_0
Definition: winbase.h:406
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define ERROR_POINT_NOT_FOUND
Definition: winerror.h:693
#define ERROR_NOACCESS
Definition: winerror.h:578
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
#define SIMPLEREGION
Definition: wingdi.h:362
int WINAPI GetRandomRgn(_In_ HDC, _In_ HRGN, _In_ INT)
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
int WINAPI GetRgnBox(_In_ HRGN, _Out_ LPRECT)
#define SW_SHOWNORMAL
Definition: winuser.h:770
#define WM_PAINT
Definition: winuser.h:1620
HWND WINAPI GetFocus(void)
Definition: window.c:1893
HWND WINAPI SetCapture(_In_ HWND hWnd)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define CS_VREDRAW
Definition: winuser.h:658
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
BOOL WINAPI GetKeyboardLayoutNameW(_Out_writes_(KL_NAMELENGTH) LPWSTR)
#define MOUSEEVENTF_ABSOLUTE
Definition: winuser.h:1194
#define SetWindowLongPtrA
Definition: winuser.h:5345
HWND WINAPI GetActiveWindow(void)
Definition: winpos.c:138
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define VK_NUMPAD3
Definition: winuser.h:2242
#define WM_SYSCOMMAND
Definition: winuser.h:1741
void WINAPI mouse_event(_In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ ULONG_PTR)
#define VK_TAB
Definition: winuser.h:2199
#define WM_MOUSEFIRST
Definition: winuser.h:1774
#define WM_QUIT
Definition: winuser.h:1623
BOOL WINAPI GetKeyboardLayoutNameA(_Out_writes_(KL_NAMELENGTH) LPSTR)
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define MAKELPARAM(l, h)
Definition: winuser.h:4008
#define WM_KEYUP
Definition: winuser.h:1716
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define COLOR_WINDOW
Definition: winuser.h:918
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define WM_MOUSELAST
Definition: winuser.h:1801
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2890
#define LLKHF_EXTENDED
Definition: winuser.h:2645
UINT WINAPI MapVirtualKeyExA(_In_ UINT, _In_ UINT, _In_opt_ HKL)
BOOL WINAPI UnregisterClassA(_In_ LPCSTR, HINSTANCE)
#define DCX_WINDOW
Definition: winuser.h:2113
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define MOUSEEVENTF_LEFTUP
Definition: winuser.h:1185
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
#define HWND_TOPMOST
Definition: winuser.h:1208
BOOL WINAPI AttachThreadInput(_In_ DWORD, _In_ DWORD, _In_ BOOL)
#define KL_NAMELENGTH
Definition: winuser.h:122
#define VK_NUMPAD1
Definition: winuser.h:2240
int WINAPI GetKeyNameTextA(_In_ LONG lParam, _Out_writes_(cchSize) LPSTR lpString, _In_ int cchSize)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4315
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
LONG WINAPI SetWindowLongA(_In_ HWND, _In_ int, _In_ LONG)
HHOOK WINAPI SetWindowsHookExW(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define VK_NUMPAD2
Definition: winuser.h:2241
#define VK_SPACE
Definition: winuser.h:2219
int WINAPI SetWindowRgn(_In_ HWND, _In_opt_ HRGN, _In_ BOOL)
int WINAPI ToAscii(_In_ UINT, _In_ UINT, _In_reads_opt_(256) CONST BYTE *, _Out_ LPWORD, _In_ UINT)
BOOL WINAPI ClipCursor(_In_opt_ LPCRECT)
#define SWP_NOMOVE
Definition: winuser.h:1244
#define MAPVK_VSC_TO_VK_EX
Definition: winuser.h:2358
#define CS_HREDRAW
Definition: winuser.h:653
#define VK_NUMPAD4
Definition: winuser.h:2243
#define KF_ALTDOWN
Definition: winuser.h:2449
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define KF_EXTENDED
Definition: winuser.h:2446
#define IDC_ARROW
Definition: winuser.h:687
#define WM_KEYFIRST
Definition: winuser.h:1714
#define VK_CONTROL
Definition: winuser.h:2203
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2670
#define HC_ACTION
Definition: winuser.h:48
#define WM_NCHITTEST
Definition: winuser.h:1686
#define WM_RBUTTONUP
Definition: winuser.h:1780
#define VK_RSHIFT
Definition: winuser.h:2283
#define VK_UP
Definition: winuser.h:2225
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define QS_ALLINPUT
Definition: winuser.h:903
int WINAPI ToUnicode(_In_ UINT wVirtKey, _In_ UINT wScanCode, _In_reads_bytes_opt_(256) CONST BYTE *lpKeyState, _Out_writes_(cchBuff) LPWSTR pwszBuff, _In_ int cchBuff, _In_ UINT wFlags)
#define SWP_NOSIZE
Definition: winuser.h:1245
#define WM_MOUSEMOVE
Definition: winuser.h:1775
HDC WINAPI GetDCEx(_In_opt_ HWND, _In_opt_ HRGN, _In_ DWORD)
#define MOUSEEVENTF_RIGHTUP
Definition: winuser.h:1187
_Check_return_ BOOL WINAPI GetKeyboardState(_Out_writes_(256) PBYTE lpKeyState)
#define VK_LSHIFT
Definition: winuser.h:2282
#define WM_LBUTTONDOWN
Definition: winuser.h:1776
BOOL WINAPI SetCursorPos(_In_ int, _In_ int)
Definition: cursoricon.c:2662
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2105
#define VK_LCONTROL
Definition: winuser.h:2284
#define VK_NUMPAD0
Definition: winuser.h:2239
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
#define VK_NUMPAD6
Definition: winuser.h:2245
#define MAPVK_VSC_TO_VK
Definition: winuser.h:2356
#define VK_NEXT
Definition: winuser.h:2221
#define IDI_APPLICATION
Definition: winuser.h:704
HHOOK WINAPI SetWindowsHookExA(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
#define VK_RCONTROL
Definition: winuser.h:2285
#define WM_RBUTTONDOWN
Definition: winuser.h:1779
#define MOUSEEVENTF_MOVE
Definition: winuser.h:1183
#define KF_UP
Definition: winuser.h:2451
UINT WINAPI MapVirtualKeyW(_In_ UINT, _In_ UINT)
BOOL WINAPI IsWindowUnicode(_In_ HWND)
#define WH_MOUSE_LL
Definition: winuser.h:44
#define MOUSEEVENTF_LEFTDOWN
Definition: winuser.h:1184
#define WM_SYSCHAR
Definition: winuser.h:1721
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
BOOL WINAPI OemToCharBuffW(_In_ LPCSTR lpszSrc, _Out_writes_(cchDstLength) LPWSTR lpszDst, _In_ DWORD cchDstLength)
#define VK_RETURN
Definition: winuser.h:2201
#define DCX_PARENTCLIP
Definition: winuser.h:2115
HWND WINAPI SetFocus(_In_opt_ HWND)
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
HWND WINAPI SetActiveWindow(_In_ HWND)
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
int WINAPI GetKeyNameTextW(_In_ LONG lParam, _Out_writes_(cchSize) LPWSTR lpString, _In_ int cchSize)
UINT WINAPI GetKeyboardLayoutList(_In_ int nBuff, _Out_writes_to_opt_(nBuff, return) HKL FAR *lpList)
#define VK_RMENU
Definition: winuser.h:2287
#define VK_NUMPAD9
Definition: winuser.h:2248
#define VK_END
Definition: winuser.h:2222
#define VK_HOME
Definition: winuser.h:2223
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpIconName)
Definition: cursoricon.c:2060
#define PM_REMOVE
Definition: winuser.h:1196
#define LLKHF_UP
Definition: winuser.h:2648
BOOL WINAPI UpdateWindow(_In_ HWND)
#define HTCLIENT
Definition: winuser.h:2475
#define WM_SYSKEYUP
Definition: winuser.h:1720
#define WH_KEYBOARD_LL
Definition: winuser.h:43
#define WS_EX_LAYERED
Definition: winuser.h:389
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4316
VOID WINAPI keybd_event(_In_ BYTE, _In_ BYTE, _In_ DWORD, _In_ ULONG_PTR)
#define WM_LBUTTONUP
Definition: winuser.h:1777
#define WM_CHAR
Definition: winuser.h:1717
#define CW_USEDEFAULT
Definition: winuser.h:225
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
#define VK_LEFT
Definition: winuser.h:2224
#define KEYEVENTF_EXTENDEDKEY
Definition: winuser.h:1101
#define VK_NUMPAD7
Definition: winuser.h:2246
#define VK_RIGHT
Definition: winuser.h:2226
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define VK_DOWN
Definition: winuser.h:2227
#define MOUSEEVENTF_RIGHTDOWN
Definition: winuser.h:1186
HWND WINAPI WindowFromPoint(_In_ POINT)
int WINAPI ToUnicodeEx(_In_ UINT wVirtKey, _In_ UINT wScanCode, _In_reads_bytes_(256) CONST BYTE *lpKeyState, _Out_writes_(cchBuff) LPWSTR pwszBuff, _In_ int cchBuff, _In_ UINT wFlags, _In_opt_ HKL dwhkl)
struct tagKBDLLHOOKSTRUCT * LPKBDLLHOOKSTRUCT
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define KF_REPEAT
Definition: winuser.h:2450
#define WM_USER
Definition: winuser.h:1895
#define VK_SHIFT
Definition: winuser.h:2202
#define SW_SHOW
Definition: winuser.h:775
#define VK_PRIOR
Definition: winuser.h:2220
#define MAPVK_VK_TO_VSC
Definition: winuser.h:2355
SHORT WINAPI GetAsyncKeyState(_In_ int)
#define WM_KEYDOWN
Definition: winuser.h:1715
#define VK_NUMPAD8
Definition: winuser.h:2247
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2906
DWORD WINAPI OemKeyScan(_In_ WORD)
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#define WM_KEYLAST
Definition: winuser.h:1728
int WINAPI ToAsciiEx(_In_ UINT, _In_ UINT, _In_reads_opt_(256) CONST BYTE *, _Out_ LPWORD, _In_ UINT, _In_opt_ HKL)
SHORT WINAPI VkKeyScanW(_In_ WCHAR)
BOOL WINAPI DestroyWindow(_In_ HWND)
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2075
#define KEYEVENTF_KEYUP
Definition: winuser.h:1102
#define WM_SYSKEYDOWN
Definition: winuser.h:1719
#define VK_INSERT
Definition: winuser.h:2232
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2090
SHORT WINAPI GetKeyState(_In_ int)
#define VK_LMENU
Definition: winuser.h:2286
#define VK_MENU
Definition: winuser.h:2204
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define GWL_EXSTYLE
Definition: winuser.h:851
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193

◆ msg_flags_t

Enumerator
sent 
posted 
parent 
wparam 
lparam 
defwinproc 
beginpaint 
optional 
hook 
winevent_hook 
kbd_hook 
sent 
posted 
parent 
wparam 
lparam 
defwinproc 
beginpaint 
optional 
hook 
winevent_hook 
id 
custdraw 
sent 
posted 
parent 
wparam 
lparam 
defwinproc 
beginpaint 
optional 
hook 
winevent_hook 
id 
sent 
posted 
parent 
wparam 
lparam 
defwinproc 
beginpaint 
optional 
hook 
winevent_hook 
sent 
posted 
parent 
wparam 
lparam 
defwinproc 
beginpaint 
optional 
hook 
winevent_hook 
kbd_hook 

Definition at line 421 of file input.c.

422 {
423 sent=0x1,
424 posted=0x2,
425 parent=0x4,
426 wparam=0x8,
427 lparam=0x10,
428 defwinproc=0x20,
429 beginpaint=0x40,
430 optional=0x80,
431 hook=0x100,
432 winevent_hook=0x200

Function Documentation

◆ BOOL()

static BOOL ( WINAPI pGetCurrentInputMessageSource)
static

◆ compare_and_check()

static void compare_and_check ( int  id,
BYTE ks1,
BYTE ks2,
const struct sendinput_test_s test,
BOOL  foreground 
)
static

Definition at line 701 of file input.c.

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 && foreground) {
711 /* We won't receive any information from GetKeyboardState() if we're
712 * not the foreground window. */
713 BOOL matched = ((ks1[t->wVk]&0x80) == (t->before_state&0x80)
714 && (ks2[t->wVk]&0x80) == (~t->before_state&0x80));
715
716 if (!matched && !t->optional && test->_todo_wine)
717 {
718 failcount++;
719 todo_wine {
720 ok(matched, "%2d (%x/%x): %02x from %02x -> %02x "
721 "instead of %02x -> %02x\n", id, test->wVk, test->dwFlags,
722 t->wVk, ks1[t->wVk]&0x80, ks2[t->wVk]&0x80, t->before_state,
723 ~t->before_state&0x80);
724 }
725 } else {
726 ok(matched || t->optional, "%2d (%x/%x): %02x from %02x -> %02x "
727 "instead of %02x -> %02x\n", id, test->wVk, test->dwFlags,
728 t->wVk, ks1[t->wVk]&0x80, ks2[t->wVk]&0x80, t->before_state,
729 ~t->before_state&0x80);
730 }
731 ks2[t->wVk] = ks1[t->wVk]; /* clear the match */
732 t++;
733 }
734 for (i = 0; i < 256; i++)
735 if (ks2[i] != ks1[i] && test->_todo_wine)
736 {
737 failcount++;
739 ok(FALSE, "%2d (%x/%x): %02x from %02x -> %02x unexpected\n",
740 id, test->wVk, test->dwFlags, i, ks1[i], ks2[i]);
741 }
742 else
743 ok(ks2[i] == ks1[i], "%2d (%x/%x): %02x from %02x -> %02x unexpected\n",
744 id, test->wVk, test->dwFlags, i, ks1[i], ks2[i]);
745
746 while (expected->message && actual_cnt < sent_messages_cnt)
747 {
748 const struct message *actual = &sent_messages[actual_cnt];
749
750 if (expected->message == actual->message)
751 {
752 if (expected->flags & wparam)
753 {
754 if ((expected->flags & optional) && (expected->wParam != actual->wParam))
755 {
756 expected++;
757 continue;
758 }
759 if (expected->wParam != actual->wParam && test->_todo_wine)
760 {
761 failcount++;
763 ok(FALSE, "%2d (%x/%x): in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
764 id, test->wVk, test->dwFlags, expected->message, expected->wParam, actual->wParam);
765 }
766 else
767 ok(expected->wParam == actual->wParam,
768 "%2d (%x/%x): in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
769 id, test->wVk, test->dwFlags, expected->message, expected->wParam, actual->wParam);
770 }
771 if (expected->flags & lparam)
772 {
773 if (expected->lParam != actual->lParam && test->_todo_wine)
774 {
775 failcount++;
777 ok(FALSE, "%2d (%x/%x): in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
778 id, test->wVk, test->dwFlags, expected->message, expected->lParam, actual->lParam);
779 }
780 else
781 ok(expected->lParam == actual->lParam,
782 "%2d (%x/%x): in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
783 id, test->wVk, test->dwFlags, expected->message, expected->lParam, actual->lParam);
784 }
785 ok((expected->flags & hook) == (actual->flags & hook),
786 "%2d (%x/%x): the msg 0x%04x should have been sent by a hook\n",
787 id, test->wVk, test->dwFlags, expected->message);
788
789 }
790 else if (expected->flags & optional)
791 {
792 expected++;
793 continue;
794 }
795 else if (!(expected->flags & hook) && !foreground)
796 {
797 /* If we weren't able to receive foreground status, we won't get
798 * any window messages. */
799 expected++;
800 continue;
801 }
802 /* NT4 doesn't send SYSKEYDOWN/UP to hooks, only KEYDOWN/UP */
803 else if ((expected->flags & hook) &&
804 (expected->message == WM_SYSKEYDOWN || expected->message == WM_SYSKEYUP) &&
805 (actual->message == expected->message - 4))
806 {
807 ok((expected->flags & hook) == (actual->flags & hook),
808 "%2d (%x/%x): the msg 0x%04x should have been sent by a hook\n",
809 id, test->wVk, test->dwFlags, expected->message);
810 }
811 /* For VK_RMENU, at least localized Win2k/XP sends KEYDOWN/UP
812 * instead of SYSKEYDOWN/UP to the WNDPROC */
813 else if (test->wVk == VK_RMENU && !(expected->flags & hook) &&
814 (expected->message == WM_SYSKEYDOWN || expected->message == WM_SYSKEYUP) &&
815 (actual->message == expected->message - 4))
816 {
817 ok(expected->wParam == actual->wParam && expected->lParam == actual->lParam,
818 "%2d (%x/%x): the msg 0x%04x was expected, but got msg 0x%04x instead\n",
819 id, test->wVk, test->dwFlags, expected->message, actual->message);
820 }
821 else if (test->_todo_wine)
822 {
823 failcount++;
825 ok(FALSE,
826 "%2d (%x/%x): the msg 0x%04x was expected, but got msg 0x%04x instead\n",
827 id, test->wVk, test->dwFlags, expected->message, actual->message);
828 }
829 else
830 ok(FALSE,
831 "%2d (%x/%x): the msg 0x%04x was expected, but got msg 0x%04x instead\n",
832 id, test->wVk, test->dwFlags, expected->message, actual->message);
833
834 actual_cnt++;
835 expected++;
836 }
837 /* skip all optional trailing messages */
838 while (expected->message && ((expected->flags & optional) || (!(expected->flags & hook) && !foreground)))
839 expected++;
840
841
842 if (expected->message || actual_cnt < sent_messages_cnt)
843 {
844 if (test->_todo_wine)
845 {
846 failcount++;
848 ok(FALSE, "%2d (%x/%x): the msg sequence is not complete: expected %04x - actual %04x\n",
849 id, test->wVk, test->dwFlags, expected->message, sent_messages[actual_cnt].message);
850 }
851 else
852 ok(FALSE, "%2d (%x/%x): the msg sequence is not complete: expected %04x - actual %04x\n",
853 id, test->wVk, test->dwFlags, expected->message, sent_messages[actual_cnt].message);
854 }
855
856 if( test->_todo_wine && !failcount) /* succeeded yet marked todo */
858 ok(TRUE, "%2d (%x/%x): marked \"todo_wine\" but succeeds\n", id, test->wVk, test->dwFlags);
859

◆ create_static_win()

static DWORD WINAPI create_static_win ( void arg)
static

Definition at line 2070 of file input.c.

2072{
2073 struct thread_data *thread_data = arg;
2074 HWND win;
2075
2076 win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
2077 100, 100, 100, 100, 0, NULL, NULL, NULL);
2078 ok(win != 0, "CreateWindow failed\n");
2081 thread_data->win = win;
2082
2085 return 0;

Referenced by test_Input_mouse().

◆ do_test()

static BOOL do_test ( HWND  hwnd,
int  seqnr,
const KEV  td[] 
)
static

Definition at line 223 of file input.c.

225{
226 TEST_INPUT inputs[MAXKEYEVENTS];
227 KMSG expmsg[MAXKEYEVENTS];
228 MSG msg;
229 char buf[100];
230 UINT evtctr=0, ret;
231 int kmctr, i;
232
233 buf[0]='\0';
234 TrackSysKey=0; /* see input.c */
235 for (i = 0; i < MAXKEYEVENTS; i++)
236 {
237 inputs[evtctr].type = INPUT_KEYBOARD;
238 inputs[evtctr].u.ki.wVk = GETVKEY[td[i]];
239 inputs[evtctr].u.ki.wScan = GETSCAN[td[i]];
240 inputs[evtctr].u.ki.dwFlags = GETFLAGS[td[i]];
241 inputs[evtctr].u.ki.dwExtraInfo = 0;
242 inputs[evtctr].u.ki.time = ++timetag;
243 if (td[i]) evtctr++;
244
245 strcat(buf, getdesc[td[i]]);
246 if(td[i])
247 expmsg[i].message = KbdMessage(td[i], &(expmsg[i].wParam), &(expmsg[i].lParam));
248 else
249 expmsg[i].message = 0;
250 }
251 for( kmctr = 0; kmctr < MAXKEYEVENTS && expmsg[kmctr].message; kmctr++)
252 ;
253 ok( evtctr <= MAXKEYEVENTS, "evtctr is above MAXKEYEVENTS\n" );
254 ret = SendInput(evtctr, (INPUT *)inputs, sizeof(INPUT));
255 ok(ret == evtctr, "SendInput failed to send some events\n");
256 i = 0;
257 if (winetest_debug > 1)
258 trace("======== key stroke sequence #%d: %s =============\n",
259 seqnr + 1, buf);
261 if (winetest_debug > 1)
262 trace("message[%d] %-15s wParam %04lx lParam %08lx time %x\n", i,
263 MSGNAME[msg.message - WM_KEYFIRST], msg.wParam, msg.lParam, msg.time);
264 if( i < kmctr ) {
265 ok( msg.message == expmsg[i].message &&
266 msg.wParam == expmsg[i].wParam &&
267 msg.lParam == expmsg[i].lParam,
268 "%u/%u: wrong message %x/%08lx/%08lx expected %s/%08lx/%08lx\n",
269 seqnr, i, msg.message, msg.wParam, msg.lParam,
270 MSGNAME[(expmsg[i]).message - WM_KEYFIRST], expmsg[i].wParam, expmsg[i].lParam );
271 }
272 i++;
273 }
274 if (winetest_debug > 1)
275 trace("%d messages retrieved\n", i);
276 if (!i && kmctr)
277 {
278 skip( "simulated keyboard input doesn't work\n" );
279 return FALSE;
280 }
281 ok( i == kmctr, "message count is wrong: got %d expected: %d\n", i, kmctr);
282 return TRUE;

◆ empty_message_queue()

static void empty_message_queue ( void  )
static

Definition at line 393 of file input.c.

395{
396 MSG msg;
397 int diff = 200;
398 int min_timeout = 50;
399 DWORD time = GetTickCount() + diff;
400
401 while (diff > 0)
402 {
403 if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT) break;
404 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
405 {
406 if (is_keyboard_message(msg.message) || is_mouse_message(msg.message))
407 ok(msg.time != 0, "message %#x has time set to 0\n", msg.message);
408
411 }
412 diff = time - GetTickCount();
413 }

◆ get_dc_region()

static void get_dc_region ( RECT region,
HWND  hwnd,
DWORD  flags 
)
static

Definition at line 2087 of file input.c.

2089{
2090 int region_type;
2091 HRGN hregion;
2092 HDC hdc;
2093
2094 hdc = GetDCEx(hwnd, 0, flags);
2095 ok(hdc != NULL, "GetDCEx failed\n");
2096 hregion = CreateRectRgn(40, 40, 60, 60);
2097 ok(hregion != NULL, "CreateRectRgn failed\n");
2098 GetRandomRgn(hdc, hregion, SYSRGN);
2099 region_type = GetRgnBox(hregion, region);
2100 ok(region_type == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", region_type);
2101 DeleteObject(hregion);
2102 ReleaseDC(hwnd, hdc);

Referenced by test_Input_mouse().

◆ get_key_state_thread()

static DWORD WINAPI get_key_state_thread ( void arg)
static

Definition at line 2878 of file input.c.

2880{
2881 HANDLE *semaphores = arg;
2882 DWORD result;
2883
2884 ReleaseSemaphore(semaphores[0], 1, NULL);
2885 result = WaitForSingleObject(semaphores[1], 1000);
2886 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2887
2888 result = GetKeyState('X');
2889 ok((result & 0x8000) || broken(!(result & 0x8000)), /* > Win 2003 */
2890 "expected that highest bit is set, got %x\n", result);
2891
2892 ReleaseSemaphore(semaphores[0], 1, NULL);
2893 result = WaitForSingleObject(semaphores[1], 1000);
2894 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2895
2896 result = GetKeyState('X');
2897 ok(!(result & 0x8000), "expected that highest bit is unset, got %x\n", result);
2898
2899 return 0;

Referenced by test_GetKeyState().

◆ hook_proc()

static LRESULT CALLBACK hook_proc ( int  code,
WPARAM  wparam,
LPARAM  lparam 
)
static

Definition at line 882 of file input.c.

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;
896 }
897
898if(0) /* For some reason not stable on Wine */
899{
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 );

◆ hook_proc1()

static LRESULT CALLBACK hook_proc1 ( int  code,
WPARAM  wparam,
LPARAM  lparam 
)
static

Definition at line 1261 of file input.c.

1263{
1265 POINT pt, pt1;
1266
1267 if (code == HC_ACTION)
1268 {
1269 /* This is our new cursor position */
1270 pt_new = hook->pt;
1271 /* Should return previous position */
1272 GetCursorPos(&pt);
1273 ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1274
1275 /* Should set new position until hook chain is finished. */
1276 pt.x = pt_old.x + STEP;
1277 pt.y = pt_old.y + STEP;
1278 SetCursorPos(pt.x, pt.y);
1279 GetCursorPos(&pt1);
1280 if (clipped)
1281 ok(pt1.x == pt_old.x && pt1.y == pt_old.y, "Wrong set pos: (%d,%d)\n", pt1.x, pt1.y);
1282 else
1283 ok(pt1.x == pt.x && pt1.y == pt.y, "Wrong set pos: (%d,%d)\n", pt1.x, pt1.y);
1284 }
1285 return CallNextHookEx( 0, code, wparam, lparam );

Referenced by test_mouse_ll_hook().

◆ hook_proc2()

static LRESULT CALLBACK hook_proc2 ( int  code,
WPARAM  wparam,
LPARAM  lparam 
)
static

Definition at line 1287 of file input.c.

1289{
1291 POINT pt;
1292
1293 if (code == HC_ACTION)
1294 {
1295 ok(hook->pt.x == pt_new.x && hook->pt.y == pt_new.y,
1296 "Wrong hook coords: (%d %d) != (%d,%d)\n", hook->pt.x, hook->pt.y, pt_new.x, pt_new.y);
1297
1298 /* Should match position set above */
1299 GetCursorPos(&pt);
1300 if (clipped)
1301 ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1302 else
1303 ok(pt.x == pt_old.x +STEP && pt.y == pt_old.y +STEP, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1304 }
1305 return CallNextHookEx( 0, code, wparam, lparam );

Referenced by test_mouse_ll_hook().

◆ hook_proc3()

static LRESULT CALLBACK hook_proc3 ( int  code,
WPARAM  wparam,
LPARAM  lparam 
)
static

Definition at line 1307 of file input.c.

1309{
1310 POINT pt;
1311
1312 if (code == HC_ACTION)
1313 {
1314 /* MSLLHOOKSTRUCT does not seem to be reliable and contains different data on each run. */
1315 GetCursorPos(&pt);
1316 ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
1317 }
1318 return CallNextHookEx( 0, code, wparam, lparam );

Referenced by test_mouse_ll_hook().

◆ init_function_pointers()

static void init_function_pointers ( void  )
static

Definition at line 151 of file input.c.

153{
154 HMODULE hdll = GetModuleHandleA("user32");
155
156#define GET_PROC(func) \
157 if (!(p ## func = (void*)GetProcAddress(hdll, #func))) \
158 trace("GetProcAddress(%s) failed\n", #func)
159
160 GET_PROC(GetCurrentInputMessageSource);
161 GET_PROC(GetMouseMovePointsEx);
162 GET_PROC(GetPointerType);
167#undef GET_PROC

Referenced by START_TEST().

◆ int()

static POINTER_INPUT_TYPE *static int ( WINAPI pGetMouseMovePointsEx)
static

◆ is_keyboard_message()

static BOOL is_keyboard_message ( UINT  message)
inlinestatic

Definition at line 382 of file input.c.

384{
385 return (message >= WM_KEYFIRST && message <= WM_KEYLAST);

Referenced by empty_message_queue().

◆ is_mouse_message()

static BOOL is_mouse_message ( UINT  message)
inlinestatic

Definition at line 387 of file input.c.

389{
390 return (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST);

Referenced by empty_message_queue().

◆ KbdMessage()

static int KbdMessage ( KEV  kev,
WPARAM pwParam,
LPARAM plParam 
)
static

Definition at line 169 of file input.c.

171{
173 int VKey = GETVKEY[kev];
174 WORD flags;
175
176 flags = LOBYTE(GETSCAN[kev]);
178
179 if (GETFLAGS[kev] & KEYEVENTF_KEYUP )
180 {
182 if( (InputKeyStateTable[VK_MENU] & 0x80) && (
183 (VKey == VK_MENU) || (VKey == VK_CONTROL) ||
184 !(InputKeyStateTable[VK_CONTROL] & 0x80))) {
185 if( TrackSysKey == VK_MENU || /* <ALT>-down/<ALT>-up sequence */
186 (VKey != VK_MENU)) /* <ALT>-down...<something else>-up */
188 TrackSysKey = 0;
189 }
190 InputKeyStateTable[VKey] &= ~0x80;
191 flags |= KF_REPEAT | KF_UP;
192 }
193 else
194 {
195 if (InputKeyStateTable[VKey] & 0x80) flags |= KF_REPEAT;
196 if (!(InputKeyStateTable[VKey] & 0x80)) InputKeyStateTable[VKey] ^= 0x01;
197 InputKeyStateTable[VKey] |= 0x80;
198 AsyncKeyStateTable[VKey] |= 0x80;
199
201 if( (InputKeyStateTable[VK_MENU] & 0x80) &&
202 !(InputKeyStateTable[VK_CONTROL] & 0x80)) {
204 TrackSysKey = VKey;
205 }
206 }
207
209
210 if( plParam) *plParam = MAKELPARAM( 1, flags );
211 if( pwParam) *pwParam = VKey;
212 return message;

Referenced by do_test().

◆ llkbd_unicode_hook()

static LRESULT CALLBACK llkbd_unicode_hook ( int  nCode,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 1145 of file input.c.

1147{
1148 if(nCode == HC_ACTION){
1150 if(!info->vkCode){
1151 key_status.sendinput_broken = TRUE;
1152 win_skip("SendInput doesn't support unicode on this platform\n");
1153 }else{
1154 if(key_status.expect_alt){
1155 ok(info->vkCode == VK_LMENU, "vkCode should have been VK_LMENU[0x%04x], was: 0x%x\n", VK_LMENU, info->vkCode);
1156 key_status.expect_alt = FALSE;
1157 }else
1158 todo_wine_if(key_status.vk != VK_PACKET)
1159 ok(info->vkCode == key_status.vk, "Unexpected vkCode %#x, expected %#x.\n", info->vkCode, key_status.vk);
1160 }
1161 switch(wParam){
1162 case WM_KEYDOWN:
1163 key_status.last_hook_down = info->scanCode;
1164 break;
1165 case WM_KEYUP:
1166 key_status.last_hook_up = info->scanCode;
1167 break;
1168 case WM_SYSKEYDOWN:
1169 key_status.last_hook_syskey_down = info->scanCode;
1170 break;
1171 case WM_SYSKEYUP:
1172 key_status.last_hook_syskey_up = info->scanCode;
1173 break;
1174 }
1175 }
1176 return CallNextHookEx(NULL, nCode, wParam, lParam);

Referenced by test_Input_unicode().

◆ msg_source_proc()

static LRESULT WINAPI msg_source_proc ( HWND  hwnd,
UINT  message,
WPARAM  wp,
LPARAM  lp 
)
static

Definition at line 2978 of file input.c.

2980{
2981 INPUT_MESSAGE_SOURCE source;
2982 MSG msg;
2983
2984 ok( pGetCurrentInputMessageSource( &source ), "GetCurrentInputMessageSource failed\n" );
2985 switch (message)
2986 {
2987 case WM_KEYDOWN:
2988 case WM_KEYUP:
2989 case WM_SYSKEYDOWN:
2990 case WM_SYSKEYUP:
2991 case WM_MOUSEMOVE:
2992 case WM_LBUTTONDOWN:
2993 case WM_LBUTTONUP:
2994 case WM_RBUTTONDOWN:
2995 case WM_RBUTTONUP:
2996 ok( source.deviceType == expect_src.deviceType || /* also accept system-generated WM_MOUSEMOVE */
2997 (message == WM_MOUSEMOVE && source.deviceType == IMDT_UNAVAILABLE),
2998 "%x: wrong deviceType %x/%x\n", message, source.deviceType, expect_src.deviceType );
2999 ok( source.originId == expect_src.originId ||
3000 (message == WM_MOUSEMOVE && source.originId == IMO_SYSTEM),
3001 "%x: wrong originId %x/%x\n", message, source.originId, expect_src.originId );
3002 SendMessageA( hwnd, WM_USER, 0, 0 );
3003 PostMessageA( hwnd, WM_USER, 0, 0 );
3005 ok( source.deviceType == expect_src.deviceType || /* also accept system-generated WM_MOUSEMOVE */
3006 (message == WM_MOUSEMOVE && source.deviceType == IMDT_UNAVAILABLE),
3007 "%x: wrong deviceType %x/%x\n", message, source.deviceType, expect_src.deviceType );
3008 ok( source.originId == expect_src.originId ||
3009 (message == WM_MOUSEMOVE && source.originId == IMO_SYSTEM),
3010 "%x: wrong originId %x/%x\n", message, source.originId, expect_src.originId );
3011 break;
3012 default:
3013 ok( source.deviceType == IMDT_UNAVAILABLE, "%x: wrong deviceType %x\n",
3014 message, source.deviceType );
3015 ok( source.originId == 0, "%x: wrong originId %x\n", message, source.originId );
3016 break;
3017 }
3018
3019 return DefWindowProcA( hwnd, message, wp, lp );

Referenced by test_input_message_source().

◆ MsgCheckProcA()

static LRESULT WINAPI MsgCheckProcA ( HWND  hwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 2578 of file input.c.

2580{
2581 if (message == WM_USER+1)
2582 {
2583 HWND hwnd = (HWND)lParam;
2584 ok(GetFocus() == hwnd, "thread expected focus %p, got %p\n", hwnd, GetFocus());
2585 ok(GetActiveWindow() == hwnd, "thread expected active %p, got %p\n", hwnd, GetActiveWindow());
2586 }

Referenced by test_attach_input().

◆ reset_key_status()

static void reset_key_status ( WORD  vk)
static

Definition at line 969 of file input.c.

971{
972 key_status.last_key_down = -1;
973 key_status.last_key_up = -1;
974 key_status.last_syskey_down = -1;
975 key_status.last_syskey_up = -1;
976 key_status.last_char = -1;
977 key_status.last_syschar = -1;
978 key_status.last_hook_down = -1;
979 key_status.last_hook_up = -1;
980 key_status.last_hook_syskey_down = -1;
981 key_status.last_hook_syskey_up = -1;
982 key_status.vk = vk;
983 key_status.expect_alt = FALSE;
984 key_status.sendinput_broken = FALSE;

Referenced by test_unicode_keys().

◆ simulate_click()

static void simulate_click ( BOOL  left,
int  x,
int  y 
)
static

Definition at line 1996 of file input.c.

1998{
1999 INPUT input[2];
2000 UINT events_no;
2001
2002 SetCursorPos(x, y);
2003 memset(input, 0, sizeof(input));
2004 input[0].type = INPUT_MOUSE;
2005 U(input[0]).mi.dx = x;
2006 U(input[0]).mi.dy = y;
2008 input[1].type = INPUT_MOUSE;
2009 U(input[1]).mi.dx = x;
2010 U(input[1]).mi.dy = y;
2011 U(input[1]).mi.dwFlags = left ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP;
2012 events_no = SendInput(2, input, sizeof(input[0]));
2013 ok(events_no == 2, "SendInput returned %d\n", events_no);

Referenced by test_input_message_source(), and test_Input_mouse().

◆ START_TEST()

START_TEST ( input  )

Definition at line 3164 of file input.c.

3166{
3167 POINT pos;
3168
3170 GetCursorPos( &pos );
3171
3176 test_keynames();
3178 test_key_map();
3180 test_ToAscii();
3189
3190 if(pGetMouseMovePointsEx)
3192 else
3193 win_skip("GetMouseMovePointsEx is not available\n");
3194
3195 if(pGetRawInputDeviceList)
3197 else
3198 win_skip("GetRawInputDeviceList is not available\n");
3199
3200 if (pGetCurrentInputMessageSource)
3202 else
3203 win_skip("GetCurrentInputMessageSource is not available\n");
3204
3205 SetCursorPos( pos.x, pos.y );
3206
3207 if(pGetPointerType)
3209 else
3210 win_skip("GetPointerType is not available\n");

◆ static_hook_proc()

static LRESULT WINAPI static_hook_proc ( HWND  hwnd,
UINT  msg,
WPARAM  wp,
LPARAM  lp 
)
static

Definition at line 2051 of file input.c.

2053{
2054 if (msg == WM_NCHITTEST)
2055 {
2056 /* break infinite hittest loop */
2057 if(hittest_no > 50) return HTCLIENT;
2058 hittest_no++;
2059 }
2060
2061 return def_static_proc(hwnd, msg, wp, lp);

Referenced by create_static_win(), and test_Input_mouse().

◆ test_attach_input()

static void test_attach_input ( void  )
static

Definition at line 2645 of file input.c.

2647{
2649 HWND ourWnd, Wnd2;
2650 DWORD ret, tid;
2651 struct wnd_event wnd_event;
2652 WNDCLASSA cls;
2653
2654 cls.style = 0;
2655 cls.lpfnWndProc = MsgCheckProcA;
2656 cls.cbClsExtra = 0;
2657 cls.cbWndExtra = 0;
2658 cls.hInstance = GetModuleHandleA(0);
2659 cls.hIcon = 0;
2660 cls.hCursor = LoadCursorW( NULL, (LPCWSTR)IDC_ARROW);
2661 cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2662 cls.lpszMenuName = NULL;
2663 cls.lpszClassName = "TestWindowClass";
2664 if(!RegisterClassA(&cls)) return;
2665
2669 wnd_event.attach_to = 0;
2672 {
2673 win_skip("skipping interthread message test under win9x\n");
2674 return;
2675 }
2676
2678 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2679
2680 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2682
2683 ourWnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
2684 0, 0, 0, 0, 0, 0, 0, NULL);
2685 ok(ourWnd!= 0, "failed to create ourWnd window\n");
2686
2687 Wnd2 = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
2688 0, 0, 0, 0, 0, 0, 0, NULL);
2689 ok(Wnd2!= 0, "failed to create Wnd2 window\n");
2690
2691 SetFocus(ourWnd);
2692 SetActiveWindow(ourWnd);
2693
2695 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2696
2697 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2698 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2699
2700 SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
2701
2703 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2704 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2705 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2706
2708
2710 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2711
2712 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2713 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2714 SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
2715
2716 SetActiveWindow(Wnd2);
2717 SetFocus(Wnd2);
2718 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2719 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2720
2722
2724 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2725 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2726 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2727
2729
2731 ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2732
2733 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2735
2739 wnd_event.attach_to = 0;
2741
2743 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2744
2745 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2747
2748 SetFocus(ourWnd);
2749 SetActiveWindow(ourWnd);
2750
2752 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2753
2754 ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
2755 ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
2756
2758
2760 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2761
2762 ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
2763 ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
2764
2766
2768 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2769
2770 ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
2771 ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
2772
2774
2775 SetFocus(Wnd2);
2776 SetActiveWindow(Wnd2);
2777 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2778 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2779
2781
2783 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2784
2785 ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
2786 ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
2787
2789
2791 ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2792
2793 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2795
2799 wnd_event.attach_to = 0;
2801
2803 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2804
2805 SetLastError(0xdeadbeef);
2807 ok(!ret, "AttachThreadInput succeeded\n");
2808 ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef) /* <= Win XP */,
2809 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2810
2811 SetLastError(0xdeadbeef);
2813 ok(!ret, "AttachThreadInput succeeded\n");
2814 ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef) /* <= Win XP */,
2815 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2816
2818
2819 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2821
2823 ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2824
2825 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2827
2831 wnd_event.attach_to = 0;
2833
2834 SetFocus(ourWnd);
2835 SetActiveWindow(ourWnd);
2836
2838 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2839
2840 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2842
2843 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2844 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2845
2847 ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2848
2849 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2851
2857
2858 SetFocus(ourWnd);
2859 SetActiveWindow(ourWnd);
2860
2862 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
2863
2864 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2866
2867 ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
2868 ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
2869
2871 ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
2872
2873 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2875 DestroyWindow(ourWnd);
2876 DestroyWindow(Wnd2);

Referenced by START_TEST().

◆ test_get_async_key_state()

static void test_get_async_key_state ( void  )
static

Definition at line 1928 of file input.c.

1930{
1931 /* input value sanity checks */
1932 ok(0 == GetAsyncKeyState(1000000), "GetAsyncKeyState did not return 0\n");
1933 ok(0 == GetAsyncKeyState(-1000000), "GetAsyncKeyState did not return 0\n");

Referenced by START_TEST().

◆ test_GetKeyboardLayoutList()

static void test_GetKeyboardLayoutList ( void  )
static

Definition at line 3130 of file input.c.

3132{
3133 int cnt, cnt2;
3134 HKL *layouts;
3135 ULONG_PTR baselayout;
3136 LANGID langid;
3137
3138 baselayout = GetUserDefaultLCID();
3139 langid = PRIMARYLANGID(LANGIDFROMLCID(baselayout));
3141 baselayout = MAKELONG( baselayout, 0xe001 ); /* IME */
3142 else
3143 baselayout |= baselayout << 16;
3144
3145 cnt = GetKeyboardLayoutList(0, NULL);
3146 /* Most users will not have more than a few keyboard layouts installed at a time. */
3147 ok(cnt > 0 && cnt < 10, "Layout count %d\n", cnt);
3148 if (cnt > 0)
3149 {
3150 layouts = HeapAlloc(GetProcessHeap(), 0, sizeof(*layouts) * cnt );
3151
3152 cnt2 = GetKeyboardLayoutList(cnt, layouts);
3153 ok(cnt == cnt2, "wrong value %d!=%d\n", cnt, cnt2);
3154 for(cnt = 0; cnt < cnt2; cnt++)
3155 {
3156 if(layouts[cnt] == (HKL)baselayout)
3157 break;
3158 }
3159 ok(cnt < cnt2, "Didnt find current keyboard\n");
3160
3161 HeapFree(GetProcessHeap(), 0, layouts);
3162 }

Referenced by START_TEST().

◆ test_GetKeyState()

static void test_GetKeyState ( void  )
static

Definition at line 2901 of file input.c.

2903{
2904 HANDLE semaphores[2];
2905 HANDLE thread;
2906 DWORD result;
2907 HWND hwnd;
2908
2909 semaphores[0] = CreateSemaphoreA(NULL, 0, 1, NULL);
2910 ok(semaphores[0] != NULL, "CreateSemaphoreA failed %u\n", GetLastError());
2911 semaphores[1] = CreateSemaphoreA(NULL, 0, 1, NULL);
2912 ok(semaphores[1] != NULL, "CreateSemaphoreA failed %u\n", GetLastError());
2913
2914 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2915 10, 10, 200, 200, NULL, NULL, NULL, NULL);
2916 ok(hwnd != NULL, "CreateWindowA failed %u\n", GetLastError());
2917
2918 thread = CreateThread(NULL, 0, get_key_state_thread, semaphores, 0, NULL);
2919 ok(thread != NULL, "CreateThread failed %u\n", GetLastError());
2920 result = WaitForSingleObject(semaphores[0], 1000);
2921 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2922
2924 SetFocus(hwnd);
2925 keybd_event('X', 0, 0, 0);
2926
2927 ReleaseSemaphore(semaphores[1], 1, NULL);
2928 result = WaitForSingleObject(semaphores[0], 1000);
2929 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2930
2931 keybd_event('X', 0, KEYEVENTF_KEYUP, 0);
2932
2933 ReleaseSemaphore(semaphores[1], 1, NULL);
2935 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
2937
2939 CloseHandle(semaphores[0]);
2940 CloseHandle(semaphores[1]);

Referenced by START_TEST().

◆ test_GetMouseMovePointsEx()

static void test_GetMouseMovePointsEx ( void  )
static

Definition at line 1454 of file input.c.

1456{
1457#define BUFLIM 64
1458#define MYERROR 0xdeadbeef
1459 int count, retval;
1460 MOUSEMOVEPOINT in;
1461 MOUSEMOVEPOINT out[200];
1462 POINT point;
1463
1464 /* Get a valid content for the input struct */
1465 if(!GetCursorPos(&point)) {
1466 win_skip("GetCursorPos() failed with error %u\n", GetLastError());
1467 return;
1468 }
1469 memset(&in, 0, sizeof(MOUSEMOVEPOINT));
1470 in.x = point.x;
1471 in.y = point.y;
1472
1473 /* test first parameter
1474 * everything different than sizeof(MOUSEMOVEPOINT)
1475 * is expected to fail with ERROR_INVALID_PARAMETER
1476 */
1478 retval = pGetMouseMovePointsEx(0, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1479 if (retval == ERROR_INVALID_PARAMETER)
1480 {
1481 win_skip( "GetMouseMovePointsEx broken on WinME\n" );
1482 return;
1483 }
1484 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1486 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1487
1489 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1490 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1492 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1493
1495 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)+1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1496 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1498 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1499
1500 /* test second and third parameter
1501 */
1503 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1504 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1506 "expected error ERROR_NOACCESS, got %u\n", GetLastError());
1507
1509 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1510 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1512 "expected error ERROR_NOACCESS, got %u\n", GetLastError());
1513
1515 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1516 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1518 "expected error ERROR_NOACCESS, got %u\n", GetLastError());
1519
1521 count = 0;
1522 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, count, GMMP_USE_DISPLAY_POINTS);
1523 if (retval == -1)
1524 ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %u\n", GetLastError());
1525 else
1526 ok(retval == count, "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1527
1528 /* test fourth parameter
1529 * a value higher than 64 is expected to fail with ERROR_INVALID_PARAMETER
1530 */
1532 count = -1;
1533 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1534 ok(retval == count, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1536 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1537
1539 count = 0;
1540 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1541 if (retval == -1)
1542 ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %u\n", GetLastError());
1543 else
1544 ok(retval == count, "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1545
1547 count = BUFLIM;
1548 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
1549 if (retval == -1)
1550 ok(GetLastError() == ERROR_POINT_NOT_FOUND, "unexpected error %u\n", GetLastError());
1551 else
1552 ok((0 <= retval) && (retval <= count), "expected GetMouseMovePointsEx to succeed, got %d\n", retval);
1553
1555 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1556 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1558 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1559
1560 /* it was not possible to force an error with the fifth parameter on win2k */
1561
1562 /* test combinations of wrong parameters to see which error wins */
1564 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1565 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1567 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1568
1570 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
1571 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1573 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1574
1576 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1577 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1579 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1580
1582 retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
1583 ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
1585 "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1586
1587#undef BUFLIM
1588#undef MYERROR

Referenced by START_TEST().

◆ test_GetPointerType()

static void test_GetPointerType ( void  )
static

Definition at line 3105 of file input.c.

3107{
3108 BOOL ret;
3109 POINTER_INPUT_TYPE type = -1;
3110 UINT id = 0;
3111
3112 SetLastError(0xdeadbeef);
3113 ret = pGetPointerType(id, NULL);
3114 ok(!ret, "GetPointerType should have failed.\n");
3116 "expected error ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
3117
3118 SetLastError(0xdeadbeef);
3119 ret = pGetPointerType(id, &type);
3121 "expected error ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
3122 ok(!ret, "GetPointerType failed, got type %d for %u.\n", type, id );
3123 ok(type == -1, " type %d\n", type );
3124
3125 id = 1;
3126 ret = pGetPointerType(id, &type);
3127 ok(ret, "GetPointerType failed, got type %d for %u.\n", type, id );
3128 ok(type == PT_MOUSE, " type %d\n", type );

Referenced by START_TEST().

◆ test_GetRawInputData()

static void test_GetRawInputData ( void  )
static

Definition at line 1693 of file input.c.

1695{
1696 UINT size;
1697 UINT ret;
1698
1699 /* Null raw input handle */
1700 ret = GetRawInputData(NULL, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
1701 ok(ret == ~0U, "Expect ret %u, got %u\n", ~0U, ret);

Referenced by START_TEST().

◆ test_GetRawInputDeviceList()

static void test_GetRawInputDeviceList ( void  )
static

Definition at line 1590 of file input.c.

1592{
1593 RAWINPUTDEVICELIST devices[32];
1594 UINT ret, oret, devcount, odevcount, i;
1595 DWORD err;
1596
1597 SetLastError(0xdeadbeef);
1598 ret = pGetRawInputDeviceList(NULL, NULL, 0);
1599 err = GetLastError();
1600 ok(ret == -1, "expected -1, got %d\n", ret);
1601 ok(err == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", err);
1602
1603 SetLastError(0xdeadbeef);
1604 ret = pGetRawInputDeviceList(NULL, NULL, sizeof(devices[0]));
1605 err = GetLastError();
1606 ok(ret == -1, "expected -1, got %d\n", ret);
1607 ok(err == ERROR_NOACCESS, "expected 998, got %d\n", err);
1608
1609 devcount = 0;
1610 ret = pGetRawInputDeviceList(NULL, &devcount, sizeof(devices[0]));
1611 ok(ret == 0, "expected 0, got %d\n", ret);
1612 ok(devcount > 0, "expected non-zero\n");
1613
1614 SetLastError(0xdeadbeef);
1615 devcount = 0;
1616 ret = pGetRawInputDeviceList(devices, &devcount, sizeof(devices[0]));
1617 err = GetLastError();
1618 ok(ret == -1, "expected -1, got %d\n", ret);
1619 ok(err == ERROR_INSUFFICIENT_BUFFER, "expected 122, got %d\n", err);
1620 ok(devcount > 0, "expected non-zero\n");
1621
1622 /* devcount contains now the correct number of devices */
1623 ret = pGetRawInputDeviceList(devices, &devcount, sizeof(devices[0]));
1624 ok(ret > 0, "expected non-zero\n");
1625
1626 for(i = 0; i < devcount; ++i)
1627 {
1628 WCHAR name[128];
1629 char nameA[128];
1630 UINT sz, len;
1631 RID_DEVICE_INFO info;
1632 HANDLE file;
1633
1634 /* get required buffer size */
1635 name[0] = '\0';
1636 sz = 5;
1637 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICENAME, name, &sz);
1638 ok(ret == -1, "GetRawInputDeviceInfo gave wrong failure: %d\n", err);
1639 ok(sz > 5 && sz < ARRAY_SIZE(name), "Size should have been set and not too large (got: %u)\n", sz);
1640
1641 /* buffer size for RIDI_DEVICENAME is in CHARs, not BYTEs */
1642 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICENAME, name, &sz);
1643 ok(ret == sz, "GetRawInputDeviceInfo gave wrong return: %d\n", err);
1644 len = lstrlenW(name);
1645 ok(len + 1 == ret, "GetRawInputDeviceInfo returned wrong length (name: %u, ret: %u)\n", len + 1, ret);
1646
1647 /* test A variant with same size */
1648 ret = pGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, nameA, &sz);
1649 ok(ret == sz, "GetRawInputDeviceInfoA gave wrong return: %d\n", err);
1650 len = strlen(nameA);
1651 ok(len + 1 == ret, "GetRawInputDeviceInfoA returned wrong length (name: %u, ret: %u)\n", len + 1, ret);
1652
1653 /* buffer size for RIDI_DEVICEINFO is in BYTEs */
1654 memset(&info, 0, sizeof(info));
1655 info.cbSize = sizeof(info);
1656 sz = sizeof(info) - 1;
1657 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz);
1658 ok(ret == -1, "GetRawInputDeviceInfo gave wrong failure: %d\n", err);
1659 ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n");
1660
1661 ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz);
1662 ok(ret == sizeof(info), "GetRawInputDeviceInfo gave wrong return: %d\n", err);
1663 ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n");
1664 ok(info.dwType == devices[i].dwType, "GetRawInputDeviceInfo set wrong type: 0x%x\n", info.dwType);
1665
1666 memset(&info, 0, sizeof(info));
1667 info.cbSize = sizeof(info);
1668 ret = pGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz);
1669 ok(ret == sizeof(info), "GetRawInputDeviceInfo gave wrong return: %d\n", err);
1670 ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n");
1671 ok(info.dwType == devices[i].dwType, "GetRawInputDeviceInfo set wrong type: 0x%x\n", info.dwType);
1672
1673 /* setupapi returns an NT device path, but CreateFile() < Vista can't
1674 * understand that; so use the \\?\ prefix instead */
1675 name[1] = '\\';
1677 todo_wine_if(info.dwType != RIM_TYPEHID)
1678 ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u\n", wine_dbgstr_w(name), GetLastError());
1680 }
1681
1682 /* check if variable changes from larger to smaller value */
1683 devcount = odevcount = ARRAY_SIZE(devices);
1684 oret = ret = pGetRawInputDeviceList(devices, &odevcount, sizeof(devices[0]));
1685 ok(ret > 0, "expected non-zero\n");
1686 ok(devcount == odevcount, "expected %d, got %d\n", devcount, odevcount);
1687 devcount = odevcount;
1688 odevcount = ARRAY_SIZE(devices);
1689 ret = pGetRawInputDeviceList(NULL, &odevcount, sizeof(devices[0]));
1690 ok(ret == 0, "expected 0, got %d\n", ret);
1691 ok(odevcount == oret, "expected %d, got %d\n", oret, odevcount);

Referenced by START_TEST().

◆ test_Input_blackbox()

static void test_Input_blackbox ( void  )
static

Definition at line 911 of file input.c.

913{
915 int ii;
916 BYTE ks1[256], ks2[256];
917 LONG_PTR prevWndProc;
918 BOOL foreground;
919 HWND window;
920 HHOOK hook;
921
922 if (GetKeyboardLayout(0) != (HKL)(ULONG_PTR)0x04090409)
923 {
924 skip("Skipping Input_blackbox test on non-US keyboard\n");
925 return;
926 }
928 |WS_VISIBLE, 0, 0, 200, 60, NULL, NULL,
929 NULL, NULL);
930 ok(window != NULL, "error: %d\n", (int) GetLastError());
932 foreground = SetForegroundWindow( window );
933 if (!foreground)
934 skip("Failed to set foreground window; some tests will be skipped.\n");
935
937 {
939 win_skip("WH_KEYBOARD_LL is not supported\n");
940 return;
941 }
942
943 /* must process all initial messages, otherwise X11DRV_KeymapNotify unsets
944 * key state set by SendInput(). */
946
948 ok(prevWndProc != 0 || GetLastError() == 0, "error: %d\n", (int) GetLastError());
949
950 i.type = INPUT_KEYBOARD;
951 i.u.ki.time = 0;
952 i.u.ki.dwExtraInfo = 0;
953
954 for (ii = 0; ii < ARRAY_SIZE(sendinput_test)-1; ii++) {
955 GetKeyboardState(ks1);
956 i.u.ki.wScan = ii+1 /* useful for debugging */;
957 i.u.ki.dwFlags = sendinput_test[ii].dwFlags;
958 i.u.ki.wVk = sendinput_test[ii].wVk;
959 SendInput(1, (INPUT*)&i, sizeof(TEST_INPUT));
961 GetKeyboardState(ks2);
962 compare_and_check(ii, ks1, ks2, &sendinput_test[ii], foreground);
963 }
964

Referenced by START_TEST().

◆ test_input_message_source()

static void test_input_message_source ( void  )
static

Definition at line 3021 of file input.c.

3023{
3024 WNDCLASSA cls;
3025 TEST_INPUT inputs[2];
3026 HWND hwnd;
3027 RECT rc;
3028 MSG msg;
3029
3030 cls.style = 0;
3032 cls.cbClsExtra = 0;
3033 cls.cbWndExtra = 0;
3034 cls.hInstance = GetModuleHandleA(0);
3035 cls.hIcon = 0;
3037 cls.hbrBackground = 0;
3038 cls.lpszMenuName = NULL;
3039 cls.lpszClassName = "message source class";
3040 RegisterClassA(&cls);
3041 hwnd = CreateWindowA( cls.lpszClassName, "test", WS_OVERLAPPED, 0, 0, 100, 100,
3042 0, 0, 0, 0 );
3044 UpdateWindow( hwnd );
3046 SetFocus( hwnd );
3047
3048 inputs[0].type = INPUT_KEYBOARD;
3049 inputs[0].u.ki.dwExtraInfo = 0;
3050 inputs[0].u.ki.time = 0;
3051 inputs[0].u.ki.wVk = 0;
3052 inputs[0].u.ki.wScan = 0x3c0;
3053 inputs[0].u.ki.dwFlags = KEYEVENTF_UNICODE;
3054 inputs[1] = inputs[0];
3055 inputs[1].u.ki.dwFlags |= KEYEVENTF_KEYUP;
3056
3057 expect_src.deviceType = IMDT_UNAVAILABLE;
3058 expect_src.originId = IMO_UNAVAILABLE;
3059 SendMessageA( hwnd, WM_KEYDOWN, 0, 0 );
3060 SendMessageA( hwnd, WM_MOUSEMOVE, 0, 0 );
3061
3062 SendInput( 2, (INPUT *)inputs, sizeof(INPUT) );
3063 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
3064 {
3065 expect_src.deviceType = IMDT_KEYBOARD;
3066 expect_src.originId = IMO_INJECTED;
3069 }
3070 GetWindowRect( hwnd, &rc );
3071 simulate_click( TRUE, (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2 );
3072 simulate_click( FALSE, (rc.left + rc.right) / 2 + 1, (rc.top + rc.bottom) / 2 + 1 );
3073 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
3074 {
3075 expect_src.deviceType = IMDT_MOUSE;
3076 expect_src.originId = IMO_INJECTED;
3079 }
3080
3081 expect_src.deviceType = IMDT_UNAVAILABLE;
3082 expect_src.originId = IMO_UNAVAILABLE;
3083 SendMessageA( hwnd, WM_KEYDOWN, 0, 0 );
3085 PostMessageA( hwnd, WM_KEYUP, 0, 0 );
3086 PostMessageA( hwnd, WM_LBUTTONUP, 0, 0 );
3087 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
3088 {
3091 }
3092
3093 expect_src.deviceType = IMDT_UNAVAILABLE;
3094 expect_src.originId = IMO_SYSTEM;
3095 SetCursorPos( (rc.left + rc.right) / 2 - 1, (rc.top + rc.bottom) / 2 - 1 );
3096 while (PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ))
3097 {
3100 }
3101

Referenced by START_TEST().

◆ test_Input_mouse()

static void test_Input_mouse ( void  )
static

Definition at line 2104 of file input.c.

2106{
2107 BOOL got_button_down, got_button_up;
2108 HWND hwnd, button_win, static_win;
2109 struct thread_data thread_data;
2110 HANDLE thread;
2112 WNDCLASSA wclass;
2113 POINT pt, pt_org;
2114 int region_type;
2115 HRGN hregion;
2116 RECT region;
2117 MSG msg;
2118 BOOL ret;
2119
2120 SetLastError(0xdeadbeef);
2122 ok(!ret, "GetCursorPos succeed\n");
2123 ok(GetLastError() == 0xdeadbeef || GetLastError() == ERROR_NOACCESS, "error %u\n", GetLastError());
2124
2125 SetLastError(0xdeadbeef);
2126 ret = GetCursorPos(&pt_org);
2127 ok(ret, "GetCursorPos failed\n");
2128 ok(GetLastError() == 0xdeadbeef, "error %u\n", GetLastError());
2129
2130 button_win = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP,
2131 100, 100, 100, 100, 0, NULL, NULL, NULL);
2132 ok(button_win != 0, "CreateWindow failed\n");
2133
2134 pt.x = pt.y = 150;
2136 if (hwnd != button_win)
2137 {
2138 skip("there's another window covering test window\n");
2139 DestroyWindow(button_win);
2140 return;
2141 }
2142
2143 /* simple button click test */
2144 simulate_click(TRUE, 150, 150);
2145 got_button_down = got_button_up = FALSE;
2146 while (wait_for_message(&msg))
2147 {
2149
2150 if (msg.message == WM_LBUTTONDOWN)
2151 {
2152 got_button_down = TRUE;
2153 }
2154 else if (msg.message == WM_LBUTTONUP)
2155 {
2156 got_button_up = TRUE;
2157 break;
2158 }
2159 }
2160 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2161 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2162
2163 /* click through HTTRANSPARENT child window */
2164 static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_CHILD,
2165 0, 0, 100, 100, button_win, NULL, NULL, NULL);
2166 ok(static_win != 0, "CreateWindow failed\n");
2167 def_static_proc = (void*)SetWindowLongPtrA(static_win,
2169 simulate_click(FALSE, 150, 150);
2170 hittest_no = 0;
2171 got_button_down = got_button_up = FALSE;
2172 while (wait_for_message(&msg))
2173 {
2175
2176 if (msg.message == WM_RBUTTONDOWN)
2177 {
2178 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2179 got_button_down = TRUE;
2180 }
2181 else if (msg.message == WM_RBUTTONUP)
2182 {
2183 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2184 got_button_up = TRUE;
2185 break;
2186 }
2187 }
2188 ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
2189 ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
2190 ok(got_button_up, "expected WM_RBUTTONUP message\n");
2191 DestroyWindow(static_win);
2192
2193 /* click through HTTRANSPARENT top-level window */
2194 static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
2195 100, 100, 100, 100, 0, NULL, NULL, NULL);
2196 ok(static_win != 0, "CreateWindow failed\n");
2197 def_static_proc = (void*)SetWindowLongPtrA(static_win,
2199 simulate_click(TRUE, 150, 150);
2200 hittest_no = 0;
2201 got_button_down = got_button_up = FALSE;
2202 while (wait_for_message(&msg))
2203 {
2205
2206 if (msg.message == WM_LBUTTONDOWN)
2207 {
2208 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2209 got_button_down = TRUE;
2210 }
2211 else if (msg.message == WM_LBUTTONUP)
2212 {
2213 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2214 got_button_up = TRUE;
2215 break;
2216 }
2217 }
2218 ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
2219 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2220 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2221 DestroyWindow(static_win);
2222
2223 /* click on HTTRANSPARENT top-level window that belongs to other thread */
2225 ok(thread_data.start_event != NULL, "CreateEvent failed\n");
2227 ok(thread_data.end_event != NULL, "CreateEvent failed\n");
2229 ok(thread != NULL, "CreateThread failed\n");
2230 hittest_no = 0;
2231 got_button_down = got_button_up = FALSE;
2233 simulate_click(FALSE, 150, 150);
2234 while (wait_for_message(&msg))
2235 {
2237
2238 if (msg.message == WM_RBUTTONDOWN)
2239 got_button_down = TRUE;
2240 else if (msg.message == WM_RBUTTONUP)
2241 got_button_up = TRUE;
2242 }
2246 ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
2247 ok(!got_button_down, "unexpected WM_RBUTTONDOWN message\n");
2248 ok(!got_button_up, "unexpected WM_RBUTTONUP message\n");
2249
2250 /* click on HTTRANSPARENT top-level window that belongs to other thread,
2251 * thread input queues are attached */
2253 ok(thread != NULL, "CreateThread failed\n");
2254 hittest_no = 0;
2255 got_button_down = got_button_up = FALSE;
2258 "AttachThreadInput failed\n");
2260 SetWindowPos(thread_data.win, button_win, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
2261 simulate_click(TRUE, 150, 150);
2262 while (wait_for_message(&msg))
2263 {
2265
2266 if (msg.message == WM_LBUTTONDOWN)
2267 got_button_down = TRUE;
2268 else if (msg.message == WM_LBUTTONUP)
2269 got_button_up = TRUE;
2270 }
2273 todo_wine ok(hittest_no > 50, "expected loop with WM_NCHITTEST messages\n");
2274 ok(!got_button_down, "unexpected WM_LBUTTONDOWN message\n");
2275 ok(!got_button_up, "unexpected WM_LBUTTONUP message\n");
2276
2277 /* click after SetCapture call */
2278 hwnd = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP,
2279 0, 0, 100, 100, 0, NULL, NULL, NULL);
2280 ok(hwnd != 0, "CreateWindow failed\n");
2281 SetCapture(button_win);
2282 got_button_down = got_button_up = FALSE;
2283 simulate_click(FALSE, 50, 50);
2284 while (wait_for_message(&msg))
2285 {
2287
2288 if (msg.message == WM_RBUTTONDOWN)
2289 {
2290 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2291 got_button_down = TRUE;
2292 }
2293 else if (msg.message == WM_RBUTTONUP)
2294 {
2295 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2296 got_button_up = TRUE;
2297 break;
2298 }
2299 }
2300 ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
2301 ok(got_button_up, "expected WM_RBUTTONUP message\n");
2303
2304 /* click on child window after SetCapture call */
2305 hwnd = CreateWindowA("button", "button2", WS_VISIBLE | WS_CHILD,
2306 0, 0, 100, 100, button_win, NULL, NULL, NULL);
2307 ok(hwnd != 0, "CreateWindow failed\n");
2308 got_button_down = got_button_up = FALSE;
2309 simulate_click(TRUE, 150, 150);
2310 while (wait_for_message(&msg))
2311 {
2313
2314 if (msg.message == WM_LBUTTONDOWN)
2315 {
2316 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2317 got_button_down = TRUE;
2318 }
2319 else if (msg.message == WM_LBUTTONUP)
2320 {
2321 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2322 got_button_up = TRUE;
2323 break;
2324 }
2325 }
2326 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2327 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2329 ok(ReleaseCapture(), "ReleaseCapture failed\n");
2330
2331 wclass.style = 0;
2332 wclass.lpfnWndProc = WndProc;
2333 wclass.cbClsExtra = 0;
2334 wclass.cbWndExtra = 0;
2336 wclass.hIcon = LoadIconA(0, (LPCSTR)IDI_APPLICATION);
2338 wclass.hbrBackground = CreateSolidBrush(RGB(128, 128, 128));
2339 wclass.lpszMenuName = NULL;
2340 wclass.lpszClassName = "InputLayeredTestClass";
2341 RegisterClassA( &wclass );
2342
2343 /* click through layered window with alpha channel / color key */
2344 hwnd = CreateWindowA(wclass.lpszClassName, "InputLayeredTest",
2345 WS_VISIBLE | WS_POPUP, 100, 100, 100, 100, button_win, NULL, NULL, NULL);
2346 ok(hwnd != NULL, "CreateWindowEx failed\n");
2347
2348 static_win = CreateWindowA("static", "Title", WS_VISIBLE | WS_CHILD,
2349 10, 10, 20, 20, hwnd, NULL, NULL, NULL);
2350 ok(static_win != NULL, "CreateWindowA failed %u\n", GetLastError());
2351
2354 ret = SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA);
2355 ok(ret, "SetLayeredWindowAttributes failed\n");
2357 Sleep(100);
2358
2359 if (pGetWindowRgnBox)
2360 {
2361 region_type = pGetWindowRgnBox(hwnd, &region);
2362 ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2363 }
2364
2366 ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2367 "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2369 ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2370 "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2371 get_dc_region(&region, hwnd, DCX_USESTYLE);
2372 ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2373 "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2374 get_dc_region(&region, static_win, DCX_PARENTCLIP);
2375 ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2376 "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2377 get_dc_region(&region, static_win, DCX_WINDOW | DCX_USESTYLE);
2378 ok(region.left == 110 && region.top == 110 && region.right == 130 && region.bottom == 130,
2379 "expected region (110,110)-(130,130), got %s\n", wine_dbgstr_rect(&region));
2380 get_dc_region(&region, static_win, DCX_USESTYLE);
2381 ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200,
2382 "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(&region));
2383
2384 got_button_down = got_button_up = FALSE;
2385 simulate_click(TRUE, 150, 150);
2386 while (wait_for_message(&msg))
2387 {
2389
2390 if (msg.message == WM_LBUTTONDOWN)
2391 {
2392 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2393 got_button_down = TRUE;
2394 }
2395 else if (msg.message == WM_LBUTTONUP)
2396 {
2397 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2398 got_button_up = TRUE;
2399 break;
2400 }
2401 }
2402 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2403 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2404
2405 ret = SetLayeredWindowAttributes(hwnd, 0, 0, LWA_ALPHA);
2406 ok(ret, "SetLayeredWindowAttributes failed\n");
2408 Sleep(100);
2409
2410 if (pGetWindowRgnBox)
2411 {
2412 region_type = pGetWindowRgnBox(hwnd, &region);
2413 ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2414 }
2415
2416 got_button_down = got_button_up = FALSE;
2417 simulate_click(TRUE, 150, 150);
2418 while (wait_for_message(&msg))
2419 {
2421
2422 if (msg.message == WM_LBUTTONDOWN)
2423 {
2424 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2425 got_button_down = TRUE;
2426 }
2427 else if (msg.message == WM_LBUTTONUP)
2428 {
2429 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2430 got_button_up = TRUE;
2431 break;
2432 }
2433 }
2434 ok(got_button_down || broken(!got_button_down), "expected WM_LBUTTONDOWN message\n");
2435 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2436
2437 ret = SetLayeredWindowAttributes(hwnd, RGB(0, 255, 0), 255, LWA_ALPHA | LWA_COLORKEY);
2438 ok(ret, "SetLayeredWindowAttributes failed\n");
2440 Sleep(100);
2441
2442 if (pGetWindowRgnBox)
2443 {
2444 region_type = pGetWindowRgnBox(hwnd, &region);
2445 ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2446 }
2447
2448 got_button_down = got_button_up = FALSE;
2449 simulate_click(TRUE, 150, 150);
2450 while (wait_for_message(&msg))
2451 {
2453
2454 if (msg.message == WM_LBUTTONDOWN)
2455 {
2456 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2457 got_button_down = TRUE;
2458 }
2459 else if (msg.message == WM_LBUTTONUP)
2460 {
2461 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2462 got_button_up = TRUE;
2463 break;
2464 }
2465 }
2466 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2467 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2468
2469 ret = SetLayeredWindowAttributes(hwnd, RGB(128, 128, 128), 0, LWA_COLORKEY);
2470 ok(ret, "SetLayeredWindowAttributes failed\n");
2472 Sleep(100);
2473
2474 if (pGetWindowRgnBox)
2475 {
2476 region_type = pGetWindowRgnBox(hwnd, &region);
2477 ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2478 }
2479
2480 got_button_down = got_button_up = FALSE;
2481 simulate_click(TRUE, 150, 150);
2482 while (wait_for_message(&msg))
2483 {
2485
2486 if (msg.message == WM_LBUTTONDOWN)
2487 {
2488 todo_wine
2489 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2490 got_button_down = TRUE;
2491 }
2492 else if (msg.message == WM_LBUTTONUP)
2493 {
2494 todo_wine
2495 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2496 got_button_up = TRUE;
2497 break;
2498 }
2499 }
2500 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2501 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2502
2505 Sleep(100);
2506
2507 if (pGetWindowRgnBox)
2508 {
2509 region_type = pGetWindowRgnBox(hwnd, &region);
2510 ok(region_type == ERROR, "expected ERROR, got %d\n", region_type);
2511 }
2512
2513 got_button_down = got_button_up = FALSE;
2514 simulate_click(TRUE, 150, 150);
2515 while (wait_for_message(&msg))
2516 {
2518
2519 if (msg.message == WM_LBUTTONDOWN)
2520 {
2521 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2522 got_button_down = TRUE;
2523 }
2524 else if (msg.message == WM_LBUTTONUP)
2525 {
2526 ok(msg.hwnd == hwnd, "msg.hwnd = %p\n", msg.hwnd);
2527 got_button_up = TRUE;
2528 break;
2529 }
2530 }
2531 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2532 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2533
2534 hregion = CreateRectRgn(0, 0, 10, 10);
2535 ok(hregion != NULL, "CreateRectRgn failed\n");
2536 ret = SetWindowRgn(hwnd, hregion, TRUE);
2537 ok(ret, "SetWindowRgn failed\n");
2538 DeleteObject(hregion);
2540 Sleep(1000);
2541
2542 if (pGetWindowRgnBox)
2543 {
2544 region_type = pGetWindowRgnBox(hwnd, &region);
2545 ok(region_type == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", region_type);
2546 }
2547
2548 got_button_down = got_button_up = FALSE;
2549 simulate_click(TRUE, 150, 150);
2550 while (wait_for_message(&msg))
2551 {
2553
2554 if (msg.message == WM_LBUTTONDOWN)
2555 {
2556 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2557 got_button_down = TRUE;
2558 }
2559 else if (msg.message == WM_LBUTTONUP)
2560 {
2561 ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
2562 got_button_up = TRUE;
2563 break;
2564 }
2565 }
2566 ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
2567 ok(got_button_up, "expected WM_LBUTTONUP message\n");
2568
2569 DestroyWindow(static_win);
2571 SetCursorPos(pt_org.x, pt_org.y);
2572
2575 DestroyWindow(button_win);

Referenced by START_TEST().

◆ test_Input_unicode()

static void test_Input_unicode ( void  )
static

Definition at line 1178 of file input.c.

1180{
1181 WCHAR classNameW[] = {'I','n','p','u','t','U','n','i','c','o','d','e',
1182 'K','e','y','T','e','s','t','C','l','a','s','s',0};
1183 WCHAR windowNameW[] = {'I','n','p','u','t','U','n','i','c','o','d','e',
1184 'K','e','y','T','e','s','t',0};
1185 MSG msg;
1186 WNDCLASSW wclass;
1188 HHOOK hook;
1189 HMODULE hModuleImm32;
1190 BOOL (WINAPI *pImmDisableIME)(DWORD);
1191
1192 wclass.lpszClassName = classNameW;
1193 wclass.style = CS_HREDRAW | CS_VREDRAW;
1195 wclass.hInstance = hInstance;
1196 wclass.hIcon = LoadIconW(0, (LPCWSTR)IDI_APPLICATION);
1198 wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1199 wclass.lpszMenuName = 0;
1200 wclass.cbClsExtra = 0;
1201 wclass.cbWndExtra = 0;
1202 if(!RegisterClassW(&wclass)){
1203 win_skip("Unicode functions not supported\n");
1204 return;
1205 }
1206
1207 hModuleImm32 = LoadLibraryA("imm32.dll");
1208 if (hModuleImm32) {
1209 pImmDisableIME = (void *)GetProcAddress(hModuleImm32, "ImmDisableIME");
1210 if (pImmDisableIME)
1211 pImmDisableIME(0);
1212 }
1213 pImmDisableIME = NULL;
1214 FreeLibrary(hModuleImm32);
1215
1216 /* create the test window that will receive the keystrokes */
1217 hWndTest = CreateWindowW(wclass.lpszClassName, windowNameW,
1218 WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100,
1219 NULL, NULL, hInstance, NULL);
1220
1223
1225 if(!hook)
1226 win_skip("unable to set WH_KEYBOARD_LL hook\n");
1227
1232
1233 /* flush pending messages */
1234 while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageW(&msg);
1235
1237
1239
1240 if(hook)

Referenced by START_TEST().

◆ test_Input_whitebox()

static void test_Input_whitebox ( void  )
static

Definition at line 347 of file input.c.

349{
350 MSG msg;
351 WNDCLASSA wclass;
353
354 wclass.lpszClassName = "InputSysKeyTestClass";
355 wclass.style = CS_HREDRAW | CS_VREDRAW;
356 wclass.lpfnWndProc = WndProc;
357 wclass.hInstance = hInstance;
358 wclass.hIcon = LoadIconA( 0, (LPCSTR)IDI_APPLICATION );
360 wclass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
361 wclass.lpszMenuName = 0;
362 wclass.cbClsExtra = 0;
363 wclass.cbWndExtra = 0;
364 RegisterClassA( &wclass );
365 /* create the test window that will receive the keystrokes */
366 hWndTest = CreateWindowA( wclass.lpszClassName, "InputSysKeyTest",
369 assert( hWndTest );
374
375 /* flush pending messages */
376 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
377

Referenced by START_TEST().

◆ test_key_map()

static void test_key_map ( void  )
static

Definition at line 1703 of file input.c.

1705{
1706 HKL kl = GetKeyboardLayout(0);
1707 UINT kL, kR, s, sL;
1708 int i;
1709 static const UINT numpad_collisions[][2] = {
1710 { VK_NUMPAD0, VK_INSERT },
1711 { VK_NUMPAD1, VK_END },
1712 { VK_NUMPAD2, VK_DOWN },
1713 { VK_NUMPAD3, VK_NEXT },
1714 { VK_NUMPAD4, VK_LEFT },
1715 { VK_NUMPAD6, VK_RIGHT },
1716 { VK_NUMPAD7, VK_HOME },
1717 { VK_NUMPAD8, VK_UP },
1718 { VK_NUMPAD9, VK_PRIOR },
1719 };
1720
1722 ok(s != 0, "MapVirtualKeyEx(VK_SHIFT) should return non-zero\n");
1724 ok(s == sL || broken(sL == 0), /* win9x */
1725 "%x != %x\n", s, sL);
1726
1727 kL = MapVirtualKeyExA(0x2a, MAPVK_VSC_TO_VK, kl);
1728 ok(kL == VK_SHIFT, "Scan code -> vKey = %x (not VK_SHIFT)\n", kL);
1729 kR = MapVirtualKeyExA(0x36, MAPVK_VSC_TO_VK, kl);
1730 ok(kR == VK_SHIFT, "Scan code -> vKey = %x (not VK_SHIFT)\n", kR);
1731
1732 kL = MapVirtualKeyExA(0x2a, MAPVK_VSC_TO_VK_EX, kl);
1733 ok(kL == VK_LSHIFT || broken(kL == 0), /* win9x */
1734 "Scan code -> vKey = %x (not VK_LSHIFT)\n", kL);
1735 kR = MapVirtualKeyExA(0x36, MAPVK_VSC_TO_VK_EX, kl);
1736 ok(kR == VK_RSHIFT || broken(kR == 0), /* win9x */
1737 "Scan code -> vKey = %x (not VK_RSHIFT)\n", kR);
1738
1739 /* test that MAPVK_VSC_TO_VK prefers the non-numpad vkey if there's ambiguity */
1740 for (i = 0; i < ARRAY_SIZE(numpad_collisions); i++)
1741 {
1742 UINT numpad_scan = MapVirtualKeyExA(numpad_collisions[i][0], MAPVK_VK_TO_VSC, kl);
1743 UINT other_scan = MapVirtualKeyExA(numpad_collisions[i][1], MAPVK_VK_TO_VSC, kl);
1744
1745 /* do they really collide for this layout? */
1746 if (numpad_scan && other_scan == numpad_scan)
1747 {
1748 UINT vkey = MapVirtualKeyExA(numpad_scan, MAPVK_VSC_TO_VK, kl);
1749 ok(vkey != numpad_collisions[i][0],
1750 "Got numpad vKey %x for scan code %x when there was another choice\n",
1751 vkey, numpad_scan);
1752 }
1753 }

Referenced by START_TEST().

◆ test_key_names()

static void test_key_names ( void  )
static

Definition at line 1956 of file input.c.

1958{
1959 char buffer[40];
1960 WCHAR bufferW[40];
1961 int ret, prev;
1962 LONG lparam = 0x1d << 16;
1963
1964 memset( buffer, 0xcc, sizeof(buffer) );
1965 ret = GetKeyNameTextA( lparam, buffer, sizeof(buffer) );
1966 ok( ret > 0, "wrong len %u for '%s'\n", ret, buffer );
1967 ok( ret == strlen(buffer), "wrong len %u for '%s'\n", ret, buffer );
1968
1969 memset( buffer, 0xcc, sizeof(buffer) );
1970 prev = ret;
1971 ret = GetKeyNameTextA( lparam, buffer, prev );
1972 ok( ret == prev - 1, "wrong len %u for '%s'\n", ret, buffer );
1973 ok( ret == strlen(buffer), "wrong len %u for '%s'\n", ret, buffer );
1974
1975 memset( buffer, 0xcc, sizeof(buffer) );
1977 ok( ret == 0, "wrong len %u for '%s'\n", ret, buffer );
1978 ok( buffer[0] == 0, "wrong string '%s'\n", buffer );
1979
1980 memset( bufferW, 0xcc, sizeof(bufferW) );
1981 ret = GetKeyNameTextW( lparam, bufferW, ARRAY_SIZE(bufferW));
1982 ok( ret > 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1983 ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1984
1985 memset( bufferW, 0xcc, sizeof(bufferW) );
1986 prev = ret;
1987 ret = GetKeyNameTextW( lparam, bufferW, prev );
1988 ok( ret == prev - 1, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1989 ok( ret == lstrlenW(bufferW), "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1990
1991 memset( bufferW, 0xcc, sizeof(bufferW) );
1992 ret = GetKeyNameTextW( lparam, bufferW, 0 );
1993 ok( ret == 0, "wrong len %u for %s\n", ret, wine_dbgstr_w(bufferW) );
1994 ok( bufferW[0] == 0xcccc, "wrong string %s\n", wine_dbgstr_w(bufferW) );

Referenced by START_TEST().

◆ test_keyboard_layout_name()

static void test_keyboard_layout_name ( void  )
static

Definition at line 1935 of file input.c.

1937{
1938 BOOL ret;
1939 char klid[KL_NAMELENGTH];
1940
1941 if (0) /* crashes on native system */
1943
1944 SetLastError(0xdeadbeef);
1946 ok(!ret, "got %d\n", ret);
1947 ok(GetLastError() == ERROR_NOACCESS, "got %d\n", GetLastError());
1948
1949 if (GetKeyboardLayout(0) != (HKL)(ULONG_PTR)0x04090409) return;
1950
1951 klid[0] = 0;
1953 ok(ret, "GetKeyboardLayoutNameA failed %u\n", GetLastError());
1954 ok(!strcmp(klid, "00000409"), "expected 00000409, got %s\n", klid);

Referenced by START_TEST().

◆ test_keynames()

static void test_keynames ( void  )
static

Definition at line 1244 of file input.c.

1246{
1247 int i, len;
1248 char buff[256];
1249
1250 for (i = 0; i < 512; i++)
1251 {
1252 strcpy(buff, "----");
1253 len = GetKeyNameTextA(i << 16, buff, sizeof(buff));
1254 ok(len || !buff[0], "%d: Buffer is not zeroed\n", i);
1255 }

Referenced by START_TEST().

◆ test_mouse_ll_hook()

static void test_mouse_ll_hook ( void  )
static

Definition at line 1320 of file input.c.

1322{
1323 HWND hwnd;
1324 HHOOK hook1, hook2;
1325 POINT pt_org, pt;
1326 RECT rc;
1327
1328 GetCursorPos(&pt_org);
1329 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1330 10, 10, 200, 200, NULL, NULL, NULL, NULL);
1331 SetCursorPos(100, 100);
1332
1334 {
1335 win_skip( "cannot set MOUSE_LL hook\n" );
1336 goto done;
1337 }
1339
1341 mouse_event(MOUSEEVENTF_MOVE, -STEP, 0, 0, 0);
1343 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);
1344 mouse_event(MOUSEEVENTF_MOVE, +STEP, 0, 0, 0);
1346 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);
1347 mouse_event(MOUSEEVENTF_MOVE, 0, -STEP, 0, 0);
1349 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);
1350 mouse_event(MOUSEEVENTF_MOVE, 0, +STEP, 0, 0);
1352 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);
1353
1354 SetRect(&rc, 50, 50, 151, 151);
1355 ClipCursor(&rc);
1356 clipped = TRUE;
1357
1358 SetCursorPos(40, 40);
1360 ok(pt_old.x == 50 && pt_old.y == 50, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
1361 SetCursorPos(160, 160);
1363 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
1366 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
1367
1368 clipped = FALSE;
1369 pt_new.x = pt_new.y = 150;
1371 UnhookWindowsHookEx(hook1);
1372
1373 /* Now check that mouse buttons do not change mouse position
1374 if we don't have MOUSEEVENTF_MOVE flag specified. */
1375
1376 /* We reusing the same hook callback, so make it happy */
1377 pt_old.x = pt_new.x - STEP;
1378 pt_old.y = pt_new.y - STEP;
1379 mouse_event(MOUSEEVENTF_LEFTUP, 123, 456, 0, 0);
1380 GetCursorPos(&pt);
1381 ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1382 mouse_event(MOUSEEVENTF_RIGHTUP, 456, 123, 0, 0);
1383 GetCursorPos(&pt);
1384 ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1385
1387 GetCursorPos(&pt);
1388 ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1390 GetCursorPos(&pt);
1391 ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y);
1392
1393 UnhookWindowsHookEx(hook2);
1395
1396 SetRect(&rc, 150, 150, 150, 150);
1397 ClipCursor(&rc);
1398 clipped = TRUE;
1399
1400 SetCursorPos(140, 140);
1402 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1403 SetCursorPos(160, 160);
1405 todo_wine
1406 ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1409 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1412 todo_wine
1413 ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1414 mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0);
1416 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1417 mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0);
1419 todo_wine
1420 ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1421
1422 clipped = FALSE;
1424
1425 SetCursorPos(140, 140);
1426 SetRect(&rc, 150, 150, 150, 150);
1427 ClipCursor(&rc);
1429 ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1431
1432 SetCursorPos(160, 160);
1433 SetRect(&rc, 150, 150, 150, 150);
1434 ClipCursor(&rc);
1436 todo_wine
1437 ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1439
1440 SetCursorPos(150, 150);
1441 SetRect(&rc, 150, 150, 150, 150);
1442 ClipCursor(&rc);
1444 todo_wine
1445 ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
1447
1448 UnhookWindowsHookEx(hook1);
1449
1450done:
1452 SetCursorPos(pt_org.x, pt_org.y);

Referenced by START_TEST().

◆ test_OemKeyScan()

static void test_OemKeyScan ( void  )
static

Definition at line 2942 of file input.c.

2944{
2945 DWORD ret, expect, vkey, scan;
2946 WCHAR oem, wchr;
2947 char oem_char;
2948
2949 for (oem = 0; oem < 0x200; oem++)
2950 {
2951 ret = OemKeyScan( oem );
2952
2953 oem_char = LOBYTE( oem );
2954 /* OemKeyScan returns -1 for any character that cannot be mapped,
2955 * whereas OemToCharBuff changes unmappable characters to question
2956 * marks. The ASCII characters 0-127, including the real question mark
2957 * character, are all mappable and are the same in all OEM codepages. */
2958 if (!OemToCharBuffW( &oem_char, &wchr, 1 ) || (wchr == '?' && oem_char < 0))
2959 expect = -1;
2960 else
2961 {
2962 vkey = VkKeyScanW( wchr );
2963 scan = MapVirtualKeyW( LOBYTE( vkey ), MAPVK_VK_TO_VSC );
2964 if (!scan)
2965 expect = -1;
2966 else
2967 {
2968 vkey &= 0xff00;
2969 vkey <<= 8;
2970 expect = vkey | scan;
2971 }
2972 }
2973 ok( ret == expect, "%04x: got %08x expected %08x\n", oem, ret, expect );
2974 }

Referenced by START_TEST().

◆ test_ToAscii()

static void test_ToAscii ( void  )
static

Definition at line 1881 of file input.c.

1883{
1884 WORD character;
1885 BYTE state[256];
1886 const BYTE SC_RETURN = 0x1c, SC_A = 0x1e;
1887 const BYTE HIGHEST_BIT = 0x80;
1888 int ret;
1889
1890 memset(state, 0, sizeof(state));
1891
1892 character = 0;
1893 ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
1894 ok(ret == 1, "ToAscii for Return key didn't return 1 (was %i)\n", ret);
1895 ok(character == '\r', "ToAscii for Return was %i (expected 13)\n", character);
1896
1897 character = 0;
1898 ret = ToAscii('A', SC_A, state, &character, 0);
1899 ok(ret == 1, "ToAscii for character 'A' didn't return 1 (was %i)\n", ret);
1900 ok(character == 'a', "ToAscii for character 'A' was %i (expected %i)\n", character, 'a');
1901
1902 state[VK_CONTROL] |= HIGHEST_BIT;
1903 state[VK_LCONTROL] |= HIGHEST_BIT;
1904 character = 0;
1905 ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
1906 ok(ret == 1, "ToAscii for CTRL + Return key didn't return 1 (was %i)\n", ret);
1907 ok(character == '\n', "ToAscii for CTRL + Return was %i (expected 10)\n", character);
1908
1909 character = 0;
1910 ret = ToAscii('A', SC_A, state, &character, 0);
1911 ok(ret == 1, "ToAscii for CTRL + character 'A' didn't return 1 (was %i)\n", ret);
1912 ok(character == 1, "ToAscii for CTRL + character 'A' was %i (expected 1)\n", character);
1913
1914 state[VK_SHIFT] |= HIGHEST_BIT;
1915 state[VK_LSHIFT] |= HIGHEST_BIT;
1916 ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
1917 ok(ret == 0, "ToAscii for CTRL + Shift + Return key didn't return 0 (was %i)\n", ret);
1918
1919 ret = ToAscii(VK_RETURN, SC_RETURN, NULL, &character, 0);
1920 ok(ret == 0, "ToAscii for NULL keystate didn't return 0 (was %i)\n", ret);
1921 ret = ToAscii('A', SC_A, NULL, &character, 0);
1922 ok(ret == 0, "ToAscii for NULL keystate didn't return 0 (was %i)\n", ret);
1923 ret = ToAsciiEx(VK_RETURN, SC_RETURN, NULL, &character, 0, GetKeyboardLayout(0));
1924 ok(ret == 0, "ToAsciiEx for NULL keystate didn't return 0 (was %i)\n", ret);
1925 ret = ToAsciiEx('A', SC_A, NULL, &character, 0, GetKeyboardLayout(0));
1926 ok(ret == 0, "ToAsciiEx for NULL keystate didn't return 0 (was %i)\n", ret);

Referenced by START_TEST().

◆ test_ToUnicode()

static void test_ToUnicode ( void  )
static

Definition at line 1808 of file input.c.

1810{
1811 WCHAR wStr[4];
1812 BYTE state[256];
1813 const BYTE SC_RETURN = 0x1c, SC_TAB = 0x0f, SC_A = 0x1e;
1814 const BYTE HIGHEST_BIT = 0x80;
1815 int i, ret;
1816 BOOL us_kbd = (GetKeyboardLayout(0) == (HKL)(ULONG_PTR)0x04090409);
1817
1818 for(i=0; i<256; i++)
1819 state[i]=0;
1820
1821 wStr[1] = 0xAA;
1822 SetLastError(0xdeadbeef);
1823 ret = ToUnicode(VK_RETURN, SC_RETURN, state, wStr, 4, 0);
1825 {
1826 win_skip("ToUnicode is not implemented\n");
1827 return;
1828 }
1829
1830 ok(ret == 1, "ToUnicode for Return key didn't return 1 (was %i)\n", ret);
1831 if(ret == 1)
1832 {
1833 ok(wStr[0]=='\r', "ToUnicode for CTRL + Return was %i (expected 13)\n", wStr[0]);
1834 ok(wStr[1]==0 || broken(wStr[1]!=0) /* nt4 */,
1835 "ToUnicode didn't null-terminate the buffer when there was room.\n");
1836 }
1837
1838 for (i = 0; i < ARRAY_SIZE(utests); i++)
1839 {
1840 UINT vk = utests[i].vk, mod = utests[i].modifiers, scan;
1841
1842 if(!vk)
1843 {
1844 short vk_ret;
1845
1846 if (!us_kbd) continue;
1847 vk_ret = VkKeyScanW(utests[i].chr);
1848 if (vk_ret == -1) continue;
1849 vk = vk_ret & 0xff;
1850 if (vk_ret & 0x100) mod |= shift;
1851 if (vk_ret & 0x200) mod |= ctrl;
1852 }
1854
1855 state[VK_SHIFT] = state[VK_LSHIFT] = (mod & shift) ? HIGHEST_BIT : 0;
1856 state[VK_CONTROL] = state[VK_LCONTROL] = (mod & ctrl) ? HIGHEST_BIT : 0;
1857
1858 ret = ToUnicode(vk, scan, state, wStr, 4, 0);
1859 ok(ret == utests[i].expect_ret, "%d: got %d expected %d\n", i, ret, utests[i].expect_ret);
1860 if (ret)
1861 ok(!lstrcmpW(wStr, utests[i].expect_buf), "%d: got %s expected %s\n", i, wine_dbgstr_w(wStr),
1862 wine_dbgstr_w(utests[i].expect_buf));
1863
1864 }
1865 state[VK_SHIFT] = state[VK_LSHIFT] = 0;
1867
1868 ret = ToUnicode(VK_TAB, SC_TAB, NULL, wStr, 4, 0);
1869 ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
1870 ret = ToUnicode(VK_RETURN, SC_RETURN, NULL, wStr, 4, 0);
1871 ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
1872 ret = ToUnicode('A', SC_A, NULL, wStr, 4, 0);
1873 ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
1874 ret = ToUnicodeEx(VK_TAB, SC_TAB, NULL, wStr, 4, 0, GetKeyboardLayout(0));
1875 ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
1876 ret = ToUnicodeEx(VK_RETURN, SC_RETURN, NULL, wStr, 4, 0, GetKeyboardLayout(0));
1877 ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
1878 ret = ToUnicodeEx('A', SC_A, NULL, wStr, 4, 0, GetKeyboardLayout(0));
1879 ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);

Referenced by START_TEST().

◆ test_unicode_keys()

static void test_unicode_keys ( HWND  hwnd,
HHOOK  hook 
)
static

Definition at line 986 of file input.c.

988{
989 TEST_INPUT inputs[2];
990 MSG msg;
991
992 /* init input data that never changes */
993 inputs[1].type = inputs[0].type = INPUT_KEYBOARD;
994 inputs[1].u.ki.dwExtraInfo = inputs[0].u.ki.dwExtraInfo = 0;
995 inputs[1].u.ki.time = inputs[0].u.ki.time = 0;
996
997 /* pressing & releasing a single unicode character */
998 inputs[0].u.ki.wVk = 0;
999 inputs[0].u.ki.wScan = 0x3c0;
1000 inputs[0].u.ki.dwFlags = KEYEVENTF_UNICODE;
1001
1002 reset_key_status(VK_PACKET);
1003 SendInput(1, (INPUT*)inputs, sizeof(INPUT));
1004 while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1005 if(msg.message == WM_KEYDOWN && msg.wParam == VK_PACKET){
1007 }
1009 }
1010 if(!key_status.sendinput_broken){
1011 ok(key_status.last_key_down == VK_PACKET,
1012 "Last keydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_down);
1013 ok(key_status.last_char == 0x3c0,
1014 "Last char msg wparam should have been 0x3c0 (was: 0x%x)\n", key_status.last_char);
1015 if(hook)
1016 ok(key_status.last_hook_down == 0x3c0,
1017 "Last hookdown msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_down);
1018 }
1019
1020 inputs[1].u.ki.wVk = 0;
1021 inputs[1].u.ki.wScan = 0x3c0;
1022 inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
1023
1024 reset_key_status(VK_PACKET);
1025 SendInput(1, (INPUT*)(inputs+1), sizeof(INPUT));
1026 while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1027 if(msg.message == WM_KEYDOWN && msg.wParam == VK_PACKET){
1029 }
1031 }
1032 if(!key_status.sendinput_broken){
1033 ok(key_status.last_key_up == VK_PACKET,
1034 "Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up);
1035 if(hook)
1036 ok(key_status.last_hook_up == 0x3c0,
1037 "Last hookup msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_up);
1038 }
1039
1040 /* holding alt, pressing & releasing a unicode character, releasing alt */
1041 inputs[0].u.ki.wVk = VK_LMENU;
1042 inputs[0].u.ki.wScan = 0;
1043 inputs[0].u.ki.dwFlags = 0;
1044
1045 inputs[1].u.ki.wVk = 0;
1046 inputs[1].u.ki.wScan = 0x3041;
1047 inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE;
1048
1049 reset_key_status(VK_PACKET);
1050 key_status.expect_alt = TRUE;
1051 SendInput(2, (INPUT*)inputs, sizeof(INPUT));
1052 while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1053 if(msg.message == WM_SYSKEYDOWN && msg.wParam == VK_PACKET){
1055 }
1057 }
1058 if(!key_status.sendinput_broken){
1059 ok(key_status.last_syskey_down == VK_PACKET,
1060 "Last syskeydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_syskey_down);
1061 ok(key_status.last_syschar == 0x3041,
1062 "Last syschar msg should have been 0x3041 (was: 0x%x)\n", key_status.last_syschar);
1063 if(hook)
1064 ok(key_status.last_hook_syskey_down == 0x3041,
1065 "Last hooksysdown msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_syskey_down);
1066 }
1067
1068 inputs[1].u.ki.wVk = 0;
1069 inputs[1].u.ki.wScan = 0x3041;
1070 inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
1071
1072 inputs[0].u.ki.wVk = VK_LMENU;
1073 inputs[0].u.ki.wScan = 0;
1074 inputs[0].u.ki.dwFlags = KEYEVENTF_KEYUP;
1075
1076 reset_key_status(VK_PACKET);
1077 key_status.expect_alt = TRUE;
1078 SendInput(2, (INPUT*)inputs, sizeof(INPUT));
1079 while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
1080 if(msg.message == WM_SYSKEYDOWN && msg.wParam == VK_PACKET){
1082 }
1084 }
1085 if(!key_status.sendinput_broken){
1086 ok(key_status.last_key_up == VK_PACKET,
1087 "Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up);
1088 if(hook)
1089 ok(key_status.last_hook_up == 0x3041,
1090 "Last hook up msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_up);
1091 }
1092
1093 /* Press and release, non-zero key code. */
1094 inputs[0].u.ki.wVk = 0x51;
1095 inputs[0].u.ki.wScan = 0x123;
1096 inputs[0].u.ki.dwFlags = KEYEVENTF_UNICODE;
1097
1098 inputs[1].u.ki.wVk = 0x51;
1099 inputs[1].u.ki.wScan = 0x123;
1100 inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
1101
1102 reset_key_status(inputs[0].u.ki.wVk);
1103 SendInput(2, (INPUT*)inputs, sizeof(INPUT));
1104 while (PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE))
1105 {
1108 }
1109
1110 if (!key_status.sendinput_broken)
1111 {
1112 ok(key_status.last_key_down == 0x51, "Unexpected key down %#x.\n", key_status.last_key_down);
1113 ok(key_status.last_key_up == 0x51, "Unexpected key up %#x.\n", key_status.last_key_up);
1114 if (hook)
1115 todo_wine
1116 ok(key_status.last_hook_up == 0x23, "Unexpected hook message %#x.\n", key_status.last_hook_up);
1117 }

Referenced by test_Input_unicode().

◆ TestASet()

static BOOL TestASet ( HWND  hWnd,
int  nrkev,
const KEV  kevdwn[],
const KEV  kevup[] 
)
static

Definition at line 285 of file input.c.

287{
288 int i,j,k,l,m,n;
289 static int count=0;
290 KEV kbuf[MAXKEYEVENTS];
291 assert( nrkev==2 || nrkev==3);
292 for(i=0;i<MAXKEYEVENTS;i++) kbuf[i]=0;
293 /* two keys involved gives 4 test cases */
294 if(nrkev==2) {
295 for(i=0;i<nrkev;i++) {
296 for(j=0;j<nrkev;j++) {
297 kbuf[0] = kevdwn[i];
298 kbuf[1] = kevdwn[1-i];
299 kbuf[2] = kevup[j];
300 kbuf[3] = kevup[1-j];
301 if (!do_test( hWnd, count++, kbuf)) return FALSE;
302 }
303 }
304 }
305 /* three keys involved gives 36 test cases */
306 if(nrkev==3){
307 for(i=0;i<nrkev;i++){
308 for(j=0;j<nrkev;j++){
309 if(j==i) continue;
310 for(k=0;k<nrkev;k++){
311 if(k==i || k==j) continue;
312 for(l=0;l<nrkev;l++){
313 for(m=0;m<nrkev;m++){
314 if(m==l) continue;
315 for(n=0;n<nrkev;n++){
316 if(n==l ||n==m) continue;
317 kbuf[0] = kevdwn[i];
318 kbuf[1] = kevdwn[j];
319 kbuf[2] = kevdwn[k];
320 kbuf[3] = kevup[l];
321 kbuf[4] = kevup[m];
322 kbuf[5] = kevup[n];
323 if (!do_test( hWnd, count++, kbuf)) return FALSE;
324 }
325 }
326 }
327 }
328 }
329 }
330 }
331 return TRUE;

Referenced by TestSysKeys().

◆ TestSysKeys()

static void TestSysKeys ( HWND  hWnd)
static

Definition at line 334 of file input.c.

336{
337 int i;
338 for(i=0; testkeyset[i].nrkev;i++)

Referenced by test_Input_whitebox().

◆ thread_proc()

static DWORD WINAPI thread_proc ( void param)
static

Definition at line 2599 of file input.c.

2601{
2602 MSG msg;
2603 struct wnd_event *wnd_event = param;
2604 BOOL ret;
2605
2606 if (wnd_event->wait_event)
2607 {
2609 "WaitForSingleObject failed\n");
2611 }
2612
2614 {
2616 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2617 }
2618
2619 if (wnd_event->attach_to)
2620 {
2622 ok(ret, "AttachThreadInput error %d\n", GetLastError());
2623 }
2624
2625 wnd_event->hwnd = CreateWindowExA(0, "TestWindowClass", "window caption text", WS_OVERLAPPEDWINDOW,
2626 100, 100, 200, 200, 0, 0, 0, NULL);
2627 ok(wnd_event->hwnd != 0, "Failed to create overlapped window\n");
2628
2629 if (wnd_event->setWindows)
2630 {
2633 }
2634
2636
2637 while (GetMessageA(&msg, 0, 0, 0))
2638 {
2641 }
2642
2643 return 0;

Referenced by test_attach_input().

◆ UINT()

static UINT ( WINAPI pGetRawInputDeviceList)
static

◆ unicode_wnd_proc()

static LRESULT CALLBACK unicode_wnd_proc ( HWND  hWnd,
UINT  msg,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 1119 of file input.c.

1122{
1123 switch(msg){
1124 case WM_KEYDOWN:
1125 key_status.last_key_down = wParam;
1126 break;
1127 case WM_SYSKEYDOWN:
1128 key_status.last_syskey_down = wParam;
1129 break;
1130 case WM_KEYUP:
1131 key_status.last_key_up = wParam;
1132 break;
1133 case WM_SYSKEYUP:
1134 key_status.last_syskey_up = wParam;
1135 break;
1136 case WM_CHAR:
1137 key_status.last_char = wParam;
1138 break;
1139 case WM_SYSCHAR:
1140 key_status.last_syschar = wParam;
1141 break;
1142 }
1143 return DefWindowProcW(hWnd, msg, wParam, lParam);

Referenced by test_Input_unicode().

◆ wait_for_event()

static BOOL wait_for_event ( HANDLE  event,
int  timeout 
)
static

Definition at line 2033 of file input.c.

2035{
2036 DWORD end_time = GetTickCount() + timeout;
2037 MSG msg;
2038
2039 do {
2041 return TRUE;
2042 while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2044 timeout = end_time - GetTickCount();
2045 }while(timeout > 0);
2046
2047 return FALSE;

Referenced by create_static_win().

◆ wait_for_message()

static BOOL wait_for_message ( MSG msg)
static

Definition at line 2015 of file input.c.

2017{
2018 BOOL ret;
2019
2020 for (;;)
2021 {
2022 ret = PeekMessageA(msg, 0, 0, 0, PM_REMOVE);
2023 if (ret)
2024 {
2025 if (msg->message == WM_PAINT) DispatchMessageA(msg);
2026 else break;
2027 }
2028 else if (MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLINPUT) == WAIT_TIMEOUT) break;
2029 }
2030 if (!ret) msg->message = 0;
2031 return ret;

Referenced by test_Input_mouse().

◆ WndProc()

static LRESULT CALLBACK WndProc ( HWND  hWnd,
UINT  msg,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 341 of file input.c.

344{
345 return DefWindowProcA( hWnd, msg, wParam, lParam );

Referenced by test_Input_mouse(), and test_Input_whitebox().

◆ WndProc2()

static LRESULT CALLBACK WndProc2 ( HWND  hWnd,
UINT  Msg,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 863 of file input.c.

866{
867 if (winetest_debug > 1) trace("MSG: %8x W:%8lx L:%8lx\n", Msg, wParam, lParam);
868
869 if ((Msg >= WM_KEYFIRST && Msg <= WM_KEYLAST) || Msg == WM_SYSCOMMAND)
870 {
871 ok(sent_messages_cnt < MAXKEYMESSAGES, "Too many messages\n");
873 {
878 }
879 }

Variable Documentation

◆ AsyncKeyStateTable

BYTE AsyncKeyStateTable[256]
static

Definition at line 147 of file input.c.

Referenced by KbdMessage().

◆ clipped

BOOL clipped
static

Definition at line 1258 of file input.c.

Referenced by hook_proc1(), hook_proc2(), test_mouse_ll_hook(), and wined3d_clip_blit().

◆ def_static_proc

WNDPROC def_static_proc
static

Definition at line 2049 of file input.c.

Referenced by create_static_win(), static_hook_proc(), and test_Input_mouse().

◆ DWORD

POINTER_INPUT_TYPE *static DWORD

Definition at line 84 of file input.c.

Referenced by test_Input_unicode().

◆ expect_alt

BOOL expect_alt

Definition at line 78 of file input.c.

◆ expect_src

INPUT_MESSAGE_SOURCE expect_src
static

Definition at line 2976 of file input.c.

Referenced by msg_source_proc(), and test_input_message_source().

◆ getdesc

const char* getdesc[] ={"", "+alt","-alt","+X","-X","+shift","-shift","+ctrl","-ctrl"}
static

Definition at line 107 of file input.c.

Referenced by do_test().

◆ GETFLAGS

const int GETFLAGS[] ={0, 0, KEYEVENTF_KEYUP, 0, KEYEVENTF_KEYUP, 0, KEYEVENTF_KEYUP, 0, KEYEVENTF_KEYUP}
static

Definition at line 105 of file input.c.

Referenced by do_test(), and KbdMessage().

◆ GETSCAN

const int GETSCAN[] ={0, 0x38, 0x38, 0x2D, 0x2D, 0x2A, 0x2A, 0x1D, 0x1D }
static

Definition at line 103 of file input.c.

Referenced by do_test(), and KbdMessage().

◆ GETVKEY

const int GETVKEY[] ={0, VK_MENU, VK_MENU, 'X', 'X', VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL}
static

Definition at line 101 of file input.c.

Referenced by do_test(), and KbdMessage().

◆ hittest_no

DWORD hittest_no
static

Definition at line 2050 of file input.c.

Referenced by static_hook_proc(), and test_Input_mouse().

◆ hWndTest

HWND hWndTest
static

◆ InputKeyStateTable

BYTE InputKeyStateTable[256]
static

Definition at line 146 of file input.c.

Referenced by KbdMessage().

◆ int

POINTER_INPUT_TYPE *static int

Definition at line 84 of file input.c.

◆ 

struct { ... } key_status

◆ keydwn

KEV keydwn[MAXKEYEVENTS]

Definition at line 134 of file input.c.

Referenced by TestSysKeys().

◆ keyup

KEV keyup[MAXKEYEVENTS]

Definition at line 135 of file input.c.

Referenced by TestSysKeys().

◆ last_char

LONG last_char

Definition at line 71 of file input.c.

Referenced by test_bitmap_font_metrics().

◆ last_hook_down

LONG last_hook_down

Definition at line 73 of file input.c.

◆ last_hook_syskey_down

LONG last_hook_syskey_down

Definition at line 75 of file input.c.

◆ last_hook_syskey_up

LONG last_hook_syskey_up

Definition at line 76 of file input.c.

◆ last_hook_up

LONG last_hook_up

Definition at line 74 of file input.c.

◆ last_key_down

LONG last_key_down

Definition at line 67 of file input.c.

◆ last_key_up

LONG last_key_up

Definition at line 68 of file input.c.

◆ last_syschar

LONG last_syschar

Definition at line 72 of file input.c.

◆ last_syskey_down

LONG last_syskey_down

Definition at line 69 of file input.c.

◆ last_syskey_up

LONG last_syskey_up

Definition at line 70 of file input.c.

◆ LPMOUSEMOVEPOINT

static POINTER_INPUT_TYPE *static LPMOUSEMOVEPOINT

Definition at line 84 of file input.c.

◆ LPRECT

void UINT *static void UINT *static LPRECT

Definition at line 88 of file input.c.

◆ MSGNAME

const char* MSGNAME[]
static
Initial value:
={"WM_KEYDOWN", "WM_KEYUP", "WM_CHAR","WM_DEADCHAR",
"WM_SYSKEYDOWN", "WM_SYSKEYUP", "WM_SYSCHAR", "WM_SYSDEADCHAR" ,"WM_KEYLAST"}

Definition at line 94 of file input.c.

Referenced by do_test().

◆ nrkev

int nrkev

Definition at line 133 of file input.c.

Referenced by TestASet(), and TestSysKeys().

◆ pt_new

POINT pt_new
static

Definition at line 1257 of file input.c.

Referenced by hook_proc1(), hook_proc2(), and test_mouse_ll_hook().

◆ pt_old

POINT pt_old
static

Definition at line 1257 of file input.c.

Referenced by hook_proc1(), hook_proc2(), hook_proc3(), and test_mouse_ll_hook().

◆ PUINT

Definition at line 85 of file input.c.

◆ sendinput_broken

BOOL sendinput_broken

Definition at line 79 of file input.c.

◆ sendinput_test

const struct sendinput_test_s sendinput_test[]
static

◆ sent_messages

struct message sent_messages[MAXKEYMESSAGES]
static

Definition at line 697 of file input.c.

Referenced by compare_and_check(), hook_proc(), and WndProc2().

◆ sent_messages_cnt

UINT sent_messages_cnt
static

Definition at line 698 of file input.c.

Referenced by compare_and_check(), hook_proc(), and WndProc2().

◆ 

const struct { ... } testkeyset[]
Initial value:
= {
{ 2, { ALTDOWN, XDOWN }, { ALTUP, XUP}},
{ 3, { ALTDOWN, XDOWN , SHIFTDOWN}, { ALTUP, XUP, SHIFTUP}},
{ 3, { ALTDOWN, XDOWN , CTRLDOWN}, { ALTUP, XUP, CTRLUP}},
{ 0 }
}

Referenced by TestSysKeys().

◆ timetag

LONG timetag = 0x10000000
static

Definition at line 64 of file input.c.

Referenced by do_test().

◆ TrackSysKey

BYTE TrackSysKey = 0
static

Definition at line 148 of file input.c.

Referenced by do_test(), and KbdMessage().

◆ UINT

void UINT *static UINT

Definition at line 85 of file input.c.

◆ utests

const struct tounicode_tests utests[]
static

Referenced by test_ToUnicode().

◆ vk