-- v4: winex11: Remove now unnecessary user locale change checks. win32u: Prevent user locale change in NtUserActivateKeyboardLayout. win32u: Keep the current user locale when loading layout. win32u: Keep the current user locale when enumerating layouts.
From: Rémi Bernon rbernon@codeweavers.com
The low word of the enumerated HKL is the desired user locale, the high word is either the keyboard layout LANGID, or the keyboard "Layout Id" for additional layouts with the same LANGID. --- dlls/win32u/input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index c11d542037d..8f71f93e0fe 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -1273,10 +1273,10 @@ UINT WINAPI NtUserGetKeyboardLayoutList( INT size, HKL *layouts ) tmp = wcstoul( key_info->Name, NULL, 16 ); if (query_reg_ascii_value( subkey, "Layout Id", value_info, sizeof(buffer) ) && value_info->Type == REG_SZ) - tmp = MAKELONG( LOWORD( tmp ), - 0xf000 | (wcstoul( (const WCHAR *)value_info->Data, NULL, 16 ) & 0xfff) ); + tmp = 0xf000 | (wcstoul( (const WCHAR *)value_info->Data, NULL, 16 ) & 0xfff); NtClose( subkey );
+ tmp = MAKELONG( LOWORD( layout ), LOWORD( tmp ) ); if (layout == UlongToHandle( tmp )) continue;
count++;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/input.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 2f4dc06f6ce..8f3cd8acae7 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -439,7 +439,8 @@ BOOL WINAPI BlockInput(BOOL fBlockIt) HKL WINAPI LoadKeyboardLayoutW( const WCHAR *name, UINT flags ) { WCHAR layout_path[MAX_PATH], value[5]; - DWORD value_size, tmp; + LCID locale = GetUserDefaultLCID(); + DWORD id, value_size, tmp; HKEY hkey; HKL layout;
@@ -449,6 +450,9 @@ HKL WINAPI LoadKeyboardLayoutW( const WCHAR *name, UINT flags ) if (HIWORD( tmp )) layout = UlongToHandle( tmp ); else layout = UlongToHandle( MAKELONG( LOWORD( tmp ), LOWORD( tmp ) ) );
+ if (!((UINT_PTR)layout >> 28)) id = LOWORD( tmp ); + else id = HIWORD( layout ); /* IME or aliased layout */ + wcscpy( layout_path, L"System\CurrentControlSet\Control\Keyboard Layouts\" ); wcscat( layout_path, name );
@@ -456,11 +460,12 @@ HKL WINAPI LoadKeyboardLayoutW( const WCHAR *name, UINT flags ) { value_size = sizeof(value); if (!RegGetValueW( hkey, NULL, L"Layout Id", RRF_RT_REG_SZ, NULL, (void *)&value, &value_size )) - layout = UlongToHandle( MAKELONG( LOWORD( tmp ), 0xf000 | (wcstoul( value, NULL, 16 ) & 0xfff) ) ); + id = 0xf000 | (wcstoul( value, NULL, 16 ) & 0xfff);
RegCloseKey( hkey ); }
+ layout = UlongToHandle( MAKELONG( locale, id ) ); if ((flags & KLF_ACTIVATE) && NtUserActivateKeyboardLayout( layout, 0 )) return layout;
/* FIXME: semi-stub: returning default layout */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/input.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 8f71f93e0fe..11bb129134c 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -1193,6 +1193,7 @@ HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags ) { struct user_thread_info *info = get_user_thread_info(); HKL old_layout; + LCID locale; HWND focus;
TRACE_(keyboard)( "layout %p, flags %x\n", layout, flags ); @@ -1206,6 +1207,13 @@ HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags ) return 0; }
+ if (NtQueryDefaultLocale( TRUE, &locale ) || LOWORD(layout) != locale) + { + RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); + FIXME_(keyboard)( "Changing user locale is not supported\n" ); + return 0; + } + if (!user_driver->pActivateKeyboardLayout( layout, flags )) return 0;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/keyboard.c | 57 ------------------------------------- 1 file changed, 57 deletions(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 616728be621..b1c47d5258e 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1514,39 +1514,6 @@ X11DRV_KEYBOARD_DetectLayout( Display *display ) TRACE("detected layout is "%s"\n", main_key_tab[kbd_layout].comment); }
-static HKL get_locale_kbd_layout(void) -{ - LCID 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. - */ - - NtQueryDefaultLocale( TRUE, &layout ); - - /* - * 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 |= layout << 16; - - return (HKL)(UINT_PTR)layout; -} -
/********************************************************************** * X11DRV_InitKeyboard @@ -1818,18 +1785,6 @@ void X11DRV_InitKeyboard( Display *display ) pthread_mutex_unlock( &kbd_mutex ); }
-static BOOL match_x11_keyboard_layout(HKL hkl) -{ - const DWORD isIME = 0xE0000000; - HKL xHkl = get_locale_kbd_layout(); - - /* if the layout is an IME, only match the low word (LCID) */ - if (((ULONG_PTR)hkl & isIME) == isIME) - return (LOWORD(hkl) == LOWORD(xHkl)); - else - return (hkl == xHkl); -} -
/*********************************************************************** * ActivateKeyboardLayout (X11DRV.@) @@ -1845,13 +1800,6 @@ BOOL X11DRV_ActivateKeyboardLayout(HKL hkl, UINT flags) return FALSE; }
- if (!match_x11_keyboard_layout(hkl)) - { - RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); - FIXME("setting keyboard of different locales not supported\n"); - return FALSE; - } - return TRUE; }
@@ -1968,8 +1916,6 @@ UINT X11DRV_MapVirtualKeyEx( UINT wCode, UINT wMapType, HKL hkl ) Display *display = thread_init_display();
TRACE("wCode=0x%x, wMapType=%d, hkl %p\n", wCode, wMapType, hkl); - if (!match_x11_keyboard_layout(hkl)) - FIXME("keyboard layout %p is not supported\n", hkl);
pthread_mutex_lock( &kbd_mutex );
@@ -2338,9 +2284,6 @@ INT X11DRV_ToUnicodeEx( UINT virtKey, UINT scanCode, const BYTE *lpKeyState, return 0; }
- if (!match_x11_keyboard_layout(hkl)) - FIXME_(key)("keyboard layout %p is not supported\n", hkl); - if ((lpKeyState[VK_MENU] & 0x80) && (lpKeyState[VK_CONTROL] & 0x80)) { TRACE_(key)("Ctrl+Alt+[key] won't generate a character\n");
v4: Removed the change that called NtUserActivateKeyboardLayout on focus change, it looks like that instead of a global keyboard layout, the default layout is reset. Or, at least, custom IME gets deselected every time a window is created or when focus changes.