Log In
New Account
  
Home My Page Project Cloud Code Snippets Project Openings

Browse | Submit A New Snippet | Create A Package

 

Getting input from the Virtual Keyboard in X11 programs

Type:
Sample Code (HOWTO)
Category:
Other
License:
BSD License
Language:
C
 
Description:
Here is some basic code that shows how you can can turn input from the virtual keyboard (or handwriting recognition) into X11 keyboard events that can be interpreted by plain X11 programs. This works for plain ASCII. If you want to handle full UTF8 input, better handle the intercepted input (see snippet) directly rather than re-posting it as X11 keyboard events! This snippet assumes that you have already created a GDK wrapper around your window (see snippet 3) and have set up the keyboard / handwriting recognition (see snippet 4).

Versions Of This Snippet::

Rene Hexel
Snippet ID Download Version Date Posted Author Delete
512006-11-13 22:55Rene Hexel

Download a raw-text version of this code by clicking on "Download Version"

 


Latest Snippet Version: :1

Display *dpy;               /* the X display */
GdkWindow *gdkWindow;       /* the GDK window wrapped around your X window */
GtkIMContext *im_context;   /* the context for the keyboard input method */

/*
 * the following three atoms are needed to get virtual keyboard input
 */
Atom hildon_com, hildon_utf, hildon_cls;

...                         /* set up your hildon / gtk program */
dpy = ...;                  /* open the display */

/*
 * now create the atoms we need
 */
hildon_com = XInternAtom(dpy, "_HILDON_IM_COM", TRUE);
hildon_utf = XInternAtom(dpy, "_HILDON_IM_INSERT_UTF8", TRUE);
hildon_cls = XInternAtom(dpy, "_HILDON_IM_CLOSE", TRUE);

/*
 * create and map your X and GDK windows, then show the keyboard (im_context)
 */
...
gdkWindow = ...;            /* see snippet 3 on how this is done */
...

/*
 * now add support for the hildon ClientMessage events to your event handler
 */
while (!quit)
{
  while (gtk_events_pending())
    gtk_main_iteration();

  XNextEvent(dpy, &event);
  switch(event.type)
  {
    case ClientMessage:
      if (event.xclient.message_type == but_hildon_cls)      /* keyboard closed */
      {
        hildon_gtk_im_context_hide(im_context);
        gtk_im_context_reset(im_context);
        g_object_unref(im_context);
        im_context = NULL;
      }
      else if (event.xclient.message_type == but_hildon_utf) /* keyboard input */
      {
        XEvent kev = event;                                  /* create new event */
        KeySym sym = XStringToKeysym(&event.xclient.data.b[4]); /* read the key */

        if (!sym) sym = event.xclient.data.b[4];             /* fall back to input */

        kev.type = KeyPress;                                 /* keyboard event */
        kev.xkey.root = ev->window;
        kev.xkey.subwindow = None;
        kev.xkey.time = CurrentTime;
        kev.xkey.x = kev.xkey.y = kev.xkey.x_root = kev.xkey.y_root = 1;
        kev.xkey.same_screen = TRUE;
        kev.xkey.keycode = XKeysymToKeycode(dpy, sym);      /* convert to key code */

        if (isupper(ev->data.b[4]))                         /* upper case letter? */
            kev.xkey.state = ShiftMask;                     /* yes: we need shift */
        else
            kev.xkey.state = 0;

        XSendEvent(dpy, win, TRUE, KeyPressMask, &kev);

        kev.type = KeyRelease;                              /* key release event */
        XSendEvent(dpy, win, TRUE, KeyReleaseMask, &kev);
      }
      else if (event.xclient.message_type == but_hildon_com)/* special key/event */
      {
        switch (event.xclient.data.b[4])
        {
          case 0:                                          /* return / enter */
            ... /* send XK_Return (or handle specially) */
            break;
          case 1:                                          /* tab */
            ... /* send XK_Tab (or handle specially) */
            break;
          case 2:                                         /* backspace */
            ... /* send XK_BackSpace (or handle specially) */
            break;
          case 4:                                        /* state change */
              break;
          case 7:                                        /* special char */
              break;
          default:
              printf("Unknown IM event data %d\n",
                        (int) event.xclient.data.b[4]);
        }
      }
      break;

    case KeyPress:
      ...
      break;

    ...
  }
}

		

Submit a new version

You can submit a new version of this snippet if you have modified it and you feel it is appropriate to share with others..


Terms of Use    Privacy Policy    Contribution Guidelines    Feedback

Powered By GForge Collaborative Development Environment