Module: wine Branch: master Commit: 4f4ede56e9f5d97029b37434badd77e80ece2e93 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4f4ede56e9f5d97029b37434ba...
Author: Hans Leidekker hans@codeweavers.com Date: Fri Jun 9 09:21:52 2017 +0200
wineandroid: Synchronize keyboard lock state.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wineandroid.drv/android.h | 2 ++ dlls/wineandroid.drv/keyboard.c | 63 +++++++++++++++++++++++++++++++++++++++++ dlls/wineandroid.drv/window.c | 1 + 3 files changed, 66 insertions(+)
diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index ca026fa..0c3f35f 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -81,6 +81,7 @@ enum android_window_messages
extern HWND get_capture_window(void) DECLSPEC_HIDDEN; extern void init_monitors( int width, int height ) DECLSPEC_HIDDEN; +extern void update_keyboard_lock_state( WORD vkey, UINT state ) DECLSPEC_HIDDEN;
/* JNI entry points */ extern void desktop_changed( JNIEnv *env, jobject obj, jint width, jint height ) DECLSPEC_HIDDEN; @@ -125,6 +126,7 @@ union event_data { enum event_type type; HWND hwnd; + UINT lock_state; INPUT input; } kbd; }; diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c index 741b76a..e6e1d02 100644 --- a/dlls/wineandroid.drv/keyboard.c +++ b/dlls/wineandroid.drv/keyboard.c @@ -33,6 +33,7 @@
#include "android.h" #include "wine/unicode.h" +#include "wine/server.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(keyboard); @@ -653,6 +654,67 @@ static const char* vkey_to_name( UINT vkey ) return NULL; }
+static BOOL get_async_key_state( BYTE state[256] ) +{ + BOOL ret; + + SERVER_START_REQ( get_key_state ) + { + req->tid = 0; + req->key = -1; + wine_server_set_reply( req, state, 256 ); + ret = !wine_server_call( req ); + } + SERVER_END_REQ; + return ret; +} + +static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags ) +{ + INPUT input; + + input.type = INPUT_KEYBOARD; + input.u.ki.wVk = vkey; + input.u.ki.wScan = scan; + input.u.ki.dwFlags = flags; + input.u.ki.time = 0; + input.u.ki.dwExtraInfo = 0; + + __wine_send_input( hwnd, &input ); +} + +/*********************************************************************** + * update_keyboard_lock_state + */ +void update_keyboard_lock_state( WORD vkey, UINT state ) +{ + BYTE keystate[256]; + + if (!get_async_key_state( keystate )) return; + + if (!(keystate[VK_CAPITAL] & 0x01) != !(state & AMETA_CAPS_LOCK_ON) && vkey != VK_CAPITAL) + { + TRACE( "adjusting CapsLock state (%02x)\n", keystate[VK_CAPITAL] ); + send_keyboard_input( 0, VK_CAPITAL, 0x3a, 0 ); + send_keyboard_input( 0, VK_CAPITAL, 0x3a, KEYEVENTF_KEYUP ); + } + + if (!(keystate[VK_NUMLOCK] & 0x01) != !(state & AMETA_NUM_LOCK_ON) && (vkey & 0xff) != VK_NUMLOCK) + { + TRACE( "adjusting NumLock state (%02x)\n", keystate[VK_NUMLOCK] ); + send_keyboard_input( 0, VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY ); + send_keyboard_input( 0, VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP ); + } + + if (!(keystate[VK_SCROLL] & 0x01) != !(state & AMETA_SCROLL_LOCK_ON) && vkey != VK_SCROLL) + { + TRACE( "adjusting ScrollLock state (%02x)\n", keystate[VK_SCROLL] ); + send_keyboard_input( 0, VK_SCROLL, 0x46, 0 ); + send_keyboard_input( 0, VK_SCROLL, 0x46, KEYEVENTF_KEYUP ); + } +} + + /*********************************************************************** * keyboard_event * @@ -671,6 +733,7 @@ jboolean keyboard_event( JNIEnv *env, jobject obj, jint win, jint action, jint k } data.type = KEYBOARD_EVENT; data.kbd.hwnd = LongToHandle( win ); + data.kbd.lock_state = state; data.kbd.input.type = INPUT_KEYBOARD; data.kbd.input.u.ki.wVk = keycode_to_vkey[keycode]; data.kbd.input.u.ki.wScan = vkey_to_scancode[data.kbd.input.u.ki.wVk]; diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 2ddcdf1..33f2240 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -482,6 +482,7 @@ static int process_events( DWORD mask ) TRACE("KEYDOWN hwnd %p vkey %x '%c' scancode %x\n", event->data.kbd.hwnd, event->data.kbd.input.u.ki.wVk, event->data.kbd.input.u.ki.wVk, event->data.kbd.input.u.ki.wScan ); + update_keyboard_lock_state( event->data.kbd.input.u.ki.wVk, event->data.kbd.lock_state ); __wine_send_input( 0, &event->data.kbd.input ); break;