Rémi Bernon : user32: Move GetKeyboardLayoutList from nulldrv.

Alexandre Julliard julliard at winehq.org
Fri Apr 30 16:03:27 CDT 2021


Module: wine
Branch: master
Commit: 66c3181444dbe4ba93b1a53c8db4fcb836e7b61f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=66c3181444dbe4ba93b1a53c8db4fcb836e7b61f

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Fri Apr 30 10:43:58 2021 +0200

user32: Move GetKeyboardLayoutList from nulldrv.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/driver.c | 54 +-----------------------------------
 dlls/user32/input.c  | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 75 insertions(+), 56 deletions(-)

diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index e3cf41561b5..c075a49a350 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -198,59 +198,7 @@ static void CDECL nulldrv_Beep(void)
 
 static UINT CDECL nulldrv_GetKeyboardLayoutList( INT size, HKL *layouts )
 {
-    HKEY hKeyKeyboard;
-    DWORD rc;
-    INT count = 0;
-    ULONG_PTR baselayout;
-    LANGID langid;
-
-    baselayout = GetUserDefaultLCID();
-    langid = PRIMARYLANGID(LANGIDFROMLCID(baselayout));
-    if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)
-        baselayout = MAKELONG( baselayout, 0xe001 ); /* IME */
-    else
-        baselayout |= baselayout << 16;
-
-    /* Enumerate the Registry */
-    rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,L"System\\CurrentControlSet\\Control\\Keyboard Layouts",&hKeyKeyboard);
-    if (rc == ERROR_SUCCESS)
-    {
-        do {
-            WCHAR szKeyName[9];
-            HKL layout;
-            rc = RegEnumKeyW(hKeyKeyboard, count, szKeyName, 9);
-            if (rc == ERROR_SUCCESS)
-            {
-                layout = (HKL)(ULONG_PTR)wcstoul(szKeyName,NULL,16);
-                if (baselayout != 0 && layout == (HKL)baselayout)
-                    baselayout = 0; /* found in the registry do not add again */
-                if (size && layouts)
-                {
-                    if (count >= size ) break;
-                    layouts[count] = layout;
-                }
-                count ++;
-            }
-        } while (rc == ERROR_SUCCESS);
-        RegCloseKey(hKeyKeyboard);
-    }
-
-    /* make sure our base layout is on the list */
-    if (baselayout != 0)
-    {
-        if (size && layouts)
-        {
-            if (count < size)
-            {
-                layouts[count] = (HKL)baselayout;
-                count++;
-            }
-        }
-        else
-            count++;
-    }
-
-    return count;
+    return ~0; /* use default implementation */
 }
 
 static INT CDECL nulldrv_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size )
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 4ecc73c4ad0..4895a007500 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -77,6 +77,43 @@ static WORD get_key_state(void)
 }
 
 
+/***********************************************************************
+ *           get_locale_kbd_layout
+ */
+static HKL get_locale_kbd_layout(void)
+{
+    ULONG_PTR layout;
+    LANGID langid;
+
+    /* FIXME:
+     *
+     * layout = main_key_tab[kbd_layout].lcid;
+     *
+     * Winword uses return value of GetKeyboardLayout as a codepage
+     * to translate ANSI keyboard messages to unicode. But we have
+     * a problem with it: for instance Polish keyboard layout is
+     * identical to the US one, and therefore instead of the Polish
+     * locale id we return the US one.
+     */
+
+    layout = GetUserDefaultLCID();
+
+    /*
+     * Microsoft Office expects this value to be something specific
+     * for Japanese and Korean Windows with an IME the value is 0xe001
+     * We should probably check to see if an IME exists and if so then
+     * set this word properly.
+     */
+    langid = PRIMARYLANGID( LANGIDFROMLCID( layout ) );
+    if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)
+        layout = MAKELONG( layout, 0xe001 ); /* IME */
+    else
+        layout = MAKELONG( layout, layout );
+
+    return (HKL)layout;
+}
+
+
 /**********************************************************************
  *		set_capture_window
  */
@@ -1297,11 +1334,45 @@ BOOL WINAPI BlockInput(BOOL fBlockIt)
  * Return number of values available if either input parm is
  *  0, per MS documentation.
  */
-UINT WINAPI GetKeyboardLayoutList(INT nBuff, HKL *layouts)
+UINT WINAPI GetKeyboardLayoutList( INT size, HKL *layouts )
 {
-    TRACE_(keyboard)( "(%d, %p)\n", nBuff, layouts );
+    WCHAR klid[KL_NAMELENGTH];
+    UINT count, tmp, i = 0;
+    HKEY hkey;
+    HKL layout;
+
+    TRACE_(keyboard)( "size %d, layouts %p.\n", size, layouts );
+
+    if ((count = USER_Driver->pGetKeyboardLayoutList( size, layouts )) != ~0) return count;
+
+    layout = get_locale_kbd_layout();
+    count = 0;
+
+    count++;
+    if (size && layouts)
+    {
+        layouts[count - 1] = layout;
+        if (count == size) return count;
+    }
+
+    if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Keyboard Layouts", &hkey ))
+    {
+        while (!RegEnumKeyW( hkey, i++, klid, ARRAY_SIZE(klid) ))
+        {
+            tmp = wcstoul( klid, NULL, 16 );
+            if (layout == UlongToHandle( tmp )) continue;
+
+            count++;
+            if (size && layouts)
+            {
+                layouts[count - 1] = UlongToHandle( tmp );
+                if (count == size) break;
+            }
+        }
+        RegCloseKey( hkey );
+    }
 
-    return USER_Driver->pGetKeyboardLayoutList( nBuff, layouts );
+    return count;
 }
 
 




More information about the wine-cvs mailing list