winemac: Generate IME messages from the default ImeToAsciiEx implementation.

This commit is contained in:
Rémi Bernon 2023-05-12 07:42:38 +02:00 committed by Alexandre Julliard
parent 8c08ffcdec
commit 8ae0c30823
7 changed files with 66 additions and 497 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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);
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;
ime_update.comp_str = NULL;
if (params->complete)
{
free(ime_update.result_params);
ime_update.result_params = params;
ime_update.result_size = size;
ime_update.result_str = params->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;
}
/* 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)
{
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;
}

View file

@ -121,313 +121,6 @@ static BOOL UnlockRealIMC(HIMC hIMC)
return FALSE;
}
static int updateField(DWORD origLen, DWORD origOffset, DWORD currentOffset,
LPBYTE target, LPBYTE source, DWORD* lenParam,
DWORD* offsetParam, BOOL wchars)
{
if (origLen > 0 && origOffset > 0)
{
int truelen = origLen;
if (wchars)
truelen *= sizeof(WCHAR);
memcpy(&target[currentOffset], &source[origOffset], truelen);
*lenParam = origLen;
*offsetParam = currentOffset;
currentOffset += truelen;
}
return currentOffset;
}
static HIMCC updateCompStr(HIMCC old, LPCWSTR compstr, DWORD len, DWORD *flags)
{
/* We need to make sure the CompStr, CompClause and CompAttr fields are all
* set and correct. */
int needed_size;
HIMCC rc;
LPBYTE newdata = NULL;
LPBYTE olddata = NULL;
LPCOMPOSITIONSTRING new_one;
LPCOMPOSITIONSTRING lpcs = NULL;
INT current_offset = 0;
TRACE("%s, %li\n", debugstr_wn(compstr, len), len);
if (old == NULL && compstr == NULL && len == 0)
return NULL;
if (compstr == NULL && len != 0)
{
ERR("compstr is NULL however we have a len! Please report\n");
len = 0;
}
if (old != NULL)
{
olddata = ImmLockIMCC(old);
lpcs = (LPCOMPOSITIONSTRING)olddata;
}
needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
len + sizeof(DWORD) * 2;
if (lpcs != NULL)
{
needed_size += lpcs->dwCompReadAttrLen;
needed_size += lpcs->dwCompReadClauseLen;
needed_size += lpcs->dwCompReadStrLen * sizeof(WCHAR);
needed_size += lpcs->dwResultReadClauseLen;
needed_size += lpcs->dwResultReadStrLen * sizeof(WCHAR);
needed_size += lpcs->dwResultClauseLen;
needed_size += lpcs->dwResultStrLen * sizeof(WCHAR);
needed_size += lpcs->dwPrivateSize;
}
rc = ImmCreateIMCC(needed_size);
newdata = ImmLockIMCC(rc);
new_one = (LPCOMPOSITIONSTRING)newdata;
new_one->dwSize = needed_size;
current_offset = sizeof(COMPOSITIONSTRING);
if (lpcs != NULL)
{
current_offset = updateField(lpcs->dwCompReadAttrLen,
lpcs->dwCompReadAttrOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadAttrLen,
&new_one->dwCompReadAttrOffset, FALSE);
current_offset = updateField(lpcs->dwCompReadClauseLen,
lpcs->dwCompReadClauseOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadClauseLen,
&new_one->dwCompReadClauseOffset, FALSE);
current_offset = updateField(lpcs->dwCompReadStrLen,
lpcs->dwCompReadStrOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadStrLen,
&new_one->dwCompReadStrOffset, TRUE);
/* new CompAttr, CompClause, CompStr, dwCursorPos */
new_one->dwDeltaStart = 0;
new_one->dwCursorPos = lpcs->dwCursorPos;
current_offset = updateField(lpcs->dwResultReadClauseLen,
lpcs->dwResultReadClauseOffset,
current_offset, newdata, olddata,
&new_one->dwResultReadClauseLen,
&new_one->dwResultReadClauseOffset, FALSE);
current_offset = updateField(lpcs->dwResultReadStrLen,
lpcs->dwResultReadStrOffset,
current_offset, newdata, olddata,
&new_one->dwResultReadStrLen,
&new_one->dwResultReadStrOffset, TRUE);
current_offset = updateField(lpcs->dwResultClauseLen,
lpcs->dwResultClauseOffset,
current_offset, newdata, olddata,
&new_one->dwResultClauseLen,
&new_one->dwResultClauseOffset, FALSE);
current_offset = updateField(lpcs->dwResultStrLen,
lpcs->dwResultStrOffset,
current_offset, newdata, olddata,
&new_one->dwResultStrLen,
&new_one->dwResultStrOffset, TRUE);
current_offset = updateField(lpcs->dwPrivateSize,
lpcs->dwPrivateOffset,
current_offset, newdata, olddata,
&new_one->dwPrivateSize,
&new_one->dwPrivateOffset, FALSE);
}
else
{
new_one->dwCursorPos = len;
*flags |= GCS_CURSORPOS;
}
/* set new data */
/* CompAttr */
new_one->dwCompAttrLen = len;
if (len > 0)
{
new_one->dwCompAttrOffset = current_offset;
memset(&newdata[current_offset], ATTR_INPUT, len);
current_offset += len;
}
/* CompClause */
if (len > 0)
{
new_one->dwCompClauseLen = sizeof(DWORD) * 2;
new_one->dwCompClauseOffset = current_offset;
*(DWORD*)&newdata[current_offset] = 0;
current_offset += sizeof(DWORD);
*(DWORD*)&newdata[current_offset] = len;
current_offset += sizeof(DWORD);
}
else
new_one->dwCompClauseLen = 0;
/* CompStr */
new_one->dwCompStrLen = len;
if (len > 0)
{
new_one->dwCompStrOffset = current_offset;
memcpy(&newdata[current_offset], compstr, len * sizeof(WCHAR));
}
ImmUnlockIMCC(rc);
if (lpcs)
ImmUnlockIMCC(old);
return rc;
}
static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len)
{
/* we need to make sure the ResultStr and ResultClause fields are all
* set and correct */
int needed_size;
HIMCC rc;
LPBYTE newdata = NULL;
LPBYTE olddata = NULL;
LPCOMPOSITIONSTRING new_one;
LPCOMPOSITIONSTRING lpcs = NULL;
INT current_offset = 0;
TRACE("%s, %li\n", debugstr_wn(resultstr, len), len);
if (old == NULL && resultstr == NULL && len == 0)
return NULL;
if (resultstr == NULL && len != 0)
{
ERR("resultstr is NULL however we have a len! Please report\n");
len = 0;
}
if (old != NULL)
{
olddata = ImmLockIMCC(old);
lpcs = (LPCOMPOSITIONSTRING)olddata;
}
needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
sizeof(DWORD) * 2;
if (lpcs != NULL)
{
needed_size += lpcs->dwCompReadAttrLen;
needed_size += lpcs->dwCompReadClauseLen;
needed_size += lpcs->dwCompReadStrLen * sizeof(WCHAR);
needed_size += lpcs->dwCompAttrLen;
needed_size += lpcs->dwCompClauseLen;
needed_size += lpcs->dwCompStrLen * sizeof(WCHAR);
needed_size += lpcs->dwResultReadClauseLen;
needed_size += lpcs->dwResultReadStrLen * sizeof(WCHAR);
needed_size += lpcs->dwPrivateSize;
}
rc = ImmCreateIMCC(needed_size);
newdata = ImmLockIMCC(rc);
new_one = (LPCOMPOSITIONSTRING)newdata;
new_one->dwSize = needed_size;
current_offset = sizeof(COMPOSITIONSTRING);
if (lpcs != NULL)
{
current_offset = updateField(lpcs->dwCompReadAttrLen,
lpcs->dwCompReadAttrOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadAttrLen,
&new_one->dwCompReadAttrOffset, FALSE);
current_offset = updateField(lpcs->dwCompReadClauseLen,
lpcs->dwCompReadClauseOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadClauseLen,
&new_one->dwCompReadClauseOffset, FALSE);
current_offset = updateField(lpcs->dwCompReadStrLen,
lpcs->dwCompReadStrOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadStrLen,
&new_one->dwCompReadStrOffset, TRUE);
current_offset = updateField(lpcs->dwCompAttrLen,
lpcs->dwCompAttrOffset,
current_offset, newdata, olddata,
&new_one->dwCompAttrLen,
&new_one->dwCompAttrOffset, FALSE);
current_offset = updateField(lpcs->dwCompClauseLen,
lpcs->dwCompClauseOffset,
current_offset, newdata, olddata,
&new_one->dwCompClauseLen,
&new_one->dwCompClauseOffset, FALSE);
current_offset = updateField(lpcs->dwCompStrLen,
lpcs->dwCompStrOffset,
current_offset, newdata, olddata,
&new_one->dwCompStrLen,
&new_one->dwCompStrOffset, TRUE);
new_one->dwCursorPos = lpcs->dwCursorPos;
new_one->dwDeltaStart = 0;
current_offset = updateField(lpcs->dwResultReadClauseLen,
lpcs->dwResultReadClauseOffset,
current_offset, newdata, olddata,
&new_one->dwResultReadClauseLen,
&new_one->dwResultReadClauseOffset, FALSE);
current_offset = updateField(lpcs->dwResultReadStrLen,
lpcs->dwResultReadStrOffset,
current_offset, newdata, olddata,
&new_one->dwResultReadStrLen,
&new_one->dwResultReadStrOffset, TRUE);
/* new ResultClause , ResultStr */
current_offset = updateField(lpcs->dwPrivateSize,
lpcs->dwPrivateOffset,
current_offset, newdata, olddata,
&new_one->dwPrivateSize,
&new_one->dwPrivateOffset, FALSE);
}
/* set new data */
/* ResultClause */
if (len > 0)
{
new_one->dwResultClauseLen = sizeof(DWORD) * 2;
new_one->dwResultClauseOffset = current_offset;
*(DWORD*)&newdata[current_offset] = 0;
current_offset += sizeof(DWORD);
*(DWORD*)&newdata[current_offset] = len;
current_offset += sizeof(DWORD);
}
else
new_one->dwResultClauseLen = 0;
/* ResultStr */
new_one->dwResultStrLen = len;
if (len > 0)
{
new_one->dwResultStrOffset = current_offset;
memcpy(&newdata[current_offset], resultstr, len * sizeof(WCHAR));
}
ImmUnlockIMCC(rc);
if (lpcs)
ImmUnlockIMCC(old);
return rc;
}
static void GenerateIMEMessage(HIMC hIMC, UINT msg, WPARAM wParam, LPARAM lParam)
{
LPINPUTCONTEXT lpIMC;
@ -524,133 +217,8 @@ BOOL WINAPI ImeSelect(HIMC hIMC, BOOL fSelect)
return TRUE;
}
static BOOL IME_SetCompositionString(void* hIMC, DWORD dwIndex, LPCVOID lpComp, DWORD dwCompLen, DWORD cursor_pos, BOOL cursor_valid)
{
LPINPUTCONTEXT lpIMC;
DWORD flags = 0;
WCHAR wParam = 0;
LPIMEPRIVATE myPrivate;
BOOL sendMessage = TRUE;
TRACE("(%p, %ld, %p, %ld):\n", hIMC, dwIndex, lpComp, dwCompLen);
/*
* Explanation:
* this sets the composition string in the imm32.dll level
* of the composition buffer.
* TODO: set the Cocoa window's marked text string and tell text input context
*/
lpIMC = LockRealIMC(hIMC);
if (lpIMC == NULL)
return FALSE;
myPrivate = ImmLockIMCC(lpIMC->hPrivate);
if (dwIndex == SCS_SETSTR)
{
HIMCC newCompStr;
if (!myPrivate->bInComposition)
{
GenerateIMEMessage(hIMC, WM_IME_STARTCOMPOSITION, 0, 0);
myPrivate->bInComposition = TRUE;
}
/* clear existing result */
newCompStr = updateResultStr(lpIMC->hCompStr, NULL, 0);
ImmDestroyIMCC(lpIMC->hCompStr);
lpIMC->hCompStr = newCompStr;
flags = GCS_COMPSTR;
if (dwCompLen && lpComp)
{
newCompStr = updateCompStr(lpIMC->hCompStr, (LPCWSTR)lpComp, dwCompLen / sizeof(WCHAR), &flags);
ImmDestroyIMCC(lpIMC->hCompStr);
lpIMC->hCompStr = newCompStr;
wParam = ((const WCHAR*)lpComp)[0];
flags |= GCS_COMPCLAUSE | GCS_COMPATTR | GCS_DELTASTART;
if (cursor_valid)
{
LPCOMPOSITIONSTRING compstr;
compstr = ImmLockIMCC(lpIMC->hCompStr);
compstr->dwCursorPos = cursor_pos;
ImmUnlockIMCC(lpIMC->hCompStr);
flags |= GCS_CURSORPOS;
}
}
else
{
ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
sendMessage = FALSE;
}
}
if (sendMessage) {
GenerateIMEMessage(hIMC, WM_IME_COMPOSITION, wParam, flags);
ImmUnlockIMCC(lpIMC->hPrivate);
UnlockRealIMC(hIMC);
}
return TRUE;
}
static void IME_NotifyComplete(void* hIMC)
{
ImmNotifyIME(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
*/

View file

@ -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"

View file

@ -31,7 +31,6 @@
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;

View file

@ -92,7 +92,6 @@
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 @@
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;