From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/dllmain.c | 1 - dlls/winemac.drv/event.c | 137 ++++++++++++++++++++++-------- dlls/winemac.drv/gdi.c | 1 + dlls/winemac.drv/ime.c | 88 ------------------- dlls/winemac.drv/macdrv.h | 5 +- dlls/winemac.drv/macdrv_dll.h | 1 - dlls/winemac.drv/macdrv_main.c | 2 - dlls/winemac.drv/unixlib.h | 12 --- dlls/winemac.drv/winemac.drv.spec | 1 - 9 files changed, 107 insertions(+), 141 deletions(-)
diff --git a/dlls/winemac.drv/dllmain.c b/dlls/winemac.drv/dllmain.c index 41e9e908b61..265d6e46d5c 100644 --- a/dlls/winemac.drv/dllmain.c +++ b/dlls/winemac.drv/dllmain.c @@ -375,7 +375,6 @@ static const kernel_callback kernel_callbacks[] = macdrv_dnd_query_drop, macdrv_dnd_query_exited, macdrv_ime_query_char_rect, - macdrv_ime_set_text, };
C_ASSERT(NtUserDriverCallbackFirst + ARRAYSIZE(kernel_callbacks) == client_func_last); diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c index cc8aa4681c6..498addf785a 100644 --- a/dlls/winemac.drv/event.c +++ b/dlls/winemac.drv/event.c @@ -32,12 +32,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(event); WINE_DECLARE_DEBUG_CHANNEL(imm);
+/* IME works synchronously, key input is passed from ImeProcessKey, to the + * host IME. We wait for it to be handled, or not, which is notified using + * the sent_text_input event. Meanwhile, while processing the key, the host + * IME may send one or more im_set_text events to update the input text. + * + * If ImeProcessKey returns TRUE, ImeToAsciiEx will then be called to retrieve + * the composition string updates. + * + * If ImeProcessKey returns FALSE, ImeToAsciiEx will not be called. + */ struct ime_update { - struct ime_set_text_params *comp_params; - DWORD comp_size; - struct ime_set_text_params *result_params; - DWORD result_size; + DWORD cursor_pos; + WCHAR *comp_str; + WCHAR *result_str; }; static struct ime_update ime_update;
@@ -159,38 +168,34 @@ static macdrv_event_mask get_event_mask(DWORD mask) static void macdrv_im_set_text(const macdrv_event *event) { HWND hwnd = macdrv_get_window_hwnd(event->window); - struct ime_set_text_params *params; - CFIndex length = 0, size; + CFIndex length = 0; + WCHAR *text = NULL;
TRACE_(imm)("win %p/%p himc %p text %s complete %u\n", hwnd, event->window, event->im_set_text.himc, debugstr_cf(event->im_set_text.text), event->im_set_text.complete);
if (event->im_set_text.text) + { length = CFStringGetLength(event->im_set_text.text); + if (!(text = malloc((length + 1) * sizeof(WCHAR)))) return; + if (length) CFStringGetCharacters(event->im_set_text.text, CFRangeMake(0, length), text); + text[length] = 0; + }
- size = offsetof(struct ime_set_text_params, text[length]); - if (!(params = malloc(size))) return; - params->hwnd = HandleToUlong(hwnd); - params->himc = (UINT_PTR)event->im_set_text.himc; - params->cursor_pos = event->im_set_text.cursor_pos; - params->complete = event->im_set_text.complete; - - if (length) - CFStringGetCharacters(event->im_set_text.text, CFRangeMake(0, length), params->text); - - free(ime_update.comp_params); - ime_update.comp_params = NULL; + /* discard any pending comp text */ + free(ime_update.comp_str); + ime_update.comp_str = NULL; + ime_update.cursor_pos = -1;
- if (params->complete) + if (event->im_set_text.complete) { - free(ime_update.result_params); - ime_update.result_params = params; - ime_update.result_size = size; + free(ime_update.result_str); + ime_update.result_str = text; } else { - ime_update.comp_params = params; - ime_update.comp_size = size; + ime_update.comp_str = text; + ime_update.cursor_pos = event->im_set_text.cursor_pos; } }
@@ -200,28 +205,90 @@ 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 || ime_update.result_params ? 1 : -1; + *event->sent_text_input.done = event->sent_text_input.handled || ime_update.result_str ? 1 : -1; }
/*********************************************************************** - * macdrv_ime_get_text_input + * ImeToAsciiEx (MACDRV.@) */ -NTSTATUS macdrv_ime_get_text_input(void *arg) +UINT macdrv_ImeToAsciiEx(UINT vkey, UINT vsc, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc) { - if (ime_update.result_params) + UINT needed = sizeof(COMPOSITIONSTRING), comp_len, result_len; + struct ime_update *update = &ime_update; + void *dst; + + TRACE_(imm)("vkey %#x, vsc %#x, state %p, compstr %p, himc %p\n", vkey, vsc, state, compstr, himc); + + if (!update->comp_str) comp_len = 0; + else + { + comp_len = wcslen(update->comp_str); + needed += comp_len * sizeof(WCHAR); /* GCS_COMPSTR */ + needed += comp_len; /* GCS_COMPATTR */ + needed += 2 * sizeof(DWORD); /* GCS_COMPCLAUSE */ + } + + if (!update->result_str) result_len = 0; + else + { + result_len = wcslen(update->result_str); + needed += result_len * sizeof(WCHAR); /* GCS_RESULTSTR */ + needed += 2 * sizeof(DWORD); /* GCS_RESULTCLAUSE */ + } + + if (compstr->dwSize < needed) { - 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; + compstr->dwSize = needed; + return STATUS_BUFFER_TOO_SMALL; } - if (ime_update.comp_params) + + memset( compstr, 0, sizeof(*compstr) ); + compstr->dwSize = sizeof(*compstr); + + if (update->comp_str) + { + compstr->dwCursorPos = update->cursor_pos; + compstr->dwDeltaStart = 0; + + compstr->dwCompStrLen = comp_len; + compstr->dwCompStrOffset = compstr->dwSize; + dst = (BYTE *)compstr + compstr->dwCompStrOffset; + memcpy(dst, update->comp_str, compstr->dwCompStrLen * sizeof(WCHAR)); + compstr->dwSize += compstr->dwCompStrLen * sizeof(WCHAR); + + compstr->dwCompClauseLen = 2 * sizeof(DWORD); + compstr->dwCompClauseOffset = compstr->dwSize; + dst = (BYTE *)compstr + compstr->dwCompClauseOffset; + *((DWORD *)dst + 0) = 0; + *((DWORD *)dst + 1) = compstr->dwCompStrLen; + compstr->dwSize += compstr->dwCompClauseLen; + + compstr->dwCompAttrLen = compstr->dwCompStrLen; + compstr->dwCompAttrOffset = compstr->dwSize; + dst = (BYTE *)compstr + compstr->dwCompAttrOffset; + memset(dst, ATTR_INPUT, compstr->dwCompAttrLen); + compstr->dwSize += compstr->dwCompAttrLen; + } + + if (update->result_str) { - 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; + compstr->dwResultStrLen = result_len; + compstr->dwResultStrOffset = compstr->dwSize; + dst = (BYTE *)compstr + compstr->dwResultStrOffset; + memcpy(dst, update->result_str, compstr->dwResultStrLen * sizeof(WCHAR)); + compstr->dwSize += compstr->dwResultStrLen * sizeof(WCHAR); + + compstr->dwResultClauseLen = 2 * sizeof(DWORD); + compstr->dwResultClauseOffset = compstr->dwSize; + dst = (BYTE *)compstr + compstr->dwResultClauseOffset; + *((DWORD *)dst + 0) = 0; + *((DWORD *)dst + 1) = compstr->dwResultStrLen; + compstr->dwSize += compstr->dwResultClauseLen; }
+ free(update->result_str); + update->result_str = NULL; return 0; }
diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index e8c35ec6ef8..bea683b77df 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -303,6 +303,7 @@ static const struct user_driver_funcs macdrv_funcs = .pUpdateLayeredWindow = macdrv_UpdateLayeredWindow, .pVkKeyScanEx = macdrv_VkKeyScanEx, .pImeProcessKey = macdrv_ImeProcessKey, + .pImeToAsciiEx = macdrv_ImeToAsciiEx, .pWindowMessage = macdrv_WindowMessage, .pWindowPosChanged = macdrv_WindowPosChanged, .pWindowPosChanging = macdrv_WindowPosChanging, diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c index bb308a7c9e8..1121c490d1a 100644 --- a/dlls/winemac.drv/ime.c +++ b/dlls/winemac.drv/ime.c @@ -495,26 +495,6 @@ static void IME_AddToSelected(HIMC hIMC) hSelectedFrom[hSelectedCount - 1] = hIMC; }
-static void UpdateDataInDefaultIMEWindow(INPUTCONTEXT *lpIMC, HWND hwnd, BOOL showable) -{ - LPCOMPOSITIONSTRING compstr; - - if (lpIMC->hCompStr) - compstr = ImmLockIMCC(lpIMC->hCompStr); - else - compstr = NULL; - - if (compstr == NULL || compstr->dwCompStrLen == 0) - ShowWindow(hwnd, SW_HIDE); - else if (showable) - ShowWindow(hwnd, SW_SHOWNOACTIVATE); - - RedrawWindow(hwnd, NULL, NULL, RDW_ERASENOW | RDW_INVALIDATE); - - if (compstr != NULL) - ImmUnlockIMCC(lpIMC->hCompStr); -} - BOOL WINAPI ImeSelect(HIMC hIMC, BOOL fSelect) { LPINPUTCONTEXT lpIMC; @@ -556,25 +536,6 @@ BOOL WINAPI ImeSelect(HIMC hIMC, BOOL fSelect) return TRUE; }
-UINT WINAPI ImeToAsciiEx(UINT uVKey, UINT uScanCode, const LPBYTE lpbKeyState, - TRANSMSGLIST *lpdwTransKey, UINT fuState, HIMC hIMC) -{ - LPINPUTCONTEXT lpIMC; - - TRACE("uVKey 0x%04x uScanCode 0x%04x fuState %u hIMC %p\n", uVKey, uScanCode, fuState, hIMC); - - /* trigger the pending client_func_ime_set_text call */ - MACDRV_CALL(ime_get_text_input, NULL); - - if ((lpIMC = LockRealIMC(hIMC))) - { - HWND hwnd = input_context_get_ui_hwnd( lpIMC ); - UpdateDataInDefaultIMEWindow( lpIMC, hwnd, FALSE ); - UnlockRealIMC(hIMC); - } - return 0; -} - BOOL WINAPI NotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue) { BOOL bRet = FALSE; @@ -812,57 +773,8 @@ BOOL WINAPI ImeSetCompositionString(HIMC hIMC, DWORD dwIndex, LPCVOID lpComp, DW return IME_SetCompositionString(hIMC, dwIndex, lpComp, dwCompLen, 0, FALSE); }
-static void IME_NotifyComplete(void* hIMC) -{ - NotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); -} - /* Interfaces to other parts of the Mac driver */
-/*********************************************************************** - * macdrv_ime_set_text - */ -NTSTATUS WINAPI macdrv_ime_set_text(void *arg, ULONG size) -{ - struct ime_set_text_params *params = arg; - ULONG length = (size - offsetof(struct ime_set_text_params, text)) / sizeof(WCHAR); - void *himc = param_ptr(params->himc); - HWND hwnd = UlongToHandle(params->hwnd); - - if (!himc) himc = RealIMC(FROM_MACDRV); - - if (length) - { - if (himc) - IME_SetCompositionString(himc, SCS_SETSTR, params->text, length * sizeof(WCHAR), - params->cursor_pos, !params->complete); - else - { - INPUT input; - unsigned int i; - - input.type = INPUT_KEYBOARD; - input.ki.wVk = 0; - input.ki.time = 0; - input.ki.dwExtraInfo = 0; - - for (i = 0; i < length; i++) - { - input.ki.wScan = params->text[i]; - input.ki.dwFlags = KEYEVENTF_UNICODE; - __wine_send_input(hwnd, &input, NULL); - - input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; - __wine_send_input(hwnd, &input, NULL); - } - } - } - - if (params->complete) - IME_NotifyComplete(himc); - return 0; -} - /************************************************************************** * macdrv_ime_query_char_rect */ diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 15ea44dadcf..7c638a44ff2 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -28,6 +28,9 @@ #endif
#include "macdrv_cocoa.h" + +#include "ntstatus.h" +#define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" #include "ntgdi.h" @@ -163,6 +166,7 @@ extern BOOL macdrv_RegisterHotKey(HWND hwnd, UINT mod_flags, UINT vkey) DECLSPEC extern void macdrv_UnregisterHotKey(HWND hwnd, UINT modifiers, UINT vkey) DECLSPEC_HIDDEN; extern SHORT macdrv_VkKeyScanEx(WCHAR wChar, HKL hkl) DECLSPEC_HIDDEN; extern UINT macdrv_ImeProcessKey(HIMC himc, UINT wparam, UINT lparam, const BYTE *state) DECLSPEC_HIDDEN; +extern UINT macdrv_ImeToAsciiEx(UINT vkey, UINT vsc, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc) DECLSPEC_HIDDEN; extern UINT macdrv_MapVirtualKeyEx(UINT wCode, UINT wMapType, HKL hkl) DECLSPEC_HIDDEN; extern INT macdrv_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState, LPWSTR bufW, int bufW_size, UINT flags, HKL hkl) DECLSPEC_HIDDEN; @@ -277,7 +281,6 @@ extern NTSTATUS macdrv_dnd_get_formats(void *arg) DECLSPEC_HIDDEN; 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_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_dll.h b/dlls/winemac.drv/macdrv_dll.h index 3a11528eabc..8f13b6b69aa 100644 --- a/dlls/winemac.drv/macdrv_dll.h +++ b/dlls/winemac.drv/macdrv_dll.h @@ -31,7 +31,6 @@ extern NTSTATUS WINAPI macdrv_dnd_query_drag(void *arg, ULONG size) DECLSPEC_HID extern NTSTATUS WINAPI macdrv_dnd_query_drop(void *arg, ULONG size) DECLSPEC_HIDDEN; extern NTSTATUS WINAPI macdrv_dnd_query_exited(void *arg, ULONG size) DECLSPEC_HIDDEN;
-extern NTSTATUS WINAPI macdrv_ime_set_text(void *params, ULONG size) DECLSPEC_HIDDEN; extern NTSTATUS WINAPI macdrv_ime_query_char_rect(void *params, ULONG size) DECLSPEC_HIDDEN;
extern HMODULE macdrv_module DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c index df7fe0ea1bc..944497c2371 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -628,7 +628,6 @@ const unixlib_entry_t __wine_unix_call_funcs[] = macdrv_dnd_release, macdrv_dnd_retain, macdrv_ime_clear, - macdrv_ime_get_text_input, macdrv_init, macdrv_notify_icon, macdrv_quit_result, @@ -731,7 +730,6 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = macdrv_dnd_release, macdrv_dnd_retain, macdrv_ime_clear, - macdrv_ime_get_text_input, wow64_init, wow64_notify_icon, macdrv_quit_result, diff --git a/dlls/winemac.drv/unixlib.h b/dlls/winemac.drv/unixlib.h index 3350ed5cc60..1afddc42614 100644 --- a/dlls/winemac.drv/unixlib.h +++ b/dlls/winemac.drv/unixlib.h @@ -27,7 +27,6 @@ enum macdrv_funcs unix_dnd_release, unix_dnd_retain, unix_ime_clear, - unix_ime_get_text_input, unix_init, unix_notify_icon, unix_quit_result, @@ -94,7 +93,6 @@ enum macdrv_client_funcs client_func_dnd_query_drop, client_func_dnd_query_exited, client_func_ime_query_char_rect, - client_func_ime_set_text, client_func_last };
@@ -170,16 +168,6 @@ struct ime_query_char_rect_params UINT32 length; };
-/* macdrv_ime_set_text params */ -struct ime_set_text_params -{ - UINT32 hwnd; - UINT32 cursor_pos; - UINT32 himc; - UINT32 complete; - WCHAR text[1]; -}; - static inline void *param_ptr(UINT64 param) { return (void *)(UINT_PTR)param; diff --git a/dlls/winemac.drv/winemac.drv.spec b/dlls/winemac.drv/winemac.drv.spec index 7c2ef82631d..bd441b7d69b 100644 --- a/dlls/winemac.drv/winemac.drv.spec +++ b/dlls/winemac.drv/winemac.drv.spec @@ -4,5 +4,4 @@ # IME @ stdcall ImeSelect(long long) @ stdcall ImeSetCompositionString(long long ptr long ptr long) -@ stdcall ImeToAsciiEx(long long ptr ptr long long) @ stdcall NotifyIME(long long long long)