-- v4: imm32: Complete the composition string when the IME is closed. imm32/tests: Test the effect of CPS_CANCEL and CPS_COMPLETE. win32u: Also pass WM_KEYUP messages to ImmProcessKey. imm32/tests: Test that WM_KEYUP are passed to ImeProcessKey. imm32: Mask the scancode before passing it to ImeToAsciiEx. imm32/tests: Adjust todo_wine for the new Wine CJK keyboard layouts.
From: Rémi Bernon rbernon@codeweavers.com
We don't return 0xe001 high word anymore, so the tests are now failing. --- dlls/imm32/tests/imm32.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 488afbd34a9..0b38d70ad8a 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -3890,7 +3890,7 @@ static void test_ImmGetProperty(void) { .fdwProperty = IME_PROP_UNICODE | IME_PROP_AT_CARET, }; - static const IMEINFO expect_ime_info_0411 = /* MS Japanese IME */ + static const IMEINFO expect_ime_info_ja_JP = /* MS Japanese IME */ { .fdwProperty = IME_PROP_CANDLIST_START_FROM_1 | IME_PROP_UNICODE | IME_PROP_AT_CARET | 0xa, .fdwConversionCaps = IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE | IME_CMODE_KATAKANA, @@ -3899,7 +3899,7 @@ static void test_ImmGetProperty(void) .fdwSelectCaps = SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE, .fdwUICaps = UI_CAP_ROT90, }; - static const IMEINFO expect_ime_info_0412 = /* MS Korean IME */ + static const IMEINFO expect_ime_info_ko_KR = /* MS Korean IME */ { .fdwProperty = IME_PROP_CANDLIST_START_FROM_1 | IME_PROP_UNICODE | IME_PROP_AT_CARET | 0xa, .fdwConversionCaps = IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE, @@ -3908,7 +3908,7 @@ static void test_ImmGetProperty(void) .fdwSelectCaps = SELECT_CAP_CONVERSION, .fdwUICaps = UI_CAP_ROT90, }; - static const IMEINFO expect_ime_info_0804 = /* MS Chinese IME */ + static const IMEINFO expect_ime_info_zh_CN = /* MS Chinese IME */ { .fdwProperty = IME_PROP_CANDLIST_START_FROM_1 | IME_PROP_UNICODE | IME_PROP_AT_CARET | 0xa, .fdwConversionCaps = IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE, @@ -3926,21 +3926,24 @@ static void test_ImmGetProperty(void) ok_ret( 0, ImmGetProperty( 0, 0 ) ); ok_ret( 0, ImmGetProperty( hkl, 0 ) );
- if (hkl == (HKL)0x04110411) expect = &expect_ime_info_0411; - else if (hkl == (HKL)0x04120412) expect = &expect_ime_info_0412; - else if (hkl == (HKL)0x08040804) expect = &expect_ime_info_0804; + if (hkl == (HKL)0x04110411) expect = &expect_ime_info_ja_JP; + else if (hkl == (HKL)0x04120412) expect = &expect_ime_info_ko_KR; + else if (hkl == (HKL)0x08040804) expect = &expect_ime_info_zh_CN; else expect = &expect_ime_info;
/* IME_PROP_COMPLETE_ON_UNSELECT seems to be sometimes set on CJK locales IMEs, sometimes not */ + todo_wine_if( expect != &expect_ime_info ) ok_ret( expect->fdwProperty, ImmGetProperty( hkl, IGP_PROPERTY ) & ~IME_PROP_COMPLETE_ON_UNSELECT ); - todo_wine + todo_wine_if( expect != &expect_ime_info_zh_CN && expect != &expect_ime_info_ko_KR ) ok_ret( expect->fdwConversionCaps, ImmGetProperty( hkl, IGP_CONVERSION ) ); todo_wine ok_ret( expect->fdwSentenceCaps, ImmGetProperty( hkl, IGP_SENTENCE ) ); + todo_wine_if( expect != &expect_ime_info ) ok_ret( expect->fdwSCSCaps, ImmGetProperty( hkl, IGP_SETCOMPSTR ) ); - todo_wine + todo_wine_if( expect != &expect_ime_info_ko_KR ) ok_ret( expect->fdwSelectCaps, ImmGetProperty( hkl, IGP_SELECT ) ); ok_ret( IMEVER_0400, ImmGetProperty( hkl, IGP_GETIMEVERSION ) ); + todo_wine_if( expect != &expect_ime_info ) ok_ret( expect->fdwUICaps, ImmGetProperty( hkl, IGP_UI ) ); todo_wine ok_ret( 0xdeadbeef, GetLastError() ); @@ -7370,7 +7373,7 @@ static void test_ga_na_da(void) UINT i;
/* this test doesn't work on Win32 / WoW64 */ - if (sizeof(void *) == 4 || default_hkl != (HKL)0x04120412 /* MS Korean IME */) + if (broken(sizeof(void *) == 4) || default_hkl != (HKL)0x04120412 /* MS Korean IME */) { skip( "Got hkl %p, skipping Korean IME-specific test\n", default_hkl ); process_messages(); @@ -7572,7 +7575,7 @@ static void test_nihongo_no(void) UINT i;
/* this test doesn't work on Win32 / WoW64 */ - if (sizeof(void *) == 4 || default_hkl != (HKL)0x04110411 /* MS Japanese IME */) + if (broken(sizeof(void *) == 4) || default_hkl != (HKL)0x04110411 /* MS Japanese IME */) { skip( "Got hkl %p, skipping Japanese IME-specific test\n", default_hkl ); return;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/imm.c | 2 +- dlls/imm32/tests/imm32.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index cc843ce4a8e..94de6c0f6d7 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -3099,7 +3099,7 @@ BOOL WINAPI ImmTranslateMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar if ((vkey = data->vkey) == VK_PROCESSKEY) return FALSE; data->vkey = VK_PROCESSKEY; GetKeyboardState( state ); - scan = lparam >> 0x10; + scan = (lparam >> 0x10) & 0xffff;
if (ime->info.fdwProperty & IME_PROP_KBD_CHAR_FIRST) { diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 0b38d70ad8a..16f9412f56a 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -7044,7 +7044,6 @@ static void test_ImmTranslateMessage( BOOL kbd_char_first ) .hkl = expect_ime, .himc = default_himc, .func = IME_TO_ASCII_EX, /* FIXME what happened to kbd_char_first here!? */ .to_ascii_ex = {.vkey = 'Q', .vsc = 0xc010}, - .todo_value = TRUE, }, {0}, };
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/tests/imm32.c | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 16f9412f56a..a306a7a065b 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -7087,6 +7087,30 @@ static void test_ImmTranslateMessage( BOOL kbd_char_first ) }, {0}, }; + struct ime_call key_down_seq[] = + { + { + .hkl = expect_ime, .himc = 0/*himc*/, .func = IME_PROCESS_KEY, + .process_key = {.vkey = 'Q', .lparam = MAKELONG(1, 0x10)}, + }, + { + .hkl = expect_ime, .himc = 0/*himc*/, .func = IME_TO_ASCII_EX, + .to_ascii_ex = {.vkey = kbd_char_first ? MAKELONG('Q', 'q') : 'Q', .vsc = 0x10}, + }, + {0}, + }; + struct ime_call key_up_seq[] = + { + { + .hkl = expect_ime, .himc = 0/*himc*/, .func = IME_PROCESS_KEY, + .process_key = {.vkey = 'Q', .lparam = MAKELONG(1, 0xc010)}, + }, + { + .hkl = expect_ime, .himc = 0/*himc*/, .func = IME_TO_ASCII_EX, + .to_ascii_ex = {.vkey = 'Q', .vsc = 0xc010}, + }, + {0}, + }; struct ime_call post_messages[] = { {.hkl = expect_ime, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_STARTCOMPOSITION, .wparam = 1}}, @@ -7169,6 +7193,8 @@ static void test_ImmTranslateMessage( BOOL kbd_char_first ) for (i = 0; i < ARRAY_SIZE(to_ascii_ex_3); i++) to_ascii_ex_3[i].himc = himc; for (i = 0; i < ARRAY_SIZE(post_messages); i++) post_messages[i].himc = himc; for (i = 0; i < ARRAY_SIZE(sent_messages); i++) sent_messages[i].himc = himc; + for (i = 0; i < ARRAY_SIZE(key_down_seq); i++) key_down_seq[i].himc = himc; + for (i = 0; i < ARRAY_SIZE(key_up_seq); i++) key_up_seq[i].himc = himc; memset( ime_calls, 0, sizeof(ime_calls) ); ime_call_count = 0;
@@ -7209,6 +7235,22 @@ static void test_ImmTranslateMessage( BOOL kbd_char_first ) ok_ret( 1, ImmGenerateMessage( himc ) ); ok_seq( empty_sequence );
+ + ignore_WM_IME_NOTIFY = TRUE; + + keybd_event( 'Q', 0x10, 0, 0 ); + flush_events(); + process_messages_( hwnd ); + ok_seq( key_down_seq ); + + keybd_event( 'Q', 0x10, KEYEVENTF_KEYUP, 0 ); + flush_events(); + process_messages_( hwnd ); + todo_wine ok_seq( key_up_seq ); + + ignore_WM_IME_NOTIFY = FALSE; + + ok_ret( 1, ImmUnlockIMC( himc ) ); ok_ret( 1, ImmDestroyContext( himc ) );
From: Rémi Bernon rbernon@codeweavers.com
And to ImmTranslateMessage if they have been processed. --- dlls/imm32/tests/imm32.c | 2 +- dlls/win32u/message.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index a306a7a065b..d59103b165e 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -7246,7 +7246,7 @@ static void test_ImmTranslateMessage( BOOL kbd_char_first ) keybd_event( 'Q', 0x10, KEYEVENTF_KEYUP, 0 ); flush_events(); process_messages_( hwnd ); - todo_wine ok_seq( key_up_seq ); + ok_seq( key_up_seq );
ignore_WM_IME_NOTIFY = FALSE;
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 21d3af8c5fc..0cd20684b4e 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2397,7 +2397,7 @@ static BOOL process_keyboard_message( MSG *msg, UINT hw_id, HWND hwnd_filter, } msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt );
- if (remove && msg->message == WM_KEYDOWN) + if (remove && (msg->message == WM_KEYDOWN || msg->message == WM_KEYUP)) if (ImmProcessKey( msg->hwnd, NtUserGetKeyboardLayout(0), msg->wParam, msg->lParam, 0 )) msg->wParam = VK_PROCESSKEY;
@@ -4399,6 +4399,11 @@ BOOL WINAPI NtUserTranslateMessage( const MSG *msg, UINT flags ) if (flags) FIXME( "unsupported flags %x\n", flags );
if (msg->message < WM_KEYFIRST || msg->message > WM_KEYLAST) return FALSE; + if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP) + { + if (msg->wParam != VK_PROCESSKEY) return TRUE; + return ImmTranslateMessage( msg->hwnd, msg->message, msg->wParam, msg->lParam ); + } if (msg->message != WM_KEYDOWN && msg->message != WM_SYSKEYDOWN) return TRUE;
TRACE_(key)( "Translating key %s (%04x), scancode %04x\n",
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/tests/imm32.c | 290 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+)
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index d59103b165e..fe7d966ea09 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -7407,6 +7407,77 @@ static void test_ga_na_da(void) {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_KEYDOWN, .wparam = 0xd, .lparam = 0x1c0001}}, {0}, }; + struct ime_call cancel_seq[] = + { + /* G */ + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_STARTCOMPOSITION, .wparam = 0, .lparam = 0}}, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\u3131", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0x3131, .lparam = GCS_COMPSTR|GCS_COMPATTR|CS_INSERTCHAR|CS_NOMOVECARET}, + }, + /* A */ + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\uac00", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0xac00, .lparam = GCS_COMPSTR|GCS_COMPATTR|CS_INSERTCHAR|CS_NOMOVECARET}, + }, + /* N */ + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\uac04", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0xac04, .lparam = GCS_COMPSTR|GCS_COMPATTR|CS_INSERTCHAR|CS_NOMOVECARET}, + }, + /* A */ + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\ub098", .result = L"\uac00", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0xac00, .lparam = GCS_RESULTSTR}, + }, + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_CHAR, .wparam = 0xac00, .lparam = 0x1}}, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\ub098", .result = L"\uac00", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0xb098, .lparam = GCS_COMPSTR|GCS_COMPATTR|CS_INSERTCHAR|CS_NOMOVECARET}, + }, + + /* CPS_CANCEL */ + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_ENDCOMPOSITION, .wparam = 0, .lparam = 0}}, + {0}, + }; + struct ime_call closed_seq[] = + { + /* G */ + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_STARTCOMPOSITION, .wparam = 0, .lparam = 0}}, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\u3131", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0x3131, .lparam = GCS_COMPSTR|GCS_COMPATTR|CS_INSERTCHAR|CS_NOMOVECARET}, + }, + /* A */ + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\uac00", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0xac00, .lparam = GCS_COMPSTR|GCS_COMPATTR|CS_INSERTCHAR|CS_NOMOVECARET}, + }, + /* N */ + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\uac04", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0xac04, .lparam = GCS_COMPSTR|GCS_COMPATTR|CS_INSERTCHAR|CS_NOMOVECARET}, + }, + /* A */ + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\ub098", .result = L"\uac00", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0xac00, .lparam = GCS_RESULTSTR}, + }, + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_CHAR, .wparam = 0xac00, .lparam = 0x1}}, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\ub098", .result = L"\uac00", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0xb098, .lparam = GCS_COMPSTR|GCS_COMPATTR|CS_INSERTCHAR|CS_NOMOVECARET}, + }, + + /* CPS_COMPLETE */ + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_ENDCOMPOSITION, .wparam = 0, .lparam = 0}}, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"", .result = L"\ub098", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0xb098, .lparam = GCS_RESULTSTR}, + }, + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_CHAR, .wparam = 0xb098, .lparam = 0x1}}, + {0}, + };
INPUTCONTEXT *ctx; HWND hwnd; @@ -7445,6 +7516,8 @@ static void test_ga_na_da(void) for (i = 0; i < ARRAY_SIZE(partial_d_seq); i++) partial_d_seq[i].himc = himc; for (i = 0; i < ARRAY_SIZE(partial_da_seq); i++) partial_da_seq[i].himc = himc; for (i = 0; i < ARRAY_SIZE(partial_return_seq); i++) partial_return_seq[i].himc = himc; + for (i = 0; i < ARRAY_SIZE(cancel_seq); i++) cancel_seq[i].himc = himc; + for (i = 0; i < ARRAY_SIZE(closed_seq); i++) closed_seq[i].himc = himc;
keybd_event( 'R', 0x13, 0, 0 ); flush_events(); @@ -7532,6 +7605,84 @@ static void test_ga_na_da(void) todo_wine ok_seq( partial_return_seq );
+ ignore_WM_IME_NOTIFY = TRUE; + + /* cancelling clears the composition string */ + + keybd_event( 'R', 0x13, 0, 0 ); + flush_events(); + keybd_event( 'R', 0x13, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'K', 0x25, 0, 0 ); + flush_events(); + keybd_event( 'K', 0x25, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'S', 0x1f, 0, 0 ); + flush_events(); + keybd_event( 'S', 0x1f, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'K', 0x25, 0, 0 ); + flush_events(); + keybd_event( 'K', 0x25, KEYEVENTF_KEYUP, 0 ); + + ok_ret( 1, ImmNotifyIME( himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0 ) ); + + flush_events(); + todo_wine ok_seq( cancel_seq ); + + + /* CPS_COMPLETE and ImmSetOpenStatus( himc, FALSE ) do the same thing */ + + keybd_event( 'R', 0x13, 0, 0 ); + flush_events(); + keybd_event( 'R', 0x13, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'K', 0x25, 0, 0 ); + flush_events(); + keybd_event( 'K', 0x25, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'S', 0x1f, 0, 0 ); + flush_events(); + keybd_event( 'S', 0x1f, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'K', 0x25, 0, 0 ); + flush_events(); + keybd_event( 'K', 0x25, KEYEVENTF_KEYUP, 0 ); + + ok_ret( 1, ImmNotifyIME( himc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0 ) ); + + flush_events(); + todo_wine ok_seq( closed_seq ); + + + keybd_event( 'R', 0x13, 0, 0 ); + flush_events(); + keybd_event( 'R', 0x13, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'K', 0x25, 0, 0 ); + flush_events(); + keybd_event( 'K', 0x25, KEYEVENTF_KEYUP, 0 ); + + /* does nothing, already open */ + ok_ret( 1, ImmSetOpenStatus( himc, TRUE ) ); + + keybd_event( 'S', 0x1f, 0, 0 ); + flush_events(); + keybd_event( 'S', 0x1f, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'K', 0x25, 0, 0 ); + flush_events(); + keybd_event( 'K', 0x25, KEYEVENTF_KEYUP, 0 ); + + ok_ret( 1, ImmSetOpenStatus( himc, FALSE ) ); + + flush_events(); + todo_wine ok_seq( closed_seq ); + + ignore_WM_IME_NOTIFY = FALSE; + + + ok_ret( 1, ImmSetConversionStatus( himc, 0, IME_SMODE_PHRASEPREDICT ) ); ok_ret( 1, ImmSetOpenStatus( himc, FALSE ) );
@@ -7610,6 +7761,61 @@ static void test_nihongo_no(void) {0}, };
+ struct ime_call cancel_seq[] = + { + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_STARTCOMPOSITION, .wparam = 0, .lparam = 0}}, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\uff4e", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0xff4e, .lparam = GCS_COMPSTR|GCS_COMPCLAUSE|GCS_COMPATTR|GCS_COMPREADSTR|GCS_DELTASTART|GCS_CURSORPOS}, + }, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\u306b", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0x306b, .lparam = GCS_COMPSTR|GCS_COMPCLAUSE|GCS_COMPATTR|GCS_COMPREADSTR|GCS_DELTASTART|GCS_CURSORPOS}, + }, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\u306b\uff48", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0x306b, .lparam = GCS_COMPSTR|GCS_COMPCLAUSE|GCS_COMPATTR|GCS_COMPREADSTR|GCS_DELTASTART|GCS_CURSORPOS}, + }, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\u306b\u307b", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0x306b, .lparam = GCS_COMPSTR|GCS_COMPCLAUSE|GCS_COMPATTR|GCS_COMPREADSTR|GCS_DELTASTART|GCS_CURSORPOS}, + }, + + /* CPS_CANCEL */ + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_ENDCOMPOSITION, .wparam = 0, .lparam = 0}}, + {0}, + }; + struct ime_call closed_seq[] = + { + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_STARTCOMPOSITION, .wparam = 0, .lparam = 0}}, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\uff4e", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0xff4e, .lparam = GCS_COMPSTR|GCS_COMPCLAUSE|GCS_COMPATTR|GCS_COMPREADSTR|GCS_DELTASTART|GCS_CURSORPOS}, + }, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\u306b", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0x306b, .lparam = GCS_COMPSTR|GCS_COMPCLAUSE|GCS_COMPATTR|GCS_COMPREADSTR|GCS_DELTASTART|GCS_CURSORPOS}, + }, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\u306b\uff48", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0x306b, .lparam = GCS_COMPSTR|GCS_COMPCLAUSE|GCS_COMPATTR|GCS_COMPREADSTR|GCS_DELTASTART|GCS_CURSORPOS}, + }, + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"\u306b\u307b", .result = L"", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0x306b, .lparam = GCS_COMPSTR|GCS_COMPCLAUSE|GCS_COMPATTR|GCS_COMPREADSTR|GCS_DELTASTART|GCS_CURSORPOS}, + }, + + /* CPS_COMPLETE */ + { + .hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .comp = L"", .result = L"\u306b\u307b", + .message = {.msg = WM_IME_COMPOSITION, .wparam = 0x306b, .lparam = GCS_RESULTSTR|GCS_RESULTCLAUSE|GCS_RESULTREADSTR|GCS_RESULTREADCLAUSE}, + }, + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_CHAR, .wparam = 0x306b, .lparam = 1}}, + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_CHAR, .wparam = 0x307b, .lparam = 1}}, + {.hkl = default_hkl, .himc = 0/*himc*/, .func = MSG_TEST_WIN, .message = {.msg = WM_IME_ENDCOMPOSITION, .wparam = 0, .lparam = 0}}, + {0}, + }; + INPUTCONTEXT *ctx; HWND hwnd; HIMC himc; @@ -7639,6 +7845,8 @@ static void test_nihongo_no(void) ime_call_count = 0;
for (i = 0; i < ARRAY_SIZE(complete_seq); i++) complete_seq[i].himc = himc; + for (i = 0; i < ARRAY_SIZE(cancel_seq); i++) cancel_seq[i].himc = himc; + for (i = 0; i < ARRAY_SIZE(closed_seq); i++) closed_seq[i].himc = himc; ignore_WM_IME_REQUEST = TRUE; ignore_WM_IME_NOTIFY = TRUE;
@@ -7704,6 +7912,88 @@ static void test_nihongo_no(void) ok_seq( empty_sequence );
+ /* changing the open status completes the composition string */ + + ignore_WM_IME_REQUEST = TRUE; + ignore_WM_IME_NOTIFY = TRUE; + + + /* cancelling clears the composition string */ + + keybd_event( 'N', 0x31, 0, 0 ); + flush_events(); + keybd_event( 'N', 0x31, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'I', 0x17, 0, 0 ); + flush_events(); + keybd_event( 'I', 0x17, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'H', 0x23, 0, 0 ); + flush_events(); + keybd_event( 'H', 0x23, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'O', 0x18, 0, 0 ); + flush_events(); + keybd_event( 'O', 0x18, KEYEVENTF_KEYUP, 0 ); + + ok_ret( 1, ImmNotifyIME( himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0 ) ); + + flush_events(); + todo_wine ok_seq( cancel_seq ); + + + /* CPS_COMPLETE and ImmSetOpenStatus( himc, FALSE ) do the same thing */ + + keybd_event( 'N', 0x31, 0, 0 ); + flush_events(); + keybd_event( 'N', 0x31, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'I', 0x17, 0, 0 ); + flush_events(); + keybd_event( 'I', 0x17, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'H', 0x23, 0, 0 ); + flush_events(); + keybd_event( 'H', 0x23, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'O', 0x18, 0, 0 ); + flush_events(); + keybd_event( 'O', 0x18, KEYEVENTF_KEYUP, 0 ); + + ok_ret( 1, ImmNotifyIME( himc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0 ) ); + + flush_events(); + todo_wine ok_seq( closed_seq ); + + + keybd_event( 'N', 0x31, 0, 0 ); + flush_events(); + keybd_event( 'N', 0x31, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'I', 0x17, 0, 0 ); + flush_events(); + keybd_event( 'I', 0x17, KEYEVENTF_KEYUP, 0 ); + + /* does nothing, already open */ + ok_ret( 1, ImmSetOpenStatus( himc, TRUE ) ); + + keybd_event( 'H', 0x23, 0, 0 ); + flush_events(); + keybd_event( 'H', 0x23, KEYEVENTF_KEYUP, 0 ); + + keybd_event( 'O', 0x18, 0, 0 ); + flush_events(); + keybd_event( 'O', 0x18, KEYEVENTF_KEYUP, 0 ); + + ok_ret( 1, ImmSetOpenStatus( himc, FALSE ) ); + + flush_events(); + todo_wine ok_seq( closed_seq ); + + ignore_WM_IME_REQUEST = FALSE; + ignore_WM_IME_NOTIFY = FALSE; + + ok_ret( 1, ImmSetConversionStatus( himc, 0, IME_SMODE_PHRASEPREDICT ) ); ok_ret( 1, ImmSetOpenStatus( himc, FALSE ) );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/ime.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index 60672b366ab..24270e89291 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -653,11 +653,7 @@ BOOL WINAPI NotifyIME( HIMC himc, DWORD action, DWORD index, DWORD value ) } break; case IMC_SETOPENSTATUS: - if (!ctx->fOpen) - { - input_context_set_comp_str( ctx, NULL, 0 ); - if ((msg = ime_set_composition_status( himc, FALSE ))) ime_send_message( himc, msg, 0, 0 ); - } + if (!ctx->fOpen) ImmNotifyIME( himc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0 ); NtUserNotifyIMEStatus( ctx->hWnd, ctx->fOpen ); break; } @@ -691,12 +687,12 @@ BOOL WINAPI NotifyIME( HIMC himc, DWORD action, DWORD index, DWORD value ) if (flags) ime_send_message( himc, WM_IME_COMPOSITION, wchr, flags ); }
- ImmSetOpenStatus( himc, FALSE ); - break; + /* fallthrough */ } case CPS_CANCEL: input_context_set_comp_str( ctx, NULL, 0 ); - ImmSetOpenStatus( himc, FALSE ); + if ((msg = ime_set_composition_status( himc, FALSE ))) + ime_send_message( himc, msg, 0, 0 ); break; default: FIXME( "himc %p, action %#lx, index %#lx, value %#lx stub!\n", himc, action, index, value );
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=142321
Your paranoid android.
=== w11pro64 (32 bit report) ===
imm32: imm32.c:7244: Test failed: kbd_char_first: 0 (missing): hkl E020047F, himc 000C02B7, IME_PROCESS_KEY vkey 0x51, lparam 0x100001 imm32.c:7244: Test failed: kbd_char_first: 1 (missing): hkl E020047F, himc 000C02B7, IME_TO_ASCII_EX vkey 0x710051, vsc 0x10, flags 0 imm32.c:7249: Test failed: kbd_char_first: 0 (missing): hkl E020047F, himc 000C02B7, IME_PROCESS_KEY vkey 0x51, lparam 0xc0100001 imm32.c:7249: Test failed: kbd_char_first: 1 (missing): hkl E020047F, himc 000C02B7, IME_TO_ASCII_EX vkey 0x51, vsc 0xc010, flags 0 imm32.c:1326: Test failed: expected WM_IME_SETCONTEXT_ACTIVATE imm32.c:818: Test failed: unexpected call WM_IME_SETCONTEXT_ACTIVATE imm32.c:1405: Test failed: expected WM_IME_SETCONTEXT_ACTIVATE imm32.c:818: Test failed: unexpected call WM_IME_SETCONTEXT_ACTIVATE
=== w7pro64 (64 bit report) ===
imm32: imm32.c:7249: Test failed: default: 2 (spurious): got hkl FFFFFFFFE020047F, himc 0000000000020135, IME_NOTIFY action 0x15, index 0x4, value 0 imm32.c:7249: Test failed: default: 3 (spurious): got hkl FFFFFFFFE020047F, himc 0000000000380159, IME_NOTIFY action 0x15, index 0x4, value 0 imm32.c:7249: Test failed: default: 4 (spurious): got hkl FFFFFFFFE020047F, himc 0000000000380159, MSG_IME_UI msg WM_IME_SELECT, wparam 0, lparam 0xffffffffe020047f imm32.c:7249: Test failed: default: 5 (spurious): got hkl 0000000004090409, himc 0000000000020135, IME_SELECT select 0 imm32.c:7249: Test failed: default: 6 (spurious): got hkl 0000000004090409, himc 0000000000380159, IME_SELECT select 0
=== w10pro64_ja (64 bit report) ===
imm32: imm32.c:7244: Test failed: kbd_char_first: 2 (spurious): got hkl FFFFFFFFE020047F, himc 00000000002102B7, IME_NOTIFY action 0x3, index 0, value 0x6
=== w10pro64_zh_CN (64 bit report) ===
imm32: imm32.c:7244: Test failed: kbd_char_first: 2 (spurious): got hkl FFFFFFFFE020047F, himc 00000000000600AF, IME_NOTIFY action 0x3, index 0, value 0x6 imm32.c:7244: Test failed: kbd_char_first: 3 (spurious): got hkl FFFFFFFFE020047F, himc 00000000000600AF, IME_NOTIFY action 0x3, index 0xffffffff, value 0x2
=== debian11b (64 bit WoW report) ===
mf: Unhandled exception: divide by zero in 64-bit code (0x0000000042e22c).
v3: Pass WM_(SYS)KEYUP only to ImmTranslateMessage.