- patterns = NULL;
- for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
- {
- GtkBindingEntry *entry = tmp_list->data;
- GtkBindingSet *binding_set;
-
- binding_set = entry->binding_set;
- binding_set->current = NULL;
- }
-
- for (; entries; entries = entries->next)
- {
- GtkBindingEntry *entry = entries->data;
- GtkBindingSet *binding_set;
- GSList *slist = NULL;
-
- if (is_release != ((entry->modifiers & GDK_RELEASE_MASK) != 0))
- continue;
-
- binding_set = entry->binding_set;
-
- if (binding_set->current)
- continue;
- binding_set->current = entry;
-
- switch (path_id)
- {
- case GTK_PATH_WIDGET:
- slist = binding_set->widget_path_pspecs;
- break;
- case GTK_PATH_WIDGET_CLASS:
- slist = binding_set->widget_class_pspecs;
- break;
- case GTK_PATH_CLASS:
- slist = binding_set->class_branch_pspecs;
- break;
- }
-
- for (; slist; slist = slist->next)
- {
- PatternSpec *pspec;
-
- pspec = slist->data;
- patterns = g_slist_insert_sorted (patterns, pspec, gtk_binding_pattern_compare);
- }
- }
-
- return patterns;
-}
-
-static gboolean
-gtk_bindings_activate_list (GtkObject *object,
- GSList *entries,
- gboolean is_release)
-{
- GtkWidget *widget = GTK_WIDGET (object);
- gboolean handled = FALSE;
-
- if (!entries)
- return FALSE;
-
- if (!handled)
- {
- guint path_length;
- gchar *path, *path_reversed;
- GSList *patterns;
- gboolean unbound;
-
- gtk_widget_path (widget, &path_length, &path, &path_reversed);
- patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_WIDGET, is_release);
- handled = binding_match_activate (patterns, object, path_length, path, path_reversed, &unbound);
- g_slist_free (patterns);
- g_free (path);
- g_free (path_reversed);
-
- if (unbound)
- return FALSE;
- }
-
- if (!handled)
- {
- guint path_length;
- gchar *path, *path_reversed;
- GSList *patterns;
- gboolean unbound;
-
- gtk_widget_class_path (widget, &path_length, &path, &path_reversed);
- patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_WIDGET_CLASS, is_release);
- handled = binding_match_activate (patterns, object, path_length, path, path_reversed, &unbound);
- g_slist_free (patterns);
- g_free (path);
- g_free (path_reversed);
-
- if (unbound)
- return FALSE;
- }
-
- if (!handled)
- {
- GSList *patterns;
- GType class_type;
- gboolean unbound = FALSE;
-
- patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_CLASS, is_release);
- class_type = G_TYPE_FROM_INSTANCE (object);
- while (class_type && !handled)
- {
- guint path_length;
- gchar *path;
- gchar *path_reversed;
-
- path = g_strdup (g_type_name (class_type));
- path_reversed = g_strdup (path);
- g_strreverse (path_reversed);
- path_length = strlen (path);
- handled = binding_match_activate (patterns, object, path_length, path, path_reversed, &unbound);
- g_free (path);
- g_free (path_reversed);
-
- if (unbound)
- break;
-
- class_type = g_type_parent (class_type);
- }
- g_slist_free (patterns);
-
- if (unbound)
- return FALSE;
- }
-
- return handled;
-}
-
-/**
- * gtk_bindings_activate:
- * @object: object to activate when binding found
- * @keyval: key value of the binding
- * @modifiers: key modifier of the binding
- *
- * Find a key binding matching @keyval and @modifiers and activate the
- * binding on @object.
- *
- * Return value: %TRUE if a binding was found and activated
- */
-gboolean
-gtk_bindings_activate (GtkObject *object,
- guint keyval,
- GdkModifierType modifiers)
-{
- GSList *entries = NULL;
- GdkDisplay *display;
- GtkKeyHash *key_hash;
- gboolean handled = FALSE;
- gboolean is_release;
-
- g_return_val_if_fail (GTK_IS_OBJECT (object), FALSE);
-
- if (!GTK_IS_WIDGET (object))
- return FALSE;
-
- is_release = (modifiers & GDK_RELEASE_MASK) != 0;
- modifiers = modifiers & BINDING_MOD_MASK () & ~GDK_RELEASE_MASK;
-
- display = gtk_widget_get_display (GTK_WIDGET (object));
- key_hash = binding_key_hash_for_keymap (gdk_keymap_get_for_display (display));
-
- entries = _gtk_key_hash_lookup_keyval (key_hash, keyval, modifiers);
-
- handled = gtk_bindings_activate_list (object, entries, is_release);
-
- g_slist_free (entries);
-
- return handled;
-}
-
-/**
- * gtk_bindings_activate_event:
- * @object: a #GtkObject (generally must be a widget)
- * @event: a #GdkEventKey
- *
- * Looks up key bindings for @object to find one matching
- * @event, and if one was found, activate it.
- *
- * Return value: %TRUE if a matching key binding was found
- */
-gboolean
-gtk_bindings_activate_event (GtkObject *object,
- GdkEventKey *event)
-{
- GSList *entries = NULL;
- GdkDisplay *display;
- GtkKeyHash *key_hash;
- gboolean handled = FALSE;
-
- g_return_val_if_fail (GTK_IS_OBJECT (object), FALSE);
-
- if (!GTK_IS_WIDGET (object))
- return FALSE;
-
- display = gtk_widget_get_display (GTK_WIDGET (object));
- key_hash = binding_key_hash_for_keymap (gdk_keymap_get_for_display (display));
-
- entries = _gtk_key_hash_lookup (key_hash,
- event->hardware_keycode,
- event->state,
- BINDING_MOD_MASK () & ~GDK_RELEASE_MASK,
- event->group);
-
- handled = gtk_bindings_activate_list (object, entries,
- event->type == GDK_KEY_RELEASE);
-
- g_slist_free (entries);
-
- return handled;
-}
-
-static guint
-gtk_binding_parse_signal (GScanner *scanner,
- GtkBindingSet *binding_set,
- guint keyval,
- GdkModifierType modifiers)
-{
- gchar *signal;
- guint expected_token = 0;
- GSList *args;
- GSList *slist;
- gboolean done;
- gboolean negate;
- gboolean need_arg;
- gboolean seen_comma;
-
- g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
-
- g_scanner_get_next_token (scanner);
- if (scanner->token != G_TOKEN_STRING)
- return G_TOKEN_STRING;
- g_scanner_peek_next_token (scanner);
- if (scanner->next_token != '(')
- {
- g_scanner_get_next_token (scanner);
- return '(';
- }
- signal = g_strdup (scanner->value.v_string);
- g_scanner_get_next_token (scanner);
-
- negate = FALSE;
- args = NULL;
- done = FALSE;
- need_arg = TRUE;
- seen_comma = FALSE;
- scanner->config->scan_symbols = FALSE;
- do
- {
- if (need_arg)
- expected_token = G_TOKEN_INT;
- else
- expected_token = ')';
- g_scanner_get_next_token (scanner);
- switch (scanner->token)
- {
- GtkBindingArg *arg;
-
- case G_TOKEN_FLOAT:
- if (need_arg)
- {
- need_arg = FALSE;
- arg = g_new (GtkBindingArg, 1);
- arg->arg_type = G_TYPE_DOUBLE;
- arg->d.double_data = scanner->value.v_float;
- if (negate)
- {
- arg->d.double_data = - arg->d.double_data;
- negate = FALSE;
- }
- args = g_slist_prepend (args, arg);
- }
- else
- done = TRUE;
- break;
- case G_TOKEN_INT:
- if (need_arg)
- {
- need_arg = FALSE;
- arg = g_new (GtkBindingArg, 1);
- arg->arg_type = G_TYPE_LONG;
- arg->d.long_data = scanner->value.v_int;
- if (negate)
- {
- arg->d.long_data = - arg->d.long_data;
- negate = FALSE;
- }
- args = g_slist_prepend (args, arg);
- }
- else
- done = TRUE;
- break;
- case G_TOKEN_STRING:
- if (need_arg && !negate)
- {
- need_arg = FALSE;
- arg = g_new (GtkBindingArg, 1);
- arg->arg_type = G_TYPE_STRING;
- arg->d.string_data = g_strdup (scanner->value.v_string);
- args = g_slist_prepend (args, arg);
- }
- else
- done = TRUE;
- break;
- case G_TOKEN_IDENTIFIER:
- if (need_arg && !negate)
- {
- need_arg = FALSE;
- arg = g_new (GtkBindingArg, 1);
- arg->arg_type = GTK_TYPE_IDENTIFIER;
- arg->d.string_data = g_strdup (scanner->value.v_identifier);
- args = g_slist_prepend (args, arg);
- }
- else
- done = TRUE;
- break;
- case '-':
- if (!need_arg)
- done = TRUE;
- else if (negate)
- {
- expected_token = G_TOKEN_INT;
- done = TRUE;
- }
- else
- negate = TRUE;
- break;
- case ',':
- seen_comma = TRUE;
- if (need_arg)
- done = TRUE;
- else
- need_arg = TRUE;
- break;
- case ')':
- if (!(need_arg && seen_comma) && !negate)
- {
- args = g_slist_reverse (args);
- _gtk_binding_entry_add_signall (binding_set,