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; - return USER_Driver->pGetKeyboardLayoutList( nBuff, layouts ); + 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 count; }