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.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402742
This commit is contained in:
Bob Pendleton 2008-03-07 20:54:11 +00:00
parent c19af725fa
commit b7ecabf860
5 changed files with 49 additions and 13 deletions

View file

@ -98,6 +98,7 @@ X11_GetSym(const char *fnname, int *rc, void **fn)
/* Annoying varargs entry point... */ /* Annoying varargs entry point... */
#ifdef X_HAVE_UTF8_STRING #ifdef X_HAVE_UTF8_STRING
XIC(*pXCreateIC) (XIM,...) = NULL; XIC(*pXCreateIC) (XIM,...) = NULL;
char *(*pXGetICValues) (XIC, ...) = NULL;
#endif #endif
/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */ /* 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 #ifdef X_HAVE_UTF8_STRING
pXCreateIC = NULL; pXCreateIC = NULL;
pXGetICValues = NULL;
#endif #endif
for (i = 0; i < SDL_TABLESIZE(x11libs); i++) { for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
@ -165,6 +167,8 @@ SDL_X11_LoadSymbols(void)
#ifdef X_HAVE_UTF8_STRING #ifdef X_HAVE_UTF8_STRING
X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8, (void **) &pXCreateIC); X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8, (void **) &pXCreateIC);
X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8,
(void **) &pXGetICValues);
#endif #endif
if (SDL_X11_HAVE_BASEXLIB) { if (SDL_X11_HAVE_BASEXLIB) {
@ -179,6 +183,7 @@ SDL_X11_LoadSymbols(void)
#else #else
#ifdef X_HAVE_UTF8_STRING #ifdef X_HAVE_UTF8_STRING
pXCreateIC = XCreateIC; pXCreateIC = XCreateIC;
pXGetICValues = XGetICValues;
#endif #endif
#endif #endif

View file

@ -68,9 +68,10 @@ extern "C"
int SDL_X11_LoadSymbols(void); int SDL_X11_LoadSymbols(void);
void SDL_X11_UnloadSymbols(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 #ifdef X_HAVE_UTF8_STRING
extern XIC(*pXCreateIC) (XIM, ...); extern XIC(*pXCreateIC) (XIM, ...);
extern char *(*pXGetICValues) (XIC, ...);
#endif #endif
/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */ /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */

View file

@ -1,3 +1,4 @@
#define DEBUG_XEVENTS
/* /*
SDL - Simple DirectMedia Layer SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga Copyright (C) 1997-2006 Sam Lantinga
@ -40,6 +41,15 @@ X11_DispatchEvent(_THIS)
SDL_zero(xevent); /* valgrind fix. --ryan. */ SDL_zero(xevent); /* valgrind fix. --ryan. */
XNextEvent(videodata->display, &xevent); 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 */ /* Send a SDL_SYSWMEVENT if the application wants them */
if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) { if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
SDL_SysWMmsg wmmsg; SDL_SysWMmsg wmmsg;
@ -182,14 +192,14 @@ X11_DispatchEvent(_THIS)
KeyCode keycode = xevent.xkey.keycode; KeyCode keycode = xevent.xkey.keycode;
KeySym keysym = NoSymbol; KeySym keysym = NoSymbol;
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
Uint32 ucs4 = 0; Status status = 0;
#ifdef DEBUG_XEVENTS #ifdef DEBUG_XEVENTS
printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode); printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
#endif #endif
SDL_SendKeyboardKey(videodata->keyboard, SDL_PRESSED, SDL_SendKeyboardKey(videodata->keyboard, SDL_PRESSED,
videodata->key_layout[keycode]); videodata->key_layout[keycode]);
#if 1 #if 0
if (videodata->key_layout[keycode] == SDLK_UNKNOWN) { if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
int min_keycode, max_keycode; int min_keycode, max_keycode;
XDisplayKeycodes(videodata->display, &min_keycode, XDisplayKeycodes(videodata->display, &min_keycode,
@ -201,9 +211,16 @@ X11_DispatchEvent(_THIS)
XKeysymToString(keysym)); XKeysymToString(keysym));
} }
#endif #endif
/* Xutf8LookupString(), works for Latin-1 */ /* */
SDL_zero(text); 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); XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
#endif
if (*text) { if (*text) {
printf("Sending text event %s\n", text); printf("Sending text event %s\n", text);
SDL_SendKeyboardText(videodata->keyboard, text); SDL_SendKeyboardText(videodata->keyboard, text);

View file

@ -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(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(XIC,XCreateIC,(XIM, ...),return) !!! ARGH! */
SDL_X11_SYM(void,XDestroyIC,(XIC a),(a),) 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,XSetICFocus,(XIC a),(a),)
SDL_X11_SYM(void,XUnsetICFocus,(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) SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d),(a,b,c,d),return)

View file

@ -455,13 +455,6 @@ X11_CreateWindow(_THIS, SDL_Window * window)
XFree(wmhints); 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) */ /* Set the class hints so we can get an icon (AfterStep) */
classhints = XAllocClassHint(); classhints = XAllocClassHint();
if (classhints != NULL) { if (classhints != NULL) {
@ -481,9 +474,29 @@ X11_CreateWindow(_THIS, SDL_Window * window)
} }
#endif #endif
XDestroyWindow(data->display, w); XDestroyWindow(data->display, w);
X11_PumpEvents(_this);
return -1; 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; return 0;
} }
@ -680,7 +693,6 @@ X11_DestroyWindow(_THIS, SDL_Window * window)
#endif #endif
if (data->created) { if (data->created) {
XDestroyWindow(display, data->window); XDestroyWindow(display, data->window);
X11_PumpEvents(_this);
} }
SDL_free(data); SDL_free(data);
} }