server-Key_State: Rebase and restore mistakenly deleted patch.

This commit is contained in:
Zebediah Figura 2020-06-30 19:15:34 -05:00
parent f904ca32a3
commit 262df397ef
3 changed files with 287 additions and 0 deletions

View File

@ -0,0 +1,120 @@
From 0fefda7a02d52d1c8813d7caaf2ca3cc6e352a29 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Thu, 12 Mar 2015 00:44:25 +0100
Subject: [PATCH] server: Introduce a helper function to update the
thread_input key state.
---
server/queue.c | 40 +++++++++++++++++++++++-----------------
1 file changed, 23 insertions(+), 17 deletions(-)
diff --git a/server/queue.c b/server/queue.c
index 432885f9e4c..0a20bd3639d 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1295,9 +1295,9 @@ static void set_input_key_state( unsigned char *keystate, unsigned char key, int
else keystate[key] &= ~0x80;
}
-/* update the input key state for a keyboard message */
-static void update_input_key_state( struct desktop *desktop, unsigned char *keystate,
- unsigned int msg, lparam_t wparam )
+/* update the key state for a keyboard message */
+static void update_key_state( struct desktop *desktop, unsigned char *keystate,
+ unsigned int msg, lparam_t wparam )
{
unsigned char key;
int down = 0;
@@ -1366,21 +1366,27 @@ static void update_desktop_mouse_state( struct desktop *desktop, unsigned int fl
if (flags & MOUSEEVENTF_MOVE)
update_desktop_cursor_pos( desktop, x, y );
if (flags & MOUSEEVENTF_LEFTDOWN)
- update_input_key_state( desktop, desktop->keystate, WM_LBUTTONDOWN, wparam );
+ update_key_state( desktop, desktop->keystate, WM_LBUTTONDOWN, wparam );
if (flags & MOUSEEVENTF_LEFTUP)
- update_input_key_state( desktop, desktop->keystate, WM_LBUTTONUP, wparam );
+ update_key_state( desktop, desktop->keystate, WM_LBUTTONUP, wparam );
if (flags & MOUSEEVENTF_RIGHTDOWN)
- update_input_key_state( desktop, desktop->keystate, WM_RBUTTONDOWN, wparam );
+ update_key_state( desktop, desktop->keystate, WM_RBUTTONDOWN, wparam );
if (flags & MOUSEEVENTF_RIGHTUP)
- update_input_key_state( desktop, desktop->keystate, WM_RBUTTONUP, wparam );
+ update_key_state( desktop, desktop->keystate, WM_RBUTTONUP, wparam );
if (flags & MOUSEEVENTF_MIDDLEDOWN)
- update_input_key_state( desktop, desktop->keystate, WM_MBUTTONDOWN, wparam );
+ update_key_state( desktop, desktop->keystate, WM_MBUTTONDOWN, wparam );
if (flags & MOUSEEVENTF_MIDDLEUP)
- update_input_key_state( desktop, desktop->keystate, WM_MBUTTONUP, wparam );
+ update_key_state( desktop, desktop->keystate, WM_MBUTTONUP, wparam );
if (flags & MOUSEEVENTF_XDOWN)
- update_input_key_state( desktop, desktop->keystate, WM_XBUTTONDOWN, wparam );
+ update_key_state( desktop, desktop->keystate, WM_XBUTTONDOWN, wparam );
if (flags & MOUSEEVENTF_XUP)
- update_input_key_state( desktop, desktop->keystate, WM_XBUTTONUP, wparam );
+ update_key_state( desktop, desktop->keystate, WM_XBUTTONUP, wparam );
+}
+
+/* update the thread input key state for a keyboard message */
+static void update_input_key_state( struct thread_input *input, unsigned int msg, lparam_t wparam )
+{
+ update_key_state( input->desktop, input->keystate, msg, wparam );
}
/* release the hardware message currently being processed by the given thread */
@@ -1413,7 +1419,7 @@ static void release_hardware_message( struct msg_queue *queue, unsigned int hw_i
}
if (clr_bit) clear_queue_bits( queue, clr_bit );
- update_input_key_state( input->desktop, input->keystate, msg->msg, msg->wparam );
+ update_input_key_state( input, msg->msg, msg->wparam );
list_remove( &msg->entry );
free_message( msg );
}
@@ -1532,7 +1538,7 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
struct thread_input *input;
unsigned int msg_code;
- update_input_key_state( desktop, desktop->keystate, msg->msg, msg->wparam );
+ update_key_state( desktop, desktop->keystate, msg->msg, msg->wparam );
last_input_time = get_tick_count();
if (msg->msg != WM_MOUSEMOVE) always_queue = 1;
@@ -1567,7 +1573,7 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
win = find_hardware_message_window( desktop, input, msg, &msg_code, &thread );
if (!win || !thread)
{
- if (input) update_input_key_state( input->desktop, input->keystate, msg->msg, msg->wparam );
+ if (input) update_input_key_state( input, msg->msg, msg->wparam );
free_message( msg );
return;
}
@@ -1905,7 +1911,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
if ((device = current->process->rawinput_kbd) && (device->flags & RIDEV_NOLEGACY))
{
- update_input_key_state( desktop, desktop->keystate, message_code, vkey );
+ update_key_state( desktop, desktop->keystate, message_code, vkey );
return 0;
}
@@ -2034,7 +2040,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
if (!win || !win_thread)
{
/* no window at all, remove it */
- update_input_key_state( input->desktop, input->keystate, msg->msg, msg->wparam );
+ update_input_key_state( input, msg->msg, msg->wparam );
list_remove( &msg->entry );
free_message( msg );
continue;
@@ -2050,7 +2056,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
else
{
/* for another thread input, drop it */
- update_input_key_state( input->desktop, input->keystate, msg->msg, msg->wparam );
+ update_input_key_state( input, msg->msg, msg->wparam );
list_remove( &msg->entry );
free_message( msg );
}
--
2.27.0

View File

@ -0,0 +1,162 @@
From 8df095ad7919b8eb1f6317ffa90e0242bc51f243 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Fri, 10 Jul 2015 16:13:53 +0200
Subject: [PATCH] server: Implement locking and synchronization of keystate
buffer. (rev 3)
---
server/queue.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/server/queue.c b/server/queue.c
index e8df9775022..8d421195f63 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -113,7 +113,9 @@ struct thread_input
user_handle_t cursor; /* current cursor */
int cursor_count; /* cursor show count */
struct list msg_list; /* list of hardware messages */
+ int lock_count; /* lock counter for keystate */
unsigned char keystate[256]; /* state of each key */
+ unsigned char shadow_keystate[256]; /* shadow copy of keystate */
};
struct msg_queue
@@ -124,6 +126,7 @@ struct msg_queue
unsigned int wake_mask; /* wakeup mask */
unsigned int changed_bits; /* changed wakeup bits */
unsigned int changed_mask; /* changed wakeup mask */
+ int keystate_locked; /* keystate is locked */
int paint_count; /* pending paint messages count */
int hotkey_count; /* pending hotkey messages count */
int quit_message; /* is there a pending quit message? */
@@ -257,9 +260,11 @@ static struct thread_input *create_thread_input( struct thread *thread )
input->move_size = 0;
input->cursor = 0;
input->cursor_count = 0;
+ input->lock_count = 0;
list_init( &input->msg_list );
set_caret_window( input, 0 );
memset( input->keystate, 0, sizeof(input->keystate) );
+ memset( input->shadow_keystate, 0, sizeof(input->shadow_keystate) );
if (!(input->desktop = get_thread_desktop( thread, 0 /* FIXME: access rights */ )))
{
@@ -290,6 +295,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
queue->wake_mask = 0;
queue->changed_bits = 0;
queue->changed_mask = 0;
+ queue->keystate_locked = 0;
queue->paint_count = 0;
queue->hotkey_count = 0;
queue->quit_message = 0;
@@ -333,8 +339,10 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_
}
if (queue->input)
{
+ if (queue->keystate_locked) queue->input->lock_count--;
queue->input->cursor_count -= queue->cursor_count;
release_object( queue->input );
+ queue->keystate_locked = 0;
}
queue->input = (struct thread_input *)grab_object( new_input );
new_input->cursor_count += queue->cursor_count;
@@ -1025,6 +1033,7 @@ static void msg_queue_destroy( struct object *obj )
free( timer );
}
if (queue->timeout) remove_timeout_user( queue->timeout );
+ if (queue->keystate_locked) queue->input->lock_count--;
queue->input->cursor_count -= queue->cursor_count;
release_object( queue->input );
if (queue->hooks) release_object( queue->hooks );
@@ -1125,7 +1134,11 @@ int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
}
ret = assign_thread_input( thread_from, input );
- if (ret) memset( input->keystate, 0, sizeof(input->keystate) );
+ if (ret)
+ {
+ memset( input->keystate, 0, sizeof(input->keystate) );
+ memset( input->shadow_keystate, 0, sizeof(input->shadow_keystate) );
+ }
release_object( input );
return ret;
}
@@ -1383,9 +1396,30 @@ static void update_desktop_mouse_state( struct desktop *desktop, unsigned int fl
update_input_key_state( desktop, desktop->keystate, WM_XBUTTONUP, wparam );
}
+/* synchronizes the thread input key state with the desktop */
+static void synchronize_input_key_state( struct thread_input *input )
+{
+ if (!input->lock_count)
+ {
+ unsigned char *shadow_keystate = input->shadow_keystate;
+ unsigned char *keystate = input->keystate;
+ unsigned int i;
+
+ for (i = 0; i < 256; i++)
+ {
+ if (input->desktop->keystate[i] != shadow_keystate[i])
+ {
+ keystate[i] = input->desktop->keystate[i] & ~0x40;
+ shadow_keystate[i] = input->desktop->keystate[i];
+ }
+ }
+ }
+}
+
/* update the thread input key state for a keyboard message */
static void update_input_key_state( struct thread_input *input, unsigned int msg, lparam_t wparam )
{
+ synchronize_input_key_state( input );
update_key_state( input->desktop, input->keystate, msg, wparam );
}
@@ -1586,6 +1620,15 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
else
{
msg->unique_id = 0; /* will be set once we return it to the app */
+
+ /* lock the keystate on the first hardware message */
+ if (!thread->queue->keystate_locked)
+ {
+ synchronize_input_key_state( input );
+ input->lock_count++;
+ thread->queue->keystate_locked = 1;
+ }
+
list_add_tail( &input->msg_list, &msg->entry );
set_queue_bits( thread->queue, get_hardware_msg_bit(msg) );
}
@@ -2524,6 +2567,13 @@ DECL_HANDLER(get_message)
queue->last_get_msg = current_time;
if (!filter) filter = QS_ALLINPUT;
+ /* no longer lock the keystate if we have processed all input */
+ if (queue->keystate_locked && !(queue->wake_bits & QS_ALLINPUT))
+ {
+ queue->input->lock_count--;
+ queue->keystate_locked = 0;
+ }
+
/* first check for sent messages */
if ((ptr = list_head( &queue->msg_list[SEND_MESSAGE] )))
{
@@ -2980,7 +3030,12 @@ DECL_HANDLER(get_key_state)
if (!(thread = get_thread_from_id( req->tid ))) return;
if (thread->queue)
{
- if (req->key >= 0) reply->state = thread->queue->input->keystate[req->key & 0xff];
+ if (req->key >= 0)
+ {
+ /* synchronize with desktop keystate, but _only_ if req->key is given */
+ synchronize_input_key_state( thread->queue->input );
+ reply->state = thread->queue->input->keystate[req->key & 0xff];
+ }
set_reply_data( thread->queue->input->keystate, size );
release_object( thread );
return;
--
2.27.0

View File

@ -0,0 +1,5 @@
# Fixes: [27238] Fallback to global key state for threads without a queue
Fixes: [31899] Implement locking and synchronization of key states
Fixes: [35907] Fix caps lock state issues with multiple processes
# Please review this for correctness; rebasing against 8cf7fe3b7c2 may have
# broken it.