In Korean input, if ime is in the composition state, when non-printable key (ENTER, TAB, etc.) are pressed, it returns a result_string and passes the non-printable key to WinProc with the WM_IME_KEYDOWN message.
This can be seen in ‘imm32/test/imm32.c::test_ga_na_da()’.
In the current winemac.drv, if you select the “Korean 2-Set Keyboard” input source and type ‘r-k-ENTER’, it only outputs the result string ‘0xAC00’. WM_IME_KEYDOWN message generation does not exist.
At this point, the WINE_IME_POST_UPDATE call occurs, and macdrv_ImeProcessKey returns FALSE. A FALSE return value means that the key was not consumed by ime, and a WM_KEYDOWN message should be generated.
However, because an ime_update call occurred, ImeProcessKey should return TRUE, and (wparam not modified) raw WM_KEYDOWN message should be generated via a different path, so a WM_IME_KEYDOWN message is required.
This patch allows the macdrv_ImeProcessKey return value to be passed to ImeToAsciiEx() to determine if a WM_IME_KEYDOWN message should be generated.
From: Byeongsik Jeon bsjeon@hanmail.net
In Korean input, if ime is in the composition state, when non-printable key (ENTER, TAB, etc.) are pressed, it returns a result_string and passes the non-printable key to WinProc with the WM_IME_KEYDOWN message.
This can be seen in ‘imm32/test/imm32.c::test_ga_na_da()’.
In the current winemac.drv, if you select the “Korean 2-Set Keyboard” input source and type ‘r-k-ENTER’, it only outputs the result string ‘0xAC00’. WM_IME_KEYDOWN message generation does not exist.
At this point, the WINE_IME_POST_UPDATE call occurs, and macdrv_ImeProcessKey returns FALSE. A FALSE return value means that the key was not consumed by ime, and a WM_KEYDOWN message should be generated.
However, because an ime_update call occurred, ImeProcessKey should return TRUE, and (wparam not modified) raw WM_KEYDOWN message should be generated via a different path, so a WM_IME_KEYDOWN message is required.
This patch allows the macdrv_ImeProcessKey return value to be passed to ImeToAsciiEx() to determine if a WM_IME_KEYDOWN message should be generated. --- dlls/imm32/ime.c | 8 ++++++++ dlls/win32u/imm.c | 10 ++++++++-- include/ntuser.h | 1 + 3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index cf80faab930..d7ffc3de115 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -533,6 +533,7 @@ UINT WINAPI ImeToAsciiEx( UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs, UINT size, count = 0; INPUTCONTEXT *ctx; NTSTATUS status; + BOOL key_consumed = TRUE;
TRACE( "vkey %#x, vsc %#x, state %p, msgs %p, flags %#x, himc %p\n", vkey, vsc, state, msgs, flags, himc ); @@ -551,6 +552,7 @@ UINT WINAPI ImeToAsciiEx( UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs, if (!(compstr = ImmLockIMCC( (ctx->hCompStr = himcc) ))) goto done;
params.compstr = compstr; + params.key_consumed = &key_consumed; status = NtUserMessageCall( ctx->hWnd, WINE_IME_TO_ASCII_EX, vkey, vsc, ¶ms, NtUserImeDriverCall, FALSE ); size = compstr->dwSize; @@ -579,6 +581,12 @@ UINT WINAPI ImeToAsciiEx( UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs, else msg.lParam |= CS_INSERTCHAR|CS_NOMOVECARET; msgs->TransMsg[count++] = msg; } + + if (!key_consumed) + { + TRANSMSG msg = {.message = WM_IME_KEYDOWN, .wParam = vkey, .lParam = vsc}; + msgs->TransMsg[count++] = msg; + } }
ImmUnlockIMCC( ctx->hCompStr ); diff --git a/dlls/win32u/imm.c b/dlls/win32u/imm.c index 99dc3e5e225..e3c94b8eb18 100644 --- a/dlls/win32u/imm.c +++ b/dlls/win32u/imm.c @@ -39,6 +39,7 @@ struct ime_update struct list entry; WORD vkey; WORD scan; + BOOL key_consumed; DWORD cursor_pos; WCHAR *comp_str; WCHAR *result_str; @@ -459,6 +460,7 @@ static void post_ime_update( HWND hwnd, UINT cursor_pos, WCHAR *comp_str, WCHAR pthread_mutex_lock( &imm_mutex ); id = update->scan = ++ime_update_count; update->vkey = VK_PROCESSKEY; + update->key_consumed = TRUE; list_add_tail( &ime_updates, &update->entry ); pthread_mutex_unlock( &imm_mutex );
@@ -482,7 +484,8 @@ static struct ime_update *find_ime_update( WORD vkey, WORD scan ) return NULL; }
-UINT ime_to_tascii_ex( UINT vkey, UINT lparam, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc ) +static UINT ime_to_tascii_ex( UINT vkey, UINT lparam, const BYTE *state, COMPOSITIONSTRING *compstr, + BOOL *key_consumed, HIMC himc ) { UINT needed = sizeof(COMPOSITIONSTRING), comp_len, result_len; struct ime_update *update; @@ -498,6 +501,8 @@ UINT ime_to_tascii_ex( UINT vkey, UINT lparam, const BYTE *state, COMPOSITIONSTR return STATUS_NOT_FOUND; }
+ *key_consumed = update->key_consumed; + if (!update->comp_str) comp_len = 0; else { @@ -590,6 +595,7 @@ LRESULT ime_driver_call( HWND hwnd, enum wine_ime_call call, WPARAM wparam, LPAR
if (data->update) { + data->update->key_consumed = res; pthread_mutex_lock( &imm_mutex ); list_add_tail( &ime_updates, &data->update->entry ); pthread_mutex_unlock( &imm_mutex ); @@ -601,7 +607,7 @@ LRESULT ime_driver_call( HWND hwnd, enum wine_ime_call call, WPARAM wparam, LPAR return res; } case WINE_IME_TO_ASCII_EX: - return ime_to_tascii_ex( wparam, lparam, params->state, params->compstr, params->himc ); + return ime_to_tascii_ex( wparam, lparam, params->state, params->compstr, params->key_consumed, params->himc ); case WINE_IME_POST_UPDATE: post_ime_update( hwnd, wparam, (WCHAR *)lparam, (WCHAR *)params ); return 0; diff --git a/include/ntuser.h b/include/ntuser.h index 848e5a4a651..66581743fbd 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -645,6 +645,7 @@ struct ime_driver_call_params HIMC himc; const BYTE *state; COMPOSITIONSTRING *compstr; + BOOL *key_consumed; };
/* NtUserSystemTrayCall calls */
From: Byeongsik Jeon bsjeon@hanmail.net
--- dlls/wow64win/user.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 2f0ec0cc181..ed6b67f075a 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -3687,12 +3687,14 @@ NTSTATUS WINAPI wow64_NtUserMessageCall( UINT *args ) ULONG himc; ULONG state; ULONG compstr; + ULONG key_consumed; } *params32 = result_info; struct ime_driver_call_params params; if (msg == WINE_IME_POST_UPDATE) ERR( "Unexpected WINE_IME_POST_UPDATE message\n" ); params.himc = UlongToPtr( params32->himc ); params.state = UlongToPtr( params32->state ); params.compstr = UlongToPtr( params32->compstr ); + params.key_consumed = UlongToPtr( params32->key_consumed ); return NtUserMessageCall( hwnd, msg, wparam, lparam, ¶ms, type, ansi ); }