diff -r -N -u gnustep-cvs/core/xgps/Headers/gnustep/xgps/XGContextWindow.h gnustep/core/xgps/Headers/gnustep/xgps/XGContextWindow.h --- gnustep-cvs/core/xgps/Headers/gnustep/xgps/XGContextWindow.h Fri Dec 21 14:16:55 2001 +++ gnustep/core/xgps/Headers/gnustep/xgps/XGContextWindow.h Thu Dec 20 00:18:47 2001 @@ -87,6 +87,9 @@ int boff; Atom protocols[4]; int numProtocols; +#ifdef USE_XIM + XIC ic; +#endif } gswindow_device_t; @interface XGContext (DPSWindow) diff -r -N -u gnustep-cvs/core/xgps/Source/GNUmakefile gnustep/core/xgps/Source/GNUmakefile --- gnustep-cvs/core/xgps/Source/GNUmakefile Fri Dec 21 14:16:56 2001 +++ gnustep/core/xgps/Source/GNUmakefile Thu Dec 20 01:03:49 2001 @@ -58,6 +58,7 @@ SharedX/raster.c \ SharedX/scale.c \ SharedX/xdnd.c \ +SharedX/xim.c \ SharedX/xutil.c \ SharedX/xrtools.c endif diff -r -N -u gnustep-cvs/core/xgps/Source/GNUmakefile.preamble gnustep/core/xgps/Source/GNUmakefile.preamble --- gnustep-cvs/core/xgps/Source/GNUmakefile.preamble Fri Dec 21 14:16:56 2001 +++ gnustep/core/xgps/Source/GNUmakefile.preamble Thu Dec 20 01:04:10 2001 @@ -49,10 +49,10 @@ $(CONFIG_SYSTEM_DEFS) # Additional flags to pass to the Objective-C compiler -ADDITIONAL_OBJCFLAGS = +ADDITIONAL_OBJCFLAGS = -DUSE_XIM # Additional flags to pass to the C compiler -ADDITIONAL_CFLAGS = +ADDITIONAL_CFLAGS = -DUSE_XIM # Additional include directories the compiler should search ADDITIONAL_INCLUDE_DIRS = -I../Headers \ diff -r -N -u gnustep-cvs/core/xgps/Source/SharedX/XGContextEvent.m gnustep/core/xgps/Source/SharedX/XGContextEvent.m --- gnustep-cvs/core/xgps/Source/SharedX/XGContextEvent.m Fri Dec 21 14:16:55 2001 +++ gnustep/core/xgps/Source/SharedX/XGContextEvent.m Fri Dec 21 14:28:52 2001 @@ -50,6 +50,10 @@ #include "SharedX/xrtools.h" #include "SharedX/xdnd.h" +#ifdef USE_XIM +#include "SharedX/xim.h" +#endif + #include "math.h" #include #include @@ -252,6 +256,15 @@ { //NSDebugLLog(@"NSEvent", @"Get next XWindows event\n"); XNextEvent(XDPY, &xEvent); + +#ifdef USE_XIM + if (XFilterEvent(&xEvent,xEvent.xkey.window)) + { + NSDebugLLog(@"NSEventI", @"Event filtered by XIM\n"); + continue; + } +#endif + switch (xEvent.type) { // mouse button events @@ -1319,37 +1332,88 @@ int control_key = 0; int command_key = 0; int alt_key = 0; +#ifdef USE_XIM + int buf_len = 255; + Status status; +#endif + Display *display = [XGContext currentXDisplay]; NSDebugLog(@"Process key event"); if (_is_keyboard_initialized == NO) initialize_keyboard (); - /* Process NSFlagsChanged events. We can't use a switch because we - are not comparing to constants. */ - if (xEvent->xkey.keycode == _control_keycodes[0]) - { - control_key = 1; - } - else if (xEvent->xkey.keycode == _control_keycodes[1]) - { - control_key = 2; - } - else if (xEvent->xkey.keycode == _command_keycodes[0]) + /* Process location */ + window = [XGContext _windowWithTag: [[NSApp keyWindow] windowNumber]]; + eventLocation.x = xEvent->xbutton.x; + if (window) { - command_key = 1; + eventLocation.y = window->siz_hints.height - xEvent->xbutton.y; } - else if (xEvent->xkey.keycode == _command_keycodes[1]) + else { - command_key = 2; + eventLocation.y = xEvent->xbutton.y; } - else if (xEvent->xkey.keycode == _alt_keycodes[0]) + + /* Process characters */ +#ifdef USE_XIM + if (window->ic) { - alt_key = 1; + count = XmbLookupString(window->ic, (XKeyEvent *)xEvent, + buf, buf_len, &keysym, &status); + // FIXME: code this + if (status==XBufferOverflow) + NSDebugLLog(@"NSEvent",@"XmbLookupString buffer overflow\n"); + /* Process keycode */ + keyCode = XKeysymToKeycode(display,keyCode); + } + else + { + count = XLookupString ((XKeyEvent *)xEvent, buf, 256, &keysym, &compose); + /* Process keycode */ + keyCode = XKeysymToKeycode(display,keyCode); } - else if (xEvent->xkey.keycode == _alt_keycodes[1]) +#else + count = XLookupString ((XKeyEvent *)xEvent, buf, 256, &keysym, &compose); + /* Process keycode */ + keyCode = XKeysymToKeycode(display,keyCode); +#endif + + + NSDebugLog (@"keysym=%d, xLocation = (%d, %d), userLocation = (%f, %f)", + keysym, xEvent->xbutton.x, xEvent->xbutton.y, + eventLocation.x, eventLocation.y); + + /* Process NSFlagsChanged events. We can't use a switch because we + are not comparing to constants. */ + // the keyCode is 0 if the input is the result of + // an input method + if (keyCode) { - alt_key = 2; + if (keyCode == _control_keycodes[0]) + { + control_key = 1; + } + else if (keyCode == _control_keycodes[1]) + { + control_key = 2; + } + else if (keyCode == _command_keycodes[0]) + { + command_key = 1; + } + else if (keyCode == _command_keycodes[1]) + { + command_key = 2; + } + else if (keyCode == _alt_keycodes[0]) + { + alt_key = 1; + } + else if (keyCode == _alt_keycodes[1]) + { + alt_key = 2; + } } if (control_key || command_key || alt_key) @@ -1378,27 +1442,6 @@ /* Process modifiers */ eventFlags = process_modifier_flags (xEvent->xkey.state); - /* Process location */ - window = [XGContext _windowWithTag: [[NSApp keyWindow] windowNumber]]; - eventLocation.x = xEvent->xbutton.x; - if (window) - { - eventLocation.y = window->siz_hints.height - xEvent->xbutton.y; - } - else - { - eventLocation.y = xEvent->xbutton.y; - } - - NSDebugLog (@"keysym=%d, xLocation = (%d, %d), userLocation = (%f, %f)", - keysym, xEvent->xbutton.x, xEvent->xbutton.y, - eventLocation.x, eventLocation.y); - - /* Process keycode */ - keyCode = ((XKeyEvent *)xEvent)->keycode; - - /* Process characters */ - count = XLookupString ((XKeyEvent *)xEvent, buf, 256, &keysym, &compose); /* Add NSNumericPadKeyMask if the key is in the KeyPad */ if (IsKeypadKey (keysym)) @@ -1439,7 +1482,20 @@ // Now the same ignoring modifiers, except Shift, ShiftLock, NumLock. xEvent->xkey.state = (xEvent->xkey.state & (ShiftMask | LockMask | _num_lock_mask)); +#ifdef USE_XIM + if (window->ic) + { + count = XmbLookupString(window->ic, (XKeyEvent *)xEvent, + buf, buf_len, &keysym, &status); + // FIXME: code this + if (status==XBufferOverflow) + NSDebugLLog(@"NSEvent",@"XmbLookupString buffer overflow\n"); + } + else + count = XLookupString ((XKeyEvent *)xEvent, buf, 256, &keysym, &compose); +#else count = XLookupString ((XKeyEvent *)xEvent, buf, 256, &keysym, &compose); +#endif // Make sure that the string is properly terminated if (count > 255) @@ -1727,4 +1783,3 @@ } @end - diff -r -N -u gnustep-cvs/core/xgps/Source/SharedX/XGContextWindow.m gnustep/core/xgps/Source/SharedX/XGContextWindow.m --- gnustep-cvs/core/xgps/Source/SharedX/XGContextWindow.m Fri Dec 21 14:16:55 2001 +++ gnustep/core/xgps/Source/SharedX/XGContextWindow.m Fri Dec 21 14:36:07 2001 @@ -41,6 +41,10 @@ #endif #include +#ifdef USE_XIM +#include "SharedX/xim.h" +#endif + #define MAX_SCREENS 100 #define XDPY (((RContext *)context)->dpy) #define XDRW (((RContext *)context)->drawable) @@ -564,6 +568,7 @@ window->xframe = NSMakeRect(x, y, width, height); NSMapInsert (windowtags, (void*)window->number, window); NSMapInsert (windowmaps, (void*)window->ident, window); + return window; } @@ -1036,6 +1041,17 @@ // Insert window into the mapping NSMapInsert(windowmaps, (void*)window->ident, window); NSMapInsert(windowtags, (void*)window->number, window); + +#ifdef USE_XIM + // Create the input context, if it fails + // we'll use the bare X input process + window->ic = xim_create_ic(XDPY,window->ident); + + if (window->ic==NULL) + { + xim_close(); + } +#endif } - (void) DPStermwindow: (int)num @@ -2052,6 +2068,10 @@ generic.desiredFocusWindow = win; generic.focusRequestNumber = XNextRequest(XDPY); XSetInputFocus(XDPY, window->ident, RevertToParent, generic.lastTime); +#ifdef USE_XIM + NSDebugLLog(@"NSEventI", @"XSetICFocus"); + XSetICFocus(window->ic); +#endif } /* diff -r -N -u gnustep-cvs/core/xgps/Source/SharedX/xim.c gnustep/core/xgps/Source/SharedX/xim.c --- gnustep-cvs/core/xgps/Source/SharedX/xim.c Thu Jan 1 01:00:00 1970 +++ gnustep/core/xgps/Source/SharedX/xim.c Fri Dec 21 14:42:38 2001 @@ -0,0 +1,153 @@ +/* + xim - X Input Method code for i18n input code for X11 backends. + + Copyright (C) 2001 Free Software Foundation, Inc. + + Written by: Christian Gillot + Date: Nov 2001 + + This file is part of the GNU Objective C User Interface Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifdef USE_XIM + +#include +#include + +#include + +// #define XIM_DEBUG +#define xim_version_at_least(a,b) ((a) <= (b)) + +#ifdef XIM_DEBUG +#define xim_debug(a,b...) printf("%s: %d: " a "\n", __FILE__, __LINE__ , ## b) +#else + +#ifdef NeXT_RUNTIME +#define xim_debug // +#else /* !NeXT_RUNTIME */ +#define xim_debug(a,b...) +#endif /* NeXT_RUNTIME */ + +#endif + + +#include "xim.h" + +static XIM xim; +static XIMStyle xim_style; +/* For the only style supported we can only use a global +context but this is temporary as we'll need to create one +per text entry */ +XIC global_xic=NULL; + +int xim_init(Display *dpy) +{ + char *current_locale; + int i=0; + + if (!setlocale (LC_ALL,"")) + xim_debug("locale not supported by C library"); + + if (!XSupportsLocale ()) + { + xim_debug("locale not supported by Xlib, locale set to C\n"); + setlocale (LC_ALL, "C"); + } + + if (!XSetLocaleModifiers ("")) + xim_debug("can not set locale modifiers\n"); + + current_locale = setlocale (LC_ALL, NULL); + + xim = XOpenIM(dpy,NULL,NULL,NULL); + if (xim == NULL) { + xim_debug("Can't open XIM.\n"); + return 0; + } + + if (!style_init()) + { + xim_close(); + return 0; + } + + return 1; +} + +static int style_init() +{ + /* FIXME: Right now we only support this style *but* + this is only temporary */ + XIMStyle xim_supported_style=XIMPreeditNothing|XIMStatusNothing; + XIMStyles *styles; + char *failed_arg; + int i; + + failed_arg = XGetIMValues(xim,XNQueryInputStyle,&styles,NULL); + if (failed_arg!=NULL) + { + xnd_debug("Can't getting the following IM value :%s",failed_arg); + return 0; + } + + for (i=0;icount_styles;i++) + { + if (styles->supported_styles[i]==xim_supported_style) + { + xim_style=xim_supported_style; + XFree(styles); + return 1; + } + } + + + + XFree(styles); + return 0; +} + +void xim_close() +{ + if (xim) + XCloseIM(xim); + xim=NULL; +} + +XIC xim_create_ic(Display *dpy, Window w) +{ + XIC xic; + xic = XCreateIC(xim,XNClientWindow,w,XNInputStyle,xim_style,XNFocusWindow, w,NULL); + if (xic==NULL) + xim_debug("Can't create the input context.\n"); + return xic; +} + +unsigned long xim_xic_get_mask(XIC xic) +{ + unsigned long xic_xmask = 0; + if (XGetICValues(xic,XNFilterEvents,&xic_xmask,NULL)!=NULL) + xim_debug("Can't get the event mask for that input context"); + + return xic_xmask; +} + +void xim_close_ic(XIC xic) +{ + XDestroyIC(xic); +} + +#endif diff -r -N -u gnustep-cvs/core/xgps/Source/SharedX/xim.h gnustep/core/xgps/Source/SharedX/xim.h --- gnustep-cvs/core/xgps/Source/SharedX/xim.h Thu Jan 1 01:00:00 1970 +++ gnustep/core/xgps/Source/SharedX/xim.h Fri Nov 30 09:37:34 2001 @@ -0,0 +1,13 @@ +#ifndef __XIM_H__ +#define __XIM_H__ + +#include + +int xim_init(Display *dpy); +static int style_init(); +void xim_close(); +XIC xim_create_ic(Display *dpy, Window w); +unsigned long xim_xic_get_mask(XIC xic); +void xim_close_ic(XIC xic); + +#endif diff -r -N -u gnustep-cvs/core/xgps/Source/XGContext.m gnustep/core/xgps/Source/XGContext.m --- gnustep-cvs/core/xgps/Source/XGContext.m Fri Dec 21 14:16:56 2001 +++ gnustep/core/xgps/Source/XGContext.m Thu Dec 20 01:07:02 2001 @@ -47,6 +47,10 @@ #include #include +#ifdef USE_XIM +#include "SharedX/xim.h" +extern XIC global_xic; +#endif #define GSI_ARRAY_TYPES GSUNION_OBJ @@ -313,6 +317,11 @@ XSetErrorHandler(XGErrorHandler); +#ifdef USE_XIM + // XIM initialization + xim_init(dpy); +#endif + [self _setupRootWindow]; return self; } @@ -386,6 +395,9 @@ } else { +#ifdef USE_XIM + xim_close(); +#endif XCloseDisplay(XDPY); [super dealloc]; }