Alexandre Julliard : server: Store the global key state in the server.

Alexandre Julliard julliard at winehq.org
Fri Feb 25 11:19:46 CST 2011


Module: wine
Branch: master
Commit: 06b78feadec13335d96cf3560e2db2ffa6cc4739
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=06b78feadec13335d96cf3560e2db2ffa6cc4739

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Feb 25 12:10:04 2011 +0100

server: Store the global key state in the server.

---

 server/queue.c      |   88 ++++++++++++++++++++++++++++++---------------------
 server/user.h       |    1 +
 server/winstation.c |    1 +
 3 files changed, 54 insertions(+), 36 deletions(-)

diff --git a/server/queue.c b/server/queue.c
index 16486cd..281c8bc 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1101,18 +1101,18 @@ static struct timer *set_timer( struct msg_queue *queue, unsigned int rate )
 }
 
 /* change the input key state for a given key */
-static void set_input_key_state( struct thread_input *input, unsigned char key, int down )
+static void set_input_key_state( unsigned char *keystate, unsigned char key, int down )
 {
     if (down)
     {
-        if (!(input->keystate[key] & 0x80)) input->keystate[key] ^= 0x01;
-        input->keystate[key] |= 0x80;
+        if (!(keystate[key] & 0x80)) keystate[key] ^= 0x01;
+        keystate[key] |= 0x80;
     }
-    else input->keystate[key] &= ~0x80;
+    else keystate[key] &= ~0x80;
 }
 
 /* update the input key state for a keyboard message */
-static void update_input_key_state( struct thread_input *input, const struct message *msg )
+static void update_input_key_state( unsigned char *keystate, const struct message *msg )
 {
     unsigned char key;
     int down = 0;
@@ -1123,26 +1123,26 @@ static void update_input_key_state( struct thread_input *input, const struct mes
         down = 1;
         /* fall through */
     case WM_LBUTTONUP:
-        set_input_key_state( input, VK_LBUTTON, down );
+        set_input_key_state( keystate, VK_LBUTTON, down );
         break;
     case WM_MBUTTONDOWN:
         down = 1;
         /* fall through */
     case WM_MBUTTONUP:
-        set_input_key_state( input, VK_MBUTTON, down );
+        set_input_key_state( keystate, VK_MBUTTON, down );
         break;
     case WM_RBUTTONDOWN:
         down = 1;
         /* fall through */
     case WM_RBUTTONUP:
-        set_input_key_state( input, VK_RBUTTON, down );
+        set_input_key_state( keystate, VK_RBUTTON, down );
         break;
     case WM_XBUTTONDOWN:
         down = 1;
         /* fall through */
     case WM_XBUTTONUP:
-        if (msg->wparam == XBUTTON1) set_input_key_state( input, VK_XBUTTON1, down );
-        else if (msg->wparam == XBUTTON2) set_input_key_state( input, VK_XBUTTON2, down );
+        if (msg->wparam == XBUTTON1) set_input_key_state( keystate, VK_XBUTTON1, down );
+        else if (msg->wparam == XBUTTON2) set_input_key_state( keystate, VK_XBUTTON2, down );
         break;
     case WM_KEYDOWN:
     case WM_SYSKEYDOWN:
@@ -1151,23 +1151,23 @@ static void update_input_key_state( struct thread_input *input, const struct mes
     case WM_KEYUP:
     case WM_SYSKEYUP:
         key = (unsigned char)msg->wparam;
-        set_input_key_state( input, key, down );
+        set_input_key_state( keystate, key, down );
         switch(key)
         {
         case VK_LCONTROL:
         case VK_RCONTROL:
-            down = (input->keystate[VK_LCONTROL] | input->keystate[VK_RCONTROL]) & 0x80;
-            set_input_key_state( input, VK_CONTROL, down );
+            down = (keystate[VK_LCONTROL] | keystate[VK_RCONTROL]) & 0x80;
+            set_input_key_state( keystate, VK_CONTROL, down );
             break;
         case VK_LMENU:
         case VK_RMENU:
-            down = (input->keystate[VK_LMENU] | input->keystate[VK_RMENU]) & 0x80;
-            set_input_key_state( input, VK_MENU, down );
+            down = (keystate[VK_LMENU] | keystate[VK_RMENU]) & 0x80;
+            set_input_key_state( keystate, VK_MENU, down );
             break;
         case VK_LSHIFT:
         case VK_RSHIFT:
-            down = (input->keystate[VK_LSHIFT] | input->keystate[VK_RSHIFT]) & 0x80;
-            set_input_key_state( input, VK_SHIFT, down );
+            down = (keystate[VK_LSHIFT] | keystate[VK_RSHIFT]) & 0x80;
+            set_input_key_state( keystate, VK_SHIFT, down );
             break;
         }
         break;
@@ -1229,7 +1229,7 @@ static void release_hardware_message( struct msg_queue *queue, unsigned int hw_i
     }
     if (remove)
     {
-        update_input_key_state( input, msg );
+        update_input_key_state( input->keystate, msg );
         list_remove( &msg->entry );
         free_message( msg );
     }
@@ -1283,11 +1283,12 @@ static void queue_hardware_message( struct desktop *desktop, struct thread_input
     if (msg->msg == WM_MOUSEMOVE) set_cursor_pos( desktop, data->x, data->y );
     data->x = desktop->cursor_x;
     data->y = desktop->cursor_y;
+    update_input_key_state( desktop->keystate, msg );
     last_input_time = get_tick_count();
     win = find_hardware_message_window( input, msg, &msg_code );
     if (!win || !(thread = get_window_thread(win)))
     {
-        if (input) update_input_key_state( input, msg );
+        if (input) update_input_key_state( input->keystate, msg );
         free( msg );
         return;
     }
@@ -1377,7 +1378,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
         if (!win || !(win_thread = get_window_thread( win )))
         {
             /* no window at all, remove it */
-            update_input_key_state( input, msg );
+            update_input_key_state( input->keystate, msg );
             list_remove( &msg->entry );
             free_message( msg );
             continue;
@@ -1393,7 +1394,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, msg );
+                update_input_key_state( input->keystate, msg );
                 list_remove( &msg->entry );
                 free_message( msg );
             }
@@ -2098,33 +2099,48 @@ DECL_HANDLER(get_thread_input)
 DECL_HANDLER(get_key_state)
 {
     struct thread *thread;
-    struct thread_input *input;
+    struct desktop *desktop;
+    data_size_t size = min( 256, get_reply_max_size() );
 
-    if (!(thread = get_thread_from_id( req->tid ))) return;
-    input = thread->queue ? thread->queue->input : NULL;
-    if (input)
+    if (!req->tid)  /* get global async key state */
     {
-        if (req->key >= 0) reply->state = input->keystate[req->key & 0xff];
-        set_reply_data( input->keystate, min( get_reply_max_size(), sizeof(input->keystate) ));
+        if (!(desktop = get_thread_desktop( current, 0 ))) return;
+        if (req->key >= 0) reply->state = desktop->keystate[req->key & 0xff];
+        set_reply_data( desktop->keystate, size );
+        release_object( desktop );
+    }
+    else
+    {
+        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];
+            set_reply_data( thread->queue->input->keystate, size );
+        }
+        release_object( thread );
     }
-    release_object( thread );
 }
 
 
 /* set queue keyboard state for a given thread */
 DECL_HANDLER(set_key_state)
 {
-    struct thread *thread = NULL;
-    struct thread_input *input;
+    struct thread *thread;
+    struct desktop *desktop;
+    data_size_t size = min( 256, get_req_data_size() );
 
-    if (!(thread = get_thread_from_id( req->tid ))) return;
-    input = thread->queue ? thread->queue->input : NULL;
-    if (input)
+    if (!req->tid)  /* set global async key state */
     {
-        data_size_t size = min( sizeof(input->keystate), get_req_data_size() );
-        if (size) memcpy( input->keystate, get_req_data(), size );
+        if (!(desktop = get_thread_desktop( current, 0 ))) return;
+        memcpy( desktop->keystate, get_req_data(), size );
+        release_object( desktop );
+    }
+    else
+    {
+        if (!(thread = get_thread_from_id( req->tid ))) return;
+        if (thread->queue) memcpy( thread->queue->input->keystate, get_req_data(), size );
+        release_object( thread );
     }
-    release_object( thread );
 }
 
 
diff --git a/server/user.h b/server/user.h
index 8fc19e9..5d7bec8 100644
--- a/server/user.h
+++ b/server/user.h
@@ -66,6 +66,7 @@ struct desktop
     int                  cursor_x;         /* cursor position */
     int                  cursor_y;
     rectangle_t          cursor_clip;      /* cursor clip rectangle */
+    unsigned char        keystate[256];    /* asynchronous key state */
 };
 
 /* user handles functions */
diff --git a/server/winstation.c b/server/winstation.c
index f23dcfe..13871cf 100644
--- a/server/winstation.c
+++ b/server/winstation.c
@@ -238,6 +238,7 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned
             desktop->cursor_clip.top    = 0;
             desktop->cursor_clip.right  = 0;
             desktop->cursor_clip.bottom = 0;
+            memset( desktop->keystate, 0, sizeof(desktop->keystate) );
             list_add_tail( &winstation->desktops, &desktop->entry );
         }
     }




More information about the wine-cvs mailing list