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