In preparation for, and split from https://gitlab.winehq.org/wine/wine/-/merge_requests/2637.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/event.c | 47 ++++++++++++++++++++++++++++++++-- dlls/winemac.drv/ime.c | 12 ++++++--- dlls/winemac.drv/macdrv.h | 1 + dlls/winemac.drv/macdrv_main.c | 2 ++ dlls/winemac.drv/unixlib.h | 1 + 5 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c index 03c49b34bae..cc8aa4681c6 100644 --- a/dlls/winemac.drv/event.c +++ b/dlls/winemac.drv/event.c @@ -32,6 +32,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(event); WINE_DECLARE_DEBUG_CHANNEL(imm);
+struct ime_update +{ + struct ime_set_text_params *comp_params; + DWORD comp_size; + struct ime_set_text_params *result_params; + DWORD result_size; +}; +static struct ime_update ime_update;
/* return the name of an Mac event */ static const char *dbgstr_event(int type) @@ -170,7 +178,20 @@ static void macdrv_im_set_text(const macdrv_event *event) if (length) CFStringGetCharacters(event->im_set_text.text, CFRangeMake(0, length), params->text);
- macdrv_client_func(client_func_ime_set_text, params, size); + free(ime_update.comp_params); + ime_update.comp_params = NULL; + + if (params->complete) + { + free(ime_update.result_params); + ime_update.result_params = params; + ime_update.result_size = size; + } + else + { + ime_update.comp_params = params; + ime_update.comp_size = size; + } }
/*********************************************************************** @@ -179,7 +200,29 @@ static void macdrv_im_set_text(const macdrv_event *event) static void macdrv_sent_text_input(const macdrv_event *event) { TRACE_(imm)("handled: %s\n", event->sent_text_input.handled ? "TRUE" : "FALSE"); - *event->sent_text_input.done = event->sent_text_input.handled ? 1 : -1; + *event->sent_text_input.done = event->sent_text_input.handled || ime_update.result_params ? 1 : -1; +} + + +/*********************************************************************** + * macdrv_ime_get_text_input + */ +NTSTATUS macdrv_ime_get_text_input(void *arg) +{ + if (ime_update.result_params) + { + macdrv_client_func(client_func_ime_set_text, ime_update.result_params, ime_update.result_size); + free(ime_update.result_params); + ime_update.result_params = NULL; + } + if (ime_update.comp_params) + { + macdrv_client_func(client_func_ime_set_text, ime_update.comp_params, ime_update.comp_size); + free(ime_update.comp_params); + ime_update.comp_params = NULL; + } + + return 0; }
diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c index 059a5c443f3..351eb28ff98 100644 --- a/dlls/winemac.drv/ime.c +++ b/dlls/winemac.drv/ime.c @@ -679,10 +679,16 @@ UINT WINAPI ImeToAsciiEx(UINT uVKey, UINT uScanCode, const LPBYTE lpbKeyState,
return msgs; } - else if ((lpIMC = LockRealIMC(hIMC))) + else { - UpdateDataInDefaultIMEWindow( lpIMC, hwnd, FALSE ); - UnlockRealIMC(hIMC); + /* trigger the pending client_func_ime_set_text call */ + MACDRV_CALL(ime_get_text_input, NULL); + + if ((lpIMC = LockRealIMC(hIMC))) + { + UpdateDataInDefaultIMEWindow( lpIMC, hwnd, FALSE ); + UnlockRealIMC(hIMC); + } } return 0; } diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 281d49c1e9a..b77e62f75db 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -277,6 +277,7 @@ extern NTSTATUS macdrv_dnd_have_format(void *arg) DECLSPEC_HIDDEN; extern NTSTATUS macdrv_dnd_release(void *arg) DECLSPEC_HIDDEN; extern NTSTATUS macdrv_dnd_retain(void *arg) DECLSPEC_HIDDEN; extern NTSTATUS macdrv_ime_process_text_input(void *arg) DECLSPEC_HIDDEN; +extern NTSTATUS macdrv_ime_get_text_input(void *arg) DECLSPEC_HIDDEN; extern NTSTATUS macdrv_notify_icon(void *arg) DECLSPEC_HIDDEN;
extern NTSTATUS macdrv_client_func(enum macdrv_client_funcs func, const void *params, diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c index a4b280283ee..bf03ab6f5fe 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -635,6 +635,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = macdrv_dnd_retain, macdrv_ime_clear, macdrv_ime_process_text_input, + macdrv_ime_get_text_input, macdrv_ime_using_input_method, macdrv_init, macdrv_notify_icon, @@ -761,6 +762,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = macdrv_dnd_retain, macdrv_ime_clear, wow64_ime_process_text_input, + macdrv_ime_get_text_input, macdrv_ime_using_input_method, wow64_init, wow64_notify_icon, diff --git a/dlls/winemac.drv/unixlib.h b/dlls/winemac.drv/unixlib.h index ca5115f4982..b3f45291904 100644 --- a/dlls/winemac.drv/unixlib.h +++ b/dlls/winemac.drv/unixlib.h @@ -28,6 +28,7 @@ enum macdrv_funcs unix_dnd_retain, unix_ime_clear, unix_ime_process_text_input, + unix_ime_get_text_input, unix_ime_using_input_method, unix_init, unix_notify_icon,
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/ime.c | 10 +++------- dlls/winemac.drv/keyboard.c | 14 ++++++-------- dlls/winemac.drv/macdrv_main.c | 2 -- dlls/winemac.drv/unixlib.h | 1 - 4 files changed, 9 insertions(+), 18 deletions(-)
diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c index 351eb28ff98..23e6d1c78cc 100644 --- a/dlls/winemac.drv/ime.c +++ b/dlls/winemac.drv/ime.c @@ -628,7 +628,7 @@ UINT WINAPI ImeToAsciiEx(UINT uVKey, UINT uScanCode, const LPBYTE lpbKeyState, LPIMEPRIVATE myPrivate; HWND hwnd; UINT repeat; - int done = 0; + UINT ret;
TRACE("uVKey 0x%04x uScanCode 0x%04x fuState %u hIMC %p\n", uVKey, uScanCode, fuState, hIMC);
@@ -660,13 +660,9 @@ UINT WINAPI ImeToAsciiEx(UINT uVKey, UINT uScanCode, const LPBYTE lpbKeyState, params.scan = uScanCode; params.repeat = repeat; params.key_state = lpbKeyState; - params.done = &done; - MACDRV_CALL(ime_process_text_input, ¶ms); + ret = MACDRV_CALL(ime_process_text_input, ¶ms);
- while (!done) - MsgWaitForMultipleObjectsEx(0, NULL, INFINITE, QS_POSTMESSAGE | QS_SENDMESSAGE, 0); - - if (done < 0) + if (!ret) { UINT msgs = 0; UINT msg = (uScanCode & 0x8000) ? WM_KEYUP : WM_KEYDOWN; diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c index 14731f2d235..17abbedb230 100644 --- a/dlls/winemac.drv/keyboard.c +++ b/dlls/winemac.drv/keyboard.c @@ -1197,7 +1197,7 @@ NTSTATUS macdrv_ime_process_text_input(void *arg) void *himc = UlongToHandle(params->himc); const BYTE *key_state = params->key_state; unsigned int flags; - int keyc; + int keyc, done = 0;
TRACE("vkey 0x%04x scan 0x%04x repeat %u himc %p\n", params->vkey, params->scan, params->repeat, himc); @@ -1224,17 +1224,15 @@ NTSTATUS macdrv_ime_process_text_input(void *arg) for (keyc = 0; keyc < ARRAY_SIZE(thread_data->keyc2vkey); keyc++) if (thread_data->keyc2vkey[keyc] == params->vkey) break;
- if (keyc >= ARRAY_SIZE(thread_data->keyc2vkey)) - { - *params->done = -1; - return 0; - } + if (keyc >= ARRAY_SIZE(thread_data->keyc2vkey)) return 0;
TRACE("flags 0x%08x keyc 0x%04x\n", flags, keyc);
macdrv_send_text_input_event(((params->scan & 0x8000) == 0), flags, params->repeat, keyc, - himc, params->done); - return 0; + himc, &done); + while (!done) NtUserMsgWaitForMultipleObjectsEx(0, NULL, INFINITE, QS_POSTMESSAGE | QS_SENDMESSAGE, 0); + + return done > 0; }
diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c index bf03ab6f5fe..7e91e0ca3e1 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -673,7 +673,6 @@ static NTSTATUS wow64_ime_process_text_input(void *arg) UINT scan; UINT repeat; ULONG key_state; - ULONG done; } *params32 = arg; struct process_text_input_params params;
@@ -682,7 +681,6 @@ static NTSTATUS wow64_ime_process_text_input(void *arg) params.scan = params32->scan; params.repeat = params32->repeat; params.key_state = UlongToPtr(params32->key_state); - params.done = UlongToPtr(params32->done); return macdrv_ime_process_text_input(¶ms); }
diff --git a/dlls/winemac.drv/unixlib.h b/dlls/winemac.drv/unixlib.h index b3f45291904..493e4f6c139 100644 --- a/dlls/winemac.drv/unixlib.h +++ b/dlls/winemac.drv/unixlib.h @@ -69,7 +69,6 @@ struct process_text_input_params UINT scan; UINT repeat; const BYTE *key_state; - int *done; };
/* macdrv_init params */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/ime.c | 72 ++++++++++-------------------------------- include/ntuser.h | 1 - 2 files changed, 17 insertions(+), 56 deletions(-)
diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c index 23e6d1c78cc..1914940f242 100644 --- a/dlls/winemac.drv/ime.c +++ b/dlls/winemac.drv/ime.c @@ -469,24 +469,6 @@ static void GenerateIMEMessage(HIMC hIMC, UINT msg, WPARAM wParam, LPARAM lParam UnlockRealIMC(hIMC); }
-static BOOL GenerateMessageToTransKey(TRANSMSGLIST *lpTransBuf, UINT *uNumTranMsgs, - UINT msg, WPARAM wParam, LPARAM lParam) -{ - LPTRANSMSG ptr; - - if (*uNumTranMsgs + 1 >= lpTransBuf->uMsgCount) - return FALSE; - - ptr = lpTransBuf->TransMsg + *uNumTranMsgs; - ptr->message = msg; - ptr->wParam = wParam; - ptr->lParam = lParam; - (*uNumTranMsgs)++; - - return TRUE; -} - - static BOOL IME_RemoveFromSelected(HIMC hIMC) { int i; @@ -535,8 +517,14 @@ static void UpdateDataInDefaultIMEWindow(INPUTCONTEXT *lpIMC, HWND hwnd, BOOL sh
BOOL WINAPI ImeProcessKey(HIMC hIMC, UINT vKey, LPARAM lKeyData, const LPBYTE lpbKeyState) { + struct process_text_input_params params = + { + .himc = (UINT_PTR)hIMC, .vkey = LOWORD(vKey), .scan = HIWORD(lKeyData), + .repeat = !!(lKeyData >> 30), .key_state = lpbKeyState, + }; LPINPUTCONTEXT lpIMC; BOOL inIME; + UINT ret;
TRACE("hIMC %p vKey 0x%04x lKeyData 0x%08Ix lpbKeyState %p\n", hIMC, vKey, lKeyData, lpbKeyState);
@@ -567,14 +555,17 @@ BOOL WINAPI ImeProcessKey(HIMC hIMC, UINT vKey, LPARAM lKeyData, const LPBYTE lp ImmSetOpenStatus(RealIMC(FROM_MACDRV), FALSE); }
- myPrivate->repeat = (lKeyData >> 30) & 0x1; - myPrivate->bInternalState = inIME; ImmUnlockIMCC(lpIMC->hPrivate); } UnlockRealIMC(hIMC);
- return inIME; + if (!inIME) return FALSE; + + TRACE( "Processing Mac 0x%04x\n", vKey ); + ret = MACDRV_CALL( ime_process_text_input, ¶ms ); + + return ret != 0; }
BOOL WINAPI ImeSelect(HIMC hIMC, BOOL fSelect) @@ -611,7 +602,6 @@ BOOL WINAPI ImeSelect(HIMC hIMC, BOOL fSelect) myPrivate->bInternalState = FALSE; myPrivate->textfont = NULL; myPrivate->hwndDefault = NULL; - myPrivate->repeat = 0; ImmUnlockIMCC(lpIMC->hPrivate); UnlockRealIMC(hIMC); } @@ -622,13 +612,10 @@ BOOL WINAPI ImeSelect(HIMC hIMC, BOOL fSelect) UINT WINAPI ImeToAsciiEx(UINT uVKey, UINT uScanCode, const LPBYTE lpbKeyState, TRANSMSGLIST *lpdwTransKey, UINT fuState, HIMC hIMC) { - struct process_text_input_params params; UINT vkey; LPINPUTCONTEXT lpIMC; LPIMEPRIVATE myPrivate; HWND hwnd; - UINT repeat; - UINT ret;
TRACE("uVKey 0x%04x uScanCode 0x%04x fuState %u hIMC %p\n", uVKey, uScanCode, fuState, hIMC);
@@ -650,41 +637,16 @@ UINT WINAPI ImeToAsciiEx(UINT uVKey, UINT uScanCode, const LPBYTE lpbKeyState, return 0; }
- repeat = myPrivate->repeat; ImmUnlockIMCC(lpIMC->hPrivate); UnlockRealIMC(hIMC);
- TRACE("Processing Mac 0x%04x\n", vkey); - params.himc = HandleToULong(hIMC); - params.vkey = uVKey; - params.scan = uScanCode; - params.repeat = repeat; - params.key_state = lpbKeyState; - ret = MACDRV_CALL(ime_process_text_input, ¶ms); - - if (!ret) - { - UINT msgs = 0; - UINT msg = (uScanCode & 0x8000) ? WM_KEYUP : WM_KEYDOWN; - - /* KeyStroke not processed by the IME - * so we need to rebuild the KeyDown message and pass it on to WINE - */ - if (!GenerateMessageToTransKey(lpdwTransKey, &msgs, msg, vkey, MAKELONG(0x0001, uScanCode))) - GenerateIMEMessage(hIMC, msg, vkey, MAKELONG(0x0001, uScanCode)); + /* trigger the pending client_func_ime_set_text call */ + MACDRV_CALL(ime_get_text_input, NULL);
- return msgs; - } - else + if ((lpIMC = LockRealIMC(hIMC))) { - /* trigger the pending client_func_ime_set_text call */ - MACDRV_CALL(ime_get_text_input, NULL); - - if ((lpIMC = LockRealIMC(hIMC))) - { - UpdateDataInDefaultIMEWindow( lpIMC, hwnd, FALSE ); - UnlockRealIMC(hIMC); - } + UpdateDataInDefaultIMEWindow( lpIMC, hwnd, FALSE ); + UnlockRealIMC(hIMC); } return 0; } diff --git a/include/ntuser.h b/include/ntuser.h index 3d43eb476e4..c7827496106 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -497,7 +497,6 @@ typedef struct ime_private BOOL bInternalState; HFONT textfont; HWND hwndDefault; - UINT repeat; } IMEPRIVATE, *LPIMEPRIVATE;
#define WM_SYSTIMER 0x0118