winex11.drv: Add XIM preedit state support.
Kusanagi Kouichi
slash at ma.neweb.ne.jp
Tue Apr 22 00:57:39 CDT 2008
This patch allows an application to control XIM through ImmSetOpenStatus
if XIM server supports preedit state.
---
dlls/winex11.drv/ime.c | 36 ++++++++++++++----------------------
dlls/winex11.drv/x11drv.h | 1 +
dlls/winex11.drv/xim.c | 35 +++++++++++++++++++++++++++++++++++
3 files changed, 50 insertions(+), 22 deletions(-)
diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c
index c3e5ccf..2fc5ea5 100644
--- a/dlls/winex11.drv/ime.c
+++ b/dlls/winex11.drv/ime.c
@@ -687,23 +687,22 @@ BOOL WINAPI NotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
TRACE("IMC_SETOPENSTATUS\n");
myPrivate = (LPIMEPRIVATE)ImmLockIMCC(lpIMC->hPrivate);
- if (lpIMC->fOpen != myPrivate->bInternalState &&
- myPrivate->bInComposition)
+ if (X11DRV_SetPreeditState(lpIMC->hWnd, lpIMC->fOpen))
{
- if(lpIMC->fOpen == FALSE)
+ if(lpIMC->fOpen == FALSE && myPrivate->bInComposition)
{
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);
- }
+
+ myPrivate->bInternalState = lpIMC->fOpen;
+ bRet = TRUE;
}
- myPrivate->bInternalState = lpIMC->fOpen;
- bRet = TRUE;
+ else
+ lpIMC->fOpen = myPrivate->bInternalState;
+
+ ImmUnlockIMCC(lpIMC->hPrivate);
}
break;
default: FIXME("Unknown\n"); break;
@@ -963,24 +962,17 @@ void IME_SetOpenStatus(BOOL fOpen)
myPrivate = (LPIMEPRIVATE)ImmLockIMCC(lpIMC->hPrivate);
- if (myPrivate->bInternalState && fOpen == FALSE)
- {
- ShowWindow(myPrivate->hwndDefault, SW_HIDE);
- ImmDestroyIMCC(lpIMC->hCompStr);
- lpIMC->hCompStr = ImeCreateBlankCompStr();
- }
-
- 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);
+ lpIMC->fOpen = fOpen;
+ myPrivate->bInternalState = fOpen;
+
+ ImmUnlockIMCC(lpIMC->hPrivate);
+ UnlockRealIMC(FROM_X11);
}
void IME_XIMPresent(BOOL present)
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 90a2abd..cd734a6 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -771,6 +771,7 @@ extern XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data);
extern void X11DRV_SetupXIM(void);
extern void X11DRV_XIMLookupChars( const char *str, DWORD count );
extern void X11DRV_ForceXIMReset(HWND hwnd);
+extern BOOL X11DRV_SetPreeditState(HWND hwnd, BOOL enable);
/* FIXME: private functions imported from user32 */
extern LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode );
diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c
index 265f9c8..339c279 100644
--- a/dlls/winex11.drv/xim.c
+++ b/dlls/winex11.drv/xim.c
@@ -315,6 +315,41 @@ static void XIMPreEditCaretCallback(XIC ic, XPointer client_data,
TRACE("Finished\n");
}
+BOOL X11DRV_SetPreeditState(HWND hwnd, BOOL enable)
+{
+ XIC ic = X11DRV_get_ic(hwnd);
+ XIMPreeditState state, state2;
+ XVaNestedList attr;
+
+ if (!ic)
+ return FALSE;
+
+ if (enable)
+ state = XIMPreeditEnable;
+ else
+ state = XIMPreeditDisable;
+
+ wine_tsx11_lock();
+ attr = XVaCreateNestedList(0, XNPreeditState, state, NULL);
+ if (!attr || XSetICValues(ic, XNPreeditAttributes, attr, NULL))
+ goto error;
+
+ XFree(attr);
+ attr = XVaCreateNestedList(0, XNPreeditState, &state2, NULL);
+ if (!attr || XGetICValues(ic, XNPreeditAttributes, attr, NULL))
+ goto error;
+
+ XFree(attr);
+ wine_tsx11_unlock();
+ return state2 == state? TRUE: FALSE;
+
+error:
+ if (attr)
+ XFree(attr);
+ wine_tsx11_unlock();
+ return FALSE;
+}
+
void X11DRV_ForceXIMReset(HWND hwnd)
{
XIC ic = X11DRV_get_ic(hwnd);
--
1.5.5
--
Kusanagi Kouichi
More information about the wine-patches
mailing list