mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
server-Key_State: Replace with new patches from Rémi Bernon.
This also serves as a rebase against 2fcc1d0ecdebc55a5f515b1390ce715303f6a6ad.
This commit is contained in:
parent
545073aafa
commit
733a420dd7
@ -1,4 +1,4 @@
|
||||
From 1aac9111b536d35eec696e20141b6c5d6d92579b Mon Sep 17 00:00:00 2001
|
||||
From 2da453ad472ce69926e158bd4e933facd985d1cd Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <zfigura@codeweavers.com>
|
||||
Date: Mon, 6 Jul 2020 16:01:56 -0500
|
||||
Subject: [PATCH] server: Create eventfd file descriptors for message queues.
|
||||
@ -8,7 +8,7 @@ Subject: [PATCH] server: Create eventfd file descriptors for message queues.
|
||||
1 file changed, 21 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 263bb46ea00..4d416a88d88 100644
|
||||
index 1f1392387df..d34bc284d08 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -43,6 +43,7 @@
|
||||
@ -19,15 +19,15 @@ index 263bb46ea00..4d416a88d88 100644
|
||||
|
||||
#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
|
||||
#define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
|
||||
@@ -141,6 +142,7 @@ struct msg_queue
|
||||
struct hook_table *hooks; /* hook table */
|
||||
@@ -144,6 +145,7 @@ struct msg_queue
|
||||
timeout_t last_get_msg; /* time of last get message call */
|
||||
int keystate_lock; /* owns an input keystate lock */
|
||||
unsigned int ignore_post_msg; /* ignore post messages newer than this unique id */
|
||||
+ int esync_fd; /* esync file descriptor (signalled on message) */
|
||||
};
|
||||
|
||||
struct hotkey
|
||||
@@ -157,6 +159,7 @@ static void msg_queue_dump( struct object *obj, int verbose );
|
||||
@@ -160,6 +162,7 @@ static void msg_queue_dump( struct object *obj, int verbose );
|
||||
static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry );
|
||||
static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry );
|
||||
static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||
@ -35,7 +35,7 @@ index 263bb46ea00..4d416a88d88 100644
|
||||
static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry );
|
||||
static void msg_queue_destroy( struct object *obj );
|
||||
static void msg_queue_poll_event( struct fd *fd, int event );
|
||||
@@ -172,7 +175,7 @@ static const struct object_ops msg_queue_ops =
|
||||
@@ -175,7 +178,7 @@ static const struct object_ops msg_queue_ops =
|
||||
msg_queue_add_queue, /* add_queue */
|
||||
msg_queue_remove_queue, /* remove_queue */
|
||||
msg_queue_signaled, /* signaled */
|
||||
@ -44,9 +44,9 @@ index 263bb46ea00..4d416a88d88 100644
|
||||
msg_queue_satisfied, /* satisfied */
|
||||
no_signal, /* signal */
|
||||
no_get_fd, /* get_fd */
|
||||
@@ -309,12 +312,16 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
|
||||
queue->hooks = NULL;
|
||||
@@ -315,12 +318,16 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
|
||||
queue->last_get_msg = current_time;
|
||||
queue->keystate_lock = 0;
|
||||
queue->ignore_post_msg = 0;
|
||||
+ queue->esync_fd = -1;
|
||||
list_init( &queue->send_result );
|
||||
@ -61,17 +61,17 @@ index 263bb46ea00..4d416a88d88 100644
|
||||
thread->queue = queue;
|
||||
}
|
||||
if (new_input) release_object( new_input );
|
||||
@@ -491,6 +498,9 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits
|
||||
{
|
||||
queue->wake_bits &= ~bits;
|
||||
queue->changed_bits &= ~bits;
|
||||
@@ -534,6 +541,9 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits
|
||||
if (queue->keystate_lock) unlock_input_keystate( queue->input );
|
||||
queue->keystate_lock = 0;
|
||||
}
|
||||
+
|
||||
+ if (do_esync() && !is_signaled( queue ))
|
||||
+ esync_clear( queue->esync_fd );
|
||||
}
|
||||
|
||||
/* check whether msg is a keyboard message */
|
||||
@@ -1004,6 +1014,13 @@ static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entr
|
||||
@@ -1047,6 +1057,13 @@ static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entr
|
||||
return ret || is_signaled( queue );
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ index 263bb46ea00..4d416a88d88 100644
|
||||
static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry )
|
||||
{
|
||||
struct msg_queue *queue = (struct msg_queue *)obj;
|
||||
@@ -2381,6 +2398,9 @@ DECL_HANDLER(get_queue_status)
|
||||
@@ -2425,6 +2442,9 @@ DECL_HANDLER(get_queue_status)
|
||||
reply->wake_bits = queue->wake_bits;
|
||||
reply->changed_bits = queue->changed_bits;
|
||||
queue->changed_bits &= ~req->clear_bits;
|
||||
@ -96,5 +96,5 @@ index 263bb46ea00..4d416a88d88 100644
|
||||
else reply->wake_bits = reply->changed_bits = 0;
|
||||
}
|
||||
--
|
||||
2.28.0
|
||||
2.30.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From df50f6973c1fa60db18b408001ac50c03fb2fa07 Mon Sep 17 00:00:00 2001
|
||||
From e0a89702e35941e75ce06f795966c92b3f195ed8 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <zfigura@codeweavers.com>
|
||||
Date: Mon, 6 Jul 2020 16:11:23 -0500
|
||||
Subject: [PATCH] server, ntdll: Implement message waits.
|
||||
@ -105,10 +105,10 @@ index fcbe563bb5a..88490e08ef9 100644
|
||||
{
|
||||
struct stat st;
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 9062a5020c2..789bc56e7f1 100644
|
||||
index cf00ab99c63..ecbb78cc9bb 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -3697,3 +3697,8 @@ enum esync_type
|
||||
@@ -3734,3 +3734,8 @@ enum esync_type
|
||||
int type;
|
||||
unsigned int shm_idx;
|
||||
@END
|
||||
@ -118,26 +118,26 @@ index 9062a5020c2..789bc56e7f1 100644
|
||||
+ int in_msgwait; /* are we in a message wait? */
|
||||
+@END
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 4d416a88d88..efaf8a0f7e7 100644
|
||||
index d34bc284d08..f4edb299dc3 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -143,6 +143,7 @@ struct msg_queue
|
||||
timeout_t last_get_msg; /* time of last get message call */
|
||||
@@ -146,6 +146,7 @@ struct msg_queue
|
||||
int keystate_lock; /* owns an input keystate lock */
|
||||
unsigned int ignore_post_msg; /* ignore post messages newer than this unique id */
|
||||
int esync_fd; /* esync file descriptor (signalled on message) */
|
||||
+ int esync_in_msgwait; /* our thread is currently waiting on us */
|
||||
};
|
||||
|
||||
struct hotkey
|
||||
@@ -313,6 +314,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
|
||||
queue->last_get_msg = current_time;
|
||||
@@ -319,6 +320,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
|
||||
queue->keystate_lock = 0;
|
||||
queue->ignore_post_msg = 0;
|
||||
queue->esync_fd = -1;
|
||||
+ queue->esync_in_msgwait = 0;
|
||||
list_init( &queue->send_result );
|
||||
list_init( &queue->callback_result );
|
||||
list_init( &queue->pending_timers );
|
||||
@@ -959,6 +961,10 @@ static int is_queue_hung( struct msg_queue *queue )
|
||||
@@ -1002,6 +1004,10 @@ static int is_queue_hung( struct msg_queue *queue )
|
||||
if (get_wait_queue_thread(entry)->queue == queue)
|
||||
return 0; /* thread is waiting on queue -> not hung */
|
||||
}
|
||||
@ -148,7 +148,7 @@ index 4d416a88d88..efaf8a0f7e7 100644
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -3385,3 +3391,18 @@ DECL_HANDLER(get_rawinput_devices)
|
||||
@@ -3416,3 +3422,18 @@ DECL_HANDLER(get_rawinput_devices)
|
||||
devices[i++] = e->device;
|
||||
}
|
||||
}
|
||||
@ -168,5 +168,5 @@ index 4d416a88d88..efaf8a0f7e7 100644
|
||||
+ set_fd_events( queue->fd, req->in_msgwait ? POLLIN : 0 );
|
||||
+}
|
||||
--
|
||||
2.28.0
|
||||
2.30.2
|
||||
|
||||
|
@ -51,7 +51,7 @@ usage()
|
||||
# Get the upstream commit sha
|
||||
upstream_commit()
|
||||
{
|
||||
echo "97b420224e767b24d89722ff5efeca38a8ecf1e2"
|
||||
echo "2fcc1d0ecdebc55a5f515b1390ce715303f6a6ad"
|
||||
}
|
||||
|
||||
# Show version information
|
||||
@ -1449,6 +1449,13 @@ if test "$enable_eventfd_synchronization" -eq 1; then
|
||||
enable_server_Signal_Thread=1
|
||||
fi
|
||||
|
||||
if test "$enable_server_PeekMessage" -eq 1; then
|
||||
if test "$enable_server_Key_State" -gt 1; then
|
||||
abort "Patchset server-Key_State disabled, but server-PeekMessage depends on that."
|
||||
fi
|
||||
enable_server_Key_State=1
|
||||
fi
|
||||
|
||||
if test "$enable_ntdll_Junction_Points" -eq 1; then
|
||||
if test "$enable_ntdll_DOS_Attributes" -gt 1; then
|
||||
abort "Patchset ntdll-DOS_Attributes disabled, but ntdll-Junction_Points depends on that."
|
||||
@ -2303,8 +2310,30 @@ if test "$enable_ntdll_Junction_Points" -eq 1; then
|
||||
patch_apply ntdll-Junction_Points/0038-server-Rewrite-absolute-reparse-point-targets-if-the.patch
|
||||
fi
|
||||
|
||||
# Patchset server-Key_State
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#26269] BioShock 2: Loss of keyboard input on loading screen
|
||||
# | * [#31899] No keyboard input in La-Mulana remake (GetKeyState should behave similar to GetAsyncKeyState for specific
|
||||
# | window messages / queue states)
|
||||
# | * [#35907] Caps Lock state gets confused with multiple processes/threads
|
||||
# | * [#45385] Wrong state of virtual keys after cycling windows. Usually VK_MENU, VK_SHIFT and VK_CONTROL, but every key can
|
||||
# | be affected.
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/user32/tests/input.c, server/queue.c
|
||||
# |
|
||||
if test "$enable_server_Key_State" -eq 1; then
|
||||
patch_apply server-Key_State/0001-server-Create-message-queue-and-thread-input-in-set_.patch
|
||||
patch_apply server-Key_State/0002-server-Lock-thread-input-keystate-whenever-it-is-mod.patch
|
||||
patch_apply server-Key_State/0003-server-Create-message-queue-and-thread-input-in-get_.patch
|
||||
fi
|
||||
|
||||
# Patchset server-PeekMessage
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * server-Key_State
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#28884] GetMessage should remove already seen messages with higher priority
|
||||
# |
|
||||
@ -2336,8 +2365,8 @@ fi
|
||||
# Patchset eventfd_synchronization
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * ntdll-DOS_Attributes, ntdll-NtQueryEaFile, ntdll-Junction_Points, server-PeekMessage, server-Realtime_Priority, server-
|
||||
# | Signal_Thread
|
||||
# | * ntdll-DOS_Attributes, ntdll-NtQueryEaFile, ntdll-Junction_Points, server-Key_State, server-PeekMessage, server-
|
||||
# | Realtime_Priority, server-Signal_Thread
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#36692] Many multi-threaded applications have poor performance due to heavy use of synchronization primitives
|
||||
@ -3324,20 +3353,6 @@ if test "$enable_server_File_Permissions" -eq 1; then
|
||||
patch_apply server-File_Permissions/0008-server-Improve-mapping-of-DACL-to-file-permissions.patch
|
||||
fi
|
||||
|
||||
# Patchset server-Key_State
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#31899] Implement locking and synchronization of key states
|
||||
# | * [#35907] Fix caps lock state issues with multiple processes
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * server/queue.c
|
||||
# |
|
||||
if test "$enable_server_Key_State" -eq 1; then
|
||||
patch_apply server-Key_State/0001-server-Introduce-a-helper-function-to-update-the-thr.patch
|
||||
patch_apply server-Key_State/0002-server-Implement-locking-and-synchronization-of-keys.patch
|
||||
fi
|
||||
|
||||
# Patchset server-Stored_ACLs
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
|
@ -0,0 +1,167 @@
|
||||
From 4778b1c3d59bd87b067b6266e38ddd9a5d8bae86 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 1 Apr 2021 23:19:18 +0200
|
||||
Subject: [PATCH] server: Create message queue and thread input in
|
||||
set_key_state.
|
||||
|
||||
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
|
||||
---
|
||||
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 );
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,120 +0,0 @@
|
||||
From be8f547f53a1f8d35d9680a8cb2f0cfa808568b8 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Thu, 12 Mar 2015 00:44:25 +0100
|
||||
Subject: [PATCH] server: Introduce a helper function to update the
|
||||
thread_input key state.
|
||||
|
||||
---
|
||||
server/queue.c | 40 +++++++++++++++++++++++-----------------
|
||||
1 file changed, 23 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 7e7e6fbdf29..344e4298a56 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1300,9 +1300,9 @@ static void set_input_key_state( unsigned char *keystate, unsigned char key, int
|
||||
else keystate[key] &= ~0x80;
|
||||
}
|
||||
|
||||
-/* update the input key state for a keyboard message */
|
||||
-static void update_input_key_state( struct desktop *desktop, unsigned char *keystate,
|
||||
- unsigned int msg, lparam_t wparam )
|
||||
+/* update the key state for a keyboard message */
|
||||
+static void update_key_state( struct desktop *desktop, unsigned char *keystate,
|
||||
+ unsigned int msg, lparam_t wparam )
|
||||
{
|
||||
unsigned char key;
|
||||
int down = 0;
|
||||
@@ -1371,21 +1371,27 @@ static void update_desktop_mouse_state( struct desktop *desktop, unsigned int fl
|
||||
if (flags & MOUSEEVENTF_MOVE)
|
||||
update_desktop_cursor_pos( desktop, x, y );
|
||||
if (flags & MOUSEEVENTF_LEFTDOWN)
|
||||
- update_input_key_state( desktop, desktop->keystate, WM_LBUTTONDOWN, wparam );
|
||||
+ update_key_state( desktop, desktop->keystate, WM_LBUTTONDOWN, wparam );
|
||||
if (flags & MOUSEEVENTF_LEFTUP)
|
||||
- update_input_key_state( desktop, desktop->keystate, WM_LBUTTONUP, wparam );
|
||||
+ update_key_state( desktop, desktop->keystate, WM_LBUTTONUP, wparam );
|
||||
if (flags & MOUSEEVENTF_RIGHTDOWN)
|
||||
- update_input_key_state( desktop, desktop->keystate, WM_RBUTTONDOWN, wparam );
|
||||
+ update_key_state( desktop, desktop->keystate, WM_RBUTTONDOWN, wparam );
|
||||
if (flags & MOUSEEVENTF_RIGHTUP)
|
||||
- update_input_key_state( desktop, desktop->keystate, WM_RBUTTONUP, wparam );
|
||||
+ update_key_state( desktop, desktop->keystate, WM_RBUTTONUP, wparam );
|
||||
if (flags & MOUSEEVENTF_MIDDLEDOWN)
|
||||
- update_input_key_state( desktop, desktop->keystate, WM_MBUTTONDOWN, wparam );
|
||||
+ update_key_state( desktop, desktop->keystate, WM_MBUTTONDOWN, wparam );
|
||||
if (flags & MOUSEEVENTF_MIDDLEUP)
|
||||
- update_input_key_state( desktop, desktop->keystate, WM_MBUTTONUP, wparam );
|
||||
+ update_key_state( desktop, desktop->keystate, WM_MBUTTONUP, wparam );
|
||||
if (flags & MOUSEEVENTF_XDOWN)
|
||||
- update_input_key_state( desktop, desktop->keystate, WM_XBUTTONDOWN, wparam );
|
||||
+ update_key_state( desktop, desktop->keystate, WM_XBUTTONDOWN, wparam );
|
||||
if (flags & MOUSEEVENTF_XUP)
|
||||
- update_input_key_state( desktop, desktop->keystate, WM_XBUTTONUP, wparam );
|
||||
+ update_key_state( desktop, desktop->keystate, WM_XBUTTONUP, wparam );
|
||||
+}
|
||||
+
|
||||
+/* update the thread input key state for a keyboard message */
|
||||
+static void update_input_key_state( struct thread_input *input, unsigned int msg, lparam_t wparam )
|
||||
+{
|
||||
+ update_key_state( input->desktop, input->keystate, msg, wparam );
|
||||
}
|
||||
|
||||
/* release the hardware message currently being processed by the given thread */
|
||||
@@ -1413,7 +1419,7 @@ static void release_hardware_message( struct msg_queue *queue, unsigned int hw_i
|
||||
}
|
||||
if (clr_bit) clear_queue_bits( queue, clr_bit );
|
||||
|
||||
- update_input_key_state( input->desktop, input->keystate, msg->msg, msg->wparam );
|
||||
+ update_input_key_state( input, msg->msg, msg->wparam );
|
||||
list_remove( &msg->entry );
|
||||
free_message( msg );
|
||||
}
|
||||
@@ -1542,7 +1548,7 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
|
||||
struct hardware_msg_data *msg_data = msg->data;
|
||||
unsigned int msg_code;
|
||||
|
||||
- update_input_key_state( desktop, desktop->keystate, msg->msg, msg->wparam );
|
||||
+ update_key_state( desktop, desktop->keystate, msg->msg, msg->wparam );
|
||||
last_input_time = get_tick_count();
|
||||
if (msg->msg != WM_MOUSEMOVE) always_queue = 1;
|
||||
|
||||
@@ -1581,7 +1587,7 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
|
||||
win = find_hardware_message_window( desktop, input, msg, &msg_code, &thread );
|
||||
if (!win || !thread)
|
||||
{
|
||||
- if (input) update_input_key_state( input->desktop, input->keystate, msg->msg, msg->wparam );
|
||||
+ if (input) update_input_key_state( input, msg->msg, msg->wparam );
|
||||
free_message( msg );
|
||||
return;
|
||||
}
|
||||
@@ -1919,7 +1925,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
|
||||
if ((device = current->process->rawinput_kbd) && (device->flags & RIDEV_NOLEGACY))
|
||||
{
|
||||
- update_input_key_state( desktop, desktop->keystate, message_code, vkey );
|
||||
+ update_key_state( desktop, desktop->keystate, message_code, vkey );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2048,7 +2054,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
|
||||
if (!win || !win_thread)
|
||||
{
|
||||
/* no window at all, remove it */
|
||||
- update_input_key_state( input->desktop, input->keystate, msg->msg, msg->wparam );
|
||||
+ update_input_key_state( input, msg->msg, msg->wparam );
|
||||
list_remove( &msg->entry );
|
||||
free_message( msg );
|
||||
continue;
|
||||
@@ -2064,7 +2070,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
|
||||
else
|
||||
{
|
||||
/* for another thread input, drop it */
|
||||
- update_input_key_state( input->desktop, input->keystate, msg->msg, msg->wparam );
|
||||
+ update_input_key_state( input, msg->msg, msg->wparam );
|
||||
list_remove( &msg->entry );
|
||||
free_message( msg );
|
||||
}
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,162 +0,0 @@
|
||||
From b4259641f65faa6272c882019d773989b1f1d3d4 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 10 Jul 2015 16:13:53 +0200
|
||||
Subject: [PATCH] server: Implement locking and synchronization of keystate
|
||||
buffer. (rev 3)
|
||||
|
||||
---
|
||||
server/queue.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 57 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index cd84684d4a0..77496da03ca 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -113,7 +113,9 @@ struct thread_input
|
||||
user_handle_t cursor; /* current cursor */
|
||||
int cursor_count; /* cursor show count */
|
||||
struct list msg_list; /* list of hardware messages */
|
||||
+ int lock_count; /* lock counter for keystate */
|
||||
unsigned char keystate[256]; /* state of each key */
|
||||
+ unsigned char shadow_keystate[256]; /* shadow copy of keystate */
|
||||
};
|
||||
|
||||
struct msg_queue
|
||||
@@ -124,6 +126,7 @@ struct msg_queue
|
||||
unsigned int wake_mask; /* wakeup mask */
|
||||
unsigned int changed_bits; /* changed wakeup bits */
|
||||
unsigned int changed_mask; /* changed wakeup mask */
|
||||
+ int keystate_locked; /* keystate is locked */
|
||||
int paint_count; /* pending paint messages count */
|
||||
int hotkey_count; /* pending hotkey messages count */
|
||||
int quit_message; /* is there a pending quit message? */
|
||||
@@ -259,9 +262,11 @@ static struct thread_input *create_thread_input( struct thread *thread )
|
||||
input->move_size = 0;
|
||||
input->cursor = 0;
|
||||
input->cursor_count = 0;
|
||||
+ input->lock_count = 0;
|
||||
list_init( &input->msg_list );
|
||||
set_caret_window( input, 0 );
|
||||
memset( input->keystate, 0, sizeof(input->keystate) );
|
||||
+ memset( input->shadow_keystate, 0, sizeof(input->shadow_keystate) );
|
||||
|
||||
if (!(input->desktop = get_thread_desktop( thread, 0 /* FIXME: access rights */ )))
|
||||
{
|
||||
@@ -292,6 +297,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
|
||||
queue->wake_mask = 0;
|
||||
queue->changed_bits = 0;
|
||||
queue->changed_mask = 0;
|
||||
+ queue->keystate_locked = 0;
|
||||
queue->paint_count = 0;
|
||||
queue->hotkey_count = 0;
|
||||
queue->quit_message = 0;
|
||||
@@ -335,8 +341,10 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_
|
||||
}
|
||||
if (queue->input)
|
||||
{
|
||||
+ if (queue->keystate_locked) queue->input->lock_count--;
|
||||
queue->input->cursor_count -= queue->cursor_count;
|
||||
release_object( queue->input );
|
||||
+ queue->keystate_locked = 0;
|
||||
}
|
||||
queue->input = (struct thread_input *)grab_object( new_input );
|
||||
new_input->cursor_count += queue->cursor_count;
|
||||
@@ -1027,6 +1035,7 @@ static void msg_queue_destroy( struct object *obj )
|
||||
free( timer );
|
||||
}
|
||||
if (queue->timeout) remove_timeout_user( queue->timeout );
|
||||
+ if (queue->keystate_locked) queue->input->lock_count--;
|
||||
queue->input->cursor_count -= queue->cursor_count;
|
||||
release_object( queue->input );
|
||||
if (queue->hooks) release_object( queue->hooks );
|
||||
@@ -1127,7 +1136,11 @@ int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
|
||||
}
|
||||
|
||||
ret = assign_thread_input( thread_from, input );
|
||||
- if (ret) memset( input->keystate, 0, sizeof(input->keystate) );
|
||||
+ if (ret)
|
||||
+ {
|
||||
+ memset( input->keystate, 0, sizeof(input->keystate) );
|
||||
+ memset( input->shadow_keystate, 0, sizeof(input->shadow_keystate) );
|
||||
+ }
|
||||
release_object( input );
|
||||
return ret;
|
||||
}
|
||||
@@ -1385,9 +1398,30 @@ static void update_desktop_mouse_state( struct desktop *desktop, unsigned int fl
|
||||
update_key_state( desktop, desktop->keystate, WM_XBUTTONUP, wparam );
|
||||
}
|
||||
|
||||
+/* synchronizes the thread input key state with the desktop */
|
||||
+static void synchronize_input_key_state( struct thread_input *input )
|
||||
+{
|
||||
+ if (!input->lock_count)
|
||||
+ {
|
||||
+ unsigned char *shadow_keystate = input->shadow_keystate;
|
||||
+ unsigned char *keystate = input->keystate;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < 256; i++)
|
||||
+ {
|
||||
+ if (input->desktop->keystate[i] != shadow_keystate[i])
|
||||
+ {
|
||||
+ keystate[i] = input->desktop->keystate[i] & ~0x40;
|
||||
+ shadow_keystate[i] = input->desktop->keystate[i];
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* update the thread input key state for a keyboard message */
|
||||
static void update_input_key_state( struct thread_input *input, unsigned int msg, lparam_t wparam )
|
||||
{
|
||||
+ synchronize_input_key_state( input );
|
||||
update_key_state( input->desktop, input->keystate, msg, wparam );
|
||||
}
|
||||
|
||||
@@ -1588,6 +1622,15 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
|
||||
else
|
||||
{
|
||||
msg->unique_id = 0; /* will be set once we return it to the app */
|
||||
+
|
||||
+ /* lock the keystate on the first hardware message */
|
||||
+ if (!thread->queue->keystate_locked)
|
||||
+ {
|
||||
+ synchronize_input_key_state( input );
|
||||
+ input->lock_count++;
|
||||
+ thread->queue->keystate_locked = 1;
|
||||
+ }
|
||||
+
|
||||
list_add_tail( &input->msg_list, &msg->entry );
|
||||
set_queue_bits( thread->queue, get_hardware_msg_bit(msg) );
|
||||
}
|
||||
@@ -2526,6 +2569,13 @@ DECL_HANDLER(get_message)
|
||||
queue->last_get_msg = current_time;
|
||||
if (!filter) filter = QS_ALLINPUT;
|
||||
|
||||
+ /* no longer lock the keystate if we have processed all input */
|
||||
+ if (queue->keystate_locked && !(queue->wake_bits & QS_ALLINPUT))
|
||||
+ {
|
||||
+ queue->input->lock_count--;
|
||||
+ queue->keystate_locked = 0;
|
||||
+ }
|
||||
+
|
||||
/* first check for sent messages */
|
||||
if ((ptr = list_head( &queue->msg_list[SEND_MESSAGE] )))
|
||||
{
|
||||
@@ -2982,7 +3032,12 @@ DECL_HANDLER(get_key_state)
|
||||
if (!(thread = get_thread_from_id( req->tid ))) return;
|
||||
if (thread->queue)
|
||||
{
|
||||
- if (req->key >= 0) reply->state = thread->queue->input->keystate[req->key & 0xff];
|
||||
+ if (req->key >= 0)
|
||||
+ {
|
||||
+ /* synchronize with desktop keystate, but _only_ if req->key is given */
|
||||
+ synchronize_input_key_state( thread->queue->input );
|
||||
+ reply->state = thread->queue->input->keystate[req->key & 0xff];
|
||||
+ }
|
||||
set_reply_data( thread->queue->input->keystate, size );
|
||||
release_object( thread );
|
||||
return;
|
||||
--
|
||||
2.27.0
|
||||
|
@ -0,0 +1,187 @@
|
||||
From a6f4d1c57d31c0a8f50afd5af9d50b7e587c84f5 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 1 Apr 2021 23:30:46 +0200
|
||||
Subject: [PATCH] server: Lock thread input keystate whenever it is modified.
|
||||
|
||||
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
|
||||
---
|
||||
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 );
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,172 @@
|
||||
From a6a449881f6643183316ad867b49bd99f53fa4a4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 1 Apr 2021 23:41:31 +0200
|
||||
Subject: [PATCH] server: Create message queue and thread input in
|
||||
get_key_state.
|
||||
|
||||
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
|
||||
---
|
||||
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 );
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Fixes: [27238] Fallback to global key state for threads without a queue
|
||||
Fixes: [31899] Implement locking and synchronization of key states
|
||||
Fixes: [35907] Fix caps lock state issues with multiple processes
|
||||
# Please review this for correctness; rebasing against 8cf7fe3b7c2 may have
|
||||
# broken it.
|
||||
Fixes: [26269] BioShock 2: Loss of keyboard input on loading screen
|
||||
# Fixes: [27238] Tesla: The Weather Man demo: movement keys not working (GetKeyState should fallback to GetAsyncKeyState for threads without message queue)
|
||||
Fixes: [31899] No keyboard input in La-Mulana remake (GetKeyState should behave similar to GetAsyncKeyState for specific window messages / queue states)
|
||||
Fixes: [35907] Caps Lock state gets confused with multiple processes/threads
|
||||
Fixes: [45385] Wrong state of virtual keys after cycling windows. Usually VK_MENU, VK_SHIFT and VK_CONTROL, but every key can be affected.
|
||||
|
@ -1,4 +1,4 @@
|
||||
From c527f32596831ae31b055cd77cb3bc848f83a8a8 Mon Sep 17 00:00:00 2001
|
||||
From 9875a6033aaa0043a7c29926a026ecafb56382e6 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 15 Mar 2015 01:05:48 +0100
|
||||
Subject: [PATCH] server: Fix handling of GetMessage after previous PeekMessage
|
||||
@ -15,10 +15,10 @@ Changes in v3:
|
||||
2 files changed, 62 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
|
||||
index f84525a0bf9..80cc0daa6c6 100644
|
||||
index 7eaa2c67945..8f8b1b98933 100644
|
||||
--- a/dlls/user32/tests/msg.c
|
||||
+++ b/dlls/user32/tests/msg.c
|
||||
@@ -12429,13 +12429,10 @@ static void test_PeekMessage3(void)
|
||||
@@ -12648,13 +12648,10 @@ static void test_PeekMessage3(void)
|
||||
ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
|
||||
PostMessageA(hwnd, WM_USER, 0, 0);
|
||||
ret = PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE);
|
||||
@ -32,7 +32,7 @@ index f84525a0bf9..80cc0daa6c6 100644
|
||||
ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
|
||||
ret = PeekMessageA(&msg, NULL, 0, 0, 0);
|
||||
ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
|
||||
@@ -12445,10 +12442,8 @@ static void test_PeekMessage3(void)
|
||||
@@ -12664,10 +12661,8 @@ static void test_PeekMessage3(void)
|
||||
ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
|
||||
PostMessageA(hwnd, WM_USER, 0, 0);
|
||||
ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
|
||||
@ -43,7 +43,7 @@ index f84525a0bf9..80cc0daa6c6 100644
|
||||
ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
|
||||
ret = PeekMessageA(&msg, NULL, 0, 0, 0);
|
||||
ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
|
||||
@@ -12460,10 +12455,8 @@ static void test_PeekMessage3(void)
|
||||
@@ -12679,10 +12674,8 @@ static void test_PeekMessage3(void)
|
||||
ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
|
||||
PostMessageA(hwnd, WM_USER, 0, 0);
|
||||
ret = GetMessageA(&msg, NULL, 0, 0);
|
||||
@ -54,7 +54,7 @@ index f84525a0bf9..80cc0daa6c6 100644
|
||||
ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
|
||||
ret = PeekMessageA(&msg, NULL, 0, 0, 0);
|
||||
ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
|
||||
@@ -12491,14 +12484,32 @@ static void test_PeekMessage3(void)
|
||||
@@ -12710,14 +12703,32 @@ static void test_PeekMessage3(void)
|
||||
ret = GetMessageA(&msg, NULL, 0, 0);
|
||||
ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
|
||||
ret = GetMessageA(&msg, NULL, 0, 0);
|
||||
@ -90,26 +90,26 @@ index f84525a0bf9..80cc0daa6c6 100644
|
||||
* because both messages are in the same queue. */
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index a65eab38bdc..bf315f5008c 100644
|
||||
index fce65e360d4..451aaeca008 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -140,6 +140,7 @@ struct msg_queue
|
||||
struct thread_input *input; /* thread input descriptor */
|
||||
@@ -143,6 +143,7 @@ struct msg_queue
|
||||
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 */
|
||||
+ unsigned int ignore_post_msg; /* ignore post messages newer than this unique id */
|
||||
};
|
||||
|
||||
struct hotkey
|
||||
@@ -300,6 +301,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
|
||||
queue->input = (struct thread_input *)grab_object( input );
|
||||
@@ -311,6 +312,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
|
||||
queue->hooks = NULL;
|
||||
queue->last_get_msg = current_time;
|
||||
queue->keystate_lock = 0;
|
||||
+ queue->ignore_post_msg = 0;
|
||||
list_init( &queue->send_result );
|
||||
list_init( &queue->callback_result );
|
||||
list_init( &queue->pending_timers );
|
||||
@@ -529,13 +531,21 @@ static inline struct msg_queue *get_current_queue(void)
|
||||
@@ -577,13 +579,21 @@ static inline struct msg_queue *get_current_queue(void)
|
||||
}
|
||||
|
||||
/* get a (pseudo-)unique id to tag hardware messages */
|
||||
@ -132,7 +132,7 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
/* try to merge a message with the last in the list; return 1 if successful */
|
||||
static int merge_message( struct thread_input *input, const struct message *msg )
|
||||
{
|
||||
@@ -813,7 +823,7 @@ static int match_window( user_handle_t win, user_handle_t msg_win )
|
||||
@@ -861,7 +871,7 @@ static int match_window( user_handle_t win, user_handle_t msg_win )
|
||||
}
|
||||
|
||||
/* retrieve a posted message */
|
||||
@ -141,7 +141,7 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
unsigned int first, unsigned int last, unsigned int flags,
|
||||
struct get_message_reply *reply )
|
||||
{
|
||||
@@ -824,6 +834,7 @@ static int get_posted_message( struct msg_queue *queue, user_handle_t win,
|
||||
@@ -872,6 +882,7 @@ static int get_posted_message( struct msg_queue *queue, user_handle_t win,
|
||||
{
|
||||
if (!match_window( win, msg->win )) continue;
|
||||
if (!check_msg_filter( msg->msg, first, last )) continue;
|
||||
@ -149,7 +149,7 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
goto found; /* found one */
|
||||
}
|
||||
return 0;
|
||||
@@ -1439,6 +1450,7 @@ found:
|
||||
@@ -1488,6 +1499,7 @@ found:
|
||||
msg->msg = WM_HOTKEY;
|
||||
msg->wparam = hotkey->id;
|
||||
msg->lparam = ((hotkey->vkey & 0xffff) << 16) | modifiers;
|
||||
@ -157,7 +157,7 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
|
||||
free( msg->data );
|
||||
msg->data = NULL;
|
||||
@@ -2061,7 +2073,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
|
||||
@@ -2125,7 +2137,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
|
||||
continue;
|
||||
}
|
||||
/* now we can return it */
|
||||
@ -166,7 +166,7 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
reply->type = MSG_HARDWARE;
|
||||
reply->win = win;
|
||||
reply->msg = msg_code;
|
||||
@@ -2167,6 +2179,7 @@ void post_message( user_handle_t win, unsigned int message, lparam_t wparam, lpa
|
||||
@@ -2231,6 +2243,7 @@ void post_message( user_handle_t win, unsigned int message, lparam_t wparam, lpa
|
||||
msg->result = NULL;
|
||||
msg->data = NULL;
|
||||
msg->data_size = 0;
|
||||
@ -174,7 +174,7 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
|
||||
get_message_defaults( thread->queue, &msg->x, &msg->y, &msg->time );
|
||||
|
||||
@@ -2411,6 +2424,7 @@ DECL_HANDLER(send_message)
|
||||
@@ -2475,6 +2488,7 @@ DECL_HANDLER(send_message)
|
||||
set_queue_bits( recv_queue, QS_SENDMESSAGE );
|
||||
break;
|
||||
case MSG_POSTED:
|
||||
@ -182,7 +182,7 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
list_add_tail( &recv_queue->msg_list[POST_MESSAGE], &msg->entry );
|
||||
set_queue_bits( recv_queue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE );
|
||||
if (msg->msg == WM_HOTKEY)
|
||||
@@ -2531,12 +2545,12 @@ DECL_HANDLER(get_message)
|
||||
@@ -2595,12 +2609,12 @@ DECL_HANDLER(get_message)
|
||||
|
||||
/* then check for posted messages */
|
||||
if ((filter & QS_POSTMESSAGE) &&
|
||||
@ -197,7 +197,7 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
return;
|
||||
|
||||
/* only check for quit messages if not posted messages pending */
|
||||
@@ -2547,7 +2561,7 @@ DECL_HANDLER(get_message)
|
||||
@@ -2611,7 +2625,7 @@ DECL_HANDLER(get_message)
|
||||
if ((filter & QS_INPUT) &&
|
||||
filter_contains_hw_range( req->get_first, req->get_last ) &&
|
||||
get_hardware_message( current, req->hw_id, get_win, req->get_first, req->get_last, req->flags, reply ))
|
||||
@ -206,7 +206,7 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
|
||||
/* now check for WM_PAINT */
|
||||
if ((filter & QS_PAINT) &&
|
||||
@@ -2560,7 +2574,7 @@ DECL_HANDLER(get_message)
|
||||
@@ -2624,7 +2638,7 @@ DECL_HANDLER(get_message)
|
||||
reply->wparam = 0;
|
||||
reply->lparam = 0;
|
||||
get_message_defaults( queue, &reply->x, &reply->y, &reply->time );
|
||||
@ -215,7 +215,7 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
}
|
||||
|
||||
/* now check for timer */
|
||||
@@ -2576,13 +2590,30 @@ DECL_HANDLER(get_message)
|
||||
@@ -2640,13 +2654,30 @@ DECL_HANDLER(get_message)
|
||||
get_message_defaults( queue, &reply->x, &reply->y, &reply->time );
|
||||
if (!(req->flags & PM_NOYIELD) && current->process->idle_event)
|
||||
set_event( current->process->idle_event );
|
||||
@ -247,7 +247,7 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
}
|
||||
|
||||
|
||||
@@ -2600,7 +2631,10 @@ DECL_HANDLER(reply_message)
|
||||
@@ -2664,7 +2695,10 @@ DECL_HANDLER(reply_message)
|
||||
DECL_HANDLER(accept_hardware_message)
|
||||
{
|
||||
if (current->queue)
|
||||
@ -259,5 +259,5 @@ index a65eab38bdc..bf315f5008c 100644
|
||||
set_error( STATUS_ACCESS_DENIED );
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
2.30.2
|
||||
|
||||
|
@ -1 +1,2 @@
|
||||
Fixes: [28884] GetMessage should remove already seen messages with higher priority
|
||||
Depends: server-Key_State
|
||||
|
Loading…
Reference in New Issue
Block a user