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; ... } }