mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 16:39:20 +00:00
winemac: Generate IME messages from the default ImeToAsciiEx implementation.
This commit is contained in:
parent
8c08ffcdec
commit
8ae0c30823
|
@ -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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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_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 @@
|
|||
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;
|
||||
|
|
Loading…
Reference in a new issue