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