gboolean ibus_hotkey_profile_remove_hotkey_by_event (IBusHotkeyProfile *profile, GQuark event) { IBusHotkeyProfilePrivate *priv; priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile); gint i; IBusHotkeyEvent *p = NULL; for ( i = 0; i < priv->events->len; i++) { p = &g_array_index (priv->events, IBusHotkeyEvent, i); if (p->event == event) break; } if (p == NULL || p->event != event) return FALSE; GList *list; for (list = p->hotkeys; list != NULL; list = list->next) { g_tree_remove (priv->hotkeys, (IBusHotkey *)list->data); } g_list_free (p->hotkeys); g_array_remove_index_fast (priv->events, i); return TRUE; }
static void ibus_hotkey_profile_destroy (IBusHotkeyProfile *profile) { IBusHotkeyProfilePrivate *priv; priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile); /* free events */ if (priv->events) { IBusHotkeyEvent *p; gint i; p = (IBusHotkeyEvent *)g_array_free (priv->events, FALSE); priv->events = NULL; for (i = 0; p[i].event != 0; i++) { g_list_free (p[i].hotkeys); } g_free (p); } if (priv->hotkeys) { g_tree_destroy (priv->hotkeys); priv->hotkeys = NULL; } IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *)profile); }
GQuark ibus_hotkey_profile_filter_key_event (IBusHotkeyProfile *profile, guint keyval, guint modifiers, guint prev_keyval, guint prev_modifiers, gpointer user_data) { IBusHotkeyProfilePrivate *priv; priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile); IBusHotkey hotkey = { .keyval = keyval, .modifiers = modifiers & priv->mask, }; if ((modifiers & IBUS_RELEASE_MASK) && keyval != prev_keyval) { return 0; } GQuark event = (GQuark) GPOINTER_TO_UINT (g_tree_lookup (priv->hotkeys, &hotkey)); if (event != 0) { g_signal_emit (profile, profile_signals[TRIGGER], event, user_data); } return event; }
static void ibus_hotkey_profile_init (IBusHotkeyProfile *profile) { IBusHotkeyProfilePrivate *priv; priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile); priv->hotkeys = g_tree_new_full ((GCompareDataFunc) ibus_hotkey_cmp_with_data, NULL, (GDestroyNotify) ibus_hotkey_free, NULL); priv->events = g_array_new (TRUE, TRUE, sizeof (IBusHotkeyEvent)); priv->mask = IBUS_SHIFT_MASK | IBUS_CONTROL_MASK | IBUS_MOD1_MASK | IBUS_RELEASE_MASK; }
gboolean ibus_hotkey_profile_remove_hotkey (IBusHotkeyProfile *profile, guint keyval, guint modifiers) { IBusHotkeyProfilePrivate *priv; priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile); IBusHotkey hotkey = { .keyval = keyval, .modifiers = modifiers }; IBusHotkey *p1; GQuark event; gboolean retval; retval = g_tree_lookup_extended (priv->hotkeys, &hotkey, (gpointer)&p1, (gpointer)&event); if (!retval) return FALSE; gint i; IBusHotkeyEvent *p2 = NULL; for ( i = 0; i < priv->events->len; i++) { p2 = &g_array_index (priv->events, IBusHotkeyEvent, i); if (p2->event == event) break; } g_assert (p2->event == event); p2->hotkeys = g_list_remove (p2->hotkeys, p1); if (p2->hotkeys == NULL) { g_array_remove_index_fast (priv->events, i); } g_tree_remove (priv->hotkeys, p1); return TRUE; }
gboolean ibus_hotkey_profile_add_hotkey (IBusHotkeyProfile *profile, guint keyval, guint modifiers, GQuark event) { IBusHotkeyProfilePrivate *priv; priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile); IBusHotkey *hotkey = ibus_hotkey_new (keyval, modifiers); /* has the same hotkey in profile */ if (g_tree_lookup (priv->hotkeys, hotkey) != NULL) { ibus_hotkey_free (hotkey); g_return_val_if_reached (FALSE); } g_tree_insert (priv->hotkeys, (gpointer) hotkey, GUINT_TO_POINTER (event)); IBusHotkeyEvent *p = NULL; gint i; for ( i = 0; i < priv->events->len; i++) { p = &g_array_index (priv->events, IBusHotkeyEvent, i); if (p->event == event) break; } if (i >= priv->events->len) { g_array_set_size (priv->events, i + 1); p = &g_array_index (priv->events, IBusHotkeyEvent, i); p->event = event; } p->hotkeys = g_list_append (p->hotkeys, hotkey); return TRUE; }