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:
parent
c19af725fa
commit
b7ecabf860
5 changed files with 49 additions and 13 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue