This marks one test case as todo, but it was an outlier, and the 'X' key state is now wrong in all cases. Overall this makes the tests results more coherent.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=26269 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=27238 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=31899 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=35907 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45385 Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
This series aims at implementing the GetKeyState details properly, it passes all the current tests, and fixes the issues above.
Some cases such as thread input attach proved hard to test, especially with current Wine window focus handling, and have been implemented by trying to do what made sense instead.
dlls/user32/tests/input.c | 52 +++++++++++++++++++-------------------- server/queue.c | 3 ++- 2 files changed, 28 insertions(+), 27 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 63163b7ed01..c146e4b5cd9 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -3761,8 +3761,8 @@ struct get_key_state_thread_params int index; };
-#define check_get_keyboard_state(i, j, c, x, todo_c, todo_x) check_get_keyboard_state_(i, j, c, x, todo_c, todo_x, __LINE__) -static void check_get_keyboard_state_(int i, int j, int c, int x, int todo_c, int todo_x, int line) +#define check_get_keyboard_state(i, j, c, x, todo_x) check_get_keyboard_state_(i, j, c, x, todo_x, __LINE__) +static void check_get_keyboard_state_(int i, int j, int c, int x, int todo_x, int line) { unsigned char keystate[256]; BOOL ret; @@ -3771,18 +3771,18 @@ static void check_get_keyboard_state_(int i, int j, int c, int x, int todo_c, in ret = GetKeyboardState(keystate); ok_(__FILE__, line)(ret, "GetKeyboardState failed, %u\n", GetLastError()); todo_wine_if(todo_x) ok_(__FILE__, line)(!(keystate['X'] & 0x80) == !x, "%d:%d: expected that X keystate is %s\n", i, j, x ? "set" : "unset"); - todo_wine_if(todo_c) ok_(__FILE__, line)(!(keystate['C'] & 0x80) == !c, "%d:%d: expected that C keystate is %s\n", i, j, c ? "set" : "unset"); + ok_(__FILE__, line)(!(keystate['C'] & 0x80) == !c, "%d:%d: expected that C keystate is %s\n", i, j, c ? "set" : "unset");
/* calling it twice shouldn't change */ memset(keystate, 0, sizeof(keystate)); ret = GetKeyboardState(keystate); ok_(__FILE__, line)(ret, "GetKeyboardState failed, %u\n", GetLastError()); todo_wine_if(todo_x) ok_(__FILE__, line)(!(keystate['X'] & 0x80) == !x, "%d:%d: expected that X keystate is %s\n", i, j, x ? "set" : "unset"); - todo_wine_if(todo_c) ok_(__FILE__, line)(!(keystate['C'] & 0x80) == !c, "%d:%d: expected that C keystate is %s\n", i, j, c ? "set" : "unset"); + ok_(__FILE__, line)(!(keystate['C'] & 0x80) == !c, "%d:%d: expected that C keystate is %s\n", i, j, c ? "set" : "unset"); }
-#define check_get_key_state(i, j, c, x, todo_c, todo_x) check_get_key_state_(i, j, c, x, todo_c, todo_x, __LINE__) -static void check_get_key_state_(int i, int j, int c, int x, int todo_c, int todo_x, int line) +#define check_get_key_state(i, j, c, x, todo_x) check_get_key_state_(i, j, c, x, todo_x, __LINE__) +static void check_get_key_state_(int i, int j, int c, int x, int todo_x, int line) { SHORT state;
@@ -3791,7 +3791,7 @@ static void check_get_key_state_(int i, int j, int c, int x, int todo_c, int tod ok_(__FILE__, line)(!(state & 0x007e), "%d:%d: expected that X undefined bits are unset, got %#x\n", i, j, state);
state = GetKeyState('C'); - todo_wine_if(todo_c) ok_(__FILE__, line)(!(state & 0x8000) == !c, "%d:%d: expected that C highest bit is %s, got %#x\n", i, j, c ? "set" : "unset", state); + ok_(__FILE__, line)(!(state & 0x8000) == !c, "%d:%d: expected that C highest bit is %s, got %#x\n", i, j, c ? "set" : "unset", state); ok_(__FILE__, line)(!(state & 0x007e), "%d:%d: expected that C undefined bits are unset, got %#x\n", i, j, state); }
@@ -3808,7 +3808,7 @@ static DWORD WINAPI get_key_state_thread(void *arg) int i = params->index, j;
test = get_key_state_tests + i; - has_queue = test->peek_message; + has_queue = test->peek_message || test->set_keyboard_state;
if (test->peek_message) { @@ -3841,18 +3841,18 @@ static DWORD WINAPI get_key_state_thread(void *arg) if (test->set_keyboard_state) expect_c = TRUE; else expect_c = FALSE;
- check_get_keyboard_state(i, j, expect_c, FALSE, /* todo */ i == 6, !has_queue); - check_get_key_state(i, j, expect_c, expect_x, /* todo */ i == 6, i != 6 && (has_queue || j == 0)); - check_get_keyboard_state(i, j, expect_c, expect_x, /* todo */ i == 6, i != 6 && (has_queue || j == 0)); + check_get_keyboard_state(i, j, expect_c, FALSE, /* todo */ !has_queue); + check_get_key_state(i, j, expect_c, expect_x, /* todo */ has_queue || j == 0); + check_get_keyboard_state(i, j, expect_c, expect_x, /* todo */ has_queue || j == 0);
/* key released */ ReleaseSemaphore(semaphores[0], 1, NULL); result = WaitForSingleObject(semaphores[1], 1000); ok(result == WAIT_OBJECT_0, "%d: WaitForSingleObject returned %u\n", i, result);
- check_get_keyboard_state(i, j, expect_c, expect_x, /* todo */ i == 6, has_queue || i == 6 || j > 0); - check_get_key_state(i, j, expect_c, FALSE, /* todo */ i == 6, FALSE); - check_get_keyboard_state(i, j, expect_c, FALSE, /* todo */ i == 6, FALSE); + check_get_keyboard_state(i, j, expect_c, expect_x, /* todo */ has_queue || j > 0); + check_get_key_state(i, j, expect_c, FALSE, /* todo */ FALSE); + check_get_keyboard_state(i, j, expect_c, FALSE, /* todo */ FALSE); }
return 0; @@ -3920,18 +3920,18 @@ static void test_GetKeyState(void) } else expect_c = FALSE;
- check_get_keyboard_state(i, j, expect_c, FALSE, /* todo */ FALSE, FALSE); - check_get_key_state(i, j, expect_c, FALSE, /* todo */ FALSE, FALSE); - check_get_keyboard_state(i, j, expect_c, FALSE, /* todo */ FALSE, FALSE); + check_get_keyboard_state(i, j, expect_c, FALSE, /* todo */ FALSE); + check_get_key_state(i, j, expect_c, FALSE, /* todo */ FALSE); + check_get_keyboard_state(i, j, expect_c, FALSE, /* todo */ FALSE);
if (test->peek_message_main) while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
if (test->peek_message_main) expect_x = TRUE; else expect_x = FALSE;
- check_get_keyboard_state(i, j, expect_c, expect_x, /* todo */ FALSE, FALSE); - check_get_key_state(i, j, expect_c, expect_x, /* todo */ FALSE, FALSE); - check_get_keyboard_state(i, j, expect_c, expect_x, /* todo */ FALSE, FALSE); + check_get_keyboard_state(i, j, expect_c, expect_x, /* todo */ FALSE); + check_get_key_state(i, j, expect_c, expect_x, /* todo */ FALSE); + check_get_keyboard_state(i, j, expect_c, expect_x, /* todo */ FALSE);
ReleaseSemaphore(params.semaphores[1], 1, NULL);
@@ -3947,15 +3947,15 @@ static void test_GetKeyState(void) SetKeyboardState(keystate); }
- check_get_keyboard_state(i, j, FALSE, expect_x, /* todo */ FALSE, FALSE); - check_get_key_state(i, j, FALSE, expect_x, /* todo */ FALSE, FALSE); - check_get_keyboard_state(i, j, FALSE, expect_x, /* todo */ FALSE, FALSE); + check_get_keyboard_state(i, j, FALSE, expect_x, /* todo */ FALSE); + check_get_key_state(i, j, FALSE, expect_x, /* todo */ FALSE); + check_get_keyboard_state(i, j, FALSE, expect_x, /* todo */ FALSE);
if (test->peek_message_main) while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
- check_get_keyboard_state(i, j, FALSE, FALSE, /* todo */ FALSE, FALSE); - check_get_key_state(i, j, FALSE, FALSE, /* todo */ FALSE, FALSE); - check_get_keyboard_state(i, j, FALSE, FALSE, /* todo */ FALSE, FALSE); + check_get_keyboard_state(i, j, FALSE, FALSE, /* todo */ FALSE); + check_get_key_state(i, j, FALSE, FALSE, /* todo */ FALSE); + check_get_keyboard_state(i, j, FALSE, FALSE, /* todo */ FALSE);
ReleaseSemaphore(params.semaphores[1], 1, NULL); } diff --git a/server/queue.c b/server/queue.c index b026c03e13d..5c9f91a13c5 100644 --- a/server/queue.c +++ b/server/queue.c @@ -3007,9 +3007,10 @@ DECL_HANDLER(get_key_state) DECL_HANDLER(set_key_state) { struct desktop *desktop; + struct msg_queue *queue = get_current_queue(); data_size_t size = min( 256, get_req_data_size() );
- if (current->queue) memcpy( current->queue->input->keystate, get_req_data(), size ); + memcpy( queue->input->keystate, get_req_data(), size ); if (req->async && (desktop = get_thread_desktop( current, 0 ))) { memcpy( desktop->keystate, get_req_data(), size );