diff --git a/patches/loader-KeyboardLayouts/0002-user32-Improve-GetKeyboardLayoutList.patch b/patches/loader-KeyboardLayouts/0002-user32-Improve-GetKeyboardLayoutList.patch index ccce00bf..1ab757e0 100644 --- a/patches/loader-KeyboardLayouts/0002-user32-Improve-GetKeyboardLayoutList.patch +++ b/patches/loader-KeyboardLayouts/0002-user32-Improve-GetKeyboardLayoutList.patch @@ -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 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; diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index e88a3e6b..db8d88ab 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -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 diff --git a/patches/server-Key_State/0001-server-Create-message-queue-and-thread-input-in-set_.patch b/patches/server-Key_State/0001-server-Create-message-queue-and-thread-input-in-set_.patch deleted file mode 100644 index facdc129..00000000 --- a/patches/server-Key_State/0001-server-Create-message-queue-and-thread-input-in-set_.patch +++ /dev/null @@ -1,167 +0,0 @@ -From d0142599d03573c50c889a7f9091a9ff2459304b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -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 - diff --git a/patches/server-Key_State/0002-server-Lock-thread-input-keystate-whenever-it-is-mod.patch b/patches/server-Key_State/0002-server-Lock-thread-input-keystate-whenever-it-is-mod.patch deleted file mode 100644 index 6e32facc..00000000 --- a/patches/server-Key_State/0002-server-Lock-thread-input-keystate-whenever-it-is-mod.patch +++ /dev/null @@ -1,187 +0,0 @@ -From ffa3222c7cfdd76ec21342e9540b01073d2e4bd7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -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 . - -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 - diff --git a/patches/server-Key_State/0003-server-Create-message-queue-and-thread-input-in-get_.patch b/patches/server-Key_State/0003-server-Create-message-queue-and-thread-input-in-get_.patch deleted file mode 100644 index 950ffeff..00000000 --- a/patches/server-Key_State/0003-server-Create-message-queue-and-thread-input-in-get_.patch +++ /dev/null @@ -1,172 +0,0 @@ -From b93e17f4dbd548edff543c2607755ba0d7a844d0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -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 - diff --git a/patches/server-Key_State/definition b/patches/server-Key_State/definition deleted file mode 100644 index a8d71deb..00000000 --- a/patches/server-Key_State/definition +++ /dev/null @@ -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. diff --git a/patches/server-PeekMessage/definition b/patches/server-PeekMessage/definition index 6f30913f..d66d0aab 100644 --- a/patches/server-PeekMessage/definition +++ b/patches/server-PeekMessage/definition @@ -1,2 +1 @@ Fixes: [28884] GetMessage should remove already seen messages with higher priority -Depends: server-Key_State diff --git a/patches/shell32-ACE_Viewer/0002-shell32-Add-security-property-tab.patch b/patches/shell32-ACE_Viewer/0002-shell32-Add-security-property-tab.patch index 749f0029..03bb15f1 100644 --- a/patches/shell32-ACE_Viewer/0002-shell32-Add-security-property-tab.patch +++ b/patches/shell32-ACE_Viewer/0002-shell32-Add-security-property-tab.patch @@ -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?= 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 @@ diff --git a/patches/user32-recursive-activation/0001-user32-focus-Prevent-a-recursive-loop-with-the-activ.patch b/patches/user32-recursive-activation/0001-user32-focus-Prevent-a-recursive-loop-with-the-activ.patch index 4da66e90..b4cc86c0 100644 --- a/patches/user32-recursive-activation/0001-user32-focus-Prevent-a-recursive-loop-with-the-activ.patch +++ b/patches/user32-recursive-activation/0001-user32-focus-Prevent-a-recursive-loop-with-the-activ.patch @@ -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?= 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 --- - 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 diff --git a/staging/upstream-commit b/staging/upstream-commit index e29d2183..dc2bf5d6 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -7af93f497c3e71f69511743f42b86b2ef5e13b32 +4ec67b7a6447dfc4af8c03c141c600b41b90ef53