+ if (sym == keymap[(i-min_keycode) * keysyms_per_keycode + j]) {
+ ret = g_renew(KeyCode, ret, ++n + 1);
+ ret[n-1] = i;
+ ret[n] = 0;
+ }
+ return ret;
+}
+
+gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XEvent *ev)
+{
+ gunichar unikey = 0;
+ KeySym sym;
+ Status status;
+ gchar *buf, fixbuf[4]; /* 4 is enough for a utf8 char */
+ gint len, bufsz;
+ gboolean got_string = FALSE;
+
+ g_return_val_if_fail(ev->type == KeyPress, 0);
+
+ if (!ic)
+ g_warning("Using obt_keyboard_keypress_to_unichar() without an "
+ "Input Context. No i18n support!");
+
+ if (ic && ic->xic) {
+ buf = fixbuf;
+ bufsz = sizeof(fixbuf);
+
+#ifdef X_HAVE_UTF8_STRING
+ len = Xutf8LookupString(ic->xic, &ev->xkey, buf, bufsz, &sym, &status);
+#else
+ len = XmbLookupString(ic->xic, &ev->xkey, buf, bufsz, &sym, &status);
+#endif
+
+ if (status == XBufferOverflow) {
+ buf = g_new(char, len);
+ bufsz = len;
+
+#ifdef X_HAVE_UTF8_STRING
+ len = Xutf8LookupString(ic->xic, &ev->xkey, buf, bufsz, &sym,
+ &status);
+#else
+ len = XmbLookupString(ic->xic, &ev->xkey, buf, bufsz, &sym,
+ &status);
+#endif
+ }
+
+ if ((status == XLookupChars || status == XLookupBoth)) {
+ if ((guchar)buf[0] >= 32) { /* not an ascii control character */
+#ifndef X_HAVE_UTF8_STRING
+ /* convert to utf8 */
+ gchar *buf2 = buf;
+ buf = g_locale_to_utf8(buf2, r, NULL, NULL, NULL);
+ g_free(buf2);
+#endif
+
+ got_string = TRUE;
+ }
+ }
+ else if (status == XLookupKeySym)
+ /* this key doesn't have a text representation, it is a command
+ key of some sort */;
+ else
+ g_message("Bad keycode lookup. Keysym 0x%x Status: %s\n",
+ (guint) sym,
+ (status == XBufferOverflow ? "BufferOverflow" :
+ status == XLookupNone ? "XLookupNone" :
+ status == XLookupKeySym ? "XLookupKeySym" :
+ "Unknown status"));
+ }
+ else {
+ buf = fixbuf;
+ bufsz = sizeof(fixbuf);
+ len = XLookupString(&ev->xkey, buf, bufsz, &sym, NULL);
+ if ((guchar)buf[0] >= 32) /* not an ascii control character */
+ got_string = TRUE;
+ }
+
+ if (got_string) {
+ gunichar u = g_utf8_get_char_validated(buf, len);
+ if (u && u != (gunichar)-1 && u != (gunichar)-2)
+ unikey = u;
+ }
+
+ if (buf != fixbuf) g_free(buf);
+
+ return unikey;