[PATCH 0/5] MR9992: Winemac IME rework part 1
From: Marc-Aurel Zent <mzent@codeweavers.com> --- dlls/imm32/ime.c | 1 + dlls/win32u/driver.c | 12 ++++++++++++ dlls/win32u/imm.c | 1 + include/ntuser.h | 1 + include/wine/gdi_driver.h | 1 + 5 files changed, 16 insertions(+) diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index 65f46f20550..ed3f262c47a 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -551,6 +551,7 @@ UINT WINAPI ImeToAsciiEx( UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs, params.compstr = compstr; params.key_consumed = &key_consumed; + params.msgs = msgs; status = NtUserMessageCall( ctx->hWnd, WINE_IME_TO_ASCII_EX, vkey, vsc, ¶ms, NtUserImeDriverCall, FALSE ); size = compstr->dwSize; diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 60aba702d1a..9664c355fc2 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -676,6 +676,11 @@ static UINT nulldrv_ImeProcessKey( HIMC himc, UINT wparam, UINT lparam, const BY return 0; } +static UINT nulldrv_ImeToAsciiEx( UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs, UINT flags, HIMC himc ) +{ + return 0; +} + static void nulldrv_NotifyIMEStatus( HWND hwnd, UINT status ) { } @@ -1103,6 +1108,11 @@ static UINT loaderdrv_ImeProcessKey( HIMC himc, UINT wparam, UINT lparam, const return load_driver()->pImeProcessKey( himc, wparam, lparam, state ); } +static UINT loaderdrv_ImeToAsciiEx( UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs, UINT flags, HIMC himc ) +{ + return load_driver()->pImeToAsciiEx( vkey, vsc, state, msgs, flags, himc ); +} + static void loaderdrv_NotifyIMEStatus( HWND hwnd, UINT status ) { return load_driver()->pNotifyIMEStatus( hwnd, status ); @@ -1256,6 +1266,7 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_KbdLayerDescriptor, loaderdrv_ReleaseKbdTables, loaderdrv_ImeProcessKey, + loaderdrv_ImeToAsciiEx, loaderdrv_NotifyIMEStatus, loaderdrv_SetIMECompositionRect, /* cursor/icon functions */ @@ -1360,6 +1371,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(KbdLayerDescriptor); SET_USER_FUNC(ReleaseKbdTables); SET_USER_FUNC(ImeProcessKey); + SET_USER_FUNC(ImeToAsciiEx); SET_USER_FUNC(NotifyIMEStatus); SET_USER_FUNC(SetIMECompositionRect); SET_USER_FUNC(DestroyCursorIcon); diff --git a/dlls/win32u/imm.c b/dlls/win32u/imm.c index 3337f66e291..ae2a3f359c8 100644 --- a/dlls/win32u/imm.c +++ b/dlls/win32u/imm.c @@ -687,6 +687,7 @@ LRESULT ime_driver_call( HWND hwnd, enum wine_ime_call call, WPARAM wparam, LPAR return res; } case WINE_IME_TO_ASCII_EX: + user_driver->pImeToAsciiEx( wparam, lparam, params->state, params->msgs, 0, 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 ); diff --git a/include/ntuser.h b/include/ntuser.h index ce1b18fdfd9..54a4949e407 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -682,6 +682,7 @@ struct ime_driver_call_params const BYTE *state; COMPOSITIONSTRING *compstr; BOOL *key_consumed; + TRANSMSGLIST *msgs; }; /* NtUserSystemTrayCall calls */ diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index f6390bce878..7e2a6005deb 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -373,6 +373,7 @@ struct user_driver_funcs void (*pReleaseKbdTables)(const KBDTABLES *); /* IME functions */ UINT (*pImeProcessKey)(HIMC,UINT,UINT,const BYTE*); + UINT (*pImeToAsciiEx)(UINT,UINT,BYTE*,TRANSMSGLIST*,UINT,HIMC); void (*pNotifyIMEStatus)(HWND,UINT); BOOL (*pSetIMECompositionRect)(HWND,RECT); /* cursor/icon functions */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9992
From: Marc-Aurel Zent <mzent@codeweavers.com> --- dlls/imm32/ime.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index ed3f262c47a..8369fa7bed9 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -361,12 +361,14 @@ static UINT ime_set_comp_string( HIMC himc, LPARAM lparam ) TRANSMSG *msgs; HIMCC himcc; UINT count; + BYTE state[256]; TRACE( "himc %p\n", himc ); if (!(ctx = ImmLockIMC( himc ))) return 0; - count = ImeToAsciiEx( VK_PROCESSKEY, lparam, NULL, &buffer.list, 0, himc ); + GetKeyboardState( state ); + count = ImeToAsciiEx( VK_PROCESSKEY, lparam, state, &buffer.list, 0, himc ); if (!count) TRACE( "ImeToAsciiEx returned no messages\n" ); else if (count >= buffer.uMsgCount) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9992
From: Marc-Aurel Zent <mzent@codeweavers.com> --- dlls/imm32/ime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index 8369fa7bed9..f448412e10b 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -594,7 +594,7 @@ UINT WINAPI ImeToAsciiEx( UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs, if (!key_consumed) { - TRANSMSG msg = {.message = WM_IME_KEYDOWN, .wParam = vkey, .lParam = vsc}; + TRANSMSG msg = {.message = WM_KEYDOWN, .wParam = LOWORD( vkey ), .lParam = MAKELONG( 1, vsc )}; msgs->TransMsg[count++] = msg; } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9992
From: Marc-Aurel Zent <mzent@codeweavers.com> --- dlls/win32u/imm.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dlls/win32u/imm.c b/dlls/win32u/imm.c index ae2a3f359c8..187e947c774 100644 --- a/dlls/win32u/imm.c +++ b/dlls/win32u/imm.c @@ -687,8 +687,17 @@ LRESULT ime_driver_call( HWND hwnd, enum wine_ime_call call, WPARAM wparam, LPAR return res; } case WINE_IME_TO_ASCII_EX: - user_driver->pImeToAsciiEx( wparam, lparam, params->state, params->msgs, 0, params->himc ); + { + UINT ret = user_driver->pImeToAsciiEx( wparam, lparam, params->state, params->msgs, 0, params->himc ); + + if (ret) + { + *params->key_consumed = FALSE; + NtUserNotifyIMEStatus( hwnd, 0 ); + return 0; + } 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; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9992
From: Marc-Aurel Zent <mzent@codeweavers.com> --- dlls/winemac.drv/gdi.c | 1 + dlls/winemac.drv/keyboard.c | 38 ++++++++++++++++++++++++++----------- dlls/winemac.drv/macdrv.h | 2 ++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 2ef941aedb4..1bf703459f5 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -278,6 +278,7 @@ static const struct user_driver_funcs macdrv_funcs = .pUpdateLayeredWindow = macdrv_UpdateLayeredWindow, .pVkKeyScanEx = macdrv_VkKeyScanEx, .pImeProcessKey = macdrv_ImeProcessKey, + .pImeToAsciiEx = macdrv_ImeToAsciiEx, .pNotifyIMEStatus = macdrv_NotifyIMEStatus, .pSetIMECompositionRect = macdrv_SetIMECompositionRect, .pWindowMessage = macdrv_WindowMessage, diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c index 7c49be7849f..0b6a81938e5 100644 --- a/dlls/winemac.drv/keyboard.c +++ b/dlls/winemac.drv/keyboard.c @@ -1086,15 +1086,13 @@ void macdrv_hotkey_press(const macdrv_event *event) UINT macdrv_ImeProcessKey(HIMC himc, UINT wparam, UINT lparam, const BYTE *key_state) { struct macdrv_thread_data *thread_data = macdrv_thread_data(); - WORD scan = HIWORD(lparam) & 0x1ff, vkey = LOWORD(wparam); + WORD vkey = LOWORD(wparam); BOOL repeat = !!(lparam >> 30), pressed = !(lparam >> 31); - unsigned int flags; - int keyc; - UINT ret; - TRACE("himc %p, scan %#x, vkey %#x, repeat %u, pressed %u\n", - himc, scan, vkey, repeat, pressed); + TRACE("himc %p, vkey %#x, repeat %u, pressed %u\n", + himc, vkey, repeat, pressed); + thread_data->repeat = repeat; if (!macdrv_using_input_method()) return 0; if (!pressed) @@ -1111,23 +1109,41 @@ UINT macdrv_ImeProcessKey(HIMC himc, UINT wparam, UINT lparam, const BYTE *key_s case VK_CONTROL: case VK_CAPITAL: case VK_MENU: + case VK_KANA: + case VK_KANJI: + TRACE("Skipping metakey\n"); return 0; } + return 1; +} + +/*********************************************************************** + * ImeToAsciiEx (MACDRV.@) + */ +UINT macdrv_ImeToAsciiEx(UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs, UINT flags, HIMC himc) +{ + struct macdrv_thread_data *thread_data = macdrv_thread_data(); + int keyc; + UINT ret; + + TRACE("himc %p, vkey %#x state %p\n", + himc, vkey, state); + flags = thread_data->last_modifiers; - if (key_state[VK_SHIFT] & 0x80) + if (state[VK_SHIFT] & 0x80) flags |= NX_SHIFTMASK; else flags &= ~(NX_SHIFTMASK | NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK); - if (key_state[VK_CAPITAL] & 0x01) + if (state[VK_CAPITAL] & 0x01) flags |= NX_ALPHASHIFTMASK; else flags &= ~NX_ALPHASHIFTMASK; - if (key_state[VK_CONTROL] & 0x80) + if (state[VK_CONTROL] & 0x80) flags |= NX_CONTROLMASK; else flags &= ~(NX_CONTROLMASK | NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK); - if (key_state[VK_MENU] & 0x80) + if (state[VK_MENU] & 0x80) flags |= NX_COMMANDMASK; else flags &= ~(NX_COMMANDMASK | NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK); @@ -1139,7 +1155,7 @@ UINT macdrv_ImeProcessKey(HIMC himc, UINT wparam, UINT lparam, const BYTE *key_s if (keyc >= ARRAY_SIZE(thread_data->keyc2vkey)) return 0; TRACE("flags 0x%08x keyc 0x%04x\n", flags, keyc); - ret = (UINT)macdrv_ime_process_key(keyc, flags, repeat, himc); + ret = !(UINT)macdrv_ime_process_key(keyc, flags, thread_data->repeat, himc); NtUserMsgWaitForMultipleObjectsEx(0, NULL, 0, QS_POSTMESSAGE | QS_SENDMESSAGE, 0); TRACE("returning %u\n", ret); return ret; diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index ac2a7853652..c415509c270 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -107,6 +107,7 @@ static inline RECT rect_from_cgrect(CGRect cgrect) CFDataRef keyboard_layout_uchr; CGEventSourceKeyboardType keyboard_type; bool iso_keyboard; + bool repeat; CGEventFlags last_modifiers; UInt32 dead_key_state; HKL active_keyboard_layout; @@ -160,6 +161,7 @@ extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hin extern void macdrv_UnregisterHotKey(HWND hwnd, UINT modifiers, UINT vkey); extern SHORT macdrv_VkKeyScanEx(WCHAR wChar, HKL hkl); extern UINT macdrv_ImeProcessKey(HIMC himc, UINT wparam, UINT lparam, const BYTE *state); +extern UINT macdrv_ImeToAsciiEx(UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs, UINT flags, HIMC himc); extern UINT macdrv_MapVirtualKeyEx(UINT wCode, UINT wMapType, HKL hkl); extern INT macdrv_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState, LPWSTR bufW, int bufW_size, UINT flags, HKL hkl); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9992
The split of ImeToAsciiEx from ImeProcessKey doesn't seem right to me. ImeProcessKey should return whether the key has been consumed or not, there's no good way to backtrack on an decision to consume a key. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9992#note_128277
participants (3)
-
Marc-Aurel Zent -
Marc-Aurel Zent (@mzent) -
Rémi Bernon (@rbernon)