winex11.drv: Keep the state of XIM and IME consistent.
This commit is contained in:
parent
10642e76db
commit
f7b18148d4
|
@ -717,30 +717,36 @@ BOOL WINAPI NotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
|
|||
}
|
||||
break;
|
||||
case IMC_SETOPENSTATUS:
|
||||
{
|
||||
LPIMEPRIVATE myPrivate;
|
||||
TRACE("IMC_SETOPENSTATUS\n");
|
||||
|
||||
myPrivate = ImmLockIMCC(lpIMC->hPrivate);
|
||||
if (lpIMC->fOpen != myPrivate->bInternalState &&
|
||||
myPrivate->bInComposition)
|
||||
/* Indirectly called from XIM callbacks */
|
||||
if (ImmGetIMCCLockCount(lpIMC->hPrivate) > 0)
|
||||
{
|
||||
if(lpIMC->fOpen == FALSE)
|
||||
bRet = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
bRet = X11DRV_SetPreeditState(lpIMC->hWnd, lpIMC->fOpen);
|
||||
if (bRet)
|
||||
{
|
||||
if (!lpIMC->fOpen)
|
||||
{
|
||||
X11DRV_ForceXIMReset(lpIMC->hWnd);
|
||||
GenerateIMEMessage(hIMC,WM_IME_ENDCOMPOSITION,0,0);
|
||||
myPrivate->bInComposition = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
GenerateIMEMessage(hIMC,WM_IME_STARTCOMPOSITION,0,0);
|
||||
GenerateIMEMessage(hIMC, WM_IME_COMPOSITION, 0, 0);
|
||||
LPIMEPRIVATE myPrivate;
|
||||
|
||||
myPrivate = ImmLockIMCC(lpIMC->hPrivate);
|
||||
if (myPrivate->bInComposition)
|
||||
{
|
||||
X11DRV_ForceXIMReset(lpIMC->hWnd);
|
||||
GenerateIMEMessage(hIMC, WM_IME_ENDCOMPOSITION, 0, 0);
|
||||
myPrivate->bInComposition = FALSE;
|
||||
}
|
||||
ImmUnlockIMCC(lpIMC->hPrivate);
|
||||
}
|
||||
}
|
||||
myPrivate->bInternalState = lpIMC->fOpen;
|
||||
bRet = TRUE;
|
||||
}
|
||||
break;
|
||||
else
|
||||
lpIMC->fOpen = !lpIMC->fOpen;
|
||||
|
||||
break;
|
||||
default: FIXME("Unknown\n"); break;
|
||||
}
|
||||
break;
|
||||
|
@ -951,35 +957,36 @@ DWORD WINAPI ImeGetImeMenuItems(HIMC hIMC, DWORD dwFlags, DWORD dwType,
|
|||
|
||||
/* Interfaces to XIM and other parts of winex11drv */
|
||||
|
||||
void IME_SetOpenStatus(BOOL fOpen)
|
||||
void IME_SetOpenStatus(BOOL fOpen, BOOL force)
|
||||
{
|
||||
HIMC imc;
|
||||
LPINPUTCONTEXT lpIMC;
|
||||
LPIMEPRIVATE myPrivate;
|
||||
|
||||
lpIMC = LockRealIMC(FROM_X11);
|
||||
imc = RealIMC(FROM_X11);
|
||||
lpIMC = ImmLockIMC(imc);
|
||||
if (lpIMC == NULL)
|
||||
return;
|
||||
|
||||
myPrivate = ImmLockIMCC(lpIMC->hPrivate);
|
||||
|
||||
if (myPrivate->bInternalState && fOpen == FALSE)
|
||||
if (!fOpen && myPrivate->bInComposition)
|
||||
{
|
||||
ShowWindow(myPrivate->hwndDefault, SW_HIDE);
|
||||
ImmDestroyIMCC(lpIMC->hCompStr);
|
||||
lpIMC->hCompStr = ImeCreateBlankCompStr();
|
||||
myPrivate->bInComposition = FALSE;
|
||||
GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0);
|
||||
}
|
||||
|
||||
if (lpIMC->fOpen && fOpen)
|
||||
ImmSetOpenStatus(imc, FALSE);
|
||||
|
||||
if (fOpen || force)
|
||||
ImmSetOpenStatus(imc, fOpen);
|
||||
|
||||
ImmUnlockIMCC(lpIMC->hPrivate);
|
||||
UnlockRealIMC(FROM_X11);
|
||||
|
||||
if (myPrivate->bInComposition && fOpen == FALSE)
|
||||
{
|
||||
GenerateIMEMessage(FROM_X11, WM_IME_ENDCOMPOSITION, 0, 0);
|
||||
myPrivate->bInComposition = FALSE;
|
||||
}
|
||||
|
||||
if (!myPrivate->bInternalState && fOpen == TRUE)
|
||||
ImmSetOpenStatus(RealIMC(FROM_X11), fOpen);
|
||||
ImmUnlockIMC(imc);
|
||||
}
|
||||
|
||||
INT IME_GetCursorPos(void)
|
||||
|
|
|
@ -300,7 +300,7 @@ extern BOOL destroy_glxpixmap(Display *display, XID glxpixmap);
|
|||
|
||||
/* IME support */
|
||||
extern void IME_UnregisterClasses(void);
|
||||
extern void IME_SetOpenStatus(BOOL fOpen);
|
||||
extern void IME_SetOpenStatus(BOOL fOpen, BOOL force);
|
||||
extern INT IME_GetCursorPos(void);
|
||||
extern void IME_SetCursorPos(DWORD pos);
|
||||
extern void IME_UpdateAssociation(HWND focus);
|
||||
|
@ -809,6 +809,7 @@ extern XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data) DECLSPEC_HIDDE
|
|||
extern void X11DRV_SetupXIM(void) DECLSPEC_HIDDEN;
|
||||
extern void X11DRV_XIMLookupChars( const char *str, DWORD count ) DECLSPEC_HIDDEN;
|
||||
extern void X11DRV_ForceXIMReset(HWND hwnd) DECLSPEC_HIDDEN;
|
||||
extern BOOL X11DRV_SetPreeditState(HWND hwnd, BOOL fOpen);
|
||||
|
||||
/* FIXME: private functions imported from user32 */
|
||||
extern LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode );
|
||||
|
|
|
@ -120,10 +120,30 @@ void X11DRV_XIMLookupChars( const char *str, DWORD count )
|
|||
HeapFree(GetProcessHeap(), 0, wcOutput);
|
||||
}
|
||||
|
||||
static BOOL XIMPreEditStateNotifyCallback(XIC xic, XPointer p, XPointer data)
|
||||
{
|
||||
const struct x11drv_win_data * const win_data = (struct x11drv_win_data *)p;
|
||||
const XIMPreeditState state = ((XIMPreeditStateNotifyCallbackStruct *)data)->state;
|
||||
|
||||
TRACE("xic = %p, win = %lx, state = %lu\n", xic, win_data->whole_window, state);
|
||||
switch (state)
|
||||
{
|
||||
case XIMPreeditEnable:
|
||||
IME_SetOpenStatus(TRUE, TRUE);
|
||||
break;
|
||||
case XIMPreeditDisable:
|
||||
IME_SetOpenStatus(FALSE, TRUE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int XIMPreEditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
|
||||
{
|
||||
TRACE("PreEditStartCallback %p\n",ic);
|
||||
IME_SetOpenStatus(TRUE);
|
||||
IME_SetOpenStatus(TRUE, FALSE);
|
||||
ximInComposeMode = TRUE;
|
||||
return -1;
|
||||
}
|
||||
|
@ -137,7 +157,7 @@ static void XIMPreEditDoneCallback(XIC ic, XPointer client_data, XPointer call_d
|
|||
dwCompStringSize = 0;
|
||||
dwCompStringLength = 0;
|
||||
CompositionString = NULL;
|
||||
IME_SetOpenStatus(FALSE);
|
||||
IME_SetOpenStatus(FALSE, FALSE);
|
||||
}
|
||||
|
||||
static void XIMPreEditDrawCallback(XIM ic, XPointer client_data,
|
||||
|
@ -244,6 +264,51 @@ void X11DRV_ForceXIMReset(HWND hwnd)
|
|||
}
|
||||
}
|
||||
|
||||
BOOL X11DRV_SetPreeditState(HWND hwnd, BOOL fOpen)
|
||||
{
|
||||
XIC ic;
|
||||
XIMPreeditState state;
|
||||
XVaNestedList attr_set, attr_get;
|
||||
BOOL ret;
|
||||
|
||||
ic = X11DRV_get_ic(hwnd);
|
||||
if (!ic)
|
||||
return FALSE;
|
||||
|
||||
if (fOpen)
|
||||
state = XIMPreeditEnable;
|
||||
else
|
||||
state = XIMPreeditDisable;
|
||||
|
||||
ret = FALSE;
|
||||
wine_tsx11_lock();
|
||||
|
||||
attr_set = XVaCreateNestedList(0, XNPreeditState, state, NULL);
|
||||
if (attr_set == NULL)
|
||||
goto error1;
|
||||
|
||||
attr_get = XVaCreateNestedList(0, XNPreeditState, &state, NULL);
|
||||
if (attr_get == NULL)
|
||||
goto error2;
|
||||
|
||||
if (XSetICValues(ic, XNPreeditAttributes, attr_set, NULL) != NULL)
|
||||
goto error3;
|
||||
|
||||
/* SCIM claims it supports XNPreeditState, but seems to ignore */
|
||||
state = XIMPreeditUnKnown;
|
||||
ret = XGetICValues(ic, XNPreeditAttributes, attr_get, NULL) == NULL &&
|
||||
((fOpen && state == XIMPreeditEnable) ||
|
||||
(!fOpen && state == XIMPreeditDisable));
|
||||
error3:
|
||||
XFree(attr_get);
|
||||
error2:
|
||||
XFree(attr_set);
|
||||
error1:
|
||||
wine_tsx11_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_InitXIM
|
||||
*
|
||||
|
@ -446,7 +511,7 @@ XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data)
|
|||
XVaNestedList status = NULL;
|
||||
XIC xic;
|
||||
XICCallback destroy = {(XPointer)data, (XICProc)X11DRV_DestroyIC};
|
||||
XICCallback P_StartCB, P_DoneCB, P_DrawCB, P_CaretCB;
|
||||
XICCallback P_StateNotifyCB, P_StartCB, P_DoneCB, P_DrawCB, P_CaretCB;
|
||||
LANGID langid = PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale()));
|
||||
Window win = data->whole_window;
|
||||
XFontSet fontSet = x11drv_thread_data()->font_set;
|
||||
|
@ -472,10 +537,12 @@ XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data)
|
|||
}
|
||||
|
||||
/* create callbacks */
|
||||
P_StateNotifyCB.client_data = (XPointer)data;
|
||||
P_StartCB.client_data = NULL;
|
||||
P_DoneCB.client_data = NULL;
|
||||
P_DrawCB.client_data = NULL;
|
||||
P_CaretCB.client_data = NULL;
|
||||
P_StateNotifyCB.callback = (XICProc)XIMPreEditStateNotifyCallback;
|
||||
P_StartCB.callback = (XICProc)XIMPreEditStartCallback;
|
||||
P_DoneCB.callback = (XICProc)XIMPreEditDoneCallback;
|
||||
P_DrawCB.callback = (XICProc)XIMPreEditDrawCallback;
|
||||
|
@ -486,6 +553,7 @@ XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data)
|
|||
preedit = XVaCreateNestedList(0,
|
||||
XNFontSet, fontSet,
|
||||
XNSpotLocation, &spot,
|
||||
XNPreeditStateNotifyCallback, &P_StateNotifyCB,
|
||||
XNPreeditStartCallback, &P_StartCB,
|
||||
XNPreeditDoneCallback, &P_DoneCB,
|
||||
XNPreeditDrawCallback, &P_DrawCB,
|
||||
|
@ -496,6 +564,7 @@ XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data)
|
|||
else
|
||||
{
|
||||
preedit = XVaCreateNestedList(0,
|
||||
XNPreeditStateNotifyCallback, &P_StateNotifyCB,
|
||||
XNPreeditStartCallback, &P_StartCB,
|
||||
XNPreeditDoneCallback, &P_DoneCB,
|
||||
XNPreeditDrawCallback, &P_DrawCB,
|
||||
|
|
Loading…
Reference in New Issue