Added patches to get rid of wineserver call for GetActiveWindow, GetFocus, GetCapture.

This commit is contained in:
Sebastian Lackner 2015-03-21 10:00:53 +01:00
parent 2f3d51e7f4
commit 8751f075a1
6 changed files with 416 additions and 4 deletions

3
debian/changelog vendored
View File

@ -21,13 +21,14 @@ wine-staging (1.7.39) UNRELEASED; urgency=low
* Added patch to improve stub for ID3DXEffectImpl_CloneEffect.
* Added patch with additional tests for server-PeekMessage.
* Added patch to only zero the buffer up 32767 bytes in GetTempPathW.
* Added patch to implement shared memory wineserver communication for various user32 functions.
* Added patches to implement shared memory wineserver communication for various user32 functions.
* Added patch to implement combase.WindowsSubstring function.
* Added patch with stub for wininet.ParseX509EncodedCertificateForListBoxEntry.
* Added patch to allow to edit winecfg library override by double clicking.
* Added patch to fix regression causing too dark/missing textures in several games.
* Added patch to fix regression causing black screen on startup.
* Added patch to implement SetupLogError[A|W] and Setup[Open|Close]Log.
* Added patches to get rid of wineserver call for GetActiveWindow, GetFocus, GetCapture.
* Removed patch to avoid hardcoded values for sizeof(GUID) (accepted upstream).
* Removed patches for SLGetWindowsInformationDWORD (accepted upstream).
* Removed patches for _ismbckata and _mbctohira (fixed upstream).

View File

@ -1022,11 +1022,19 @@ if test "$enable_server_Shared_Memory" -eq 1; then
if test "$enable_ntdll_Threading" -gt 1; then
abort "Patchset ntdll-Threading disabled, but server-Shared_Memory depends on that."
fi
if test "$enable_server_Key_State" -gt 1; then
abort "Patchset server-Key_State disabled, but server-Shared_Memory depends on that."
fi
if test "$enable_server_PeekMessage" -gt 1; then
abort "Patchset server-PeekMessage disabled, but server-Shared_Memory depends on that."
fi
if test "$enable_user32_Key_State" -gt 1; then
abort "Patchset user32-Key_State disabled, but server-Shared_Memory depends on that."
fi
enable_dinput_Events=1
enable_ntdll_Threading=1
enable_server_Key_State=1
enable_server_PeekMessage=1
enable_user32_Key_State=1
fi
@ -3853,9 +3861,10 @@ fi
# Patchset server-Shared_Memory
# |
# | Modified files:
# | * dlls/ntdll/ntdll_misc.h, dlls/ntdll/server.c, dlls/ntdll/thread.c, dlls/ntdll/virtual.c, dlls/user32/input.c,
# | dlls/user32/message.c, dlls/user32/user_private.h, include/wine/server.h, include/winternl.h, server/fd.c,
# | server/file.h, server/main.c, server/mapping.c, server/protocol.def, server/queue.c, server/thread.c, server/thread.h
# | * dlls/ntdll/ntdll_misc.h, dlls/ntdll/server.c, dlls/ntdll/thread.c, dlls/ntdll/virtual.c, dlls/user32/focus.c,
# | dlls/user32/input.c, dlls/user32/message.c, dlls/user32/user_private.h, dlls/user32/winstation.c, include/wine/server.h,
# | include/winternl.h, server/fd.c, server/file.h, server/main.c, server/mapping.c, server/protocol.def, server/queue.c,
# | server/thread.c, server/thread.h
# |
if test "$enable_server_Shared_Memory" -eq 1; then
patch_apply server-Shared_Memory/0001-ntdll-Implement-virtual_map_shared_memory.patch
@ -3864,6 +3873,9 @@ if test "$enable_server_Shared_Memory" -eq 1; then
patch_apply server-Shared_Memory/0004-user32-Avoid-unnecessary-wineserver-calls-in-PeekMes.patch
patch_apply server-Shared_Memory/0005-user32-Get-rid-of-wineserver-call-for-GetLastInputIn.patch
patch_apply server-Shared_Memory/0006-ntdll-Only-enable-wineserver-shared-memory-communica.patch
patch_apply server-Shared_Memory/0007-user32-Move-key_state-cache-into-separate-structure.patch
patch_apply server-Shared_Memory/0008-server-Store-a-list-of-associated-queues-for-each-th.patch
patch_apply server-Shared_Memory/0009-user32-Get-rid-of-wineserver-call-for-GetActiveWindo.patch
(
echo '+ { "Sebastian Lackner", "ntdll: Implement virtual_map_shared_memory.", 1 },';
echo '+ { "Michael Müller", "server: Implement support for global and local shared memory blocks based on memfd.", 1 },';
@ -3871,6 +3883,9 @@ if test "$enable_server_Shared_Memory" -eq 1; then
echo '+ { "Sebastian Lackner", "user32: Avoid unnecessary wineserver calls in PeekMessage/GetMessage.", 1 },';
echo '+ { "Michael Müller", "user32: Get rid of wineserver call for GetLastInputInfo.", 1 },';
echo '+ { "Sebastian Lackner", "ntdll: Only enable wineserver shared memory communication when a special environment variable is set.", 1 },';
echo '+ { "Sebastian Lackner", "user32: Move key_state cache into separate structure.", 1 },';
echo '+ { "Sebastian Lackner", "server: Store a list of associated queues for each thread input.", 1 },';
echo '+ { "Sebastian Lackner", "user32: Get rid of wineserver call for GetActiveWindow, GetFocus, GetCapture.", 1 },';
) >> "$patchlist"
fi

View File

@ -0,0 +1,159 @@
From 66fe18ed16b77c3f69511ea9b41e6ed729624fcd Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 21 Mar 2015 08:09:03 +0100
Subject: user32: Move key_state cache into separate structure.
We're running soon out of TEB space, so just move other key_state related fields
into the allocated memory block.
---
dlls/user32/input.c | 26 +++++++++++++++++---------
dlls/user32/message.c | 9 +++++----
dlls/user32/user_private.h | 17 ++++++++++++-----
dlls/user32/winstation.c | 3 ++-
4 files changed, 36 insertions(+), 19 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 2512887..8608f75 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -376,6 +376,7 @@ void CDECL __wine_check_for_events( UINT flags )
SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
{
struct user_thread_info *thread_info = get_user_thread_info();
+ struct user_key_state_info *key_state_info = thread_info->key_state;
INT epoch = global_key_state_epoch;
SHORT ret;
@@ -385,26 +386,33 @@ SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
if ((ret = USER_Driver->pGetAsyncKeyState( key )) == -1)
{
- if (thread_info->key_state &&
- !(thread_info->key_state[key] & 0xc0) &&
- GetTickCount() - thread_info->key_state_time < 50 &&
- thread_info->key_state_epoch == epoch)
+ if (key_state_info && !(key_state_info->key_state[key] & 0xc0) &&
+ GetTickCount() - key_state_info->key_state_time < 50 &&
+ key_state_info->key_state_epoch == epoch)
+ {
return 0;
-
- if (!thread_info->key_state) thread_info->key_state = HeapAlloc( GetProcessHeap(), 0, 256 );
+ }
+ else if (!key_state_info)
+ {
+ key_state_info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*key_state_info) );
+ if (key_state_info) thread_info->key_state = key_state_info;
+ }
ret = 0;
SERVER_START_REQ( get_key_state )
{
req->tid = 0;
req->key = key;
- if (thread_info->key_state) wine_server_set_reply( req, thread_info->key_state, 256 );
+ if (key_state_info) wine_server_set_reply( req, key_state_info->key_state, sizeof(key_state_info->key_state) );
if (!wine_server_call( req ))
{
if (reply->state & 0x40) ret |= 0x0001;
if (reply->state & 0x80) ret |= 0x8000;
- thread_info->key_state_time = GetTickCount();
- thread_info->key_state_epoch = epoch;
+ if (key_state_info)
+ {
+ key_state_info->key_state_time = GetTickCount();
+ key_state_info->key_state_epoch = epoch;
+ }
}
}
SERVER_END_REQ;
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 4bc17e9..33e826e 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3304,6 +3304,7 @@ static BOOL send_message( struct send_message_info *info, DWORD_PTR *res_ptr, BO
NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
{
struct user_thread_info *thread_info = get_user_thread_info();
+ struct user_key_state_info *key_state_info = thread_info->key_state;
struct send_message_info info;
int prev_x, prev_y, new_x, new_y;
NTSTATUS ret;
@@ -3343,7 +3344,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
req->input.hw.lparam = MAKELONG( input->u.hi.wParamL, input->u.hi.wParamH );
break;
}
- if (thread_info->key_state) wine_server_set_reply( req, thread_info->key_state, 256 );
+ if (key_state_info) wine_server_set_reply( req, key_state_info->key_state, sizeof(key_state_info->key_state) );
ret = wine_server_call( req );
wait = reply->wait;
prev_x = reply->prev_x;
@@ -3355,10 +3356,10 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
if (!ret)
{
- if (thread_info->key_state)
+ if (key_state_info)
{
- thread_info->key_state_time = GetTickCount();
- thread_info->key_state_epoch = epoch;
+ key_state_info->key_state_time = GetTickCount();
+ key_state_info->key_state_epoch = epoch;
}
if ((flags & SEND_HWMSG_INJECTED) && (prev_x != new_x || prev_y != new_y))
USER_Driver->pSetCursorPos( new_x, new_y );
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index adf73ff..a35ebf3 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -184,19 +184,26 @@ struct user_thread_info
DWORD GetMessageTimeVal; /* Value for GetMessageTime */
DWORD GetMessagePosVal; /* Value for GetMessagePos */
ULONG_PTR GetMessageExtraInfoVal; /* Value for GetMessageExtraInfo */
- UINT active_hooks; /* Bitmap of active hooks */
- UINT key_state_time; /* Time of last key state refresh */
- BYTE *key_state; /* Cache of global key state */
HWND top_window; /* Desktop window */
HWND msg_window; /* HWND_MESSAGE parent window */
RAWINPUT *rawinput;
- INT key_state_epoch; /* Counter to invalidate the key state */
+ struct user_key_state_info *key_state; /* Cache of global key state */
+ UINT active_hooks; /* Bitmap of active hooks */
DWORD last_get_msg; /* Last message time */
- ULONG pad[3]; /* Available for more data */
+ ULONG pad[5]; /* Available for more data */
};
#include <poppack.h>
+C_ASSERT( sizeof(struct user_thread_info) <= sizeof(((TEB *)0)->Win32ClientInfo) );
+
+struct user_key_state_info
+{
+ UINT key_state_time; /* Time of last key state refresh */
+ INT key_state_epoch; /* Counter to invalidate the key state */
+ BYTE key_state[256]; /* State for each key */
+};
+
extern INT global_key_state_epoch DECLSPEC_HIDDEN;
struct hook_extra_info
diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c
index 12b9edc..0e8260a 100644
--- a/dlls/user32/winstation.c
+++ b/dlls/user32/winstation.c
@@ -399,9 +399,10 @@ BOOL WINAPI SetThreadDesktop( HDESK handle )
if (ret) /* reset the desktop windows */
{
struct user_thread_info *thread_info = get_user_thread_info();
+ struct user_key_state_info *key_state_info = thread_info->key_state;
thread_info->top_window = 0;
thread_info->msg_window = 0;
- thread_info->key_state_time = 0;
+ if (key_state_info) key_state_info->key_state_time = 0;
}
return ret;
}
--
2.3.2

View File

@ -0,0 +1,79 @@
From 94d2d107e2a3b1b09fdeaa1fdd179d955383f89d Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 21 Mar 2015 09:00:17 +0100
Subject: server: Store a list of associated queues for each thread input.
Required by the following patches, splitted as a separate patch for easier
reviewing.
---
server/queue.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/server/queue.c b/server/queue.c
index 4697d15..8f60a7e 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -99,6 +99,7 @@ struct thread_input
{
struct object obj; /* object header */
struct desktop *desktop; /* desktop that this thread input belongs to */
+ struct list queues; /* list of all queues this input belongs to */
user_handle_t focus; /* focus window */
user_handle_t capture; /* capture window */
user_handle_t active; /* active window */
@@ -139,6 +140,7 @@ struct msg_queue
lparam_t next_timer_id; /* id for the next timer with a 0 window */
struct timeout_user *timeout; /* timeout for next timer to expire */
struct thread_input *input; /* thread input descriptor */
+ struct list input_entry; /* entry in input->queues */
struct hook_table *hooks; /* hook table */
timeout_t last_get_msg; /* time of last get message call */
unsigned int ignore_post_msg; /* ignore post messages newer than this unique id */
@@ -254,6 +256,7 @@ static struct thread_input *create_thread_input( struct thread *thread )
input->cursor = 0;
input->cursor_count = 0;
input->lock_count = 0;
+ list_init( &input->queues );
list_init( &input->msg_list );
set_caret_window( input, 0 );
memset( input->keystate, 0, sizeof(input->keystate) );
@@ -297,6 +300,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
queue->next_timer_id = 0x7fff;
queue->timeout = NULL;
queue->input = (struct thread_input *)grab_object( input );
+ list_add_tail( &input->queues, &queue->input_entry );
queue->hooks = NULL;
queue->last_get_msg = current_time;
queue->ignore_post_msg = 0;
@@ -336,10 +340,12 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_
{
if (queue->keystate_locked) queue->input->lock_count--;
queue->input->cursor_count -= queue->cursor_count;
+ list_remove( &queue->input_entry );
release_object( queue->input );
queue->keystate_locked = 0;
}
queue->input = (struct thread_input *)grab_object( new_input );
+ list_add_tail( &new_input->queues, &queue->input_entry );
new_input->cursor_count += queue->cursor_count;
return 1;
}
@@ -1003,6 +1009,7 @@ static void msg_queue_destroy( struct object *obj )
if (queue->timeout) remove_timeout_user( queue->timeout );
if (queue->keystate_locked) queue->input->lock_count--;
queue->input->cursor_count -= queue->cursor_count;
+ list_remove( &queue->input_entry );
release_object( queue->input );
if (queue->hooks) release_object( queue->hooks );
if (queue->fd) release_object( queue->fd );
@@ -1029,6 +1036,7 @@ static void thread_input_destroy( struct object *obj )
{
struct thread_input *input = (struct thread_input *)obj;
+ assert( list_empty(&input->queues) );
empty_msg_list( &input->msg_list );
if (input->desktop)
{
--
2.3.2

View File

@ -0,0 +1,156 @@
From f984ad3f5502b815480cc135703e0ea843eb84a3 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 21 Mar 2015 09:45:54 +0100
Subject: user32: Get rid of wineserver call for GetActiveWindow, GetFocus,
GetCapture.
---
dlls/user32/focus.c | 4 ++++
dlls/user32/input.c | 2 ++
server/protocol.def | 5 ++++-
server/queue.c | 30 +++++++++++++++++++++++++++++-
4 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/focus.c b/dlls/user32/focus.c
index c47a82d..35fe89b 100644
--- a/dlls/user32/focus.c
+++ b/dlls/user32/focus.c
@@ -329,8 +329,10 @@ BOOL WINAPI SetForegroundWindow( HWND hwnd )
*/
HWND WINAPI GetActiveWindow(void)
{
+ shmlocal_t *shm = wine_get_shmlocal();
HWND ret = 0;
+ if (shm) return wine_server_ptr_handle( shm->input_active );
SERVER_START_REQ( get_thread_input )
{
req->tid = GetCurrentThreadId();
@@ -346,8 +348,10 @@ HWND WINAPI GetActiveWindow(void)
*/
HWND WINAPI GetFocus(void)
{
+ shmlocal_t *shm = wine_get_shmlocal();
HWND ret = 0;
+ if (shm) return wine_server_ptr_handle( shm->input_focus );
SERVER_START_REQ( get_thread_input )
{
req->tid = GetCurrentThreadId();
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 8608f75..e534ac1 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -342,8 +342,10 @@ BOOL WINAPI DECLSPEC_HOTPATCH ReleaseCapture(void)
*/
HWND WINAPI GetCapture(void)
{
+ shmlocal_t *shm = wine_get_shmlocal();
HWND ret = 0;
+ if (shm) return wine_server_ptr_handle( shm->input_capture );
SERVER_START_REQ( get_thread_input )
{
req->tid = GetCurrentThreadId();
diff --git a/server/protocol.def b/server/protocol.def
index cf6d783..7eaa6cd 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -76,7 +76,10 @@ typedef struct
typedef struct
{
- int queue_bits; /* queue wake bits */
+ int queue_bits; /* queue wake bits */
+ user_handle_t input_focus; /* focus window */
+ user_handle_t input_capture; /* capture window */
+ user_handle_t input_active; /* active window */
} shmlocal_t;
/* debug event data */
diff --git a/server/queue.c b/server/queue.c
index 0ca35d7..54611c2 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -269,6 +269,25 @@ static struct thread_input *create_thread_input( struct thread *thread )
return input;
}
+/* synchronize the input state with the shared memory */
+static void update_shm_thread_input( struct thread_input *input )
+{
+ struct msg_queue *queue;
+
+ /* the loop doesn't matter, usually it should only have one or a few entries */
+ LIST_FOR_EACH_ENTRY( queue, &input->queues, struct msg_queue, input_entry )
+ {
+ shmlocal_t *shm;
+ if (!queue->thread) return;
+ if ((shm = queue->thread->shm))
+ {
+ shm->input_active = input->active;
+ shm->input_focus = input->focus;
+ shm->input_capture = input->capture;
+ }
+ }
+}
+
/* create a message queue object */
static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_input *input )
{
@@ -310,7 +329,11 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
thread->queue = queue;
}
- if (new_input) release_object( new_input );
+ if (new_input)
+ {
+ update_shm_thread_input( new_input );
+ release_object( new_input );
+ }
return queue;
}
@@ -345,6 +368,7 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_
queue->input = (struct thread_input *)grab_object( new_input );
list_add_tail( &new_input->queues, &queue->input_entry );
new_input->cursor_count += queue->cursor_count;
+ update_shm_thread_input( new_input );
return 1;
}
@@ -1045,6 +1069,7 @@ static inline void thread_input_cleanup_window( struct msg_queue *queue, user_ha
if (window == input->menu_owner) input->menu_owner = 0;
if (window == input->move_size) input->move_size = 0;
if (window == input->caret) set_caret_window( input, 0 );
+ update_shm_thread_input( input );
}
/* check if the specified window can be set in the input data of a given queue */
@@ -2954,6 +2979,7 @@ DECL_HANDLER(set_focus_window)
{
reply->previous = queue->input->focus;
queue->input->focus = get_user_full_handle( req->handle );
+ update_shm_thread_input( queue->input );
}
}
@@ -2970,6 +2996,7 @@ DECL_HANDLER(set_active_window)
{
reply->previous = queue->input->active;
queue->input->active = get_user_full_handle( req->handle );
+ update_shm_thread_input( queue->input );
}
else set_error( STATUS_INVALID_HANDLE );
}
@@ -2996,6 +3023,7 @@ DECL_HANDLER(set_capture_window)
input->capture = get_user_full_handle( req->handle );
input->menu_owner = (req->flags & CAPTURE_MENU) ? input->capture : 0;
input->move_size = (req->flags & CAPTURE_MOVESIZE) ? input->capture : 0;
+ update_shm_thread_input( input );
reply->full_handle = input->capture;
}
}
--
2.3.2

View File

@ -1,3 +1,5 @@
Depends: ntdll-Threading
Depends: user32-Key_State
Depends: dinput-Events
Depends: server-Key_State
Depends: server-PeekMessage