summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Pendleton <bob@pendleton.com>2008-03-07 20:54:11 +0000
committerBob Pendleton <bob@pendleton.com>2008-03-07 20:54:11 +0000
commit508ef6f863e36fc9c757e08837d0f493cfec8f4f (patch)
tree64103d6374e6eb90f1a1e6961165fc3dad3dc20e
parentc88c1fa6867359d0ef1d86b1cdbdd4b3badd66a5 (diff)
downloadsdl-508ef6f863e36fc9c757e08837d0f493cfec8f4f.tar.gz
Next version of internationalized input for X11. On my machine (famous last words :-) with a US English keyboard and locale I can compose ` and e and get a text
input event with the character ?. You still get the keypress keyrelease events for the individual keys that go into composing the character.
-rw-r--r--src/video/x11/SDL_x11dyn.c5
-rw-r--r--src/video/x11/SDL_x11dyn.h3
-rw-r--r--src/video/x11/SDL_x11events.c23
-rw-r--r--src/video/x11/SDL_x11sym.h1
-rw-r--r--src/video/x11/SDL_x11window.c30
5 files changed, 49 insertions, 13 deletions
diff --git a/src/video/x11/SDL_x11dyn.c b/src/video/x11/SDL_x11dyn.c
index 0bc668813..0fa037506 100644
--- a/src/video/x11/SDL_x11dyn.c
+++ b/src/video/x11/SDL_x11dyn.c
@@ -98,6 +98,7 @@ X11_GetSym(const char *fnname, int *rc, void **fn)
/* Annoying varargs entry point... */
#ifdef X_HAVE_UTF8_STRING
XIC(*pXCreateIC) (XIM,...) = NULL;
+char *(*pXGetICValues) (XIC, ...) = NULL;
#endif
/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
@@ -128,6 +129,7 @@ SDL_X11_UnloadSymbols(void)
#ifdef X_HAVE_UTF8_STRING
pXCreateIC = NULL;
+ pXGetICValues = NULL;
#endif
for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
@@ -165,6 +167,8 @@ SDL_X11_LoadSymbols(void)
#ifdef X_HAVE_UTF8_STRING
X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8, (void **) &pXCreateIC);
+ X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8,
+ (void **) &pXGetICValues);
#endif
if (SDL_X11_HAVE_BASEXLIB) {
@@ -179,6 +183,7 @@ SDL_X11_LoadSymbols(void)
#else
#ifdef X_HAVE_UTF8_STRING
pXCreateIC = XCreateIC;
+ pXGetICValues = XGetICValues;
#endif
#endif
diff --git a/src/video/x11/SDL_x11dyn.h b/src/video/x11/SDL_x11dyn.h
index 31d312f35..fc99073d0 100644
--- a/src/video/x11/SDL_x11dyn.h
+++ b/src/video/x11/SDL_x11dyn.h
@@ -68,9 +68,10 @@ extern "C"
int SDL_X11_LoadSymbols(void);
void SDL_X11_UnloadSymbols(void);
-/* That's really annoying...make this a function pointer no matter what. */
+/* That's really annoying...make these function pointers no matter what. */
#ifdef X_HAVE_UTF8_STRING
extern XIC(*pXCreateIC) (XIM, ...);
+ extern char *(*pXGetICValues) (XIC, ...);
#endif
/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c
index eddeee5d7..882482ce1 100644
--- a/src/video/x11/SDL_x11events.c
+++ b/src/video/x11/SDL_x11events.c
@@ -1,3 +1,4 @@
+#define DEBUG_XEVENTS
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
@@ -40,6 +41,15 @@ X11_DispatchEvent(_THIS)
SDL_zero(xevent); /* valgrind fix. --ryan. */
XNextEvent(videodata->display, &xevent);
+ /* filter events catchs XIM events and sends them to the correct
+ handler */
+ if (XFilterEvent(&xevent, None) == True) {
+#ifdef DEBUG_XEVENTS
+ printf("Filtered event of type = 0x%X\n", xevent.type);
+#endif
+ return;
+ }
+
/* Send a SDL_SYSWMEVENT if the application wants them */
if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
SDL_SysWMmsg wmmsg;
@@ -182,14 +192,14 @@ X11_DispatchEvent(_THIS)
KeyCode keycode = xevent.xkey.keycode;
KeySym keysym = NoSymbol;
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
- Uint32 ucs4 = 0;
+ Status status = 0;
#ifdef DEBUG_XEVENTS
printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
#endif
SDL_SendKeyboardKey(videodata->keyboard, SDL_PRESSED,
videodata->key_layout[keycode]);
-#if 1
+#if 0
if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
int min_keycode, max_keycode;
XDisplayKeycodes(videodata->display, &min_keycode,
@@ -201,9 +211,16 @@ X11_DispatchEvent(_THIS)
XKeysymToString(keysym));
}
#endif
- /* Xutf8LookupString(), works for Latin-1 */
+ /* */
SDL_zero(text);
+#ifdef X_HAVE_UTF8_STRING
+ if (data->ic) {
+ Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text),
+ &keysym, status);
+ }
+#else
XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
+#endif
if (*text) {
printf("Sending text event %s\n", text);
SDL_SendKeyboardText(videodata->keyboard, text);
diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h
index 45aaec885..be881ab18 100644
--- a/src/video/x11/SDL_x11sym.h
+++ b/src/video/x11/SDL_x11sym.h
@@ -156,6 +156,7 @@ SDL_X11_SYM(int,Xutf8TextListToTextProperty,(Display* a,char** b,int c,XICCEncod
SDL_X11_SYM(int,Xutf8LookupString,(XIC a,XKeyPressedEvent* b,char* c,int d,KeySym* e,Status* f),(a,b,c,d,e,f),return)
/*SDL_X11_SYM(XIC,XCreateIC,(XIM, ...),return) !!! ARGH! */
SDL_X11_SYM(void,XDestroyIC,(XIC a),(a),)
+/*SDL_X11_SYM(char*,XGetICValues,(XIC, ...),return) !!! ARGH! */
SDL_X11_SYM(void,XSetICFocus,(XIC a),(a),)
SDL_X11_SYM(void,XUnsetICFocus,(XIC a),(a),)
SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d),(a,b,c,d),return)
diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c
index 50f4b9645..9de82581c 100644
--- a/src/video/x11/SDL_x11window.c
+++ b/src/video/x11/SDL_x11window.c
@@ -455,13 +455,6 @@ X11_CreateWindow(_THIS, SDL_Window * window)
XFree(wmhints);
}
- XSelectInput(data->display, w,
- (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
- ExposureMask | ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | KeyPressMask | KeyReleaseMask |
- PropertyChangeMask | StructureNotifyMask |
- KeymapStateMask));
-
/* Set the class hints so we can get an icon (AfterStep) */
classhints = XAllocClassHint();
if (classhints != NULL) {
@@ -481,9 +474,29 @@ X11_CreateWindow(_THIS, SDL_Window * window)
}
#endif
XDestroyWindow(data->display, w);
- X11_PumpEvents(_this);
return -1;
}
+#ifdef X_HAVE_UTF8_STRING
+ {
+ Uint32 fevent = 0;
+ pXGetICValues(((SDL_WindowData *) window->driverdata)->ic,
+ XNFilterEvents, &fevent, NULL);
+ XSelectInput(data->display, w,
+ (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
+ ExposureMask | ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | KeyPressMask | KeyReleaseMask |
+ PropertyChangeMask | StructureNotifyMask |
+ KeymapStateMask | fevent));
+ }
+#else
+ XSelectInput(data->display, w,
+ (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
+ ExposureMask | ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | KeyPressMask | KeyReleaseMask |
+ PropertyChangeMask | StructureNotifyMask |
+ KeymapStateMask));
+#endif
+
return 0;
}
@@ -680,7 +693,6 @@ X11_DestroyWindow(_THIS, SDL_Window * window)
#endif
if (data->created) {
XDestroyWindow(display, data->window);
- X11_PumpEvents(_this);
}
SDL_free(data);
}