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 );
And synchronize it with desktop async keystate, on GetKeyState calls, if it is not locked yet.
Based on a patch from Sebastian Lackner sebastian@fds-team.de.
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 --- dlls/user32/tests/input.c | 6 ++--- server/queue.c | 51 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index c146e4b5cd9..246569961be 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -3842,15 +3842,15 @@ static DWORD WINAPI get_key_state_thread(void *arg) else expect_c = FALSE;
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); + 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 */ has_queue || j > 0); + 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); } diff --git a/server/queue.c b/server/queue.c index 5c9f91a13c5..0782c526327 100644 --- a/server/queue.c +++ b/server/queue.c @@ -114,6 +114,8 @@ struct thread_input int cursor_count; /* cursor show count */ struct list msg_list; /* list of hardware messages */ unsigned char keystate[256]; /* state of each key */ + unsigned char desktop_keystate[256]; /* desktop keystate when keystate was synced */ + int keystate_lock; /* keystate is locked */ };
struct msg_queue @@ -140,6 +142,7 @@ struct msg_queue struct thread_input *input; /* thread input descriptor */ struct hook_table *hooks; /* hook table */ timeout_t last_get_msg; /* time of last get message call */ + int keystate_lock; /* owns an input keystate lock */ };
struct hotkey @@ -265,12 +268,14 @@ static struct thread_input *create_thread_input( struct thread *thread ) list_init( &input->msg_list ); set_caret_window( input, 0 ); memset( input->keystate, 0, sizeof(input->keystate) ); + input->keystate_lock = 0;
if (!(input->desktop = get_thread_desktop( thread, 0 /* FIXME: access rights */ ))) { release_object( input ); return NULL; } + memcpy( input->desktop_keystate, input->desktop->keystate, sizeof(input->desktop_keystate) ); } return input; } @@ -305,6 +310,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_ queue->input = (struct thread_input *)grab_object( input ); queue->hooks = NULL; queue->last_get_msg = current_time; + queue->keystate_lock = 0; list_init( &queue->send_result ); list_init( &queue->callback_result ); list_init( &queue->pending_timers ); @@ -326,6 +332,31 @@ void free_msg_queue( struct thread *thread ) thread->queue = NULL; }
+/* synchronize thread input keystate with the desktop */ +static void sync_input_keystate( struct thread_input *input ) +{ + int i; + if (!input->desktop || input->keystate_lock) return; + for (i = 0; i < sizeof(input->keystate); ++i) + { + if (input->desktop_keystate[i] == input->desktop->keystate[i]) continue; + input->keystate[i] = input->desktop_keystate[i] = input->desktop->keystate[i]; + } +} + +/* locks thread input keystate to prevent synchronization */ +static void lock_input_keystate( struct thread_input *input ) +{ + input->keystate_lock++; +} + +/* unlock the thread input keystate and synchronize it again */ +static void unlock_input_keystate( struct thread_input *input ) +{ + input->keystate_lock--; + if (!input->keystate_lock) sync_input_keystate( input ); +} + /* change the thread input data of a given thread */ static int assign_thread_input( struct thread *thread, struct thread_input *new_input ) { @@ -339,9 +370,11 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_ if (queue->input) { queue->input->cursor_count -= queue->cursor_count; + if (queue->keystate_lock) unlock_input_keystate( queue->input ); release_object( queue->input ); } queue->input = (struct thread_input *)grab_object( new_input ); + if (queue->keystate_lock) lock_input_keystate( queue->input ); new_input->cursor_count += queue->cursor_count; return 1; } @@ -477,6 +510,11 @@ static inline int is_signaled( struct msg_queue *queue ) /* set some queue bits */ static inline void set_queue_bits( struct msg_queue *queue, unsigned int bits ) { + if (bits & (QS_KEY | QS_MOUSEBUTTON)) + { + if (!queue->keystate_lock) lock_input_keystate( queue->input ); + queue->keystate_lock = 1; + } queue->wake_bits |= bits; queue->changed_bits |= bits; if (is_signaled( queue )) wake_up( &queue->obj, 0 ); @@ -487,6 +525,11 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits { queue->wake_bits &= ~bits; queue->changed_bits &= ~bits; + if (!(queue->wake_bits & (QS_KEY | QS_MOUSEBUTTON))) + { + if (queue->keystate_lock) unlock_input_keystate( queue->input ); + queue->keystate_lock = 0; + } }
/* check whether msg is a keyboard message */ @@ -1031,6 +1074,7 @@ static void msg_queue_destroy( struct object *obj ) } if (queue->timeout) remove_timeout_user( queue->timeout ); queue->input->cursor_count -= queue->cursor_count; + if (queue->keystate_lock) unlock_input_keystate( queue->input ); release_object( queue->input ); if (queue->hooks) release_object( queue->hooks ); if (queue->fd) release_object( queue->fd ); @@ -2997,7 +3041,11 @@ DECL_HANDLER(get_key_state) else { unsigned char *keystate = current->queue->input->keystate; - if (req->key >= 0) reply->state = keystate[req->key & 0xff]; + if (req->key >= 0) + { + if (current->queue) sync_input_keystate( current->queue->input ); + reply->state = keystate[req->key & 0xff]; + } set_reply_data( keystate, size ); } } @@ -3011,6 +3059,7 @@ DECL_HANDLER(set_key_state) data_size_t size = min( 256, get_req_data_size() );
memcpy( queue->input->keystate, get_req_data(), size ); + memcpy( queue->input->desktop_keystate, queue->input->desktop->keystate, 256 ); if (req->async && (desktop = get_thread_desktop( current, 0 ))) { memcpy( desktop->keystate, get_req_data(), size );
This removes the fallback to desktop async keystate and uses instead the keystate synchronization logic in all cases.
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 --- dlls/user32/tests/input.c | 50 +++++++++++++++++++-------------------- server/queue.c | 18 +++----------- 2 files changed, 28 insertions(+), 40 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 246569961be..561f932b18b 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_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) +#define check_get_keyboard_state(i, j, c, x) check_get_keyboard_state_(i, j, c, x, __LINE__) +static void check_get_keyboard_state_(int i, int j, int c, int x, int line) { unsigned char keystate[256]; BOOL ret; @@ -3770,24 +3770,24 @@ static void check_get_keyboard_state_(int i, int j, int c, int x, int todo_x, in 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"); + ok_(__FILE__, line)(!(keystate['X'] & 0x80) == !x, "%d:%d: expected that X keystate is %s\n", i, j, x ? "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"); + ok_(__FILE__, line)(!(keystate['X'] & 0x80) == !x, "%d:%d: expected that X keystate is %s\n", i, j, x ? "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_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) +#define check_get_key_state(i, j, c, x) check_get_key_state_(i, j, c, x, __LINE__) +static void check_get_key_state_(int i, int j, int c, int x, int line) { SHORT state;
state = GetKeyState('X'); - todo_wine_if(todo_x) ok_(__FILE__, line)(!(state & 0x8000) == !x, "%d:%d: expected that X highest bit is %s, got %#x\n", i, j, x ? "set" : "unset", state); + ok_(__FILE__, line)(!(state & 0x8000) == !x, "%d:%d: expected that X highest bit is %s, got %#x\n", i, j, x ? "set" : "unset", state); ok_(__FILE__, line)(!(state & 0x007e), "%d:%d: expected that X undefined bits are unset, got %#x\n", i, j, state);
state = GetKeyState('C'); @@ -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 */ !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); + check_get_keyboard_state(i, j, expect_c, FALSE); + check_get_key_state(i, j, expect_c, expect_x); + check_get_keyboard_state(i, j, expect_c, expect_x);
/* 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 */ !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); + check_get_keyboard_state(i, j, expect_c, expect_x); + check_get_key_state(i, j, expect_c, FALSE); + check_get_keyboard_state(i, j, expect_c, 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); - check_get_key_state(i, j, expect_c, FALSE, /* todo */ FALSE); - check_get_keyboard_state(i, j, expect_c, FALSE, /* todo */ FALSE); + check_get_keyboard_state(i, j, expect_c, FALSE); + check_get_key_state(i, j, expect_c, FALSE); + check_get_keyboard_state(i, j, expect_c, 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); - check_get_key_state(i, j, expect_c, expect_x, /* todo */ FALSE); - check_get_keyboard_state(i, j, expect_c, expect_x, /* todo */ FALSE); + check_get_keyboard_state(i, j, expect_c, expect_x); + check_get_key_state(i, j, expect_c, expect_x); + check_get_keyboard_state(i, j, expect_c, expect_x);
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); - check_get_key_state(i, j, FALSE, expect_x, /* todo */ FALSE); - check_get_keyboard_state(i, j, FALSE, expect_x, /* todo */ FALSE); + check_get_keyboard_state(i, j, FALSE, expect_x); + check_get_key_state(i, j, FALSE, expect_x); + check_get_keyboard_state(i, j, FALSE, expect_x);
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); - check_get_key_state(i, j, FALSE, FALSE, /* todo */ FALSE); - check_get_keyboard_state(i, j, FALSE, FALSE, /* todo */ FALSE); + check_get_keyboard_state(i, j, FALSE, FALSE); + check_get_key_state(i, j, FALSE, FALSE); + check_get_keyboard_state(i, j, FALSE, FALSE);
ReleaseSemaphore(params.semaphores[1], 1, NULL); } diff --git a/server/queue.c b/server/queue.c index 0782c526327..fce65e360d4 100644 --- a/server/queue.c +++ b/server/queue.c @@ -3025,25 +3025,13 @@ DECL_HANDLER(get_key_state) set_reply_data( desktop->keystate, size ); release_object( desktop ); } - else if (!current->queue) - { - unsigned char *keystate; - /* fallback to desktop keystate */ - if (!(desktop = get_thread_desktop( current, 0 ))) return; - if (req->key >= 0) reply->state = desktop->keystate[req->key & 0xff] & ~0x40; - if ((keystate = set_reply_data_size( size ))) - { - unsigned int i; - for (i = 0; i < size; i++) keystate[i] = desktop->keystate[i] & ~0x40; - } - release_object( desktop ); - } else { - unsigned char *keystate = current->queue->input->keystate; + struct msg_queue *queue = get_current_queue(); + unsigned char *keystate = queue->input->keystate; if (req->key >= 0) { - if (current->queue) sync_input_keystate( current->queue->input ); + sync_input_keystate( queue->input ); reply->state = keystate[req->key & 0xff]; } set_reply_data( keystate, size );
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88345
Your paranoid android.
=== w7u_el (32 bit report) ===
user32: input.c:2299: Test failed: Spurious WM_INPUT messages
=== w10pro64_ar (64 bit report) ===
user32: input.c:3240: Test failed: expected WM_LBUTTONDOWN message input.c:3241: Test failed: expected WM_LBUTTONUP message input.c:3268: Test failed: expected WM_NCHITTEST message input.c:3269: Test failed: expected WM_RBUTTONDOWN message input.c:3270: Test failed: expected WM_RBUTTONUP message input.c:3299: Test failed: expected WM_LBUTTONDOWN message input.c:3300: Test failed: expected WM_LBUTTONUP message input.c:3353: Test failed: expected loop with WM_NCHITTEST messages input.c:3406: Test failed: expected WM_LBUTTONDOWN message input.c:3407: Test failed: expected WM_LBUTTONUP message
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88343
Your paranoid android.
=== w7u_el (32 bit report) ===
user32: input.c:2299: Test failed: Spurious WM_INPUT messages
=== w1064v1809 (64 bit report) ===
user32: input.c:2747: Test failed: 0: expected WM_MOUSEMOVE message input.c:2747: Test failed: 1: expected WM_MOUSEMOVE message input.c:2747: Test failed: 2: expected WM_MOUSEMOVE message