XIM support patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch is intended to implement XIM support in
wine. I hope it will support Chinese, Japanese and
Korean input method. But as I am Chinese I only tested
it with Chinese IM. 

For this patch is based on the patch of Mike
McCormack, which is made for Japanese IM, I think mine
will work with Japanese too. But I am not sure whether
this one can get along with Korean IMs.

If u would like to try it, please give me some
suggestions or/and bug reports.

This patch implemented features include:
One thread only create one connection with XIM server
and one IC.
Support OVER_THE_SPOT and ROOT IM style.
Enable/disable XIM support by editing the config file.
The font used in the XIM can be specified in the
config file.
Some other modifications for convenience purpose.

Hope this one helps CJK users.

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com
? patch.diff
? dlls/x11drv/xim.h
Index: controls/edit.c
===================================================================
RCS file: /home/wine/wine/controls/edit.c,v
retrieving revision 1.108
diff -r1.108 edit.c
58a59
> WINE_DECLARE_DEBUG_CHANNEL(xim);
275a277
> extern BOOL XIM_SetIMPos(RECT );
762a765,777
> 	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_(xim)("charW:%d\n",charW);
> 		EDIT_WM_Char(es, charW);
> 		break;
> 	}
Index: dlls/kernel/locale.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/locale.c,v
retrieving revision 1.5
diff -r1.5 locale.c
51a52
> 	char charset[128];
181a183
> 	char buf_charset[128];
189a192
> 	buf_charset[0] = '\0';
198a202,205
>     GetLocaleInfoA(lcid, LOCALE_SCHARSETNAMES | LOCALE_NOUSEROVERRIDE,
> 		   buf_charset, sizeof(buf_charset));
>     TRACE("LOCALE_SCHARSETNAMES: %s\n", buf_charset);
> 
204a212
> #if (0)
208a217,258
> #endif
> 				char *p, *q;
> 
> 				if (l_data->charset != NULL && strlen(l_data->charset) > 0) {
> 					p = buf_charset;
> 					do {
> 					q = p;
> 					if ((p = strchr(p, ',')) != NULL) {
> 						*p++ = '\0';
> 					}
> 					TRACE("q = 0x%x, %s\n", q, ((q == NULL) ? "" : q));
> 					if (q != NULL && strcasecmp(l_data->charset, q) == 0) {
> 						l_data->found_lang_id[0] = LangID;
> 						l_data->n_found = 1;
> 						TRACE("Found lang_id %04X for %s_%s.%s\n", LangID, l_data->lang, l_data->country, l_data->charset);
> 						return FALSE;
> 					}
> 					} while (p != NULL);
> 				} else {
> 					p = buf_charset;
> 					do {
> 					q = p;
> 					if ((p = strchr(p, ',')) != NULL) {
> 						*p++ = '\0';
> 					}
> 					TRACE("q = 0x%x, %s\n", q, ((q == NULL) ? "" : q));
> 					if (q == NULL || *q == '\0') {
> 						l_data->found_lang_id[0] = LangID;
> 						l_data->n_found = 1;
> 						TRACE("Found lang_id %04X for %s_%s\n", LangID, l_data->lang, l_data->country);
> 						return FALSE;
> 					}
> 					} while (p != NULL);
> 				}
> 				if (l_data->n_found < NLS_MAX_LANGUAGES) {
> 					l_data->found_lang_id[l_data->n_found] = LangID;
> 					strncpy(l_data->found_country[l_data->n_found], buf_country, 3);
> 					strncpy(l_data->found_language[l_data->n_found], buf_language, 3);
> 					l_data->n_found++;
> 					TRACE("Found lang_id %04X for %s_%s\n", LangID, l_data->lang, l_data->country);
> 					return TRUE;
> 				}
267a318,320
> 	FIXME(" Lang(%s) Country(%s) CharSet(%s) Dialect(%s)\n",
> 			Lang, Country, Charset, Dialect);
> 
279a333,336
>     if (Charset != NULL && strlen(Charset) > 0) {
> 	strncpy(l_data.charset, Charset, sizeof(l_data.charset));
>     }
> 
289a347,355
>     if (!l_data.n_found) {
> 	if (l_data.charset != NULL && strlen(l_data.charset) > 0) {
> 	    MESSAGE("Warning: Language '%s.%s' was not found, retrying without charset name...\n", lang_string, l_data.charset);
> 	    l_data.charset[0] = '\0';
> 	    EnumResourceLanguagesA(GetModuleHandleA("KERNEL32"), RT_STRINGA,
> 		(LPCSTR) LOCALE_ILANGUAGE, find_language_id_proc, (LONG) &l_data);
> 	}
>     }
> 
306a373,377
>     }
> 
>     if (l_data.charset != NULL && strlen(l_data.charset) > 0) {
> 	strcat(lang_string, ".");
> 	strcat(lang_string, l_data.charset);
Index: dlls/x11drv/X11_calls
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/X11_calls,v
retrieving revision 1.1
diff -r1.1 X11_calls
12a13
> XCloseIM
16a18
> XCreateFontSet
19a22
> XDestroyIC
28a32
> XFilterEvent
34a39
> XFreeFontSet
35a41
> XFreeStringList
68a75
> XSetICFocus
80a88,89
> XUnsetICFocus
> XmbLookupString
Index: dlls/x11drv/event.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/event.c,v
retrieving revision 1.15
diff -r1.15 event.c
48a49
> WINE_DECLARE_DEBUG_CHANNEL(xim);
194c195,201
<   TRACE( "called.\n" );
---
>   if( event->type != KeyPress && event->type != KeyRelease
>         && TSXFilterEvent(event, None))
>   {
>     TRACE_(xim)("Filtered event: %s(%d) window %08x\n",event_names[event->type],
> 	    event->type, (unsigned int)event->xany.window);
>     return;
>   }
477a485,489
>     XIC xic = NULL;
>     xic = X11DRV_GetXIC(event->window);
>     if(xic)
> 	    TSXSetICFocus(xic);
> 
Index: dlls/x11drv/keyboard.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/keyboard.c,v
retrieving revision 1.15
diff -r1.15 keyboard.c
41a42
> #include "heap.h"
51a53
> WINE_DECLARE_DEBUG_CHANNEL(xim);
63a66
> extern Window root_window;
941a945,1062
> #define NALLOC 64
> static BOOL XIM_KeyEvent(HWND hwnd, XKeyEvent *event)
> {
>     static BOOL updatedXIMPos = 0;
>     BOOL done = FALSE;
> 	Window orgWindow = event->window;
> 	struct x11drv_thread_data *data = NtCurrentTeb()->driver_data;
> 
>     TRACE_(xim)("hwnd %04x root_window(%08lx)\n", (unsigned int) hwnd, root_window);
> 
>     event->window = root_window;
>     if (!data->xim)
>         done = FALSE; /* No input method defined */
> 	else if (TSXFilterEvent((XEvent *) event, None))
>     {
>         TRACE_(xim)("Filtered.\n");
> 		if (!updatedXIMPos){
> 		    XIC xic = X11DRV_GetXIC(root_window);
> 			POINT p;
> 			XVaNestedList preedit_attr;
>             GetCaretPos(&p);
> 			ClientToScreen(hwnd, &p);
> 			XPoint spot;
> 			spot.x = p.x;
> 			spot.y = p.y;
> 			spot.y += 25;   //FIXME: How to get the caret's height
>             preedit_attr = XVaCreateNestedList(0,
> 								XNSpotLocation, &spot,
>                                 NULL);
>             XSetICValues(xic,XNPreeditAttributes,preedit_attr,NULL);
> 			/* use this variable to check whether we need to update XIM position */
> 			updatedXIMPos = 1;
> 		}
>         done = TRUE;
>     }
> 	else if (event->type == KeyPress)
>     {
>     	XIC xic;
>         KeySym keysym;
>         Status status;
>         int i, nbyte;
>         DWORD dwOutput;
>         WCHAR wcOutput[NALLOC];
>         LPSTR bytes;
>         DWORD nalloc = NALLOC;
>     	Window w = root_window;
> 
>         updatedXIMPos = 0;
>  		if ((xic = X11DRV_GetXIC(w)) == NULL)
> 		{
> 			WARN_(xim)("Unable tp retrieve input context\n");
> 			return FALSE;
> 		}
> 
>         bytes = HeapAlloc(GetProcessHeap(),0,NALLOC);
> 
>         nbyte = TSXmbLookupString(xic, event, bytes, nalloc, &keysym, &status);
>         TRACE_(xim)("nbyte = %d, status = 0x%x\n", nbyte, status);
> 
>         if (status == XBufferOverflow)
>         {
> 			nalloc = nbyte;
>             bytes = HeapReAlloc(GetProcessHeap(), 0, bytes, nbyte);
>             nbyte = TSXmbLookupString(xic, event, bytes, nalloc, &keysym, &status);
>             TRACE_(xim)("nbyte = %d, status = 0x%x\n", nbyte, status);
>         }
> 
>         switch (status)
>         {
>         case XLookupBoth:
>             if (keysym < 128 || (keysym & 0xff00) == 0xff00)
>             {
>                 TRACE_(xim)("keysym = 0x%x\n", (int)keysym);
> 				break; /* Leave to the default handler */
>             }
>             /* fall through */
>         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_(xim)("sending wchar %04x\n", wcOutput[i]);
> 				PostMessageW(hwnd, WM_IME_CHAR, wcOutput[i], 1);
> 			}
>             done = True;
>             break;
> 		}
> 
>         case XLookupKeySym:
>             TRACE_(xim)("XLookupKeySym\n");
>             break; /* Leave to the default handler */
> 
>         case XLookupNone:
>             TRACE_(xim)("XLookupNone\n");
>             done = True; /* No further processing is necessary */
>             break;
>         }
> 
>         HeapFree(GetProcessHeap(),0,bytes);
>     }
>     event->window = orgWindow;
>     return done;
> }
> 
955a1077,1080
> 
> 	/* forward to XIM */
>     if(XIM_KeyEvent(GetFocus(), event) && event->type == KeyPress)
>         return;
Index: dlls/x11drv/ts_xlib.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/ts_xlib.c,v
retrieving revision 1.1
diff -r1.1 ts_xlib.c
11a12
> #include <X11/Xutil.h>
672a674,689
> XFontSet  TSXCreateFontSet(Display* a0, const  char* a1, char*** a2, int* a3, char** a4)
> {
>   XFontSet  r;
>   wine_tsx11_lock();
>   r = XCreateFontSet(a0, a1, a2, a3, a4);
>   wine_tsx11_unlock();
>   return r;
> }
> 
> void  TSXFreeFontSet(Display* a0, XFontSet a1)
> {
>   wine_tsx11_lock();
>   XFreeFontSet(a0, a1);
>   wine_tsx11_unlock();
> }
> 
679a697,737
> }
> 
> int   TSXCloseIM(XIM a0)
> {
>   int   r;
>   wine_tsx11_lock();
>   r = XCloseIM(a0);
>   wine_tsx11_unlock();
>   return r;
> }
> 
> void  TSXSetICFocus(XIC a0)
> {
>   wine_tsx11_lock();
>   XSetICFocus(a0);
>   wine_tsx11_unlock();
> }
> 
> void  TSXUnsetICFocus(XIC a0)
> {
>   wine_tsx11_lock();
>   XUnsetICFocus(a0);
>   wine_tsx11_unlock();
> }
> 
> int   TSXFilterEvent(XEvent* a0, Window a1)
> {
>   int   r;
>   wine_tsx11_lock();
>   r = XFilterEvent(a0, a1);
>   wine_tsx11_unlock();
>   return r;
> }
> 
> int  TSXmbLookupString(XIC a0, XKeyPressedEvent* a1, char* a2, int a3, KeySym* a4, int * a5)
> {
>   int  r;
>   wine_tsx11_lock();
>   r = XmbLookupString(a0, a1, a2, a3, a4, a5);
>    wine_tsx11_unlock();
>    return r;
Index: dlls/x11drv/ts_xlib.h
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/ts_xlib.h,v
retrieving revision 1.1
diff -r1.1 ts_xlib.h
30a31,32
> //xim added
> //extern void  TSXFreeStringList(char**);
94a97,100
> //xim added
> extern XFontSet  TSXCreateFontSet(Display*, const  char*, char***, int*, char**);
> extern void  TSXFreeFontSet(Display*, XFontSet);
> 
95a102,107
> //xim added
> extern int   TSXCloseIM(XIM);
> extern void  TSXSetICFocus(XIC);
> extern void  TSXUnsetICFocus(XIC);
> extern int   TSXFilterEvent(XEvent*, Window);
> extern int  TSXmbLookupString(XIC, XKeyPressedEvent*, char*, int, KeySym*, int *);
Index: dlls/x11drv/window.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/window.c,v
retrieving revision 1.46
diff -r1.46 window.c
42a43,44
> #include "xim.h"
> 
43a46
> WINE_DECLARE_DEBUG_CHANNEL(xim);
52a56,58
> XContext ximContext = 0;
> 
> extern Window root_window;
98a105,118
> }
> 
> //xim added
> XIC X11DRV_GetXIC(Window w)
> {
> 
>    XIC xic = NULL;
> 
>     if (ximContext != 0 ){
> 	    wine_tsx11_lock();
>         XFindContext(thread_display(), root_window , ximContext, (XPointer *) &xic);
> 		wine_tsx11_unlock();
>     }
>     return xic;
Index: documentation/samples/config
===================================================================
RCS file: /home/wine/wine/documentation/samples/config,v
retrieving revision 1.37
diff -r1.37 config
179a180,186
> [InputMethod]
> ; Use XIM Input Method
> "UseXIM" = "Y"
> ; XIM Input Style : "overthespot" or "offthespot" or "root" (default).
> "InputStyle" = "overthespot"
> "XIMFontSet" = "-adobe-helvetica-medium-r-normal--16-*-*-*-*-*-*-*,-*-*-medium-r-normal--18-*-*-*-*-*-gb2312.1980-0,*-r-*"
> 
Index: include/winnls.h
===================================================================
RCS file: /home/wine/wine/include/winnls.h,v
retrieving revision 1.37
diff -r1.37 winnls.h
147a148,149
> //xim added
> #define LOCALE_SCHARSETNAMES 0x00001015
Index: include/x11drv.h
===================================================================
RCS file: /home/wine/wine/include/x11drv.h,v
retrieving revision 1.118
diff -r1.118 x11drv.h
101a102,105
> //xim added
> extern XIMStyle ximStyle;
> extern XFontSet ximFontSet;
> extern XIC X11DRV_GetXIC(Window w);
339a344
> 	XIM      xim;
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ dlls/x11drv/xim.h	2002-12-13 11:40:39.000000000 +0000
@@ -0,0 +1,30 @@
+/*
+ * xim.h 
+ * define some constant used in XIM
+ * 
+ * Copyright 2002  liuspider
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#if !defined(__WINE_XIM_H)
+	
+#define __WINE_XIM_H
+
+#define STYLE_OFFTHESPOT (XIMPreeditArea | XIMStatusArea)
+#define STYLE_OVERTHESPOT (XIMPreeditPosition | XIMStatusNothing)
+#define STYLE_ROOT (XIMPreeditNothing | XIMStatusNothing)
+#define STYLE_NONE (XIMPreeditNone | XIMStatusNone)
+
+#endif /* !defined(__WINE_XIM_H) */

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux