Rebase against 4ec67b7a6447dfc4af8c03c141c600b41b90ef53.

This commit is contained in:
Zebediah Figura 2022-04-26 16:52:01 -05:00
parent 91cb025138
commit 87212e802d
10 changed files with 39 additions and 612 deletions

View File

@ -1,4 +1,4 @@
From dc71919fd156f8fabcb47594cb13ee3210ff571c Mon Sep 17 00:00:00 2001
From cc964cf26e79a89fb3d7345847a23d93368e3eed Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 9 Jul 2019 14:13:28 +1000
Subject: [PATCH] user32: Do not enumerate the registry in
@ -9,23 +9,23 @@ not the complete list from the registry.
---
dlls/user32/input.c | 1 -
dlls/user32/tests/input.c | 35 +++++++++++++++++++++++++++++++++++
dlls/win32u/input.c | 35 ++---------------------------------
3 files changed, 37 insertions(+), 34 deletions(-)
dlls/win32u/input.c | 33 +--------------------------------
3 files changed, 36 insertions(+), 33 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 6cf60abeae2..3907430dd22 100644
index 06756b5551e..99abab38ccf 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -802,7 +802,6 @@ static void CALLBACK TrackMouseEventProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent,
}
@@ -521,7 +521,6 @@ BOOL WINAPI UnloadKeyboardLayout( HKL layout )
return FALSE;
}
-
/***********************************************************************
* TrackMouseEvent [USER32]
*
* EnableMouseInPointer (USER32.@)
*/
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 79f3dfc3dc0..b3c1bd560ae 100644
index 8b84a39d009..d7520459c6d 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -4481,6 +4481,40 @@ static void test_SendInput(void)
@ -78,10 +78,10 @@ index 79f3dfc3dc0..b3c1bd560ae 100644
if(pGetMouseMovePointsEx)
test_GetMouseMovePointsEx(argv[0]);
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c
index 72af32fd471..a18f81fc331 100644
index 28fc5a918c8..24782e405a7 100644
--- a/dlls/win32u/input.c
+++ b/dlls/win32u/input.c
@@ -821,11 +821,7 @@ HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags )
@@ -933,11 +933,7 @@ HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags )
*/
UINT WINAPI NtUserGetKeyboardLayoutList( INT size, HKL *layouts )
{
@ -94,7 +94,7 @@ index 72af32fd471..a18f81fc331 100644
HKL layout;
TRACE_(keyboard)( "size %d, layouts %p.\n", size, layouts );
@@ -839,33 +835,6 @@ UINT WINAPI NtUserGetKeyboardLayoutList( INT size, HKL *layouts )
@@ -951,33 +947,6 @@ UINT WINAPI NtUserGetKeyboardLayoutList( INT size, HKL *layouts )
if (size && layouts)
{
layouts[count - 1] = layout;

View File

@ -51,7 +51,7 @@ usage()
# Get the upstream commit sha
upstream_commit()
{
echo "7af93f497c3e71f69511743f42b86b2ef5e13b32"
echo "4ec67b7a6447dfc4af8c03c141c600b41b90ef53"
}
# Show version information
@ -173,7 +173,6 @@ patch_enable_all ()
enable_sapi_iteration_tokens="$1"
enable_secur32_InitializeSecurityContextW="$1"
enable_server_File_Permissions="$1"
enable_server_Key_State="$1"
enable_server_PeekMessage="$1"
enable_server_Realtime_Priority="$1"
enable_server_Signal_Thread="$1"
@ -547,9 +546,6 @@ patch_enable ()
server-File_Permissions)
enable_server_File_Permissions="$2"
;;
server-Key_State)
enable_server_Key_State="$2"
;;
server-PeekMessage)
enable_server_PeekMessage="$2"
;;
@ -1339,13 +1335,6 @@ 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."
@ -1874,30 +1863,8 @@ if test "$enable_ntdll_Junction_Points" -eq 1; then
patch_apply ntdll-Junction_Points/0040-Fix-warnings.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
# |
@ -1929,8 +1896,8 @@ fi
# Patchset eventfd_synchronization
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * ntdll-DOS_Attributes, ntdll-NtQueryEaFile, ntdll-Junction_Points, server-Key_State, server-PeekMessage, server-
# | Realtime_Priority, server-Signal_Thread
# | * ntdll-DOS_Attributes, ntdll-NtQueryEaFile, ntdll-Junction_Points, 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
@ -3356,7 +3323,7 @@ fi
# | * [#46274] user32: Prevent a recursive loop with the activation messages.
# |
# | Modified files:
# | * dlls/user32/focus.c, dlls/user32/tests/msg.c, dlls/win32u/input.c, dlls/win32u/ntuser_private.h
# | * dlls/user32/tests/msg.c, dlls/win32u/input.c, dlls/win32u/ntuser_private.h
# |
if test "$enable_user32_recursive_activation" -eq 1; then
patch_apply user32-recursive-activation/0001-user32-focus-Prevent-a-recursive-loop-with-the-activ.patch

View File

@ -1,167 +0,0 @@
From d0142599d03573c50c889a7f9091a9ff2459304b 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 6cbf0d6254e..853c0f66df6 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -3962,8 +3962,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;
@@ -3972,18 +3972,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;
@@ -3992,7 +3992,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);
}
@@ -4009,7 +4009,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)
{
@@ -4042,18 +4042,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;
@@ -4121,18 +4121,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);
@@ -4148,15 +4148,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 );
--
2.35.1

View File

@ -1,187 +0,0 @@
From ffa3222c7cfdd76ec21342e9540b01073d2e4bd7 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 853c0f66df6..848b52d3870 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -4043,15 +4043,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 );
--
2.35.1

View File

@ -1,172 +0,0 @@
From b93e17f4dbd548edff543c2607755ba0d7a844d0 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 848b52d3870..71eaace7d7f 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -3962,8 +3962,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;
@@ -3971,24 +3971,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');
@@ -4042,18 +4042,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;
@@ -4121,18 +4121,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);
@@ -4148,15 +4148,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 );
--
2.35.1

View File

@ -1,5 +0,0 @@
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.

View File

@ -1,2 +1 @@
Fixes: [28884] GetMessage should remove already seen messages with higher priority
Depends: server-Key_State

View File

@ -1,4 +1,4 @@
From 12fc8bc5d9f0464b91d9412cd8a29ef5bda89caf Mon Sep 17 00:00:00 2001
From 5d9bbd0a9af79752f777975a53837af52b5539cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Mon, 8 May 2017 23:33:45 +0200
Subject: [PATCH] shell32: Add security property tab.
@ -11,11 +11,10 @@ Subject: [PATCH] shell32: Add security property tab.
4 files changed, 438 insertions(+), 1 deletion(-)
diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in
index eeb6cd63d60..7cc704e56b6 100644
index 9e2395126fc..f233acca65a 100644
--- a/dlls/shell32/Makefile.in
+++ b/dlls/shell32/Makefile.in
@@ -1,7 +1,7 @@
EXTRADEFS = -D_SHELL32_
@@ -1,6 +1,6 @@
MODULE = shell32.dll
IMPORTLIB = shell32
-IMPORTS = uuid shlwapi user32 gdi32 advapi32
@ -62,7 +61,7 @@ index 264947d337d..90898b7ed98 100644
/* FIXME: Some will be unused until desktop.ini support is implemented */
IDS_PROGRAMS "Programs"
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
index 176ce6061e6..57d0904af23 100644
index 14cd9aeeebe..ed3a07c423d 100644
--- a/dlls/shell32/shlview_cmenu.c
+++ b/dlls/shell32/shlview_cmenu.c
@@ -38,14 +38,133 @@

View File

@ -1,4 +1,4 @@
From 308420aac52197c2add1e472f509b109a17db961 Mon Sep 17 00:00:00 2001
From c336f99371aaf087b85257de1087b475452f2f84 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gabriel=20Iv=C4=83ncescu?= <gabrielopcode@gmail.com>
Date: Mon, 22 Jul 2019 15:29:25 +0300
Subject: [PATCH] user32/focus: Prevent a recursive loop with the activation
@ -15,26 +15,13 @@ actually depend on this behavior, so it is needed.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46274
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
---
dlls/user32/focus.c | 1 -
dlls/user32/tests/msg.c | 2 +-
dlls/win32u/input.c | 40 ++++++++++++++++++++++++------------
dlls/win32u/input.c | 41 ++++++++++++++++++++++++------------
dlls/win32u/ntuser_private.h | 1 +
4 files changed, 29 insertions(+), 15 deletions(-)
3 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/dlls/user32/focus.c b/dlls/user32/focus.c
index ff41cf716a1..a044133ab40 100644
--- a/dlls/user32/focus.c
+++ b/dlls/user32/focus.c
@@ -31,7 +31,6 @@
#include "user_private.h"
#include "wine/server.h"
-
/*******************************************************************
* FOCUS_MouseActivate
*
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index f939e91764c..af4fee6b3fc 100644
index c0a74d8edbe..585ff299142 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -5571,7 +5571,7 @@ static void test_messages(void)
@ -47,10 +34,10 @@ index f939e91764c..af4fee6b3fc 100644
if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_MINIMIZE)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c
index 328f270fb1f..ade8c313423 100644
index 28fc5a918c8..b8fd5622468 100644
--- a/dlls/win32u/input.c
+++ b/dlls/win32u/input.c
@@ -1287,7 +1287,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
@@ -1547,7 +1547,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
{
HWND previous = get_active_window();
BOOL ret;
@ -59,7 +46,7 @@ index 328f270fb1f..ade8c313423 100644
CBTACTIVATESTRUCT cbt;
if (previous == hwnd)
@@ -1296,16 +1296,24 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
@@ -1556,16 +1556,24 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
return TRUE;
}
@ -93,7 +80,7 @@ index 328f270fb1f..ade8c313423 100644
}
SERVER_START_REQ( set_active_window )
@@ -1325,7 +1333,11 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
@@ -1585,7 +1593,11 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
if (send_message( hwnd, WM_QUERYNEWPALETTE, 0, 0 ))
send_message_timeout( HWND_BROADCAST, WM_PALETTEISCHANGING, (WPARAM)hwnd, 0,
SMTO_ABORTIFHUNG, 2000, NULL, FALSE );
@ -106,7 +93,7 @@ index 328f270fb1f..ade8c313423 100644
}
old_thread = previous ? get_window_thread( previous, NULL ) : 0;
@@ -1357,7 +1369,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
@@ -1617,7 +1629,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
}
}
@ -115,7 +102,13 @@ index 328f270fb1f..ade8c313423 100644
{
send_message( hwnd, WM_NCACTIVATE, hwnd == NtUserGetForegroundWindow(), (LPARAM)previous );
send_message( hwnd, WM_ACTIVATE,
@@ -1382,7 +1394,9 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
@@ -1637,12 +1649,15 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
/* Do not change focus if the window is no more active */
if (hwnd == info.hwndActive)
{
+ /* this line exists to keep this patch from applying in the wrong place */
if (!info.hwndFocus || !hwnd || NtUserGetAncestor( info.hwndFocus, GA_ROOT ) != hwnd)
set_focus_window( hwnd );
}
}
@ -127,7 +120,7 @@ index 328f270fb1f..ade8c313423 100644
/**********************************************************************
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h
index 6afe3955787..9994b56bac2 100644
index fe9d7e18bc9..e852a0d5aa0 100644
--- a/dlls/win32u/ntuser_private.h
+++ b/dlls/win32u/ntuser_private.h
@@ -121,6 +121,7 @@ typedef struct tagWND
@ -139,5 +132,5 @@ index 6afe3955787..9994b56bac2 100644
#define WND_OTHER_PROCESS ((WND *)1) /* returned by WIN_GetPtr on unknown window handles */
#define WND_DESKTOP ((WND *)2) /* returned by WIN_GetPtr on the desktop window */
--
2.35.1
2.34.1

View File

@ -1 +1 @@
7af93f497c3e71f69511743f42b86b2ef5e13b32
4ec67b7a6447dfc4af8c03c141c600b41b90ef53