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
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;
INPUTCONTEXT *ctx;
UINT msg = 0;
if (!(ctx = ImmLockIMC( himc ))) return;
if (!(ctx = ImmLockIMC( himc ))) return 0;
if ((priv = ImmLockIMCC( ctx->hPrivate )))
{
if (!priv->bInComposition && composition) msg = WM_IME_STARTCOMPOSITION;
......@@ -180,7 +180,7 @@ static void ime_set_composition_status( HIMC himc, BOOL composition )
}
ImmUnlockIMC( himc );
if (msg) ime_send_message( himc, msg, 0, 0 );
return msg;
}
static void ime_ui_paint( HIMC himc, HWND hwnd )
......@@ -485,10 +485,35 @@ UINT WINAPI ImeToAsciiEx( UINT vkey, UINT vsc, BYTE *state, TRANSMSGLIST *msgs,
} while (status == STATUS_BUFFER_TOO_SMALL);
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 );
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 );
return count;
}
......@@ -524,10 +549,10 @@ BOOL WINAPI ImeSetCompositionString( HIMC himc, DWORD index, const void *comp, D
FIXME( "index %#lx not implemented\n", index );
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;
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 );
}
......@@ -540,6 +565,7 @@ BOOL WINAPI NotifyIME( HIMC himc, DWORD action, DWORD index, DWORD value )
{
struct ime_private *priv;
INPUTCONTEXT *ctx;
UINT msg;
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 )
if (!ctx->fOpen)
{
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 );
break;
......
......@@ -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);
......
......@@ -34,15 +34,22 @@
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;
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;
......@@ -164,42 +171,33 @@ 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 + 1]);
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);
params->text[length] = 0;
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;
ime_update.result_str = params->text;
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 = params->text;
ime_update.comp_str = text;
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
compstr->dwSize += compstr->dwResultClauseLen;
}
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;
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;
}
free(update->result_str);
update->result_str = NULL;
return 0;
}
......
......@@ -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"
......
......@@ -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;
......
......@@ -92,7 +92,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
};
......@@ -168,16 +167,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;
......
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