const gchar * ibus_key_event_to_string (guint keyval, guint modifiers) { guint i; GString *str; const gchar *keyval_name; g_return_val_if_fail (keyval != IBUS_KEY_VoidSymbol, NULL); keyval_name = ibus_keyval_name (keyval); g_return_val_if_fail (keyval_name != NULL, NULL); str = g_string_new (""); for (i = 0; i < 32; i++) { guint mask = 1 << i; if ((modifiers & mask) == 0) continue; if (modifier_name[i] == NULL) continue; g_string_append (str, modifier_name[i]); g_string_append_c (str, '+'); } g_string_append (str, keyval_name); return g_string_free (str, FALSE); }
/* Note on AltGr (Level3 Shift) handling: While currently we expect AltGr == mod5, it would be better to not expect the modifier always be assigned to particular modX. However, it needs some code like: KeyCode altgr = XKeysymToKeycode (display, XK_ISO_Level3_Shift); XModifierKeymap *mods = XGetModifierMapping (display); for (i = 3; i < 8; i++) for (j = 0; j < mods->max_keypermod; j++) { KeyCode code = mods->modifiermap[i * mods->max_keypermod + j]; if (code == altgr) ... } Since IBus engines are supposed to be cross-platform, the code should go into IBus core, instead of ibus-m17n. */ MSymbol ibus_m17n_key_event_to_symbol (guint keycode, guint keyval, guint modifiers) { GString *keysym; MSymbol mkeysym = Mnil; guint mask = 0; IBusKeymap *keymap; if (keyval >= IBUS_Shift_L && keyval <= IBUS_Hyper_R) { return Mnil; } /* Here, keyval is already translated by IBUS_MOD5_MASK. Obtain the untranslated keyval from the underlying keymap and represent the translated keyval as the form "G-<untranslated keyval>", which m17n-lib accepts. */ if (modifiers & IBUS_MOD5_MASK) { keymap = ibus_keymap_get ("us"); keyval = ibus_keymap_lookup_keysym (keymap, keycode, modifiers & ~IBUS_MOD5_MASK); g_object_unref (keymap); } keysym = g_string_new (""); if (keyval >= IBUS_space && keyval <= IBUS_asciitilde) { gint c = keyval; if (keyval == IBUS_space && modifiers & IBUS_SHIFT_MASK) mask |= IBUS_SHIFT_MASK; if (modifiers & IBUS_CONTROL_MASK) { if (c >= IBUS_a && c <= IBUS_z) c += IBUS_A - IBUS_a; mask |= IBUS_CONTROL_MASK; } g_string_append_c (keysym, c); } else { mask |= modifiers & (IBUS_CONTROL_MASK | IBUS_SHIFT_MASK); g_string_append (keysym, ibus_keyval_name (keyval)); if (keysym->len == 0) { g_string_free (keysym, TRUE); return Mnil; } } mask |= modifiers & (IBUS_MOD1_MASK | IBUS_MOD5_MASK | IBUS_META_MASK | IBUS_SUPER_MASK | IBUS_HYPER_MASK); if (mask & IBUS_HYPER_MASK) { g_string_prepend (keysym, "H-"); } if (mask & IBUS_SUPER_MASK) { g_string_prepend (keysym, "s-"); } if (mask & IBUS_MOD5_MASK) { g_string_prepend (keysym, "G-"); } if (mask & IBUS_MOD1_MASK) { g_string_prepend (keysym, "A-"); } if (mask & IBUS_META_MASK) { g_string_prepend (keysym, "M-"); } if (mask & IBUS_CONTROL_MASK) { g_string_prepend (keysym, "C-"); } if (mask & IBUS_SHIFT_MASK) { g_string_prepend (keysym, "S-"); } mkeysym = msymbol (keysym->str); g_string_free (keysym, TRUE); return mkeysym; }