From abf362b37a3424926d233b8997cb6c7b6a42b0c4 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Thu, 19 Mar 2015 02:07:24 +0100
Subject: user32: Avoid unnecessary wineserver calls in PeekMessage/GetMessage.

---
 dlls/user32/message.c      | 13 +++++++++++++
 dlls/user32/user_private.h |  3 ++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 5a76523..d47fee4 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -2740,6 +2740,18 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
     unsigned int hw_id = 0;  /* id of previous hardware message */
     void *buffer;
     size_t buffer_size = 256;
+    shmlocal_t *shm = wine_get_shmlocal();
+
+    /* From time to time we are forced to do a wineserver call in
+     * order to update last_msg_time stored for each server thread. */
+    if (shm && GetTickCount() - thread_info->last_get_msg < 500)
+    {
+        int filter = flags >> 16;
+        if (!filter) filter = QS_ALLINPUT;
+        filter |= QS_SENDMESSAGE;
+        if (filter & QS_INPUT) filter |= QS_INPUT;
+        if (!(shm->queue_bits & filter)) return FALSE;
+    }
 
     if (!(buffer = HeapAlloc( GetProcessHeap(), 0, buffer_size ))) return FALSE;
 
@@ -2752,6 +2764,7 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
         size_t size = 0;
         const message_data_t *msg_data = buffer;
 
+        if (shm) thread_info->last_get_msg = GetTickCount();
         SERVER_START_REQ( get_message )
         {
             req->flags     = flags;
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index d3affb0..4de34c7 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -176,7 +176,7 @@ struct user_thread_info
     WORD                          recursion_count;        /* SendMessage recursion counter */
     WORD                          message_count;          /* Get/PeekMessage loop counter */
     WORD                          hook_call_depth;        /* Number of recursively called hook procs */
-    BOOL                          hook_unicode;           /* Is current hook unicode? */
+    WORD                          hook_unicode;           /* Is current hook unicode? */
     HHOOK                         hook;                   /* Current hook */
     struct received_message_info *receive_info;           /* Message being currently received */
     struct wm_char_mapping_data  *wmchar_data;            /* Data for WM_CHAR mappings */
@@ -184,6 +184,7 @@ struct user_thread_info
     DWORD                         GetMessagePosVal;       /* Value for GetMessagePos */
     ULONG_PTR                     GetMessageExtraInfoVal; /* Value for GetMessageExtraInfo */
     UINT                          active_hooks;           /* Bitmap of active hooks */
+    DWORD                         last_get_msg;           /* Last time of Get/PeekMessage call */
     struct user_key_state_info   *key_state;              /* Cache of global key state */
     HWND                          top_window;             /* Desktop window */
     HWND                          msg_window;             /* HWND_MESSAGE parent window */
-- 
2.4.4

