[PATCH v2 1/4] user32: Move ToUnicodeEx from wineandroid.drv to user32.

Rémi Bernon rbernon at codeweavers.com
Fri Apr 23 12:30:05 CDT 2021


As a default implementation for en_US keyboard layout, calling the
driver implementation next so that it can override the result.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

v2: Move code from driver to user32 common code instead of nulldrv,
    graphics drivers callbacks are then called to have a chance to
    override the default values.

    The last patch completely removes LoadKeyboardLayout driver call,
    it was unimplemented anyway. It can just be ignored if that's not
    the right way forward.

    IMHO it'd make things easier to have an internal keyboard layout
    management, with key translations being done according to the thread
    and process active layouts, but I can also see why we would like to
    make it more seamlessly integrated with the system (although I'm not
    sure if it's possible to map all Windows specificities).

Supersdes: 204099-204104

 dlls/user32/driver.c                      |  8 +-
 dlls/user32/input.c                       | 79 ++++++++++++++++++-
 dlls/user32/user_private.h                |  2 +-
 dlls/wineandroid.drv/keyboard.c           | 94 -----------------------
 dlls/wineandroid.drv/wineandroid.drv.spec |  1 -
 dlls/winemac.drv/keyboard.c               |  2 +-
 dlls/winemac.drv/winemac.drv.spec         |  2 +-
 dlls/winex11.drv/keyboard.c               |  2 +-
 dlls/winex11.drv/winex11.drv.spec         |  2 +-
 9 files changed, 84 insertions(+), 108 deletions(-)

diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index 7ac77141696..7f26a48657f 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -284,9 +284,9 @@ static BOOL CDECL nulldrv_RegisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
 }
 
 static INT CDECL nulldrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str,
-                                      int size, UINT flags, HKL layout )
+                                      int size, UINT flags, HKL layout, INT default_ret )
 {
-    return 0;
+    return default_ret;
 }
 
 static BOOL CDECL nulldrv_UnloadKeyboardLayout( HKL layout )
@@ -592,9 +592,9 @@ static BOOL CDECL loaderdrv_RegisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
 }
 
 static INT CDECL loaderdrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str,
-                                  int size, UINT flags, HKL layout )
+                                        int size, UINT flags, HKL layout, INT default_ret )
 {
-    return load_driver()->pToUnicodeEx( virt, scan, state, str, size, flags, layout );
+    return load_driver()->pToUnicodeEx( virt, scan, state, str, size, flags, layout, default_ret );
 }
 
 static BOOL CDECL loaderdrv_UnloadKeyboardLayout( HKL layout )
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 805bfe3e9de..4f0be6be3f2 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -877,11 +877,82 @@ INT WINAPI ToUnicode(UINT virtKey, UINT scanCode, const BYTE *lpKeyState,
 /****************************************************************************
  *		ToUnicodeEx (USER32.@)
  */
-INT WINAPI ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState,
-		       LPWSTR lpwStr, int size, UINT flags, HKL hkl)
+INT WINAPI ToUnicodeEx( UINT virt, UINT scan, const BYTE *state,
+		                WCHAR *str, int size, UINT flags, HKL layout )
 {
-    if (!lpKeyState) return 0;
-    return USER_Driver->pToUnicodeEx(virtKey, scanCode, lpKeyState, lpwStr, size, flags, hkl);
+    static HKL us_layout = (HKL)MAKELONG(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT));
+    BOOL shift, ctrl, numlock;
+    WCHAR buffer[2];
+    INT len;
+
+    TRACE_(keyboard)( "virt %u, scan %u, state %p, str %p, size %d, flags %x, layout %p.\n",
+                      virt, scan, state, str, size, flags, layout );
+
+    if (!state) return 0;
+
+    shift = state[VK_SHIFT] & 0x80;
+    ctrl = state[VK_CONTROL] & 0x80;
+    numlock = state[VK_NUMLOCK] & 0x01;
+
+    if (layout != us_layout) buffer[0] = 0; /* FIXME: non-us layout */
+    else if (scan & 0x8000) buffer[0] = 0; /* key up */
+    else if (!ctrl)
+    {
+        switch (virt)
+        {
+        case VK_BACK:       buffer[0] = '\b'; break;
+        case VK_OEM_1:      buffer[0] = shift ? ':' : ';'; break;
+        case VK_OEM_2:      buffer[0] = shift ? '?' : '/'; break;
+        case VK_OEM_3:      buffer[0] = shift ? '~' : '`'; break;
+        case VK_OEM_4:      buffer[0] = shift ? '{' : '['; break;
+        case VK_OEM_5:      buffer[0] = shift ? '|' : '\\'; break;
+        case VK_OEM_6:      buffer[0] = shift ? '}' : ']'; break;
+        case VK_OEM_7:      buffer[0] = shift ? '"' : '\''; break;
+        case VK_OEM_COMMA:  buffer[0] = shift ? '<' : ','; break;
+        case VK_OEM_MINUS:  buffer[0] = shift ? '_' : '-'; break;
+        case VK_OEM_PERIOD: buffer[0] = shift ? '>' : '.'; break;
+        case VK_OEM_PLUS:   buffer[0] = shift ? '+' : '='; break;
+        case VK_RETURN:     buffer[0] = '\r'; break;
+        case VK_SPACE:      buffer[0] = ' '; break;
+        case VK_TAB:        buffer[0] = '\t'; break;
+        case VK_MULTIPLY:   buffer[0] = '*'; break;
+        case VK_ADD:        buffer[0] = '+'; break;
+        case VK_SUBTRACT:   buffer[0] = '-'; break;
+        case VK_DIVIDE:     buffer[0] = '/'; break;
+        default:
+            if (virt >= '0' && virt <= '9')
+                buffer[0] = shift ? ")!@#$%^&*("[virt - '0'] : virt;
+            else if (virt >= 'A' && virt <= 'Z')
+                buffer[0] = shift || (state[VK_CAPITAL] & 0x01) ? virt : virt + 'a' - 'A';
+            else if (virt >= VK_NUMPAD0 && virt <= VK_NUMPAD9 && numlock && !shift)
+                buffer[0] = '0' + virt - VK_NUMPAD0;
+            else if (virt == VK_DECIMAL && numlock && !shift)
+                buffer[0] = '.';
+            else
+                buffer[0] = 0;
+            break;
+        }
+    }
+    else /* Control codes */
+    {
+        switch (virt)
+        {
+        case VK_OEM_4:     buffer[0] = 0x1b; break;
+        case VK_OEM_5:     buffer[0] = 0x1c; break;
+        case VK_OEM_6:     buffer[0] = 0x1d; break;
+        case VK_SUBTRACT:  buffer[0] = 0x1e; break;
+        default:
+            if (virt >= 'A' && virt <= 'Z') buffer[0] = virt - 'A' + 1;
+            else buffer[0] = 0;
+            break;
+        }
+    }
+    buffer[1] = 0;
+
+    wcsncpy( str, buffer, size );
+    len = USER_Driver->pToUnicodeEx( virt, scan, state, str, size, flags, layout, wcslen( buffer ) );
+    TRACE_(keyboard)( "ret %d, str %s.\n", len, debugstr_wn(str, len) );
+    return len;
 }
 
 /****************************************************************************
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 5f8059a12a0..98eec94da57 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -71,7 +71,7 @@ typedef struct tagUSER_DRIVER {
     HKL    (CDECL *pLoadKeyboardLayout)(LPCWSTR, UINT);
     UINT   (CDECL *pMapVirtualKeyEx)(UINT, UINT, HKL);
     BOOL   (CDECL *pRegisterHotKey)(HWND, UINT, UINT);
-    INT    (CDECL *pToUnicodeEx)(UINT, UINT, const BYTE *, LPWSTR, int, UINT, HKL);
+    INT    (CDECL *pToUnicodeEx)(UINT, UINT, const BYTE *, LPWSTR, int, UINT, HKL, INT);
     BOOL   (CDECL *pUnloadKeyboardLayout)(HKL);
     void   (CDECL *pUnregisterHotKey)(HWND, UINT, UINT);
     SHORT  (CDECL *pVkKeyScanEx)(WCHAR, HKL);
diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c
index 0a6ede0ec5f..04565c3fad8 100644
--- a/dlls/wineandroid.drv/keyboard.c
+++ b/dlls/wineandroid.drv/keyboard.c
@@ -750,100 +750,6 @@ jboolean keyboard_event( JNIEnv *env, jobject obj, jint win, jint action, jint k
 }
 
 
-/***********************************************************************
- *           ANDROID_ToUnicodeEx
- */
-INT CDECL ANDROID_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state,
-                               LPWSTR buf, int size, UINT flags, HKL hkl )
-{
-    WCHAR buffer[2];
-    BOOL shift = state[VK_SHIFT] & 0x80;
-    BOOL ctrl = state[VK_CONTROL] & 0x80;
-    BOOL numlock = state[VK_NUMLOCK] & 0x01;
-
-    buffer[0] = buffer[1] = 0;
-
-    if (scan & 0x8000) return 0;  /* key up */
-
-    /* FIXME: hardcoded layout */
-
-    if (!ctrl)
-    {
-        switch (virt)
-        {
-        case VK_BACK:       buffer[0] = '\b'; break;
-        case VK_OEM_1:      buffer[0] = shift ? ':' : ';'; break;
-        case VK_OEM_2:      buffer[0] = shift ? '?' : '/'; break;
-        case VK_OEM_3:      buffer[0] = shift ? '~' : '`'; break;
-        case VK_OEM_4:      buffer[0] = shift ? '{' : '['; break;
-        case VK_OEM_5:      buffer[0] = shift ? '|' : '\\'; break;
-        case VK_OEM_6:      buffer[0] = shift ? '}' : ']'; break;
-        case VK_OEM_7:      buffer[0] = shift ? '"' : '\''; break;
-        case VK_OEM_COMMA:  buffer[0] = shift ? '<' : ','; break;
-        case VK_OEM_MINUS:  buffer[0] = shift ? '_' : '-'; break;
-        case VK_OEM_PERIOD: buffer[0] = shift ? '>' : '.'; break;
-        case VK_OEM_PLUS:   buffer[0] = shift ? '+' : '='; break;
-        case VK_RETURN:     buffer[0] = '\r'; break;
-        case VK_SPACE:      buffer[0] = ' '; break;
-        case VK_TAB:        buffer[0] = '\t'; break;
-        case VK_MULTIPLY:   buffer[0] = '*'; break;
-        case VK_ADD:        buffer[0] = '+'; break;
-        case VK_SUBTRACT:   buffer[0] = '-'; break;
-        case VK_DIVIDE:     buffer[0] = '/'; break;
-        default:
-            if (virt >= '0' && virt <= '9')
-            {
-                buffer[0] = shift ? ")!@#$%^&*("[virt - '0'] : virt;
-                break;
-            }
-            if (virt >= 'A' && virt <= 'Z')
-            {
-                buffer[0] =  shift || (state[VK_CAPITAL] & 0x01) ? virt : virt + 'a' - 'A';
-                break;
-            }
-            if (virt >= VK_NUMPAD0 && virt <= VK_NUMPAD9 && numlock && !shift)
-            {
-                buffer[0] = '0' + virt - VK_NUMPAD0;
-                break;
-            }
-            if (virt == VK_DECIMAL && numlock && !shift)
-            {
-                buffer[0] = '.';
-                break;
-            }
-            break;
-        }
-    }
-    else /* Control codes */
-    {
-        if (virt >= 'A' && virt <= 'Z')
-            buffer[0] = virt - 'A' + 1;
-        else
-        {
-            switch (virt)
-            {
-            case VK_OEM_4:
-                buffer[0] = 0x1b;
-                break;
-            case VK_OEM_5:
-                buffer[0] = 0x1c;
-                break;
-            case VK_OEM_6:
-                buffer[0] = 0x1d;
-                break;
-            case VK_SUBTRACT:
-                buffer[0] = 0x1e;
-                break;
-            }
-        }
-    }
-
-    lstrcpynW( buf, buffer, size );
-    TRACE( "returning %d / %s\n", strlenW( buffer ), debugstr_wn(buf, strlenW( buffer )));
-    return strlenW( buffer );
-}
-
-
 /***********************************************************************
  *           ANDROID_GetKeyNameText
  */
diff --git a/dlls/wineandroid.drv/wineandroid.drv.spec b/dlls/wineandroid.drv/wineandroid.drv.spec
index 00de23de27e..6f27c1586b3 100644
--- a/dlls/wineandroid.drv/wineandroid.drv.spec
+++ b/dlls/wineandroid.drv/wineandroid.drv.spec
@@ -7,7 +7,6 @@
 @ cdecl GetKeyNameText(long ptr long) ANDROID_GetKeyNameText
 @ cdecl GetKeyboardLayout(long) ANDROID_GetKeyboardLayout
 @ cdecl MapVirtualKeyEx(long long long) ANDROID_MapVirtualKeyEx
-@ cdecl ToUnicodeEx(long long ptr ptr long long long) ANDROID_ToUnicodeEx
 @ cdecl VkKeyScanEx(long long) ANDROID_VkKeyScanEx
 @ cdecl SetCursor(long) ANDROID_SetCursor
 @ cdecl ChangeDisplaySettingsEx(ptr ptr long long long) ANDROID_ChangeDisplaySettingsEx
diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c
index 1ea15f59341..5e4b5882c77 100644
--- a/dlls/winemac.drv/keyboard.c
+++ b/dlls/winemac.drv/keyboard.c
@@ -1553,7 +1553,7 @@ BOOL CDECL macdrv_RegisterHotKey(HWND hwnd, UINT mod_flags, UINT vkey)
  *
  */
 INT CDECL macdrv_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState,
-                             LPWSTR bufW, int bufW_size, UINT flags, HKL hkl)
+                             LPWSTR bufW, int bufW_size, UINT flags, HKL hkl, INT default_ret)
 {
     struct macdrv_thread_data *thread_data = macdrv_init_thread_data();
     INT ret = 0;
diff --git a/dlls/winemac.drv/winemac.drv.spec b/dlls/winemac.drv/winemac.drv.spec
index 39cf33370b4..3baa730eabc 100644
--- a/dlls/winemac.drv/winemac.drv.spec
+++ b/dlls/winemac.drv/winemac.drv.spec
@@ -34,7 +34,7 @@
 @ cdecl SysCommand(long long long) macdrv_SysCommand
 @ cdecl SystemParametersInfo(long long ptr long) macdrv_SystemParametersInfo
 @ cdecl ThreadDetach() macdrv_ThreadDetach
-@ cdecl ToUnicodeEx(long long ptr ptr long long long) macdrv_ToUnicodeEx
+@ cdecl ToUnicodeEx(long long ptr ptr long long long long) macdrv_ToUnicodeEx
 @ cdecl UnregisterHotKey(long long long) macdrv_UnregisterHotKey
 @ cdecl UpdateClipboard() macdrv_UpdateClipboard
 @ cdecl UpdateLayeredWindow(long ptr ptr) macdrv_UpdateLayeredWindow
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 01620c5e4a4..82dd67d9373 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -2432,7 +2432,7 @@ static char KEYBOARD_MapDeadKeysym(KeySym keysym)
  *
  */
 INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState,
-                             LPWSTR bufW, int bufW_size, UINT flags, HKL hkl)
+                             LPWSTR bufW, int bufW_size, UINT flags, HKL hkl, INT default_ret)
 {
     Display *display = thread_init_display();
     XKeyEvent e;
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index c0e24d8fe82..7aecac2c016 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -11,7 +11,7 @@
 @ cdecl GetKeyboardLayoutName(ptr) X11DRV_GetKeyboardLayoutName
 @ cdecl LoadKeyboardLayout(wstr long) X11DRV_LoadKeyboardLayout
 @ cdecl MapVirtualKeyEx(long long long) X11DRV_MapVirtualKeyEx
-@ cdecl ToUnicodeEx(long long ptr ptr long long long) X11DRV_ToUnicodeEx
+@ cdecl ToUnicodeEx(long long ptr ptr long long long long) X11DRV_ToUnicodeEx
 @ cdecl UnloadKeyboardLayout(long) X11DRV_UnloadKeyboardLayout
 @ cdecl VkKeyScanEx(long long) X11DRV_VkKeyScanEx
 @ cdecl DestroyCursorIcon(long) X11DRV_DestroyCursorIcon
-- 
2.31.0




More information about the wine-devel mailing list