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 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 2f4dc06f6ce..87ce153ed54 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -439,6 +439,7 @@ BOOL WINAPI BlockInput(BOOL fBlockIt) HKL WINAPI LoadKeyboardLayoutW( const WCHAR *name, UINT flags ) { WCHAR layout_path[MAX_PATH], value[5]; + LCID locale = GetUserDefaultLCID(); DWORD value_size, tmp; HKEY hkey; HKL layout; @@ -456,11 +457,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) ) ); + layout = UlongToHandle( 0xf000 | (wcstoul( value, NULL, 16 ) & 0xfff) );
RegCloseKey( hkey ); }
+ layout = UlongToHandle( MAKELONG( locale, LOWORD( layout ) ) ); 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");
From: Rémi Bernon rbernon@codeweavers.com
Tracking and activating the global keyboard layout. --- dlls/win32u/input.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 11bb129134c..9415011aee4 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -406,6 +406,7 @@ static const KBDTABLES kbdus_tables =
LONG global_key_state_counter = 0; +static HKL global_layout;
static void kbd_tables_init_vsc2vk( const KBDTABLES *tables, BYTE vsc2vk[0x300] ) @@ -1217,6 +1218,8 @@ HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags ) if (!user_driver->pActivateKeyboardLayout( layout, flags )) return 0;
+ InterlockedExchangePointer( (void *)&global_layout, layout ); + old_layout = info->kbd_layout; info->kbd_layout = layout; if (old_layout != layout) @@ -1784,6 +1787,7 @@ BOOL WINAPI release_capture(void) static HWND set_focus_window( HWND hwnd ) { HWND previous = 0, ime_hwnd; + HKL layout; BOOL ret;
SERVER_START_REQ( set_focus_window ) @@ -1811,6 +1815,9 @@ static HWND set_focus_window( HWND hwnd ) { user_driver->pSetFocus(hwnd);
+ if ((layout = InterlockedCompareExchangePointer( (void *)&global_layout, NULL, NULL ))) + NtUserActivateKeyboardLayout( layout, 0 ); + ime_hwnd = get_default_ime_window( hwnd ); if (ime_hwnd) send_message( ime_hwnd, WM_IME_INTERNAL, IME_INTERNAL_ACTIVATE,
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=130409
Your paranoid android.
=== debian11 (32 bit zh:CN report) ===
user32: input.c:3381: Test failed: e0010804: LoadKeyboardLayoutW returned 08040804, expected E0010804 input.c:3385: Test failed: e0010804: GetKeyboardLayoutNameW returned L"00000804", expected L"E0010804"