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
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 ); }