Commit 06b78fea authored by Alexandre Julliard's avatar Alexandre Julliard

server: Store the global key state in the server.

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