[PATCH 0/5] MR2494: imm32: Make a few tests pass and test ImmActivateLayout.
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/imm32/imm.c | 4 ++-- dlls/imm32/tests/imm32.c | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index c22c1fb9e64..f202c4cf1e7 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -1006,7 +1006,7 @@ LRESULT WINAPI ImmEscapeA( HKL hkl, HIMC himc, UINT code, void *data ) if (!(ime = ime_acquire( hkl ))) return 0; - if (!EscapeRequiresWA( code ) || !ime_is_unicode( ime )) + if (!EscapeRequiresWA( code ) || !ime_is_unicode( ime ) || !data) ret = ime->pImeEscape( himc, code, data ); else { @@ -1039,7 +1039,7 @@ LRESULT WINAPI ImmEscapeW( HKL hkl, HIMC himc, UINT code, void *data ) if (!(ime = ime_acquire( hkl ))) return 0; - if (!EscapeRequiresWA( code ) || ime_is_unicode( ime )) + if (!EscapeRequiresWA( code ) || ime_is_unicode( ime ) || !data) ret = ime->pImeEscape( himc, code, data ); else { diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 93185402441..7088f663535 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -2574,15 +2574,9 @@ static LRESULT WINAPI ime_ImeEscape( HIMC himc, UINT escape, void *data ) case IME_ESC_SET_EUDC_DICTIONARY: if (!data) return 4; if (ime_info.fdwProperty & IME_PROP_UNICODE) - { - todo_wine_if(*(WCHAR *)data != 'E') ok_wcs( L"EscapeIme", data ); - } else - { - todo_wine_if(*(char *)data != 'E') ok_str( "EscapeIme", data ); - } /* fallthrough */ case IME_ESC_QUERY_SUPPORT: case IME_ESC_SEQUENCE_TO_INTERNAL: -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2494
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/imm32/imm.c | 40 ++++++++++++++++++++++++++++++++++++++-- dlls/imm32/tests/imm32.c | 4 ---- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index f202c4cf1e7..e47e8aa4c44 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -928,6 +928,23 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC) return IMM_DestroyContext(hIMC); } +struct enum_register_word_params_WtoA +{ + REGISTERWORDENUMPROCA proc; + void *user; +}; + +static int CALLBACK enum_register_word_WtoA( const WCHAR *readingW, DWORD style, + const WCHAR *stringW, void *user ) +{ + char *readingA = strdupWtoA( readingW ), *stringA = strdupWtoA( stringW ); + struct enum_register_word_params_WtoA *params = user; + int ret = params->proc( readingA, style, stringA, params->user ); + free( readingA ); + free( stringA ); + return ret; +} + /*********************************************************************** * ImmEnumRegisterWordA (IMM32.@) */ @@ -946,8 +963,9 @@ UINT WINAPI ImmEnumRegisterWordA( HKL hkl, REGISTERWORDENUMPROCA procA, const ch ret = ime->pImeEnumRegisterWord( procA, readingA, style, stringA, user ); else { + struct enum_register_word_params_WtoA params = {.proc = procA, .user = user}; WCHAR *readingW = strdupAtoW( readingA ), *stringW = strdupAtoW( stringA ); - ret = ime->pImeEnumRegisterWord( procA, readingW, style, stringW, user ); + ret = ime->pImeEnumRegisterWord( enum_register_word_WtoA, readingW, style, stringW, ¶ms ); free( readingW ); free( stringW ); } @@ -956,6 +974,23 @@ UINT WINAPI ImmEnumRegisterWordA( HKL hkl, REGISTERWORDENUMPROCA procA, const ch return ret; } +struct enum_register_word_params_AtoW +{ + REGISTERWORDENUMPROCW proc; + void *user; +}; + +static int CALLBACK enum_register_word_AtoW( const char *readingA, DWORD style, + const char *stringA, void *user ) +{ + WCHAR *readingW = strdupAtoW( readingA ), *stringW = strdupAtoW( stringA ); + struct enum_register_word_params_AtoW *params = user; + int ret = params->proc( readingW, style, stringW, params->user ); + free( readingW ); + free( stringW ); + return ret; +} + /*********************************************************************** * ImmEnumRegisterWordW (IMM32.@) */ @@ -974,8 +1009,9 @@ UINT WINAPI ImmEnumRegisterWordW( HKL hkl, REGISTERWORDENUMPROCW procW, const WC ret = ime->pImeEnumRegisterWord( procW, readingW, style, stringW, user ); else { + struct enum_register_word_params_AtoW params = {.proc = procW, .user = user}; char *readingA = strdupWtoA( readingW ), *stringA = strdupWtoA( stringW ); - ret = ime->pImeEnumRegisterWord( procW, readingA, style, stringA, user ); + ret = ime->pImeEnumRegisterWord( enum_register_word_AtoW, readingA, style, stringA, ¶ms ); free( readingA ); free( stringA ); } diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 7088f663535..5f6cefe3bd9 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -3408,9 +3408,7 @@ static int CALLBACK enum_register_wordA( const char *reading, DWORD style, const ime_trace( "reading %s, style %#lx, string %s, user %p\n", debugstr_a(reading), style, debugstr_a(string), user ); ok_eq( 0xdeadbeef, style, UINT, "%#x" ); - todo_wine_if( reading[1] == 0 ) ok_str( "Reading", reading ); - todo_wine_if( string[1] == 0 ) ok_str( "String", string ); return 0xdeadbeef; @@ -3421,9 +3419,7 @@ static int CALLBACK enum_register_wordW( const WCHAR *reading, DWORD style, cons ime_trace( "reading %s, style %#lx, string %s, user %p\n", debugstr_w(reading), style, debugstr_w(string), user ); ok_eq( 0xdeadbeef, style, UINT, "%#x" ); - todo_wine_if( reading[0] != 'R' ) ok_wcs( L"Reading", reading ); - todo_wine_if( string[0] != 'S' ) ok_wcs( L"String", string ); return 0xdeadbeef; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2494
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/imm32/tests/imm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 5f6cefe3bd9..154e809a187 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -2849,7 +2849,7 @@ static HKL ime_install(void) ok( !wcscmp( buffer, L"WineTest IME" ), "got Layout Text %s\n", debugstr_w(buffer) ); len = sizeof(buffer); - memset( buffer, 0xcd, sizeof(buffer) ); + memset( buffer, 0, sizeof(buffer) ); ret = RegQueryValueExW( hkey, L"Layout File", NULL, NULL, (BYTE *)buffer, &len ); todo_wine ok( !ret, "RegQueryValueExW returned %#lx, error %lu\n", ret, GetLastError() ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2494
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/imm32/imm.c | 6 ++++++ dlls/imm32/imm32.spec | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index e47e8aa4c44..1b8caf90c1c 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -564,6 +564,12 @@ static void ime_release( struct ime *ime ) LeaveCriticalSection( &ime_cs ); } +BOOL WINAPI ImmActivateLayout( HKL hkl ) +{ + FIXME( "hkl %p stub!\n", hkl ); + return FALSE; +} + static BOOL free_input_context_data( HIMC hIMC ) { struct imc *data = query_imc_data( hIMC ); diff --git a/dlls/imm32/imm32.spec b/dlls/imm32/imm32.spec index 9c7ce13319f..47b3916c822 100644 --- a/dlls/imm32/imm32.spec +++ b/dlls/imm32/imm32.spec @@ -1,4 +1,4 @@ -@ stub ImmActivateLayout +@ stdcall ImmActivateLayout(long) @ stdcall ImmAssociateContext(long long) @ stdcall ImmAssociateContextEx(long long long) @ stdcall ImmConfigureIMEA(long long long ptr) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2494
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/imm32/tests/imm32.c | 183 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 179 insertions(+), 4 deletions(-) diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 154e809a187..06880d4c62c 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -84,6 +84,7 @@ static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t); extern BOOL WINAPI ImmFreeLayout(HKL); extern BOOL WINAPI ImmLoadIME(HKL); +extern BOOL WINAPI ImmActivateLayout(HKL); #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE, enabled_ ## func = FALSE @@ -2489,6 +2490,104 @@ DEFINE_EXPECT( IME_DLL_PROCESS_DETACH ); static IMEINFO ime_info; +enum ime_function +{ + IME_SELECT = 1, + IME_NOTIFY, +}; + +struct ime_call +{ + enum ime_function func; + HIMC himc; + + union + { + int select; + struct + { + int action; + int index; + int value; + } notify; + }; + + BOOL todo; +}; + +struct ime_call empty_sequence[] = {{0}}; +static struct ime_call ime_calls[1024]; +static ULONG ime_call_count; + +#define ok_call( a, b ) ok_call_( __FILE__, __LINE__, a, b ) +static void ok_call_( const char *file, int line, const struct ime_call *expected, const struct ime_call *received ) +{ + int ret; + + if ((ret = expected->func - received->func)) goto done; + if ((ret = (UINT_PTR)expected->himc - (UINT_PTR)received->himc)) goto done; + switch (expected->func) + { + case IME_SELECT: + if ((ret = expected->select - received->select)) goto done; + break; + case IME_NOTIFY: + if ((ret = expected->notify.action - received->notify.action)) goto done; + if ((ret = expected->notify.index - received->notify.index)) goto done; + if ((ret = expected->notify.value - received->notify.value)) goto done; + break; + } + +done: + switch (received->func) + { + case IME_SELECT: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "got IME_SELECT himc %p, select %u\n", received->himc, received->select ); + return; + case IME_NOTIFY: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "got IME_NOTIFY himc %p, action %#x, index %#x, value %#x\n", + received->himc, received->notify.action, received->notify.index, + received->notify.value ); + return; + } + + switch (expected->func) + { + case IME_SELECT: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "IME_SELECT himc %p, select %u\n", expected->himc, expected->select ); + break; + case IME_NOTIFY: + todo_wine_if( expected->todo ) + ok_(file, line)( !ret, "IME_NOTIFY himc %p, action %#x, index %#x, value %#x\n", + expected->himc, expected->notify.action, expected->notify.index, + expected->notify.value ); + break; + } +} + +#define ok_seq( a ) ok_seq_( __FILE__, __LINE__, a, #a ) +static void ok_seq_( const char *file, int line, const struct ime_call *expected, const char *context ) +{ + const struct ime_call *received = ime_calls; + UINT i = 0; + + while (expected->func || received->func) + { + winetest_push_context( "%u%s%s", i++, !expected->func ? " (spurious)" : "", + !received->func ? " (missing)" : "" ); + ok_call_( file, line, expected, received ); + if (expected->func) expected++; + if (received->func) received++; + winetest_pop_context(); + } + + memset( ime_calls, 0, sizeof(ime_calls) ); + ime_call_count = 0; +} + static LRESULT CALLBACK ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { ime_trace( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam ); @@ -2683,9 +2782,10 @@ static BOOL WINAPI ime_ImeRegisterWord( const WCHAR *reading, DWORD style, const static BOOL WINAPI ime_ImeSelect( HIMC himc, BOOL select ) { + struct ime_call call = {.func = IME_SELECT, .himc = himc, .select = select}; ime_trace( "himc %p, select %d\n", himc, select ); - ok( 0, "unexpected call\n" ); - return FALSE; + ime_calls[ime_call_count++] = call; + return TRUE; } static BOOL WINAPI ime_ImeSetActiveContext( HIMC himc, BOOL flag ) @@ -2735,8 +2835,9 @@ static BOOL WINAPI ime_ImeUnregisterWord( const WCHAR *reading, DWORD style, con static BOOL WINAPI ime_NotifyIME( HIMC himc, DWORD action, DWORD index, DWORD value ) { - ime_trace( "himc %p, action %lu, index %lu, value %lu\n", himc, action, index, value ); - ok( 0, "unexpected call\n" ); + struct ime_call call = {.func = IME_NOTIFY, .himc = himc, .notify = {.action = action, .index = index, .value = value}}; + ime_trace( "himc %p, action %#lx, index %lu, value %lu\n", himc, action, index, value ); + ime_calls[ime_call_count++] = call; return FALSE; } @@ -3672,6 +3773,78 @@ cleanup: winetest_pop_context(); } +static void test_ImmActivateLayout(void) +{ + const struct ime_call activate_seq[] = + { + {.func = IME_SELECT, .himc = default_himc, .select = 1, .todo = TRUE}, + {0}, + }; + const struct ime_call deactivate_seq[] = + { + {.func = IME_NOTIFY, .himc = default_himc, .notify = {.action = NI_COMPOSITIONSTR, .index = CPS_CANCEL, .value = 0}, .todo = TRUE}, + {.func = IME_SELECT, .himc = default_himc, .select = 0, .todo = TRUE}, + {0}, + }; + HKL hkl, old_hkl = GetKeyboardLayout( 0 ); + UINT ret; + + SET_ENABLE( ImeInquire, TRUE ); + SET_ENABLE( ImeDestroy, TRUE ); + + todo_wine + ok_ret( 1, ImmActivateLayout( old_hkl ) ); + + ime_info.fdwProperty = IME_PROP_END_UNLOAD | IME_PROP_UNICODE; + + if (!(hkl = ime_install())) goto cleanup; + + /* ActivateKeyboardLayout doesn't call ImeInquire / ImeDestroy */ + + ok_seq( empty_sequence ); + ok_eq( old_hkl, ActivateKeyboardLayout( hkl, 0 ), HKL, "%p" ); + ok_eq( hkl, GetKeyboardLayout( 0 ), HKL, "%p" ); + ok_eq( hkl, ActivateKeyboardLayout( old_hkl, 0 ), HKL, "%p" ); + ok_seq( empty_sequence ); + ok_eq( old_hkl, GetKeyboardLayout( 0 ), HKL, "%p" ); + + + /* ImmActivateLayout changes active HKL */ + + SET_EXPECT( ImeInquire ); + todo_wine + ok_ret( 1, ImmActivateLayout( hkl ) ); + ok_seq( activate_seq ); + todo_wine + CHECK_CALLED( ImeInquire ); + + todo_wine + ok_eq( hkl, GetKeyboardLayout( 0 ), HKL, "%p" ); + + todo_wine + ok_ret( 1, ImmActivateLayout( old_hkl ) ); + ok_seq( deactivate_seq ); + + ok_eq( old_hkl, GetKeyboardLayout( 0 ), HKL, "%p" ); + + ime_cleanup( hkl ); + ok_seq( empty_sequence ); + + + /* ImmActivateLayout leaks the IME, we need to free it manually */ + + SET_EXPECT( ImeDestroy ); + ret = ImmFreeLayout( hkl ); + ok( ret, "ImmFreeLayout returned %u\n", ret ); + todo_wine + CHECK_CALLED( ImeDestroy ); + ok_seq( empty_sequence ); + +cleanup: + SET_ENABLE( ImeInquire, FALSE ); + SET_ENABLE( ImeDestroy, FALSE ); +} + START_TEST(imm32) { if (!is_ime_enabled()) @@ -3701,6 +3874,8 @@ START_TEST(imm32) test_ImmUnregisterWord( FALSE ); test_ImmUnregisterWord( TRUE ); + test_ImmActivateLayout(); + if (init()) { test_ImmNotifyIME(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2494
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 full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=131055 Your paranoid android. === build (build log) === error: patch failed: dlls/imm32/imm.c:564 Task: Patch failed to apply === debian11 (build log) === error: patch failed: dlls/imm32/imm.c:564 error: patch failed: dlls/imm32/imm32.spec:1 error: patch failed: dlls/imm32/tests/imm32.c:84 Task: Patch failed to apply === debian11b (build log) === error: patch failed: dlls/imm32/imm.c:564 error: patch failed: dlls/imm32/imm32.spec:1 error: patch failed: dlls/imm32/tests/imm32.c:84 Task: Patch failed to apply
participants (2)
-
Marvin -
Rémi Bernon