Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=28170
Supersedes https://gitlab.winehq.org/wine/wine/-/merge_requests/5361
From: Vijay Kiran Kamuju infyquest@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=28170 --- dlls/user32/input.c | 11 +++++++++++ dlls/user32/user32.spec | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 1fff29c7f87..00337aa72b7 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -476,6 +476,17 @@ HKL WINAPI LoadKeyboardLayoutA(LPCSTR pwszKLID, UINT Flags) }
+/*********************************************************************** + * LoadKeyboardLayoutEx (USER32.@) + */ +HKL WINAPI LoadKeyboardLayoutEx( HKL layout, const WCHAR *name, UINT flags ) +{ + FIXME_(keyboard)( "layout %p, name %s, flags %x, semi-stub!\n", layout, debugstr_w( name ), flags ); + + if (!layout) return NULL; + return LoadKeyboardLayoutW( name, flags ); +} + /*********************************************************************** * UnloadKeyboardLayout (USER32.@) */ diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index 14246b3e3e0..21fa904082c 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -507,7 +507,7 @@ @ stdcall LoadImageA(long str long long long long) @ stdcall LoadImageW(long wstr long long long long) @ stdcall LoadKeyboardLayoutA(str long) -# @ stub LoadKeyboardLayoutEx +@ stdcall LoadKeyboardLayoutEx(long wstr long) @ stdcall LoadKeyboardLayoutW(wstr long) @ stdcall LoadLocalFonts() @ stdcall LoadMenuA(long str)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/tests/input.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index a78ea3b7c43..95683e4afe4 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -3953,6 +3953,7 @@ static void test_SendInput_mouse_messages(void) if (broken(!ret)) /* broken on Win7 probably because of the separate desktop */ { win_skip("Skipping broken SetLayeredWindowAttributes tests\n"); + winetest_pop_context(); DestroyWindow( other ); break; }
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=28170 --- dlls/user32/tests/input.c | 124 +++++++++++++++++++++++++++++++++++--- 1 file changed, 116 insertions(+), 8 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 95683e4afe4..b92e59396ac 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -376,6 +376,7 @@ static UINT (WINAPI *pGetRawInputDeviceList) (PRAWINPUTDEVICELIST, PUINT, UINT); static UINT (WINAPI *pGetRawInputDeviceInfoW) (HANDLE, UINT, void *, UINT *); static UINT (WINAPI *pGetRawInputDeviceInfoA) (HANDLE, UINT, void *, UINT *); static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); +static HKL (WINAPI *pLoadKeyboardLayoutEx)(HKL, const WCHAR *, UINT);
/**********************adapted from input.c **********************************/
@@ -401,6 +402,7 @@ static void init_function_pointers(void) GET_PROC(GetRawInputDeviceList); GET_PROC(GetRawInputDeviceInfoW); GET_PROC(GetRawInputDeviceInfoA); + GET_PROC(LoadKeyboardLayoutEx);
hdll = GetModuleHandleA("kernel32"); GET_PROC(IsWow64Process); @@ -3025,13 +3027,28 @@ static void test_get_async_key_state(void) ok(0 == GetAsyncKeyState(-1000000), "GetAsyncKeyState did not return 0\n"); }
+static HKL *get_keyboard_layouts( UINT *count ) +{ + HKL *layouts; + + *count = GetKeyboardLayoutList( 0, NULL ); + ok_ne( 0, *count, UINT, "%u" ); + layouts = malloc( *count * sizeof(HKL) ); + ok_ne( NULL, layouts, void *, "%p" ); + *count = GetKeyboardLayoutList( *count, layouts ); + ok_ne( 0, *count, UINT, "%u" ); + + return layouts; +} + static void test_keyboard_layout_name(void) { WCHAR klid[KL_NAMELENGTH], tmpklid[KL_NAMELENGTH], layout_path[MAX_PATH], value[5]; HKL layout, tmplayout, *layouts, *layouts_preload; DWORD status, value_size, klid_size, type, id; - int i, j, len; + int i, j; HKEY hkey; + UINT len; BOOL ret;
if (0) /* crashes on native system */ @@ -3054,15 +3071,9 @@ static void test_keyboard_layout_name(void) return; }
- len = GetKeyboardLayoutList(0, NULL); - ok(len > 0, "GetKeyboardLayoutList returned %d\n", len); - - layouts = malloc(len * sizeof(HKL)); + layouts = get_keyboard_layouts( &len ); ok(layouts != NULL, "Could not allocate memory\n");
- len = GetKeyboardLayoutList(len, layouts); - ok(len > 0, "GetKeyboardLayoutList returned %d\n", len); - layouts_preload = calloc(1, sizeof(HKL)); ok(layouts_preload != NULL, "Could not allocate memory\n");
@@ -5531,6 +5542,101 @@ static void test_keyboard_ll_hook_blocking(void) ok_ret( 1, DestroyWindow( hwnd ) ); }
+static void test_LoadKeyboardLayoutEx(void) +{ + static const WCHAR test_layout_name[] = L"00000429"; + static const HKL test_hkl = (HKL)0x04290429; + + HKL *new_layouts, *layouts, old_hkl, hkl; + UINT i, j, len, new_len; + WCHAR layout_name[64]; + + old_hkl = GetKeyboardLayout( 0 ); + ok_ne( 0, old_hkl, HKL, "%p" ); + + hkl = pLoadKeyboardLayoutEx( NULL, test_layout_name, 0 ); + ok_eq( 0, hkl, HKL, "%p" ); + + layouts = get_keyboard_layouts( &len ); + for (i = 0; i < len; i++) if (layouts[i] == test_hkl) break; + if (i != len) + { + skip( "Test HKL is already loaded, skipping tests\n" ); + free( layouts ); + return; + } + + /* LoadKeyboardLayoutEx replaces loaded layouts, but will lose mixed layout / locale */ + for (i = 0, j = len; i < len; i++) + { + if (HIWORD(layouts[i]) != LOWORD(layouts[i])) continue; + if (j == len) j = i; + else break; + } + if (i == len) i = j; + if (i == len) + { + skip( "Failed to find appropriate layouts, skipping tests\n" ); + free( layouts ); + return; + } + + trace( "using layouts %p / %p\n", layouts[i], layouts[j] ); + + ActivateKeyboardLayout( layouts[i], 0 ); + ok_eq( layouts[i], GetKeyboardLayout( 0 ), HKL, "%p" ); + ok_ret( 1, GetKeyboardLayoutNameW( layout_name ) ); + + /* LoadKeyboardLayoutEx replaces a currently loaded layout */ + hkl = pLoadKeyboardLayoutEx( layouts[i], test_layout_name, 0 ); + todo_wine + ok_eq( test_hkl, hkl, HKL, "%p" ); + new_layouts = get_keyboard_layouts( &new_len ); + ok_eq( len, new_len, UINT, "%u" ); + todo_wine + ok_eq( test_hkl, new_layouts[i], HKL, "%p" ); + new_layouts[i] = layouts[i]; + ok( !memcmp( new_layouts, layouts, len * sizeof(*layouts) ), "keyboard layouts changed\n" ); + free( new_layouts ); + + hkl = pLoadKeyboardLayoutEx( test_hkl, layout_name, 0 ); + ok_eq( layouts[i], hkl, HKL, "%p" ); + new_layouts = get_keyboard_layouts( &new_len ); + ok_eq( len, new_len, UINT, "%u" ); + ok( !memcmp( new_layouts, layouts, len * sizeof(*layouts) ), "keyboard layouts changed\n" ); + free( new_layouts ); + + if (j == i) skip( "Only one layout found, skipping tests\n" ); + else + { + /* it also works if a different layout is active */ + ActivateKeyboardLayout( layouts[j], 0 ); + ok_eq( layouts[j], GetKeyboardLayout( 0 ), HKL, "%p" ); + + hkl = pLoadKeyboardLayoutEx( layouts[i], test_layout_name, 0 ); + todo_wine + ok_eq( test_hkl, hkl, HKL, "%p" ); + new_layouts = get_keyboard_layouts( &new_len ); + ok_eq( len, new_len, UINT, "%u" ); + todo_wine + ok_eq( test_hkl, new_layouts[i], HKL, "%p" ); + new_layouts[i] = layouts[i]; + ok( !memcmp( new_layouts, layouts, len * sizeof(*layouts) ), "keyboard layouts changed\n" ); + free( new_layouts ); + + hkl = pLoadKeyboardLayoutEx( test_hkl, layout_name, 0 ); + ok_eq( layouts[i], hkl, HKL, "%p" ); + new_layouts = get_keyboard_layouts( &new_len ); + ok_eq( len, new_len, UINT, "%u" ); + ok( !memcmp( new_layouts, layouts, len * sizeof(*layouts) ), "keyboard layouts changed\n" ); + free( new_layouts ); + } + + free( layouts ); + ActivateKeyboardLayout( old_hkl, 0 ); + ok_eq( old_hkl, GetKeyboardLayout( 0 ), HKL, "%p" ); +} + /* run the tests in a separate desktop to avoid interaction with other * tests, current desktop state, or user actions. */ static void test_input_desktop( char **argv ) @@ -5555,6 +5661,8 @@ static void test_input_desktop( char **argv ) test_GetRawInputData(); test_GetRawInputBuffer();
+ test_LoadKeyboardLayoutEx(); + ok_ret( 1, SetCursorPos( pos.x, pos.y ) ); }
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=144326
Your paranoid android.
=== w11pro64 (32 bit report) ===
user32: input.c:3987: Test failed: layered 0: button_up_hwnd_todo 0: got MSG_TEST_WIN hwnd 00050040, msg WM_LBUTTONUP, wparam 0, lparam 0x320032 input.c:3987: Test failed: layered 0: button_up_hwnd_todo 1 (missing): MSG_TEST_WIN hwnd 00050040, WM_LBUTTONUP, wparam 0, lparam 0x320032
This merge request was approved by Rémi Bernon.