[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: XIM patch
From: |
Adam Fedor |
Subject: |
Re: XIM patch |
Date: |
Wed, 16 Jan 2002 21:20:45 -0700 |
User-agent: |
Mozilla/5.0 (X11; U; Linux ppc; en-US; rv:0.9.4) Gecko/20011009 |
Christian Gillot wrote:
Sorry to resend that patch I think the attachment wasn't in the
previous mail.
Hi,
Well, I finally did it. Here is a very first XIM implementation.
It just works for european languages (dead keys/compose).
I've been late making it because I had to learn the OpenStep API
before digging deeper GNUstep. Don't hesitate mailing me if something
is wrong in it. I just would like to stress that it's a first
incomplete implementation but it do works.
Well sorry it's been so long, but we've had to put out a few library
releases, plus I know XIM is complicated and we want to give it a good look.
First after reading about it, I realize that an input server can be
incredibly complicated (particularly for asian languages), so I agree
that we don't need to have remote servers of our own, since X already
provides them (or interfaces with them via XIM). We just need a proper
interface to XIM to exploit it.
Some things we do need however is to be able to switch the input method
(on the fly). So anyway, I've rewritten your patch to convert the XIM
functions into an encapsulated object (XIMInputServer), which at least
makes it easier to switch out the input method (perhaps to a remote
server if necessary) or change the XIM modifiers - although I haven't
actually implemented any of the code to do this.
Please look at the attached patch (which includes a few other random
changes which you can ignore) and see if it still works. I had to fix a
few bugs in process_key_codes which caused problems with the key
modifiers (command, alt, etc), but perhaps that fix broke something with
XIM. I don't know - try to test it with the GSTest app (using Keyboard
test and NSTextView test).
--
Adam Fedor, Digital Optics | I'm glad I hate spinach, because
http://www.doc.com | if I didn't, I'd eat it, and you
http://www.gnustep.org | know how I hate the stuff.
? xim2.patch
? xim.patch
? Documentation/version.texi
? Documentation/unknown.gsdocrefs
? Source/powerpc
Index: Headers/gnustep/xgps/XGContext.h
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/xgps/Headers/gnustep/xgps/XGContext.h,v
retrieving revision 1.44
diff -c -r1.44 XGContext.h
*** Headers/gnustep/xgps/XGContext.h 19 Oct 2001 03:57:18 -0000 1.44
--- Headers/gnustep/xgps/XGContext.h 17 Jan 2002 04:09:04 -0000
***************
*** 44,50 ****
#include <X11/Xlib.h>
#include <X11/Xutil.h>
! #include <SharedX/XGGeneric.h>
@class XGGState;
--- 44,50 ----
#include <X11/Xlib.h>
#include <X11/Xutil.h>
! #include <XGGeneric.h>
@class XGGState;
***************
*** 78,83 ****
--- 78,84 ----
Window grabWindow;
XGDrawMechanism drawMechanism;
struct XGGeneric generic; /* Defined in XGGeneric.h */
+ id inputServer;
}
+ (Display*) currentXDisplay;
Index: Headers/gnustep/xgps/XGContextWindow.h
===================================================================
RCS file:
/cvsroot/gnustep/gnustep/core/xgps/Headers/gnustep/xgps/XGContextWindow.h,v
retrieving revision 1.13
diff -c -r1.13 XGContextWindow.h
*** Headers/gnustep/xgps/XGContextWindow.h 17 Dec 2001 21:32:39 -0000
1.13
--- Headers/gnustep/xgps/XGContextWindow.h 17 Jan 2002 04:09:04 -0000
***************
*** 87,92 ****
--- 87,93 ----
int boff;
Atom protocols[4];
int numProtocols;
+ XIC ic;
} gswindow_device_t;
@interface XGContext (DPSWindow)
Index: Source/GNUmakefile
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/xgps/Source/GNUmakefile,v
retrieving revision 1.44
diff -c -r1.44 GNUmakefile
*** Source/GNUmakefile 3 Dec 2001 04:32:33 -0000 1.44
--- Source/GNUmakefile 17 Jan 2002 04:09:05 -0000
***************
*** 68,73 ****
--- 68,74 ----
SharedX/XGContextWindow.m \
SharedX/XGBitmapImageRep.m \
SharedX/XGDragView.m \
+ SharedX/XIMInputServer.m \
XGBitmap.m \
XGCommonFont.m \
XGFont.m \
Index: Source/GNUmakefile.postamble
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/xgps/Source/GNUmakefile.postamble,v
retrieving revision 1.15
diff -c -r1.15 GNUmakefile.postamble
*** Source/GNUmakefile.postamble 4 Dec 2001 11:08:42 -0000 1.15
--- Source/GNUmakefile.postamble 17 Jan 2002 04:09:05 -0000
***************
*** 49,60 ****
# Things to do before installing
# before-install::
- $(GNUSTEP_HEADERS)/gnustep/xgps/SharedX:
- $(MKDIRS) $(GNUSTEP_HEADERS)/gnustep/xgps/SharedX
-
# Things to do after installing
! after-install:: $(GNUSTEP_HEADERS)/gnustep/xgps/SharedX
! $(INSTALL_DATA) SharedX/XGGeneric.h
$(GNUSTEP_HEADERS)/gnustep/xgps/SharedX
# Things to do before uninstalling
# before-uninstall::
--- 49,57 ----
# Things to do before installing
# before-install::
# Things to do after installing
! after-install::
! $(INSTALL_DATA) SharedX/XGGeneric.h $(GNUSTEP_HEADERS)/gnustep/xgps
# Things to do before uninstalling
# before-uninstall::
Index: Source/XGContext.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/xgps/Source/XGContext.m,v
retrieving revision 1.88
diff -c -r1.88 XGContext.m
*** Source/XGContext.m 11 Jan 2002 10:07:54 -0000 1.88
--- Source/XGContext.m 17 Jan 2002 04:09:08 -0000
***************
*** 23,31 ****
--- 23,33 ----
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+ #include "config.h"
#include "gnustep/xgps/XGContext.h"
#include "gnustep/xgps/XGGState.h"
#include "SharedX/xrtools.h"
+ #include "SharedX/XGInputServer.h"
#include <AppKit/AppKitExceptions.h>
#include <AppKit/NSAffineTransform.h>
#include <AppKit/NSColor.h>
***************
*** 382,387 ****
--- 384,391 ----
XSetErrorHandler(XGErrorHandler);
[self _setupRootWindow];
+ inputServer = [[XIMInputServer allocWithZone: [self zone]]
+ initWithDelegate: nil display: dpy name: @"XIM"];
return self;
}
***************
*** 409,415 ****
gstack = NSZoneMalloc(z, sizeof(GSIArray_t));
GSIArrayInitWithZoneAndCapacity((GSIArray)gstack, z, 2);
ulist = [[NSMutableArray allocWithZone: z] initWithCapacity: 32];
!
// Set up font cache
fontid = [NSMutableArray arrayWithCapacity: 32];
--- 413,419 ----
gstack = NSZoneMalloc(z, sizeof(GSIArray_t));
GSIArrayInitWithZoneAndCapacity((GSIArray)gstack, z, 2);
ulist = [[NSMutableArray allocWithZone: z] initWithCapacity: 32];
!
// Set up font cache
fontid = [NSMutableArray arrayWithCapacity: 32];
***************
*** 449,454 ****
--- 453,459 ----
GSIArrayEmpty((GSIArray)gstack);
NSZoneFree([self zone], gstack);
DESTROY(ulist);
+ DESTROY(inputServer);
// FIXME: This wont work with garbage collection
AUTORELEASE(RETAIN(self));
}
Index: Source/SharedX/XGContextEvent.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/xgps/Source/SharedX/XGContextEvent.m,v
retrieving revision 1.80
diff -c -r1.80 XGContextEvent.m
*** Source/SharedX/XGContextEvent.m 9 Jan 2002 20:46:21 -0000 1.80
--- Source/SharedX/XGContextEvent.m 17 Jan 2002 04:09:17 -0000
***************
*** 22,27 ****
--- 22,30 ----
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
+ #include "config.h"
+
#include <AppKit/AppKitExceptions.h>
#include <AppKit/NSGraphics.h>
#include <AppKit/NSWindow.h>
***************
*** 45,50 ****
--- 48,54 ----
#include "gnustep/xgps/XGContextPrivate.h"
#include "XGDrawingEngine.h"
#endif
+ #include "SharedX/XGInputServer.h"
#include "SharedX/XGDragView.h"
#include "SharedX/XGGeneric.h"
#include "SharedX/xrtools.h"
***************
*** 251,258 ****
// loop and grab all of the events from the X queue
while (count-- > 0)
{
- //NSDebugLLog(@"NSEvent", @"Get next XWindows event\n");
XNextEvent(XDPY, &xEvent);
switch (xEvent.type)
{
// mouse button events
--- 255,270 ----
// loop and grab all of the events from the X queue
while (count-- > 0)
{
XNextEvent(XDPY, &xEvent);
+
+ #ifdef USE_XIM
+ if (XFilterEvent(&xEvent, None))
+ {
+ NSDebugLLog(@"NSKeyEvent", @"Event filtered (by XIM?)\n");
+ continue;
+ }
+ #endif
+
switch (xEvent.type)
{
// mouse button events
***************
*** 1045,1051 ****
break;
case MotionNotify:
! NSDebugLLog(@"NSEvent", @"%d MotionNotify - %d %d\n",
xEvent.xmotion.window, xEvent.xmotion.x, xEvent.xmotion.y);
{
unsigned int state;
--- 1057,1063 ----
break;
case MotionNotify:
! NSDebugLLog(@"NSMotionEvent", @"%d MotionNotify - %d %d\n",
xEvent.xmotion.window, xEvent.xmotion.x, xEvent.xmotion.y);
{
unsigned int state;
***************
*** 1306,1314 ****
static NSEvent*
process_key_event (XEvent* xEvent, XGContext* context, NSEventType eventType)
{
- char buf[256];
- int count;
- XComposeStatus compose;
NSString *keys, *ukeys;
KeySym keysym;
NSPoint eventLocation;
--- 1318,1323 ----
***************
*** 1320,1331 ****
int control_key = 0;
int command_key = 0;
int alt_key = 0;
- 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])
--- 1329,1351 ----
int control_key = 0;
int command_key = 0;
int alt_key = 0;
+ Display *display = [XGContext currentXDisplay];
if (_is_keyboard_initialized == NO)
initialize_keyboard ();
+ /* 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;
+ }
+
/* Process NSFlagsChanged events. We can't use a switch because we
are not comparing to constants. */
if (xEvent->xkey.keycode == _control_keycodes[0])
***************
*** 1375,1406 ****
_alt_pressed &= ~alt_key;
}
}
!
/* 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))
eventFlags = eventFlags | NSNumericPadKeyMask;
--- 1395,1417 ----
_alt_pressed &= ~alt_key;
}
}
!
/* Process modifiers */
eventFlags = process_modifier_flags (xEvent->xkey.state);
! /* Process characters */
! keys = [context->inputServer lookupStringForEvent: (XKeyEvent *)xEvent
! window: window
! keysym: &keysym];
!
/* Process keycode */
keyCode = ((XKeyEvent *)xEvent)->keycode;
! //keyCode = XKeysymToKeycode(display,keysym);
+ NSDebugLLog (@"NSKeyEvent",
+ @"keysym=%d, keyCode=%d originalkeyCode=%d flags=%d",
+ keysym, keyCode, ((XKeyEvent *)xEvent)->keycode, eventFlags);
+
/* Add NSNumericPadKeyMask if the key is in the KeyPad */
if (IsKeypadKey (keysym))
eventFlags = eventFlags | NSNumericPadKeyMask;
***************
*** 1412,1438 ****
/* if (IsFunctionKey (keysym) || IsMiscFunctionKey (keysym))
eventFlags = eventFlags | NSFunctionKeyMask; */
- // Make sure that the string is properly terminated
- if (count > 255)
- buf[255] = '\0';
- else
- {
- if (count < 1)
- buf[0] = '\0';
- else
- buf[count] = '\0';
- }
-
/* Now we get the unicode character for the pressed key using
our internal table */
unicode = process_char (keysym, &eventFlags);
/* If that didn't work, we use what X gave us */
! if (unicode == 0)
! {
! keys = [NSString stringWithCString: buf];
! }
! else
{
keys = [NSString stringWithCharacters: &unicode length: 1];
}
--- 1423,1434 ----
/* if (IsFunctionKey (keysym) || IsMiscFunctionKey (keysym))
eventFlags = eventFlags | NSFunctionKeyMask; */
/* Now we get the unicode character for the pressed key using
our internal table */
unicode = process_char (keysym, &eventFlags);
/* If that didn't work, we use what X gave us */
! if (unicode != 0)
{
keys = [NSString stringWithCharacters: &unicode length: 1];
}
***************
*** 1440,1470 ****
// Now the same ignoring modifiers, except Shift, ShiftLock, NumLock.
xEvent->xkey.state = (xEvent->xkey.state & (ShiftMask | LockMask
| _num_lock_mask));
! count = XLookupString ((XKeyEvent *)xEvent, buf, 256, &keysym, &compose);
!
! // Make sure that the string is properly terminated
! if (count > 255)
! buf[255] = '\0';
! else
! {
! if (count < 1)
! buf[0] = '\0';
! else
! buf[count] = '\0';
! }
!
unicode = process_char (keysym, &eventFlags);
!
! if (unicode == 0)
! {
! ukeys = [NSString stringWithCString: buf];
! }
! else
{
ukeys = [NSString stringWithCharacters: &unicode length: 1];
}
! if (unicode == 0 && *buf == '\0'
&& context->generic.lastKeyFlags != eventFlags)
{
eventType = NSFlagsChanged;
--- 1436,1451 ----
// Now the same ignoring modifiers, except Shift, ShiftLock, NumLock.
xEvent->xkey.state = (xEvent->xkey.state & (ShiftMask | LockMask
| _num_lock_mask));
! ukeys = [context->inputServer lookupStringForEvent: (XKeyEvent *)xEvent
! window: window
! keysym: &keysym];
unicode = process_char (keysym, &eventFlags);
! if (unicode != 0)
{
ukeys = [NSString stringWithCharacters: &unicode length: 1];
}
! if (unicode == 0 && [ukeys length] == 0
&& context->generic.lastKeyFlags != eventFlags)
{
eventType = NSFlagsChanged;
***************
*** 1728,1731 ****
}
@end
-
--- 1709,1711 ----
Index: Source/SharedX/XGContextWindow.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/xgps/Source/SharedX/XGContextWindow.m,v
retrieving revision 1.92
diff -c -r1.92 XGContextWindow.m
*** Source/SharedX/XGContextWindow.m 9 Jan 2002 20:46:21 -0000 1.92
--- Source/SharedX/XGContextWindow.m 17 Jan 2002 04:09:24 -0000
***************
*** 22,27 ****
--- 22,28 ----
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+ #include "config.h"
#include <math.h>
#include <Foundation/NSString.h>
#include <Foundation/NSArray.h>
***************
*** 29,34 ****
--- 30,36 ----
#include <AppKit/NSGraphics.h>
#include "SharedX/XGDragView.h"
+ #include "SharedX/XGInputServer.h"
#ifdef XDPS_BACKEND_LIBRARY
#define XGContext NSDPSContext
***************
*** 1015,1020 ****
--- 1017,1023 ----
window->region = XCreateRegion();
window->buffer = 0;
window->alpha_buffer = 0;
+ window->ic = 0;
// make sure that new window has the correct cursor
[self _initializeCursorForXWindow: window->ident];
***************
*** 1047,1052 ****
--- 1050,1059 ----
return;
NSDebugLLog(@"XGTrace", @"DPSwindow: %d", num);
+ if (window->ic)
+ {
+ [inputServer ximCloseIC: window->ic];
+ }
if (window->ident)
{
XDestroyWindow(XDPY, window->ident);
***************
*** 2087,2092 ****
--- 2094,2100 ----
generic.desiredFocusWindow = win;
generic.focusRequestNumber = XNextRequest(XDPY);
XSetInputFocus(XDPY, window->ident, RevertToParent, generic.lastTime);
+ [inputServer ximFocusICWindow: window];
}
/*
Index: Source/SharedX/XGInputServer.h
===================================================================
RCS file: Source/SharedX/XGInputServer.h
diff -N Source/SharedX/XGInputServer.h
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- Source/SharedX/XGInputServer.h 17 Jan 2002 04:09:27 -0000
***************
*** 0 ****
--- 1,55 ----
+ /* XGInputServer - Keyboard input handling
+
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+ Author: Adam Fedor <fedor@gnu.org>
+ Date: January 2002
+
+ This file is part of the GNUstep GUI 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; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+ #ifndef _GNUstep_H_XGInputServer
+ #define _GNUstep_H_XGInputServer
+
+ #include <AppKit/NSInputServer.h>
+ #include "gnustep/xgps/XGContextWindow.h"
+
+ @protocol XInputFiltering
+ - (BOOL) filterEvent: (XEvent *)event;
+ - (NSString *) lookupStringForEvent: (XKeyEvent *)event
+ window: (gswindow_device_t *)window
+ keysym: (KeySym *)keysymptr;
+ @end
+
+
+ @interface XIMInputServer: NSInputServer <XInputFiltering>
+ {
+ id delegate;
+ NSString *server_name;
+ XIM xim;
+ XIMStyle xim_style;
+ }
+
+ - (id) initWithDelegate: (id)aDelegate
+ display: (Display *)dpy
+ name: (NSString *)name;
+ - (void) ximFocusICWindow: (gswindow_device_t *)windev;
+ - (void) ximCloseIC: (XIC)xic;
+ @end
+
+ #endif
Index: Source/SharedX/XIMInputServer.m
===================================================================
RCS file: Source/SharedX/XIMInputServer.m
diff -N Source/SharedX/XIMInputServer.m
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- Source/SharedX/XIMInputServer.m 17 Jan 2002 04:09:27 -0000
***************
*** 0 ****
--- 1,288 ----
+ /* XIMInputServer - XIM Keyboard input handling
+
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+ Author: Christian Gillot <cgillot@neo-rousseaux.org>
+ Date: Nov 2001
+ Author: Adam Fedor <fedor@gnu.org>
+ Date: Jan 2002
+
+ This file is part of the GNUstep GUI 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; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+ #include "config.h"
+ #include "XGInputServer.h"
+
+ @interface XIMInputServer (XIMPrivate)
+ - (BOOL) ximInit: (Display *)dpy;
+ - (void) ximClose;
+ - (int) ximStyleInit;
+ - (XIC) ximCreateIC: (Window)w;
+ - (unsigned long) ximXicGetMask: (XIC)xic;
+ @end
+
+ @implementation XIMInputServer
+
+ - (id) initWithDelegate: (id)aDelegate
+ name: (NSString *)name
+ {
+ Display *dpy = [XGContext currentXDisplay];
+ return [self initWithDelegate: aDelegate display: dpy name: name];
+ }
+
+ - (id) initWithDelegate: (id)aDelegate
+ display: (Display *)dpy
+ name: (NSString *)name
+ {
+ delegate = aDelegate;
+ ASSIGN(server_name, name);
+
+ #if USE_XIM
+ if ([self ximInit: dpy] == NO)
+ {
+ NSLog(@"Error occured while initializing XIM");
+ [self dealloc];
+ return nil;
+ }
+ #endif
+ return self;
+ }
+
+ - (void) dealloc
+ {
+ DESTROY(server_name);
+ [self ximClose];
+ }
+
+ /* ----------------------------------------------------------------------
+ XInputFiltering protocol methods
+ */
+ - (BOOL) filterEvent: (XEvent *)event
+ {
+ if (XFilterEvent(event, None))
+ {
+ NSDebugLLog(@"NSKeyEvent", @"Event filtered by XIM\n");
+ return YES;
+ }
+ return NO;
+ }
+
+ #define BUF_LEN 255
+
+ - (NSString *) lookupStringForEvent: (XKeyEvent *)event
+ window: (gswindow_device_t *)windev
+ keysym: (KeySym *)keysymptr
+ {
+ int count;
+ Status status;
+ NSString *keys;
+ KeySym keysym;
+ XComposeStatus compose;
+ char buf[BUF_LEN+1];
+
+ /* Process characters */
+ if (windev->ic)
+ {
+ count = XmbLookupString(windev->ic, event, buf, BUF_LEN,
+ &keysym, &status);
+ // FIXME: code this
+ if (status==XBufferOverflow)
+ NSDebugLLog(@"NSKeyEvent",@"XmbLookupString buffer overflow\n");
+ }
+ else
+ {
+ count = XLookupString (event, buf, BUF_LEN, &keysym, &compose);
+ }
+
+ // Make sure that the string is properly terminated
+ if (count > BUF_LEN)
+ buf[BUF_LEN] = '\0';
+ else
+ {
+ if (count < 1)
+ buf[0] = '\0';
+ else
+ buf[count] = '\0';
+ }
+ keys = [NSString stringWithCString: buf];
+
+ if (keysymptr)
+ *keysymptr = keysym;
+
+ return keys;
+ }
+
+ /* ----------------------------------------------------------------------
+ NSInputServiceProvider protocol methods
+ */
+ - (void) activeConversationChanged: (id)sender
+ toNewConversation: (long)newConversation
+ {
+ NSWindow *window;
+ gswindow_device_t *windev;
+
+ [super activeConversationChanged: sender
+ toNewConversation: newConversation];
+
+ if ([sender respondsToSelector: @selector(window)] == NO)
+ {
+ [NSException raise: NSInvalidArgumentException
+ format: @"NSTextInput sender does not respond to window"];
+ }
+ window = [sender window];
+ windev = [XGContext _windowWithTag: [window windowNumber]];
+ if (windev == NULL)
+ {
+ [NSException raise: NSInvalidArgumentException
+ format: @"NSTextInput sender has invalid window"];
+ }
+
+ [self ximFocusICWindow: windev];
+ }
+
+ - (void) activeConversationWillChange: (id)sender
+ fromOldConversation: (long)oldConversation
+ {
+ [super activeConversationWillChange: sender
+ fromOldConversation: oldConversation];
+ }
+
+ /* ----------------------------------------------------------------------
+ XIM private methods
+ */
+ - (BOOL) ximInit: (Display *)dpy
+ {
+ XClassHint class_hints;
+
+ if (!XSupportsLocale ())
+ {
+ NSDebugLLog(@"XIM", @"locale not supported by Xlib\n");
+ /* FIXME: Should we reset the locale or just hope that X
+ can deal with it? */
+ //setlocale (LC_ALL, "C");
+ }
+
+ if (!XSetLocaleModifiers (""))
+ NSDebugLLog(@"XIM", @"can not set locale modifiers\n");
+
+ /* FIXME: Get these */
+ class_hints.res_name = class_hints.res_class = NULL;
+ xim = XOpenIM(dpy, NULL, class_hints.res_name, class_hints.res_class);
+ if (xim == NULL)
+ {
+ NSDebugLLog(@"XIM", @"Can't open XIM.\n");
+ return NO;
+ }
+
+ if (![self ximStyleInit])
+ {
+ [self ximClose];
+ return NO;
+ }
+
+ NSDebugLLog(@"XIM", @"Initialized XIM\n");
+ return YES;
+ }
+
+ - (int) ximStyleInit
+ {
+ /* 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)
+ {
+ NSDebugLLog(@"XIM", @"Can't getting the following IM value :%s",
+ failed_arg);
+ return 0;
+ }
+
+ for (i=0;i<styles->count_styles;i++)
+ {
+ if (styles->supported_styles[i]==xim_supported_style)
+ {
+ xim_style=xim_supported_style;
+ XFree(styles);
+ return 1;
+ }
+ }
+
+ XFree(styles);
+ return 0;
+ }
+
+ - (void) ximClose
+ {
+ NSDebugLLog(@"XIM", @"Closed XIM\n");
+ if (xim)
+ XCloseIM(xim);
+ xim=NULL;
+ }
+
+ - (void) ximFocusICWindow: (gswindow_device_t *)windev
+ {
+ /* Make sure we have an ic for this window */
+ #if USE_XIM
+ if (windev->ic == NULL)
+ {
+ windev->ic = [self ximCreateIC: windev->ident];
+ if (windev->ic == NULL)
+ {
+ [self ximClose];
+ }
+ }
+ #endif
+
+ /* Now set focus to this window */
+ if (windev->ic)
+ {
+ NSDebugLLog(@"XIM", @"XSetICFocus to window %p",
+ windev->ident);
+ XSetICFocus(windev->ic);
+ }
+ }
+
+ - (XIC) ximCreateIC: (Window)w
+ {
+ XIC xic;
+ xic = XCreateIC(xim, XNClientWindow, w, XNInputStyle,
+ xim_style, XNFocusWindow, w, NULL);
+ if (xic==NULL)
+ NSDebugLLog(@"XIM", @"Can't create the input context.\n");
+ return xic;
+ }
+
+ - (unsigned long) ximXicGetMask: (XIC)xic
+ {
+ unsigned long xic_xmask = 0;
+ if (XGetICValues(xic,XNFilterEvents,&xic_xmask,NULL)!=NULL)
+ NSDebugLLog(@"XIM", @"Can't get the event mask for that input context");
+
+ return xic_xmask;
+ }
+
+ - (void) ximCloseIC: (XIC)xic
+ {
+ XDestroyIC(xic);
+ }
+
+ @end
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: XIM patch,
Adam Fedor <=