Module: wine Branch: master Commit: 36c76dcc24c1f66ccbfeb55495da4794c74dc868 URL: http://source.winehq.org/git/wine.git/?a=commit;h=36c76dcc24c1f66ccbfeb55495...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Feb 2 17:19:34 2012 +0100
winex11: Update only the key state on KeymapNotify without sending fake key events.
---
dlls/winex11.drv/keyboard.c | 54 ++++++++++++++++++++++++++++------------ include/wine/server_protocol.h | 4 ++- server/protocol.def | 1 + server/queue.c | 5 +++ server/request.h | 3 +- server/trace.c | 1 + 6 files changed, 50 insertions(+), 18 deletions(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 160b986..57deb59 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1176,6 +1176,31 @@ static BOOL get_async_key_state( BYTE state[256] ) }
/*********************************************************************** + * set_async_key_state + */ +static void set_async_key_state( const BYTE state[256] ) +{ + SERVER_START_REQ( set_key_state ) + { + req->tid = GetCurrentThreadId(); + req->async = 1; + wine_server_add_data( req, state, 256 ); + wine_server_call( req ); + } + SERVER_END_REQ; +} + +static void update_key_state( BYTE *keystate, BYTE key, int down ) +{ + if (down) + { + if (!(keystate[key] & 0x80)) keystate[key] ^= 0x01; + keystate[key] |= 0x80; + } + else keystate[key] &= ~0x80; +} + +/*********************************************************************** * X11DRV_KeymapNotify * * Update modifiers state (Ctrl, Alt, Shift) when window is activated. @@ -1187,12 +1212,11 @@ static BOOL get_async_key_state( BYTE state[256] ) void X11DRV_KeymapNotify( HWND hwnd, XEvent *event ) { int i, j; - DWORD time = GetCurrentTime(); BYTE keystate[256]; WORD vkey; + BOOL changed = FALSE; struct { WORD vkey; - WORD scan; BOOL pressed; } modifiers[6]; /* VK_LSHIFT through VK_RMENU are contiguous */
@@ -1220,15 +1244,9 @@ void X11DRV_KeymapNotify( HWND hwnd, XEvent *event ) case VK_LSHIFT: case VK_RSHIFT: m = (vkey & 0xff) - VK_LSHIFT; - /* Take the vkey and scan from the first keycode we encounter - for this modifier. */ - if (!modifiers[m].vkey) - { - modifiers[m].vkey = vkey; - modifiers[m].scan = keyc2scan[(i * 8) + j]; - } - if (event->xkeymap.key_vector[i] & (1<<j)) - modifiers[m].pressed = TRUE; + /* Take the vkey from the first keycode we encounter for this modifier */ + if (!modifiers[m].vkey) modifiers[m].vkey = vkey; + if (event->xkeymap.key_vector[i] & (1<<j)) modifiers[m].pressed = TRUE; break; } } @@ -1239,16 +1257,20 @@ void X11DRV_KeymapNotify( HWND hwnd, XEvent *event ) int m = vkey - VK_LSHIFT; if (modifiers[m].vkey && !(keystate[vkey] & 0x80) != !modifiers[m].pressed) { - DWORD flags = modifiers[m].vkey & 0x100 ? KEYEVENTF_EXTENDEDKEY : 0; - if (!modifiers[m].pressed) flags |= KEYEVENTF_KEYUP; - TRACE( "Adjusting state for vkey %#.2x. State before %#.2x\n", modifiers[m].vkey, keystate[vkey]);
- /* Fake key being pressed inside wine */ - X11DRV_send_keyboard_input( hwnd, vkey, modifiers[m].scan & 0xff, flags, time ); + update_key_state( keystate, vkey, modifiers[m].pressed ); + changed = TRUE; } } + + if (!changed) return; + + update_key_state( keystate, VK_CONTROL, (keystate[VK_LCONTROL] | keystate[VK_RCONTROL]) & 0x80 ); + update_key_state( keystate, VK_MENU, (keystate[VK_LMENU] | keystate[VK_RMENU]) & 0x80 ); + update_key_state( keystate, VK_SHIFT, (keystate[VK_LSHIFT] | keystate[VK_RSHIFT]) & 0x80 ); + set_async_key_state( keystate ); }
static void update_lock_state( HWND hwnd, WORD vkey, UINT state, DWORD time ) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index fc51291..0e989da 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -3838,7 +3838,9 @@ struct set_key_state_request { struct request_header __header; thread_id_t tid; + int async; /* VARARG(keystate,bytes); */ + char __pad_20[4]; }; struct set_key_state_reply { @@ -5644,6 +5646,6 @@ union generic_reply struct set_suspend_context_reply set_suspend_context_reply; };
-#define SERVER_PROTOCOL_VERSION 430 +#define SERVER_PROTOCOL_VERSION 431
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index 73f2d8e..80c0cd3 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2706,6 +2706,7 @@ enum coords_relative /* Set queue keyboard state for a given thread */ @REQ(set_key_state) thread_id_t tid; /* id of thread */ + int async; /* whether to change the async state too */ VARARG(keystate,bytes); /* state array for all the keys */ @END
diff --git a/server/queue.c b/server/queue.c index 2cd82b4..4fd32ed 100644 --- a/server/queue.c +++ b/server/queue.c @@ -2724,6 +2724,11 @@ DECL_HANDLER(set_key_state) { if (!(thread = get_thread_from_id( req->tid ))) return; if (thread->queue) memcpy( thread->queue->input->keystate, get_req_data(), size ); + if (req->async && (desktop = get_thread_desktop( thread, 0 ))) + { + memcpy( desktop->keystate, get_req_data(), size ); + release_object( desktop ); + } release_object( thread ); } } diff --git a/server/request.h b/server/request.h index c1cca4c..5b45cf9 100644 --- a/server/request.h +++ b/server/request.h @@ -1756,7 +1756,8 @@ C_ASSERT( sizeof(struct get_key_state_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_key_state_reply, state) == 8 ); C_ASSERT( sizeof(struct get_key_state_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_key_state_request, tid) == 12 ); -C_ASSERT( sizeof(struct set_key_state_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct set_key_state_request, async) == 16 ); +C_ASSERT( sizeof(struct set_key_state_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct set_foreground_window_request, handle) == 12 ); C_ASSERT( sizeof(struct set_foreground_window_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_foreground_window_reply, previous) == 8 ); diff --git a/server/trace.c b/server/trace.c index b8dc316..cfef963 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3162,6 +3162,7 @@ static void dump_get_key_state_reply( const struct get_key_state_reply *req ) static void dump_set_key_state_request( const struct set_key_state_request *req ) { fprintf( stderr, " tid=%04x", req->tid ); + fprintf( stderr, ", async=%d", req->async ); dump_varargs_bytes( ", keystate=", cur_size ); }