winex11.drv: Update caret position correctry.

Kusanagi Kouichi slash at ma.neweb.ne.jp
Sat Apr 12 12:59:16 CDT 2008


If composition string is inserted, caret is placed before inserted text.
Caret position is restored if caret is moved.
---
 dlls/user32/edit.c        |   13 +++++++++++--
 dlls/winex11.drv/ime.c    |   30 ++++++++++++++++++++++++++++++
 dlls/winex11.drv/x11drv.h |    1 +
 dlls/winex11.drv/xim.c    |    9 ++++-----
 4 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c
index b2bfe1c..c3e1089 100644
--- a/dlls/user32/edit.c
+++ b/dlls/user32/edit.c
@@ -1033,18 +1033,22 @@ static LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg,
 	/* 
 	 * FIXME in IME: This message is not always sent like it should be
 	 */
+#if 0
 		if (es->selection_start != es->selection_end)
 		{
 			static const WCHAR empty_stringW[] = {0};
 			EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE);
 		}
+#endif
 		es->composition_start = es->selection_end;
 		es->composition_len = 0;
 		break;
 
 	case WM_IME_COMPOSITION:
 	{
-		int caret_pos = es->selection_end;
+                HIMC hIMC;
+                int cursor;
+
 		if (es->composition_len == 0)
 		{
 			if (es->selection_start != es->selection_end)
@@ -1056,7 +1060,12 @@ static LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg,
 			es->composition_start = es->selection_end;
 		}
 		EDIT_ImeComposition(hwnd,lParam,es);
-		EDIT_SetCaretPos(es, caret_pos, es->flags & EF_AFTER_WRAP);
+                hIMC = ImmGetContext(hwnd);
+                if (hIMC)
+                        cursor = ImmGetCompositionStringW(hIMC, GCS_CURSORPOS, 0, 0);
+                else
+                        cursor = es->composition_len;
+                EDIT_SetCaretPos(es, es->composition_start + cursor, es->flags & EF_AFTER_WRAP);
 		break;
 	}
 
diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c
index a1c229e..53176f4 100644
--- a/dlls/winex11.drv/ime.c
+++ b/dlls/winex11.drv/ime.c
@@ -1012,6 +1012,36 @@ INT IME_GetCursorPos()
     return rc;
 }
 
+void IME_SetCursorPos(DWORD pos)
+{
+    LPINPUTCONTEXT lpIMC;
+    LPCOMPOSITIONSTRING compstr;
+
+    if (!hSelectedFrom)
+        return;
+
+    lpIMC = LockRealIMC(FROM_X11);
+    if (!lpIMC)
+        return;
+
+    compstr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
+    if (!compstr)
+    {
+        UnlockRealIMC(FROM_X11);
+        return;
+    }
+
+    if (pos < 0)
+        pos = 0;
+    else if (pos > compstr->dwCursorPos)
+        pos = compstr->dwCursorPos;
+    compstr->dwCursorPos = pos;
+    ImmUnlockIMCC(lpIMC->hCompStr);
+    UnlockRealIMC(FROM_X11);
+    GenerateIMEMessage(FROM_X11, WM_IME_COMPOSITION, pos, GCS_CURSORPOS);
+    return;
+}
+
 void IME_UpdateAssociation(HWND focus)
 {
     ImmGetContext(focus);
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index e682f07..139e705 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -280,6 +280,7 @@ extern void IME_SetOpenStatus(BOOL fOpen);
 extern void IME_XIMPresent(BOOL present);
 extern LRESULT IME_SendMessageToSelectedHWND(UINT msg, WPARAM wParam, LPARAM lParam);
 extern INT IME_GetCursorPos();
+extern void IME_SetCursorPos(DWORD pos);
 extern void IME_UpdateAssociation(HWND focus);
 extern BOOL IME_SetCompositionString(DWORD dwIndex, LPCVOID lpComp,
                                      DWORD dwCompLen, LPCVOID lpRead,
diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c
index d4df9f7..b2da04d 100644
--- a/dlls/winex11.drv/xim.c
+++ b/dlls/winex11.drv/xim.c
@@ -43,7 +43,6 @@ static LPBYTE CompositionString = NULL;
 static DWORD dwCompStringSize = 0;
 static LPBYTE ResultString = NULL;
 static DWORD dwResultStringSize = 0;
-static DWORD dwPreeditPos = 0;
 
 #define STYLE_OFFTHESPOT (XIMPreeditArea | XIMStatusArea)
 #define STYLE_OVERTHESPOT (XIMPreeditPosition | XIMStatusNothing)
@@ -211,7 +210,7 @@ static int XIMPreEditStartCallback(XIC ic, XPointer client_data, XPointer call_d
     TRACE("PreEditStartCallback %p\n",ic);
     X11DRV_ImmSetOpenStatus(TRUE);
     ximInComposeMode = TRUE;
-    IME_SendMessageToSelectedHWND(EM_GETSEL, 0, (LPARAM)&dwPreeditPos);
+    IME_SendMessageToSelectedHWND(WM_IME_STARTCOMPOSITION, 0, 0);
     return -1;
 }
 
@@ -220,7 +219,7 @@ static void XIMPreEditDoneCallback(XIC ic, XPointer client_data, XPointer call_d
     TRACE("PreeditDoneCallback %p\n",ic);
     ximInComposeMode = FALSE;
     X11DRV_ImmSetOpenStatus(FALSE);
-    dwPreeditPos = 0;
+    IME_SendMessageToSelectedHWND(WM_IME_ENDCOMPOSITION, 0, 0);
 }
 
 static void XIMPreEditDrawCallback(XIM ic, XPointer client_data,
@@ -263,6 +262,7 @@ static void XIMPreEditDrawCallback(XIM ic, XPointer client_data,
                                              (LPWSTR)P_DR->text->string.wide_char,
                                              P_DR->text->length);
             }
+            IME_SetCursorPos(P_DR->caret);
         }
         else
             X11DRV_ImmSetInternalString (GCS_COMPSTR, sel, len, NULL, 0);
@@ -306,8 +306,7 @@ static void XIMPreEditCaretCallback(XIC ic, XPointer client_data,
                 FIXME("Not implemented\n");
                 break;
         }
-        IME_SendMessageToSelectedHWND( EM_SETSEL, dwPreeditPos + pos,
-                     dwPreeditPos + pos);
+        IME_SetCursorPos(pos);
         P_C->position = pos;
     }
     TRACE("Finished\n");
-- 
1.5.5




More information about the wine-patches mailing list