Commit 8ae0c308 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

winemac: Generate IME messages from the default ImeToAsciiEx implementation.

parent 8c08ffcd
...@@ -164,13 +164,13 @@ static void ime_send_message( HIMC himc, UINT message, WPARAM wparam, LPARAM lpa ...@@ -164,13 +164,13 @@ static void ime_send_message( HIMC himc, UINT message, WPARAM wparam, LPARAM lpa
ImmGenerateMessage( himc ); ImmGenerateMessage( himc );
} }
static void ime_set_composition_status( HIMC himc, BOOL composition ) static UINT ime_set_composition_status( HIMC himc, BOOL composition )
{ {
struct ime_private *priv; struct ime_private *priv;
INPUTCONTEXT *ctx; INPUTCONTEXT *ctx;
UINT msg = 0; UINT msg = 0;
if (!(ctx = ImmLockIMC( himc ))) return; if (!(ctx = ImmLockIMC( himc ))) return 0;
if ((priv = ImmLockIMCC( ctx->hPrivate ))) if ((priv = ImmLockIMCC( ctx->hPrivate )))
{ {
if (!priv->bInComposition && composition) msg = WM_IME_STARTCOMPOSITION; if (!priv->bInComposition && composition) msg = WM_IME_STARTCOMPOSITION;
...@@ -180,7 +180,7 @@ static void ime_set_composition_status( HIMC himc, BOOL composition ) ...@@ -180,7 +180,7 @@ static void ime_set_composition_status( HIMC himc, BOOL composition )
} }
ImmUnlockIMC( himc ); ImmUnlockIMC( himc );
if (msg) ime_send_message( himc, msg, 0, 0 ); return msg;
} }
static void ime_ui_paint( HIMC himc, HWND hwnd ) static void ime_ui_paint( HIMC himc, HWND hwnd )
...@@ -485,10 +485,35 @@ UINT WINAPI ImeToAsciiEx( UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs, ...@@ -485,10 +485,35 @@ UINT WINAPI ImeToAsciiEx( UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs,
} while (status == STATUS_BUFFER_TOO_SMALL); } while (status == STATUS_BUFFER_TOO_SMALL);
if (status) WARN( "WINE_IME_TO_ASCII_EX returned status %#lx\n", status ); if (status) WARN( "WINE_IME_TO_ASCII_EX returned status %#lx\n", status );
else
{
TRANSMSG status_msg = {.message = ime_set_composition_status( himc, !!compstr->dwCompStrOffset )};
if (status_msg.message) msgs->TransMsg[count++] = status_msg;
if (compstr->dwResultStrLen)
{
const WCHAR *result = (WCHAR *)((BYTE *)compstr + compstr->dwResultStrOffset);
TRANSMSG msg = {.message = WM_IME_COMPOSITION, .wParam = result[0], .lParam = GCS_RESULTSTR};
if (compstr->dwResultClauseOffset) msg.lParam |= GCS_RESULTCLAUSE;
msgs->TransMsg[count++] = msg;
}
if (compstr->dwCompStrLen)
{
const WCHAR *comp = (WCHAR *)((BYTE *)compstr + compstr->dwCompStrOffset);
TRANSMSG msg = {.message = WM_IME_COMPOSITION, .wParam = comp[0], .lParam = GCS_COMPSTR | GCS_CURSORPOS | GCS_DELTASTART};
if (compstr->dwCompAttrOffset) msg.lParam |= GCS_COMPATTR;
if (compstr->dwCompClauseOffset) msg.lParam |= GCS_COMPCLAUSE;
else msg.lParam |= CS_INSERTCHAR|CS_NOMOVECARET;
msgs->TransMsg[count++] = msg;
}
}
ImmUnlockIMCC( ctx->hCompStr ); ImmUnlockIMCC( ctx->hCompStr );
done: done:
if (count >= msgs->uMsgCount) FIXME( "More than %u messages queued, messages possibly lost\n", msgs->uMsgCount );
else TRACE( "Returning %u messages queued\n", count );
ImmUnlockIMC( himc ); ImmUnlockIMC( himc );
return count; return count;
} }
...@@ -524,10 +549,10 @@ BOOL WINAPI ImeSetCompositionString( HIMC himc, DWORD index, const void *comp, D ...@@ -524,10 +549,10 @@ BOOL WINAPI ImeSetCompositionString( HIMC himc, DWORD index, const void *comp, D
FIXME( "index %#lx not implemented\n", index ); FIXME( "index %#lx not implemented\n", index );
else else
{ {
UINT flags = GCS_COMPSTR | GCS_COMPCLAUSE | GCS_COMPATTR | GCS_DELTASTART | GCS_CURSORPOS; UINT msg, flags = GCS_COMPSTR | GCS_COMPCLAUSE | GCS_COMPATTR | GCS_DELTASTART | GCS_CURSORPOS;
WCHAR wparam = comp && comp_len >= sizeof(WCHAR) ? *(WCHAR *)comp : 0; WCHAR wparam = comp && comp_len >= sizeof(WCHAR) ? *(WCHAR *)comp : 0;
input_context_set_comp_str( ctx, comp, comp_len / sizeof(WCHAR) ); input_context_set_comp_str( ctx, comp, comp_len / sizeof(WCHAR) );
ime_set_composition_status( himc, TRUE ); if ((msg = ime_set_composition_status( himc, TRUE ))) ime_send_message( himc, msg, 0, 0 );
ime_send_message( himc, WM_IME_COMPOSITION, wparam, flags ); ime_send_message( himc, WM_IME_COMPOSITION, wparam, flags );
} }
...@@ -540,6 +565,7 @@ BOOL WINAPI NotifyIME( HIMC himc, DWORD action, DWORD index, DWORD value ) ...@@ -540,6 +565,7 @@ BOOL WINAPI NotifyIME( HIMC himc, DWORD action, DWORD index, DWORD value )
{ {
struct ime_private *priv; struct ime_private *priv;
INPUTCONTEXT *ctx; INPUTCONTEXT *ctx;
UINT msg;
TRACE( "himc %p, action %#lx, index %#lx, value %#lx stub!\n", himc, action, index, value ); TRACE( "himc %p, action %#lx, index %#lx, value %#lx stub!\n", himc, action, index, value );
...@@ -562,7 +588,7 @@ BOOL WINAPI NotifyIME( HIMC himc, DWORD action, DWORD index, DWORD value ) ...@@ -562,7 +588,7 @@ BOOL WINAPI NotifyIME( HIMC himc, DWORD action, DWORD index, DWORD value )
if (!ctx->fOpen) if (!ctx->fOpen)
{ {
input_context_set_comp_str( ctx, NULL, 0 ); input_context_set_comp_str( ctx, NULL, 0 );
ime_set_composition_status( himc, FALSE ); if ((msg = ime_set_composition_status( himc, TRUE ))) ime_send_message( himc, msg, 0, 0 );
} }
NtUserNotifyIMEStatus( ctx->hWnd, ctx->fOpen ); NtUserNotifyIMEStatus( ctx->hWnd, ctx->fOpen );
break; break;
......
...@@ -375,7 +375,6 @@ static const kernel_callback kernel_callbacks[] = ...@@ -375,7 +375,6 @@ static const kernel_callback kernel_callbacks[] =
macdrv_dnd_query_drop, macdrv_dnd_query_drop,
macdrv_dnd_query_exited, macdrv_dnd_query_exited,
macdrv_ime_query_char_rect, macdrv_ime_query_char_rect,
macdrv_ime_set_text,
}; };
C_ASSERT(NtUserDriverCallbackFirst + ARRAYSIZE(kernel_callbacks) == client_func_last); C_ASSERT(NtUserDriverCallbackFirst + ARRAYSIZE(kernel_callbacks) == client_func_last);
......
...@@ -34,15 +34,22 @@ ...@@ -34,15 +34,22 @@
WINE_DEFAULT_DEBUG_CHANNEL(event); WINE_DEFAULT_DEBUG_CHANNEL(event);
WINE_DECLARE_DEBUG_CHANNEL(imm); 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 struct ime_update
{ {
DWORD cursor_pos; DWORD cursor_pos;
WCHAR *comp_str; WCHAR *comp_str;
WCHAR *result_str; WCHAR *result_str;
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; static struct ime_update ime_update;
...@@ -164,42 +171,33 @@ static macdrv_event_mask get_event_mask(DWORD mask) ...@@ -164,42 +171,33 @@ static macdrv_event_mask get_event_mask(DWORD mask)
static void macdrv_im_set_text(const macdrv_event *event) static void macdrv_im_set_text(const macdrv_event *event)
{ {
HWND hwnd = macdrv_get_window_hwnd(event->window); HWND hwnd = macdrv_get_window_hwnd(event->window);
struct ime_set_text_params *params; CFIndex length = 0;
CFIndex length = 0, size; WCHAR *text = NULL;
TRACE_(imm)("win %p/%p himc %p text %s complete %u\n", hwnd, event->window, event->im_set_text.himc, 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); debugstr_cf(event->im_set_text.text), event->im_set_text.complete);
if (event->im_set_text.text) if (event->im_set_text.text)
{
length = CFStringGetLength(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 + 1]); /* discard any pending comp text */
if (!(params = malloc(size))) return; free(ime_update.comp_str);
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);
params->text[length] = 0;
free(ime_update.comp_params);
ime_update.comp_params = NULL;
ime_update.comp_str = NULL; ime_update.comp_str = NULL;
ime_update.cursor_pos = -1;
if (params->complete) if (event->im_set_text.complete)
{ {
free(ime_update.result_params); free(ime_update.result_str);
ime_update.result_params = params; ime_update.result_str = text;
ime_update.result_size = size;
ime_update.result_str = params->text;
} }
else else
{ {
ime_update.comp_params = params; ime_update.comp_str = text;
ime_update.comp_size = size;
ime_update.comp_str = params->text;
ime_update.cursor_pos = event->im_set_text.cursor_pos; ime_update.cursor_pos = event->im_set_text.cursor_pos;
} }
} }
...@@ -291,21 +289,8 @@ UINT macdrv_ImeToAsciiEx(UINT vkey, UINT vsc, const BYTE *state, COMPOSITIONSTRI ...@@ -291,21 +289,8 @@ UINT macdrv_ImeToAsciiEx(UINT vkey, UINT vsc, const BYTE *state, COMPOSITIONSTRI
compstr->dwSize += compstr->dwResultClauseLen; compstr->dwSize += compstr->dwResultClauseLen;
} }
if (ime_update.result_params) free(update->result_str);
{ update->result_str = NULL;
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;
ime_update.result_str = 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;
ime_update.comp_str = NULL;
}
return 0; return 0;
} }
......
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
#endif #endif
#include "macdrv_cocoa.h" #include "macdrv_cocoa.h"
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "ntgdi.h" #include "ntgdi.h"
......
...@@ -31,7 +31,6 @@ extern NTSTATUS WINAPI macdrv_dnd_query_drag(void *arg, ULONG size) DECLSPEC_HID ...@@ -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_drop(void *arg, ULONG size) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI macdrv_dnd_query_exited(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 NTSTATUS WINAPI macdrv_ime_query_char_rect(void *params, ULONG size) DECLSPEC_HIDDEN;
extern HMODULE macdrv_module DECLSPEC_HIDDEN; extern HMODULE macdrv_module DECLSPEC_HIDDEN;
......
...@@ -92,7 +92,6 @@ enum macdrv_client_funcs ...@@ -92,7 +92,6 @@ enum macdrv_client_funcs
client_func_dnd_query_drop, client_func_dnd_query_drop,
client_func_dnd_query_exited, client_func_dnd_query_exited,
client_func_ime_query_char_rect, client_func_ime_query_char_rect,
client_func_ime_set_text,
client_func_last client_func_last
}; };
...@@ -168,16 +167,6 @@ struct ime_query_char_rect_params ...@@ -168,16 +167,6 @@ struct ime_query_char_rect_params
UINT32 length; 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) static inline void *param_ptr(UINT64 param)
{ {
return (void *)(UINT_PTR)param; return (void *)(UINT_PTR)param;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment