-- v2: win32u: Remove now unnecessary ImeToAsciiEx driver entry. winemac: Use the default ImeToAsciiEx implementation. win32u: Support posting IME updates while processing keys. win32u: Move ImeToAsciiEx implementation from winex11. winex11: Return STATUS_NOT_FOUND when IME update isn't found.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/xim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 209d63f0402..155cd13809e 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -555,7 +555,7 @@ UINT X11DRV_ImeToAsciiEx( UINT vkey, UINT lparam, const BYTE *state, COMPOSITION if (!(update = find_ime_update( lparam ))) { pthread_mutex_unlock( &ime_mutex ); - return 0; + return STATUS_NOT_FOUND; }
if (!update->comp_str) comp_len = 0;
From: Rémi Bernon rbernon@codeweavers.com
Using a new WINE_IME_POST_UPDATE NtUserMessageCall call for the drivers. --- dlls/win32u/driver.c | 2 +- dlls/win32u/imm.c | 144 +++++++++++++++++++++++++++++++++++- dlls/winex11.drv/init.c | 1 - dlls/winex11.drv/x11drv.h | 2 - dlls/winex11.drv/xim.c | 149 +------------------------------------- dlls/wow64win/user.c | 1 + include/ntuser.h | 1 + 7 files changed, 149 insertions(+), 151 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index bc3409a9e34..2937f0d7248 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -731,7 +731,7 @@ static UINT nulldrv_ImeProcessKey( HIMC himc, UINT wparam, UINT lparam, const BY
static UINT nulldrv_ImeToAsciiEx( UINT vkey, UINT vsc, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc ) { - return 0; + return STATUS_NOT_IMPLEMENTED; }
static void nulldrv_NotifyIMEStatus( HWND hwnd, UINT status ) diff --git a/dlls/win32u/imm.c b/dlls/win32u/imm.c index a14d199e253..5f5e626869e 100644 --- a/dlls/win32u/imm.c +++ b/dlls/win32u/imm.c @@ -34,6 +34,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(imm);
+struct ime_update +{ + struct list entry; + DWORD id; + DWORD cursor_pos; + WCHAR *comp_str; + WCHAR *result_str; + WCHAR buffer[]; +};
struct imc { @@ -53,6 +62,7 @@ struct imm_thread_data
static struct list thread_data_list = LIST_INIT( thread_data_list ); static pthread_mutex_t imm_mutex = PTHREAD_MUTEX_INITIALIZER; +static struct list ime_updates = LIST_INIT( ime_updates ); static BOOL disable_ime;
static struct imc *get_imc_ptr( HIMC handle ) @@ -421,15 +431,147 @@ NTSTATUS WINAPI NtUserBuildHimcList( UINT thread_id, UINT count, HIMC *buffer, U return STATUS_SUCCESS; }
+static void post_ime_update( HWND hwnd, UINT cursor_pos, WCHAR *comp_str, WCHAR *result_str ) +{ + static UINT ime_update_count; + UINT id, comp_len, result_len; + struct ime_update *update; + + TRACE( "hwnd %p, cursor_pos %u, comp_str %s, result_str %s\n", hwnd, cursor_pos, + debugstr_w(comp_str), debugstr_w(result_str) ); + + comp_len = comp_str ? wcslen( comp_str ) + 1 : 0; + result_len = result_str ? wcslen( result_str ) + 1 : 0; + + if (!(update = malloc( offsetof(struct ime_update, buffer[comp_len + result_len]) ))) return; + update->cursor_pos = cursor_pos; + update->comp_str = comp_str ? memcpy( update->buffer, comp_str, comp_len * sizeof(WCHAR) ) : NULL; + update->result_str = result_str ? memcpy( update->buffer + comp_len, result_str, result_len * sizeof(WCHAR) ) : NULL; + + pthread_mutex_lock( &imm_mutex ); + id = update->id = ++ime_update_count; + list_add_tail( &ime_updates, &update->entry ); + pthread_mutex_unlock( &imm_mutex ); + + NtUserPostMessage( hwnd, WM_IME_NOTIFY, IMN_WINE_SET_COMP_STRING, id ); +} + +static struct ime_update *find_ime_update( UINT id ) +{ + struct ime_update *update; + + LIST_FOR_EACH_ENTRY( update, &ime_updates, struct ime_update, entry ) + if (update->id == id) return update; + + return NULL; +} + +UINT ime_to_tascii_ex( UINT vkey, UINT lparam, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc ) +{ + UINT needed = sizeof(COMPOSITIONSTRING), comp_len, result_len; + struct ime_update *update; + void *dst; + + TRACE( "vkey %#x, lparam %#x, state %p, compstr %p, himc %p\n", vkey, lparam, state, compstr, himc ); + + pthread_mutex_lock( &imm_mutex ); + + if (!(update = find_ime_update( lparam ))) + { + pthread_mutex_unlock( &imm_mutex ); + return STATUS_NOT_FOUND; + } + + 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) + { + compstr->dwSize = needed; + pthread_mutex_unlock( &imm_mutex ); + return STATUS_BUFFER_TOO_SMALL; + } + + list_remove( &update->entry ); + pthread_mutex_unlock( &imm_mutex ); + + memset( compstr, 0, sizeof(*compstr) ); + compstr->dwSize = sizeof(*compstr); + + if (update->comp_str) + { + compstr->dwCursorPos = update->cursor_pos; + + 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) + { + 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 ); + return 0; +} + LRESULT ime_driver_call( HWND hwnd, enum wine_ime_call call, WPARAM wparam, LPARAM lparam, struct ime_driver_call_params *params ) { + LRESULT res; + switch (call) { case WINE_IME_PROCESS_KEY: return user_driver->pImeProcessKey( params->himc, wparam, lparam, params->state ); case WINE_IME_TO_ASCII_EX: - return user_driver->pImeToAsciiEx( wparam, lparam, params->state, params->compstr, params->himc ); + res = user_driver->pImeToAsciiEx( wparam, lparam, params->state, params->compstr, params->himc ); + if ((NTSTATUS)res != STATUS_NOT_IMPLEMENTED) return res; + return ime_to_tascii_ex( wparam, lparam, params->state, params->compstr, params->himc ); + case WINE_IME_POST_UPDATE: + post_ime_update( hwnd, wparam, (WCHAR *)lparam, (WCHAR *)params ); + return 0; default: ERR( "Unknown IME driver call %#x\n", call ); return 0; diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 2cef05d2140..43fb0ac0c1c 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -397,7 +397,6 @@ static const struct user_driver_funcs x11drv_funcs = .pMapVirtualKeyEx = X11DRV_MapVirtualKeyEx, .pToUnicodeEx = X11DRV_ToUnicodeEx, .pVkKeyScanEx = X11DRV_VkKeyScanEx, - .pImeToAsciiEx = X11DRV_ImeToAsciiEx, .pNotifyIMEStatus = X11DRV_NotifyIMEStatus, .pDestroyCursorIcon = X11DRV_DestroyCursorIcon, .pSetCursor = X11DRV_SetCursor, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index c80e4b3d3c9..6bd671db3ff 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -208,8 +208,6 @@ extern INT X11DRV_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size ); extern UINT X11DRV_MapVirtualKeyEx( UINT code, UINT map_type, HKL hkl ); extern INT X11DRV_ToUnicodeEx( UINT virtKey, UINT scanCode, const BYTE *lpKeyState, LPWSTR bufW, int bufW_size, UINT flags, HKL hkl ); -extern UINT X11DRV_ImeToAsciiEx( UINT vkey, UINT vsc, const BYTE *state, - COMPOSITIONSTRING *compstr, HIMC himc ); extern SHORT X11DRV_VkKeyScanEx( WCHAR wChar, HKL hkl ); extern void X11DRV_NotifyIMEStatus( HWND hwnd, UINT status ); extern void X11DRV_DestroyCursorIcon( HCURSOR handle ); diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 155cd13809e..d304dbb26fa 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -44,19 +44,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(xim); #define XICProc XIMProc #endif
-struct ime_update -{ - struct list entry; - DWORD id; - DWORD cursor_pos; - WCHAR *comp_str; - WCHAR *result_str; - WCHAR buffer[]; -}; - -static pthread_mutex_t ime_mutex = PTHREAD_MUTEX_INITIALIZER; -static struct list ime_updates = LIST_INIT(ime_updates); -static DWORD ime_update_count; static WCHAR *ime_comp_buf;
static XIMStyle input_style = 0; @@ -89,23 +76,8 @@ BOOL xim_in_compose_mode(void)
static void post_ime_update( HWND hwnd, UINT cursor_pos, WCHAR *comp_str, WCHAR *result_str ) { - UINT id, comp_len, result_len; - struct ime_update *update; - - comp_len = comp_str ? wcslen( comp_str ) + 1 : 0; - result_len = result_str ? wcslen( result_str ) + 1 : 0; - - if (!(update = malloc( offsetof(struct ime_update, buffer[comp_len + result_len]) ))) return; - update->cursor_pos = cursor_pos; - update->comp_str = comp_str ? memcpy( update->buffer, comp_str, comp_len * sizeof(WCHAR) ) : NULL; - update->result_str = result_str ? memcpy( update->buffer + comp_len, result_str, result_len * sizeof(WCHAR) ) : NULL; - - pthread_mutex_lock( &ime_mutex ); - id = update->id = ++ime_update_count; - list_add_tail( &ime_updates, &update->entry ); - pthread_mutex_unlock( &ime_mutex ); - - NtUserPostMessage( hwnd, WM_IME_NOTIFY, IMN_WINE_SET_COMP_STRING, id ); + NtUserMessageCall( hwnd, WINE_IME_POST_UPDATE, cursor_pos, (LPARAM)comp_str, + result_str, NtUserImeDriverCall, FALSE ); }
static void xim_update_comp_string( UINT offset, UINT old_len, const WCHAR *text, UINT new_len ) @@ -511,123 +483,8 @@ XIC X11DRV_get_ic( HWND hwnd )
void xim_set_focus( HWND hwnd, BOOL focus ) { - struct list updates = LIST_INIT(updates); - struct ime_update *update, *next; XIC xic; - - if (!(xic = X11DRV_get_ic( hwnd ))) return; - + if ((xic = X11DRV_get_ic( hwnd ))) return; if (focus) XSetICFocus( xic ); else XUnsetICFocus( xic ); - - pthread_mutex_lock( &ime_mutex ); - list_move_tail( &updates, &ime_updates ); - pthread_mutex_unlock( &ime_mutex ); - - LIST_FOR_EACH_ENTRY_SAFE( update, next, &updates, struct ime_update, entry ) free( update ); -} - -static struct ime_update *find_ime_update( UINT id ) -{ - struct ime_update *update; - LIST_FOR_EACH_ENTRY( update, &ime_updates, struct ime_update, entry ) - if (update->id == id) return update; - return NULL; -} - -/*********************************************************************** - * ImeToAsciiEx (X11DRV.@) - * - * As XIM filters key events upfront, we don't use ImeProcessKey and ImeToAsciiEx is instead called - * back from the IME UI window procedure when WM_IME_NOTIFY / IMN_WINE_SET_COMP_STRING messages are - * sent to it, to retrieve composition string updates and generate WM_IME messages. - */ -UINT X11DRV_ImeToAsciiEx( UINT vkey, UINT lparam, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc ) -{ - UINT needed = sizeof(COMPOSITIONSTRING), comp_len, result_len; - struct ime_update *update; - void *dst; - - TRACE( "vkey %#x, lparam %#x, state %p, compstr %p, himc %p\n", vkey, lparam, state, compstr, himc ); - - pthread_mutex_lock( &ime_mutex ); - - if (!(update = find_ime_update( lparam ))) - { - pthread_mutex_unlock( &ime_mutex ); - return STATUS_NOT_FOUND; - } - - 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) - { - compstr->dwSize = needed; - pthread_mutex_unlock( &ime_mutex ); - return STATUS_BUFFER_TOO_SMALL; - } - - list_remove( &update->entry ); - pthread_mutex_unlock( &ime_mutex ); - - memset( compstr, 0, sizeof(*compstr) ); - compstr->dwSize = sizeof(*compstr); - - if (update->comp_str) - { - compstr->dwCursorPos = update->cursor_pos; - - 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) - { - 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 ); - return 0; } diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 44b422ef62c..0d5bbf82d84 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -3596,6 +3596,7 @@ NTSTATUS WINAPI wow64_NtUserMessageCall( UINT *args ) ULONG compstr; } *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 ); diff --git a/include/ntuser.h b/include/ntuser.h index f23249ace5a..f8fbe64769c 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -511,6 +511,7 @@ enum wine_ime_call { WINE_IME_PROCESS_KEY, WINE_IME_TO_ASCII_EX, + WINE_IME_POST_UPDATE, /* for the user drivers */ };
/* NtUserImeDriverCall params */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/imm.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/imm.c b/dlls/win32u/imm.c index 5f5e626869e..82124f72567 100644 --- a/dlls/win32u/imm.c +++ b/dlls/win32u/imm.c @@ -37,7 +37,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm); struct ime_update { struct list entry; - DWORD id; + WORD vkey; + WORD scan; DWORD cursor_pos; WCHAR *comp_str; WCHAR *result_str; @@ -58,6 +59,9 @@ struct imm_thread_data HWND default_hwnd; BOOL disable_ime; UINT window_cnt; + WORD ime_process_scan; /* scan code of the key being processed */ + WORD ime_process_vkey; /* vkey of the key being processed */ + BOOL ime_process_result; /* result string has been received */ };
static struct list thread_data_list = LIST_INIT( thread_data_list ); @@ -434,7 +438,9 @@ NTSTATUS WINAPI NtUserBuildHimcList( UINT thread_id, UINT count, HIMC *buffer, U static void post_ime_update( HWND hwnd, UINT cursor_pos, WCHAR *comp_str, WCHAR *result_str ) { static UINT ime_update_count; - UINT id, comp_len, result_len; + + struct imm_thread_data *data = get_imm_thread_data(); + UINT id = -1, comp_len, result_len; struct ime_update *update;
TRACE( "hwnd %p, cursor_pos %u, comp_str %s, result_str %s\n", hwnd, cursor_pos, @@ -449,19 +455,25 @@ static void post_ime_update( HWND hwnd, UINT cursor_pos, WCHAR *comp_str, WCHAR update->result_str = result_str ? memcpy( update->buffer + comp_len, result_str, result_len * sizeof(WCHAR) ) : NULL;
pthread_mutex_lock( &imm_mutex ); - id = update->id = ++ime_update_count; + update->scan = data->ime_process_scan; + if (!(update->vkey = data->ime_process_vkey)) + { + id = update->scan = ++ime_update_count; + update->vkey = VK_PROCESSKEY; + } list_add_tail( &ime_updates, &update->entry ); pthread_mutex_unlock( &imm_mutex );
- NtUserPostMessage( hwnd, WM_IME_NOTIFY, IMN_WINE_SET_COMP_STRING, id ); + if (!data->ime_process_vkey) NtUserPostMessage( hwnd, WM_IME_NOTIFY, IMN_WINE_SET_COMP_STRING, id ); + if (result_str) data->ime_process_result = TRUE; }
-static struct ime_update *find_ime_update( UINT id ) +static struct ime_update *find_ime_update( WORD vkey, WORD scan ) { struct ime_update *update;
LIST_FOR_EACH_ENTRY( update, &ime_updates, struct ime_update, entry ) - if (update->id == id) return update; + if (update->vkey == vkey && update->scan == scan) return update;
return NULL; } @@ -476,7 +488,7 @@ UINT ime_to_tascii_ex( UINT vkey, UINT lparam, const BYTE *state, COMPOSITIONSTR
pthread_mutex_lock( &imm_mutex );
- if (!(update = find_ime_update( lparam ))) + if (!(update = find_ime_update( vkey, lparam ))) { pthread_mutex_unlock( &imm_mutex ); return STATUS_NOT_FOUND; @@ -564,7 +576,19 @@ LRESULT ime_driver_call( HWND hwnd, enum wine_ime_call call, WPARAM wparam, LPAR switch (call) { case WINE_IME_PROCESS_KEY: - return user_driver->pImeProcessKey( params->himc, wparam, lparam, params->state ); + { + struct imm_thread_data *data = get_imm_thread_data(); + + data->ime_process_scan = HIWORD(lparam) & 0x1ff; + data->ime_process_vkey = LOWORD(wparam); + data->ime_process_result = FALSE; + res = user_driver->pImeProcessKey( params->himc, wparam, lparam, params->state ); + data->ime_process_vkey = data->ime_process_scan = 0; + if (!res) res = data->ime_process_result; + + TRACE( "processing scan %#x, vkey %#x -> %u\n", LOWORD(wparam), HIWORD(lparam) & 0x1ff, (UINT)res ); + return res; + } case WINE_IME_TO_ASCII_EX: res = user_driver->pImeToAsciiEx( wparam, lparam, params->state, params->compstr, params->himc ); if ((NTSTATUS)res != STATUS_NOT_IMPLEMENTED) return res;
From: Rémi Bernon rbernon@codeweavers.com
And support updates pushed from the host IME directly. --- dlls/winemac.drv/event.c | 129 +++----------------------------------- dlls/winemac.drv/gdi.c | 1 - dlls/winemac.drv/macdrv.h | 1 - 3 files changed, 10 insertions(+), 121 deletions(-)
diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c index 2fc699e3f77..9fbbe9d3d66 100644 --- a/dlls/winemac.drv/event.c +++ b/dlls/winemac.drv/event.c @@ -34,25 +34,6 @@ 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 is then be called to retrieve - * the composition string updates. We use ime_update.comp_str != NULL as flag that - * composition is started, even if the preedit text is empty. - * - * If ImeProcessKey returns FALSE, ImeToAsciiEx will not be called. - */ -struct ime_update -{ - DWORD cursor_pos; - WCHAR *comp_str; - WCHAR *result_str; -}; -static struct ime_update ime_update; - /* return the name of an Mac event */ static const char *dbgstr_event(int type) { @@ -166,6 +147,11 @@ static macdrv_event_mask get_event_mask(DWORD mask) return event_mask; }
+static void post_ime_update( HWND hwnd, UINT cursor_pos, WCHAR *comp_str, WCHAR *result_str ) +{ + NtUserMessageCall( hwnd, WINE_IME_POST_UPDATE, cursor_pos, (LPARAM)comp_str, + result_str, NtUserImeDriverCall, FALSE ); +}
/*********************************************************************** * macdrv_im_set_text @@ -173,7 +159,6 @@ 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); - 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, @@ -181,27 +166,16 @@ static void macdrv_im_set_text(const macdrv_event *event)
if (event->im_set_text.text) { - length = CFStringGetLength(event->im_set_text.text); + CFIndex 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; }
- /* discard any pending comp text */ - free(ime_update.comp_str); - ime_update.comp_str = NULL; - ime_update.cursor_pos = -1; + if (event->im_set_text.complete) post_ime_update(hwnd, -1, NULL, text); + else post_ime_update(hwnd, event->im_set_text.cursor_pos, text, NULL);
- if (event->im_set_text.complete) - { - free(ime_update.result_str); - ime_update.result_str = text; - } - else - { - ime_update.comp_str = text; - ime_update.cursor_pos = event->im_set_text.cursor_pos; - } + free(text); }
/*********************************************************************** @@ -210,90 +184,7 @@ 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_str ? 1 : -1; -} - - -/*********************************************************************** - * ImeToAsciiEx (MACDRV.@) - */ -UINT macdrv_ImeToAsciiEx(UINT vkey, UINT vsc, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc) -{ - 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) - { - compstr->dwSize = needed; - return STATUS_BUFFER_TOO_SMALL; - } - - memset( compstr, 0, sizeof(*compstr) ); - compstr->dwSize = sizeof(*compstr); - - if (update->comp_str) - { - compstr->dwCursorPos = update->cursor_pos; - - 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) - { - 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; + *event->sent_text_input.done = event->sent_text_input.handled ? 1 : -1; }
diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 6c2241514a9..137945c4b74 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -304,7 +304,6 @@ static const struct user_driver_funcs macdrv_funcs = .pUpdateLayeredWindow = macdrv_UpdateLayeredWindow, .pVkKeyScanEx = macdrv_VkKeyScanEx, .pImeProcessKey = macdrv_ImeProcessKey, - .pImeToAsciiEx = macdrv_ImeToAsciiEx, .pNotifyIMEStatus = macdrv_NotifyIMEStatus, .pWindowMessage = macdrv_WindowMessage, .pWindowPosChanged = macdrv_WindowPosChanged, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index b9cd9fde2ed..7e43314dce1 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -167,7 +167,6 @@ extern BOOL macdrv_RegisterHotKey(HWND hwnd, UINT mod_flags, UINT vkey); 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, const BYTE *state, COMPOSITIONSTRING *compstr, 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);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 12 ------------ dlls/win32u/imm.c | 2 -- include/wine/gdi_driver.h | 1 - 3 files changed, 15 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 2937f0d7248..fcfb7d55d54 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -729,11 +729,6 @@ static UINT nulldrv_ImeProcessKey( HIMC himc, UINT wparam, UINT lparam, const BY return 0; }
-static UINT nulldrv_ImeToAsciiEx( UINT vkey, UINT vsc, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc ) -{ - return STATUS_NOT_IMPLEMENTED; -} - static void nulldrv_NotifyIMEStatus( HWND hwnd, UINT status ) { } @@ -1138,11 +1133,6 @@ 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, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc ) -{ - return load_driver()->pImeToAsciiEx( vkey, vsc, state, compstr, himc ); -} - static void loaderdrv_NotifyIMEStatus( HWND hwnd, UINT status ) { return load_driver()->pNotifyIMEStatus( hwnd, status ); @@ -1292,7 +1282,6 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_KbdLayerDescriptor, loaderdrv_ReleaseKbdTables, loaderdrv_ImeProcessKey, - loaderdrv_ImeToAsciiEx, loaderdrv_NotifyIMEStatus, /* cursor/icon functions */ nulldrv_DestroyCursorIcon, @@ -1384,7 +1373,6 @@ 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(DestroyCursorIcon); SET_USER_FUNC(SetCursor); diff --git a/dlls/win32u/imm.c b/dlls/win32u/imm.c index 82124f72567..05b8b60090f 100644 --- a/dlls/win32u/imm.c +++ b/dlls/win32u/imm.c @@ -590,8 +590,6 @@ LRESULT ime_driver_call( HWND hwnd, enum wine_ime_call call, WPARAM wparam, LPAR return res; } case WINE_IME_TO_ASCII_EX: - res = user_driver->pImeToAsciiEx( wparam, lparam, params->state, params->compstr, params->himc ); - if ((NTSTATUS)res != STATUS_NOT_IMPLEMENTED) return res; return ime_to_tascii_ex( wparam, lparam, params->state, params->compstr, params->himc ); case WINE_IME_POST_UPDATE: post_ime_update( hwnd, wparam, (WCHAR *)lparam, (WCHAR *)params ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 26562bfef2b..bd827c31cb1 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -299,7 +299,6 @@ struct user_driver_funcs void (*pReleaseKbdTables)(const KBDTABLES *); /* IME functions */ UINT (*pImeProcessKey)(HIMC,UINT,UINT,const BYTE*); - UINT (*pImeToAsciiEx)(UINT,UINT,const BYTE*,COMPOSITIONSTRING*,HIMC); void (*pNotifyIMEStatus)(HWND,UINT); /* cursor/icon functions */ void (*pDestroyCursorIcon)(HCURSOR);
v2: Fix macOS build.
This merge request was approved by Huw Davies.