winex11.drv: Fix IME status handling.

This commit is contained in:
Kusanagi Kouichi 2012-01-09 16:36:10 +09:00 committed by Alexandre Julliard
parent f56e1fcf7c
commit dc02e4d1a7
3 changed files with 41 additions and 67 deletions

View File

@ -719,32 +719,21 @@ BOOL WINAPI NotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
case IMC_SETOPENSTATUS: case IMC_SETOPENSTATUS:
TRACE("IMC_SETOPENSTATUS\n"); TRACE("IMC_SETOPENSTATUS\n");
/* Indirectly called from XIM callbacks */ bRet = TRUE;
if (ImmGetIMCCLockCount(lpIMC->hPrivate) > 0) X11DRV_SetPreeditState(lpIMC->hWnd, lpIMC->fOpen);
if (!lpIMC->fOpen)
{ {
bRet = TRUE; LPIMEPRIVATE myPrivate;
break;
}
bRet = X11DRV_SetPreeditState(lpIMC->hWnd, lpIMC->fOpen); myPrivate = ImmLockIMCC(lpIMC->hPrivate);
if (bRet) if (myPrivate->bInComposition)
{
if (!lpIMC->fOpen)
{ {
LPIMEPRIVATE myPrivate; X11DRV_ForceXIMReset(lpIMC->hWnd);
GenerateIMEMessage(hIMC, WM_IME_ENDCOMPOSITION, 0, 0);
myPrivate = ImmLockIMCC(lpIMC->hPrivate); myPrivate->bInComposition = FALSE;
if (myPrivate->bInComposition)
{
X11DRV_ForceXIMReset(lpIMC->hWnd);
GenerateIMEMessage(hIMC, WM_IME_ENDCOMPOSITION, 0, 0);
myPrivate->bInComposition = FALSE;
}
ImmUnlockIMCC(lpIMC->hPrivate);
} }
ImmUnlockIMCC(lpIMC->hPrivate);
} }
else
lpIMC->fOpen = !lpIMC->fOpen;
break; break;
default: FIXME("Unknown\n"); break; default: FIXME("Unknown\n"); break;
@ -957,7 +946,15 @@ DWORD WINAPI ImeGetImeMenuItems(HIMC hIMC, DWORD dwFlags, DWORD dwType,
/* Interfaces to XIM and other parts of winex11drv */ /* Interfaces to XIM and other parts of winex11drv */
void IME_SetOpenStatus(BOOL fOpen, BOOL force) void IME_SetOpenStatus(BOOL fOpen)
{
HIMC imc;
imc = RealIMC(FROM_X11);
ImmSetOpenStatus(imc, fOpen);
}
void IME_SetCompositionStatus(BOOL fOpen)
{ {
HIMC imc; HIMC imc;
LPINPUTCONTEXT lpIMC; LPINPUTCONTEXT lpIMC;
@ -970,20 +967,18 @@ void IME_SetOpenStatus(BOOL fOpen, BOOL force)
myPrivate = ImmLockIMCC(lpIMC->hPrivate); myPrivate = ImmLockIMCC(lpIMC->hPrivate);
if (!fOpen && myPrivate->bInComposition) if (fOpen && !myPrivate->bInComposition)
{
GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0);
}
else if (!fOpen && myPrivate->bInComposition)
{ {
ShowWindow(myPrivate->hwndDefault, SW_HIDE); ShowWindow(myPrivate->hwndDefault, SW_HIDE);
ImmDestroyIMCC(lpIMC->hCompStr); ImmDestroyIMCC(lpIMC->hCompStr);
lpIMC->hCompStr = ImeCreateBlankCompStr(); lpIMC->hCompStr = ImeCreateBlankCompStr();
myPrivate->bInComposition = FALSE;
GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0); GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0);
} }
myPrivate->bInComposition = fOpen;
if (lpIMC->fOpen && fOpen)
ImmSetOpenStatus(imc, FALSE);
if (fOpen || force)
ImmSetOpenStatus(imc, fOpen);
ImmUnlockIMCC(lpIMC->hPrivate); ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(imc); ImmUnlockIMC(imc);
@ -1059,7 +1054,6 @@ void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen)
LPINPUTCONTEXT lpIMC; LPINPUTCONTEXT lpIMC;
HIMCC newCompStr; HIMCC newCompStr;
LPIMEPRIVATE myPrivate; LPIMEPRIVATE myPrivate;
BOOL fOpen;
imc = RealIMC(FROM_X11); imc = RealIMC(FROM_X11);
lpIMC = ImmLockIMC(imc); lpIMC = ImmLockIMC(imc);
@ -1071,15 +1065,11 @@ void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen)
lpIMC->hCompStr = newCompStr; lpIMC->hCompStr = newCompStr;
myPrivate = ImmLockIMCC(lpIMC->hPrivate); myPrivate = ImmLockIMCC(lpIMC->hPrivate);
fOpen = lpIMC->fOpen;
ImmSetOpenStatus(imc, TRUE);
if (!myPrivate->bInComposition) if (!myPrivate->bInComposition)
GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0); GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0);
GenerateIMEMessage(imc, WM_IME_COMPOSITION, 0, GCS_RESULTSTR); GenerateIMEMessage(imc, WM_IME_COMPOSITION, 0, GCS_RESULTSTR);
if (!myPrivate->bInComposition) if (!myPrivate->bInComposition)
GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0); GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0);
if (!fOpen)
ImmSetOpenStatus(imc, FALSE);
ImmUnlockIMCC(lpIMC->hPrivate); ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(imc); ImmUnlockIMC(imc);

View File

@ -289,7 +289,8 @@ extern BOOL destroy_glxpixmap(Display *display, XID glxpixmap) DECLSPEC_HIDDEN;
/* IME support */ /* IME support */
extern void IME_UnregisterClasses(void) DECLSPEC_HIDDEN; extern void IME_UnregisterClasses(void) DECLSPEC_HIDDEN;
extern void IME_SetOpenStatus(BOOL fOpen, BOOL force) DECLSPEC_HIDDEN; extern void IME_SetOpenStatus(BOOL fOpen) DECLSPEC_HIDDEN;
extern void IME_SetCompositionStatus(BOOL fOpen) DECLSPEC_HIDDEN;
extern INT IME_GetCursorPos(void) DECLSPEC_HIDDEN; extern INT IME_GetCursorPos(void) DECLSPEC_HIDDEN;
extern void IME_SetCursorPos(DWORD pos) DECLSPEC_HIDDEN; extern void IME_SetCursorPos(DWORD pos) DECLSPEC_HIDDEN;
extern void IME_UpdateAssociation(HWND focus) DECLSPEC_HIDDEN; extern void IME_UpdateAssociation(HWND focus) DECLSPEC_HIDDEN;
@ -716,7 +717,7 @@ extern XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data) DECLSPEC_HIDDE
extern void X11DRV_SetupXIM(void) DECLSPEC_HIDDEN; extern void X11DRV_SetupXIM(void) DECLSPEC_HIDDEN;
extern void X11DRV_XIMLookupChars( const char *str, DWORD count ) DECLSPEC_HIDDEN; extern void X11DRV_XIMLookupChars( const char *str, DWORD count ) DECLSPEC_HIDDEN;
extern void X11DRV_ForceXIMReset(HWND hwnd) DECLSPEC_HIDDEN; extern void X11DRV_ForceXIMReset(HWND hwnd) DECLSPEC_HIDDEN;
extern BOOL X11DRV_SetPreeditState(HWND hwnd, BOOL fOpen) DECLSPEC_HIDDEN; extern void X11DRV_SetPreeditState(HWND hwnd, BOOL fOpen) DECLSPEC_HIDDEN;
#define XEMBED_MAPPED (1 << 0) #define XEMBED_MAPPED (1 << 0)

View File

@ -129,10 +129,10 @@ static BOOL XIMPreEditStateNotifyCallback(XIC xic, XPointer p, XPointer data)
switch (state) switch (state)
{ {
case XIMPreeditEnable: case XIMPreeditEnable:
IME_SetOpenStatus(TRUE, TRUE); IME_SetOpenStatus(TRUE);
break; break;
case XIMPreeditDisable: case XIMPreeditDisable:
IME_SetOpenStatus(FALSE, TRUE); IME_SetOpenStatus(FALSE);
break; break;
default: default:
break; break;
@ -143,7 +143,7 @@ static BOOL XIMPreEditStateNotifyCallback(XIC xic, XPointer p, XPointer data)
static int XIMPreEditStartCallback(XIC ic, XPointer client_data, XPointer call_data) static int XIMPreEditStartCallback(XIC ic, XPointer client_data, XPointer call_data)
{ {
TRACE("PreEditStartCallback %p\n",ic); TRACE("PreEditStartCallback %p\n",ic);
IME_SetOpenStatus(TRUE, FALSE); IME_SetCompositionStatus(TRUE);
ximInComposeMode = TRUE; ximInComposeMode = TRUE;
return -1; return -1;
} }
@ -157,7 +157,7 @@ static void XIMPreEditDoneCallback(XIC ic, XPointer client_data, XPointer call_d
dwCompStringSize = 0; dwCompStringSize = 0;
dwCompStringLength = 0; dwCompStringLength = 0;
CompositionString = NULL; CompositionString = NULL;
IME_SetOpenStatus(FALSE, FALSE); IME_SetCompositionStatus(FALSE);
} }
static void XIMPreEditDrawCallback(XIM ic, XPointer client_data, static void XIMPreEditDrawCallback(XIM ic, XPointer client_data,
@ -264,48 +264,31 @@ void X11DRV_ForceXIMReset(HWND hwnd)
} }
} }
BOOL X11DRV_SetPreeditState(HWND hwnd, BOOL fOpen) void X11DRV_SetPreeditState(HWND hwnd, BOOL fOpen)
{ {
XIC ic; XIC ic;
XIMPreeditState state; XIMPreeditState state;
XVaNestedList attr_set, attr_get; XVaNestedList attr;
BOOL ret;
ic = X11DRV_get_ic(hwnd); ic = X11DRV_get_ic(hwnd);
if (!ic) if (!ic)
return FALSE; return;
if (fOpen) if (fOpen)
state = XIMPreeditEnable; state = XIMPreeditEnable;
else else
state = XIMPreeditDisable; state = XIMPreeditDisable;
ret = FALSE;
wine_tsx11_lock(); wine_tsx11_lock();
attr_set = XVaCreateNestedList(0, XNPreeditState, state, NULL); attr = XVaCreateNestedList(0, XNPreeditState, state, NULL);
if (attr_set == NULL) if (attr != NULL)
goto error1; {
XSetICValues(ic, XNPreeditAttributes, attr, NULL);
XFree(attr);
}
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(); wine_tsx11_unlock();
return ret;
} }