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 +++------------------------------------ 1 file changed, 10 insertions(+), 119 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; }
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);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=141996
Your paranoid android.
=== debian11b (64 bit WoW report) ===
wmvcore: wmvcore.c:1705: Test failed: Stream 0: Format 1: Got hr 0xc00d0041. wmvcore.c:1722: Test failed: Stream 0: Format 1: Media types didn't match.