Based on a patch from Sebastian Lackner sebastian@fds-team.de, the series has been in Proton for a while.
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
-- v2: server: Create message queue and thread input in get_key_state. server: Lock thread input keystate whenever it is modified. server: Create message queue and thread input in set_key_state.
From: Rémi Bernon rbernon@codeweavers.com
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 Signed-off-by: Alexandre Julliard julliard@winehq.org --- 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 14641591bff..38a2e4eea84 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -3961,8 +3961,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; @@ -3971,18 +3971,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, %lu\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, %lu\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;
@@ -3991,7 +3991,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); }
@@ -4008,7 +4008,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) { @@ -4041,18 +4041,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 %lu\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; @@ -4120,18 +4120,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);
@@ -4147,15 +4147,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 4f69a082b74..561fa825ee7 100644 --- a/server/queue.c +++ b/server/queue.c @@ -3080,9 +3080,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 );
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=113488
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
user32: input.c:757: Test failed: 0 (a4/0): 00 from 00 -> 80 unexpected input.c:757: Test failed: 0 (a4/0): 41 from 01 -> 00 unexpected
=== w10pro64_ja (64 bit report) ===
user32: input.c:3438: Test failed: expected WM_NCHITTEST message input.c:3439: Test failed: expected WM_RBUTTONDOWN message input.c:3440: Test failed: expected WM_RBUTTONUP message input.c:3468: Test failed: expected WM_NCHITTEST message input.c:3469: Test failed: expected WM_LBUTTONDOWN message input.c:3470: Test failed: expected WM_LBUTTONUP message input.c:3496: Test failed: expected WM_NCHITTEST message input.c:3523: Test failed: expected loop with WM_NCHITTEST messages input.c:3576: Test failed: expected WM_LBUTTONDOWN message input.c:3577: Test failed: expected WM_LBUTTONUP message
From: Rémi Bernon rbernon@codeweavers.com
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 Signed-off-by: Alexandre Julliard julliard@winehq.org --- 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 38a2e4eea84..4ab8c9b5f63 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -4042,15 +4042,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 %lu\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 561fa825ee7..9e0b9836965 100644 --- a/server/queue.c +++ b/server/queue.c @@ -112,6 +112,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 @@ -138,6 +140,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 @@ -263,12 +266,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; } @@ -303,6 +308,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 ); @@ -324,6 +330,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 ) { @@ -337,9 +368,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; } @@ -476,6 +509,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 ); @@ -486,6 +524,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 */ @@ -1030,6 +1073,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 ); @@ -3070,7 +3114,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 ); } } @@ -3084,6 +3132,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 );
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=113489
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
user32: input.c:757: Test failed: 0 (a4/0): 00 from 00 -> 80 unexpected input.c:757: Test failed: 0 (a4/0): 41 from 01 -> 00 unexpected
=== w1064 (64 bit report) ===
user32: input.c:3438: Test failed: expected WM_NCHITTEST message input.c:3439: Test failed: expected WM_RBUTTONDOWN message input.c:3440: Test failed: expected WM_RBUTTONUP message input.c:3469: Test failed: expected WM_LBUTTONDOWN message input.c:3470: Test failed: expected WM_LBUTTONUP message input.c:3523: Test failed: expected loop with WM_NCHITTEST messages input.c:3576: Test failed: expected WM_LBUTTONDOWN message input.c:3577: Test failed: expected WM_LBUTTONUP message
=== w1064_tsign (64 bit report) ===
user32: input.c:3438: Test failed: expected WM_NCHITTEST message input.c:3439: Test failed: expected WM_RBUTTONDOWN message input.c:3440: Test failed: expected WM_RBUTTONUP message input.c:3469: Test failed: expected WM_LBUTTONDOWN message input.c:3470: Test failed: expected WM_LBUTTONUP message input.c:3523: Test failed: expected loop with WM_NCHITTEST messages input.c:3576: Test failed: expected WM_LBUTTONDOWN message input.c:3577: Test failed: expected WM_LBUTTONUP message
From: Rémi Bernon rbernon@codeweavers.com
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 Signed-off-by: Alexandre Julliard julliard@winehq.org --- 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 4ab8c9b5f63..8b84a39d009 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -3961,8 +3961,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; @@ -3970,24 +3970,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, %lu\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, %lu\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'); @@ -4041,18 +4041,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 %lu\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; @@ -4120,18 +4120,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);
@@ -4147,15 +4147,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 9e0b9836965..d79add56fba 100644 --- a/server/queue.c +++ b/server/queue.c @@ -3098,25 +3098,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=113490
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
user32: input.c:757: Test failed: 0 (a4/0): 00 from 00 -> 80 unexpected input.c:757: Test failed: 0 (a4/0): 41 from 01 -> 00 unexpected
=== w1064_tsign (32 bit report) ===
user32: input.c:3468: Test failed: expected WM_NCHITTEST message input.c:3469: Test failed: expected WM_LBUTTONDOWN message input.c:3470: Test failed: expected WM_LBUTTONUP message input.c:3523: Test failed: expected loop with WM_NCHITTEST messages input.c:3576: Test failed: expected WM_LBUTTONDOWN message input.c:3577: Test failed: expected WM_LBUTTONUP message
This merge request was accepted by Alexandre Julliard.