Patch for crash caused by XIM and make XIM functions properly (2ed)

liu spider liuspider at yahoo.com
Fri Jan 24 11:13:08 CST 2003


To my delight indeed, I found that Alexandre Julliard
just commited several patchs for "support for dead key
used by XIM". 

After compile the newest CVS, I found that I can not
input Chinese using this wine! But what's worse, when
I close the application ( I use notepad as a test),
debug window comes out, and if I close the debug
window, another one will comes up!

This patch is just for these two terrible problems.
After apply the changes made to
dlls/x11drv/x11drv_main.c ( described below, the
bottom item ), the second problem can be solve.
The first one need some more works as stated below.
(thanks for Dmitry Timoshkov's corrections)

BTW: one month ago, I submited a patch for all these
features and some more, but it had been ignored
without any comments. Hope this one would be
different.

ChangLog:
- controls/edit.c
  new message type WM_IME_CHAR to handle XIM input.
- dlls/x11drv/keyboard.c
  new function XIM_KeyEvent to process XIM key events.
- dlls/x11drv/window.c
  new attributs added when creating a IC
- dlls/x11drv/x11drv_main.c
  exchange the order of XCloseDisplay and XCloseIM
(otherwise it will crash when closed)

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com
-------------- next part --------------
Index: controls/edit.c
===================================================================
RCS file: /home/wine/wine/controls/edit.c,v
retrieving revision 1.108
diff -u -r1.108 edit.c
--- controls/edit.c	2 Dec 2002 18:11:00 -0000	1.108
+++ controls/edit.c	24 Jan 2003 13:46:16 -0000
@@ -761,6 +761,20 @@
 		}
 		break;
 
+	case WM_IME_CHAR:
+	{
+		WCHAR charW = wParam;
+		if ((charW == VK_RETURN || charW == VK_ESCAPE) && es->hwndListBox)
+		{
+		   if (SendMessageW(GetParent(hwnd), CB_GETDROPPEDSTATE, 0, 0))
+		      SendMessageW(GetParent(hwnd), WM_KEYDOWN, charW, 0);
+		   break;
+		}
+		TRACE_(edit)("WM_IME_CHAR :%d\n",charW);
+		EDIT_WM_Char(es, charW);
+		break;
+	}
+
 	case WM_CHAR:
 	{
 		WCHAR charW;
Index: dlls/x11drv/keyboard.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/keyboard.c,v
retrieving revision 1.20
diff -u -r1.20 keyboard.c
--- dlls/x11drv/keyboard.c	24 Jan 2003 00:47:08 -0000	1.20
+++ dlls/x11drv/keyboard.c	24 Jan 2003 13:46:18 -0000
@@ -980,6 +980,106 @@
 }
 
 /***********************************************************************
+ *           XIM_KeyEvent
+ *
+ * Handle XIM inputs
+ * If no further processing is necessary, return true; otherwise, return
+ * false indicating that the default handler should process it.
+ *
+ * CJK (Chinese, Japanese and Korean) has more characters than the keyboard
+ * can hold. So XIM inputs can NOT been directed to send_keyboard_input()
+ * FIXME: this approache DO NOT use IMM32 interfaces which is the standard 
+ * way under MS windows.
+ */
+#define NALLOC 64
+static BOOL XIM_KeyEvent(HWND hwnd, XIC xic, XKeyEvent *event)
+{
+    static BOOL updatedXIMPos = 0;
+    BOOL done = FALSE;
+
+    TRACE_(key)("hwnd %04x \n", (unsigned int) hwnd);
+
+    event->window = root_window;
+    if (event->type == KeyPress)
+    {
+        KeySym keysym;
+        Status status;
+        int i, nbyte;
+        DWORD dwOutput;
+        WCHAR wcOutput[NALLOC];
+        LPSTR bytes;
+        DWORD nalloc = NALLOC;
+
+        updatedXIMPos = 0;
+        if (xic == NULL)
+        {
+            WARN_(key)("Unable tp retrieve input context\n");
+            return FALSE;
+        }
+
+        bytes = HeapAlloc(GetProcessHeap(), 0, NALLOC);
+
+        nbyte = XmbLookupString(xic, event, bytes, nalloc, &keysym, &status);
+        TRACE_(key)("nbyte = %d, status = 0x%x\n", nbyte, status);
+
+        if (status == XBufferOverflow)
+        {
+            nalloc = nbyte;
+            bytes = HeapReAlloc(GetProcessHeap(), 0, bytes, nbyte);
+            nbyte = XmbLookupString(xic, event, bytes, nalloc, &keysym, &status);
+            TRACE_(key)("nbyte = %d, status = 0x%x\n", nbyte, status);
+        }
+
+        switch (status){
+        case XLookupBoth:
+            if (keysym < 128 || (keysym & 0xff00) == 0xff00)
+            {
+                TRACE_(key)("keysym = 0x%x\n", (int)keysym);
+                break; /* Leave to the default handler */
+            }
+
+        case XLookupChars:
+        {
+            INT codepage = GetACP();
+            if (codepage == 932)
+            {
+                /*
+                 * Japanese is encoded with windows as SJIS (932) however
+                 * Under unix we use EUS (20932) So we need to translate
+                 * the input as 20932...
+                 */
+                dwOutput = MultiByteToWideChar(20932,
+                    0, bytes, nbyte, wcOutput, sizeof(wcOutput));
+            }
+            else
+                dwOutput = MultiByteToWideChar(codepage,
+                    0, bytes, nbyte, wcOutput, sizeof(wcOutput));
+
+            for(i=0; i<dwOutput; i++)
+            {
+                TRACE_(key)("sending wchar %04x\n", wcOutput[i]);
+                PostMessageW(hwnd, WM_IME_CHAR, wcOutput[i], 1);
+            }
+            done = True;
+            break;
+        }
+
+        case XLookupKeySym:
+            TRACE_(key)("XLookupKeySym\n");
+            break; /* Leave to the default handler */
+
+        case XLookupNone:
+            TRACE_(key)("XLookupNone\n");
+            done = True; /* No further processing is necessary */
+            break;
+        }
+
+        HeapFree(GetProcessHeap(),0,bytes);
+    }
+    return done;
+}
+
+/***********************************************************************
  *           X11DRV_KeyEvent
  *
  * Handle a X key event
@@ -1000,8 +1100,14 @@

     wine_tsx11_lock();
     if (xic)
-        ascii_chars = XmbLookupString(xic, event, Str, sizeof(Str), &keysym, NULL);
-    else
+    {
+        if(XIM_KeyEvent(GetFocus(), xic, event))
+        {
+            wine_tsx11_unlock();
+            return;
+         }
+    }
+
         ascii_chars = XLookupString(event, Str, sizeof(Str), &keysym, NULL);
     wine_tsx11_unlock();
 
Index: dlls/x11drv/window.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/window.c,v
retrieving revision 1.49
diff -u -r1.49 window.c
--- dlls/x11drv/window.c	23 Jan 2003 01:28:12 -0000	1.49
+++ dlls/x11drv/window.c	24 Jan 2003 13:46:18 -0000
@@ -694,6 +694,7 @@
         if (xim) data->xic = XCreateIC( xim,
                                         XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
                                         XNClientWindow, data->whole_window,
+                                        XNFocusWindow, data->whole_window,
                                         0 );
     }
 
Index: dlls/x11drv/x11drv_main.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv_main.c,v
retrieving revision 1.66
diff -u -r1.66 x11drv_main.c
--- dlls/x11drv/x11drv_main.c	23 Jan 2003 01:28:12 -0000	1.66
+++ dlls/x11drv/x11drv_main.c	24 Jan 2003 13:46:18 -0000
@@ -368,8 +368,8 @@
     {
         CloseHandle( data->display_fd );
         wine_tsx11_lock();
-        XCloseDisplay( data->display );
         if (data->xim) XCloseIM( data->xim );
+        XCloseDisplay( data->display );
         wine_tsx11_unlock();
         HeapFree( GetProcessHeap(), 0, data );
     }


More information about the wine-patches mailing list