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
authorBob Pendleton <bob@pendleton.com>
Fri, 07 Mar 2008 20:54:11 +0000
changeset 2325c7bcf84ba1b9
parent 2324 3202e4826c57
child 2326 133562468ff2
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.
src/video/x11/SDL_x11dyn.c
src/video/x11/SDL_x11dyn.h
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11sym.h
src/video/x11/SDL_x11window.c
     1.1 --- a/src/video/x11/SDL_x11dyn.c	Fri Mar 07 17:20:37 2008 +0000
     1.2 +++ b/src/video/x11/SDL_x11dyn.c	Fri Mar 07 20:54:11 2008 +0000
     1.3 @@ -98,6 +98,7 @@
     1.4  /* Annoying varargs entry point... */
     1.5  #ifdef X_HAVE_UTF8_STRING
     1.6  XIC(*pXCreateIC) (XIM,...) = NULL;
     1.7 +char *(*pXGetICValues) (XIC, ...) = NULL;
     1.8  #endif
     1.9  
    1.10  /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
    1.11 @@ -128,6 +129,7 @@
    1.12  
    1.13  #ifdef X_HAVE_UTF8_STRING
    1.14              pXCreateIC = NULL;
    1.15 +            pXGetICValues = NULL;
    1.16  #endif
    1.17  
    1.18              for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
    1.19 @@ -165,6 +167,8 @@
    1.20  
    1.21  #ifdef X_HAVE_UTF8_STRING
    1.22          X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8, (void **) &pXCreateIC);
    1.23 +        X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8,
    1.24 +                   (void **) &pXGetICValues);
    1.25  #endif
    1.26  
    1.27          if (SDL_X11_HAVE_BASEXLIB) {
    1.28 @@ -179,6 +183,7 @@
    1.29  #else
    1.30  #ifdef X_HAVE_UTF8_STRING
    1.31      pXCreateIC = XCreateIC;
    1.32 +    pXGetICValues = XGetICValues;
    1.33  #endif
    1.34  #endif
    1.35  
     2.1 --- a/src/video/x11/SDL_x11dyn.h	Fri Mar 07 17:20:37 2008 +0000
     2.2 +++ b/src/video/x11/SDL_x11dyn.h	Fri Mar 07 20:54:11 2008 +0000
     2.3 @@ -68,9 +68,10 @@
     2.4      int SDL_X11_LoadSymbols(void);
     2.5      void SDL_X11_UnloadSymbols(void);
     2.6  
     2.7 -/* That's really annoying...make this a function pointer no matter what. */
     2.8 +/* That's really annoying...make these function pointers no matter what. */
     2.9  #ifdef X_HAVE_UTF8_STRING
    2.10      extern XIC(*pXCreateIC) (XIM, ...);
    2.11 +    extern char *(*pXGetICValues) (XIC, ...);
    2.12  #endif
    2.13  
    2.14  /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
     3.1 --- a/src/video/x11/SDL_x11events.c	Fri Mar 07 17:20:37 2008 +0000
     3.2 +++ b/src/video/x11/SDL_x11events.c	Fri Mar 07 20:54:11 2008 +0000
     3.3 @@ -1,3 +1,4 @@
     3.4 +#define DEBUG_XEVENTS
     3.5  /*
     3.6      SDL - Simple DirectMedia Layer
     3.7      Copyright (C) 1997-2006 Sam Lantinga
     3.8 @@ -40,6 +41,15 @@
     3.9      SDL_zero(xevent);           /* valgrind fix. --ryan. */
    3.10      XNextEvent(videodata->display, &xevent);
    3.11  
    3.12 +    /* filter events catchs XIM events and sends them to the correct
    3.13 +       handler */
    3.14 +    if (XFilterEvent(&xevent, None) == True) {
    3.15 +#ifdef DEBUG_XEVENTS
    3.16 +        printf("Filtered event of type = 0x%X\n", xevent.type);
    3.17 +#endif
    3.18 +        return;
    3.19 +    }
    3.20 +
    3.21      /* Send a SDL_SYSWMEVENT if the application wants them */
    3.22      if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
    3.23          SDL_SysWMmsg wmmsg;
    3.24 @@ -182,14 +192,14 @@
    3.25              KeyCode keycode = xevent.xkey.keycode;
    3.26              KeySym keysym = NoSymbol;
    3.27              char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
    3.28 -            Uint32 ucs4 = 0;
    3.29 +            Status status = 0;
    3.30  
    3.31  #ifdef DEBUG_XEVENTS
    3.32              printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
    3.33  #endif
    3.34              SDL_SendKeyboardKey(videodata->keyboard, SDL_PRESSED,
    3.35                                  videodata->key_layout[keycode]);
    3.36 -#if 1
    3.37 +#if 0
    3.38              if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
    3.39                  int min_keycode, max_keycode;
    3.40                  XDisplayKeycodes(videodata->display, &min_keycode,
    3.41 @@ -201,9 +211,16 @@
    3.42                          XKeysymToString(keysym));
    3.43              }
    3.44  #endif
    3.45 -            /* Xutf8LookupString(), works for Latin-1 */
    3.46 +            /* */
    3.47              SDL_zero(text);
    3.48 +#ifdef X_HAVE_UTF8_STRING
    3.49 +            if (data->ic) {
    3.50 +                Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text),
    3.51 +                                  &keysym, status);
    3.52 +            }
    3.53 +#else
    3.54              XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
    3.55 +#endif
    3.56              if (*text) {
    3.57                  printf("Sending text event %s\n", text);
    3.58                  SDL_SendKeyboardText(videodata->keyboard, text);
     4.1 --- a/src/video/x11/SDL_x11sym.h	Fri Mar 07 17:20:37 2008 +0000
     4.2 +++ b/src/video/x11/SDL_x11sym.h	Fri Mar 07 20:54:11 2008 +0000
     4.3 @@ -156,6 +156,7 @@
     4.4  SDL_X11_SYM(int,Xutf8LookupString,(XIC a,XKeyPressedEvent* b,char* c,int d,KeySym* e,Status* f),(a,b,c,d,e,f),return)
     4.5  /*SDL_X11_SYM(XIC,XCreateIC,(XIM, ...),return)  !!! ARGH! */
     4.6  SDL_X11_SYM(void,XDestroyIC,(XIC a),(a),)
     4.7 +/*SDL_X11_SYM(char*,XGetICValues,(XIC, ...),return)  !!! ARGH! */
     4.8  SDL_X11_SYM(void,XSetICFocus,(XIC a),(a),)
     4.9  SDL_X11_SYM(void,XUnsetICFocus,(XIC a),(a),)
    4.10  SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d),(a,b,c,d),return)
     5.1 --- a/src/video/x11/SDL_x11window.c	Fri Mar 07 17:20:37 2008 +0000
     5.2 +++ b/src/video/x11/SDL_x11window.c	Fri Mar 07 20:54:11 2008 +0000
     5.3 @@ -455,13 +455,6 @@
     5.4          XFree(wmhints);
     5.5      }
     5.6  
     5.7 -    XSelectInput(data->display, w,
     5.8 -                 (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
     5.9 -                  ExposureMask | ButtonPressMask | ButtonReleaseMask |
    5.10 -                  PointerMotionMask | KeyPressMask | KeyReleaseMask |
    5.11 -                  PropertyChangeMask | StructureNotifyMask |
    5.12 -                  KeymapStateMask));
    5.13 -
    5.14      /* Set the class hints so we can get an icon (AfterStep) */
    5.15      classhints = XAllocClassHint();
    5.16      if (classhints != NULL) {
    5.17 @@ -481,9 +474,29 @@
    5.18          }
    5.19  #endif
    5.20          XDestroyWindow(data->display, w);
    5.21 -        X11_PumpEvents(_this);
    5.22          return -1;
    5.23      }
    5.24 +#ifdef X_HAVE_UTF8_STRING
    5.25 +    {
    5.26 +        Uint32 fevent = 0;
    5.27 +        pXGetICValues(((SDL_WindowData *) window->driverdata)->ic,
    5.28 +                      XNFilterEvents, &fevent, NULL);
    5.29 +        XSelectInput(data->display, w,
    5.30 +                     (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
    5.31 +                      ExposureMask | ButtonPressMask | ButtonReleaseMask |
    5.32 +                      PointerMotionMask | KeyPressMask | KeyReleaseMask |
    5.33 +                      PropertyChangeMask | StructureNotifyMask |
    5.34 +                      KeymapStateMask | fevent));
    5.35 +    }
    5.36 +#else
    5.37 +    XSelectInput(data->display, w,
    5.38 +                 (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
    5.39 +                  ExposureMask | ButtonPressMask | ButtonReleaseMask |
    5.40 +                  PointerMotionMask | KeyPressMask | KeyReleaseMask |
    5.41 +                  PropertyChangeMask | StructureNotifyMask |
    5.42 +                  KeymapStateMask));
    5.43 +#endif
    5.44 +
    5.45      return 0;
    5.46  }
    5.47  
    5.48 @@ -680,7 +693,6 @@
    5.49  #endif
    5.50          if (data->created) {
    5.51              XDestroyWindow(display, data->window);
    5.52 -            X11_PumpEvents(_this);
    5.53          }
    5.54          SDL_free(data);
    5.55      }