1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * GtkBindingSet: Keybinding manager for GtkObjects.
5 * Copyright (C) 1998 Tim Janik
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
25 * file for a list of people on the GTK+ Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
33 #include "gtkbindings.h"
34 #include "gtksignal.h"
35 #include "gtkwidget.h"
40 #define BINDING_MOD_MASK() (gtk_accelerator_get_default_mod_mask () | GDK_RELEASE_MASK)
43 /* --- structures --- */
51 /* --- variables --- */
52 static GHashTable *binding_entry_hash_table = NULL;
53 static GSList *binding_set_list = NULL;
54 static const gchar *key_class_binding_set = "gtk-class-binding-set";
55 static GQuark key_id_class_binding_set = 0;
58 /* --- functions --- */
59 static GtkBindingSignal*
60 binding_signal_new (const gchar *signal_name,
63 GtkBindingSignal *signal;
65 signal = g_new (GtkBindingSignal, 1);
67 signal->signal_name = g_strdup (signal_name);
68 signal->n_args = n_args;
69 signal->args = g_new0 (GtkBindingArg, n_args);
75 binding_signal_free (GtkBindingSignal *sig)
79 for (i = 0; i < sig->n_args; i++)
81 if (GTK_FUNDAMENTAL_TYPE (sig->args[i].arg_type) == GTK_TYPE_STRING)
82 g_free (sig->args[i].d.string_data);
85 g_free (sig->signal_name);
90 binding_entry_hash (gconstpointer key)
92 register const GtkBindingEntry *e = key;
102 binding_entries_compare (gconstpointer a,
105 register const GtkBindingEntry *ea = a;
106 register const GtkBindingEntry *eb = b;
108 return (ea->keyval == eb->keyval && ea->modifiers == eb->modifiers);
111 static GtkBindingEntry*
112 binding_entry_new (GtkBindingSet *binding_set,
116 GtkBindingEntry *entry;
118 if (!binding_entry_hash_table)
119 binding_entry_hash_table = g_hash_table_new (binding_entry_hash, binding_entries_compare);
121 entry = g_new (GtkBindingEntry, 1);
122 entry->keyval = keyval;
123 entry->modifiers = modifiers;
124 entry->binding_set = binding_set,
125 entry->destroyed = FALSE;
126 entry->in_emission = FALSE;
127 entry->signals = NULL;
129 entry->set_next = binding_set->entries;
130 binding_set->entries = entry;
132 entry->hash_next = g_hash_table_lookup (binding_entry_hash_table, entry);
133 if (entry->hash_next)
134 g_hash_table_remove (binding_entry_hash_table, entry->hash_next);
135 g_hash_table_insert (binding_entry_hash_table, entry, entry);
141 binding_entry_free (GtkBindingEntry *entry)
143 GtkBindingSignal *sig;
145 g_assert (entry->set_next == NULL &&
146 entry->hash_next == NULL &&
147 entry->in_emission == FALSE &&
148 entry->destroyed == TRUE);
150 entry->destroyed = FALSE;
152 sig = entry->signals;
155 GtkBindingSignal *prev;
159 binding_signal_free (prev);
165 binding_entry_destroy (GtkBindingEntry *entry)
167 GtkBindingEntry *o_entry;
168 register GtkBindingEntry *tmp;
169 GtkBindingEntry *begin;
170 register GtkBindingEntry *last;
172 /* unlink from binding set
175 tmp = entry->binding_set->entries;
181 last->set_next = entry->set_next;
183 entry->binding_set->entries = entry->set_next;
187 tmp = last->set_next;
189 entry->set_next = NULL;
191 o_entry = g_hash_table_lookup (binding_entry_hash_table, entry);
200 last->hash_next = entry->hash_next;
202 begin = entry->hash_next;
206 tmp = last->hash_next;
208 entry->hash_next = NULL;
211 g_hash_table_remove (binding_entry_hash_table, entry);
212 else if (begin != o_entry)
214 g_hash_table_remove (binding_entry_hash_table, entry);
215 g_hash_table_insert (binding_entry_hash_table, begin, begin);
218 entry->destroyed = TRUE;
220 if (!entry->in_emission)
221 binding_entry_free (entry);
224 static GtkBindingEntry*
225 binding_ht_lookup_list (guint keyval,
228 GtkBindingEntry lookup_entry = { 0 };
230 if (!binding_entry_hash_table)
233 lookup_entry.keyval = keyval;
234 lookup_entry.modifiers = modifiers;
236 return g_hash_table_lookup (binding_entry_hash_table, &lookup_entry);
239 static GtkBindingEntry*
240 binding_ht_lookup_entry (GtkBindingSet *set,
244 GtkBindingEntry lookup_entry = { 0 };
245 GtkBindingEntry *entry;
247 if (!binding_entry_hash_table)
250 lookup_entry.keyval = keyval;
251 lookup_entry.modifiers = modifiers;
253 entry = g_hash_table_lookup (binding_entry_hash_table, &lookup_entry);
254 for (; entry; entry = entry->hash_next)
255 if (entry->binding_set == set)
262 binding_compose_params (GtkBindingArg *args,
267 const GtkType *types;
271 params = g_new0 (GtkArg, query->n_params);
274 types = query->param_types;
276 for (i = 0; i < query->n_params && valid; i++)
280 params->type = *types;
282 param_ftype = GTK_FUNDAMENTAL_TYPE (params->type);
283 switch (GTK_FUNDAMENTAL_TYPE (args->arg_type))
285 case GTK_TYPE_DOUBLE:
286 if (param_ftype == GTK_TYPE_FLOAT)
287 GTK_VALUE_FLOAT (*params) = args->d.double_data;
288 else if (param_ftype == GTK_TYPE_DOUBLE)
289 GTK_VALUE_DOUBLE (*params) = args->d.double_data;
294 if (param_ftype == GTK_TYPE_BOOL &&
295 (args->d.long_data == 0 ||
296 args->d.long_data == 1))
297 GTK_VALUE_BOOL (*params) = args->d.long_data;
298 else if (param_ftype == GTK_TYPE_INT ||
299 param_ftype == GTK_TYPE_ENUM)
300 GTK_VALUE_INT (*params) = args->d.long_data;
301 else if ((param_ftype == GTK_TYPE_UINT ||
302 param_ftype == GTK_TYPE_FLAGS) &&
303 args->d.long_data >= 0)
304 GTK_VALUE_UINT (*params) = args->d.long_data;
305 else if (param_ftype == GTK_TYPE_LONG)
306 GTK_VALUE_LONG (*params) = args->d.long_data;
307 else if (param_ftype == GTK_TYPE_ULONG &&
308 args->d.long_data >= 0)
309 GTK_VALUE_ULONG (*params) = args->d.long_data;
310 else if (param_ftype == GTK_TYPE_FLOAT)
311 GTK_VALUE_FLOAT (*params) = args->d.long_data;
312 else if (param_ftype == GTK_TYPE_DOUBLE)
313 GTK_VALUE_DOUBLE (*params) = args->d.long_data;
317 case GTK_TYPE_STRING:
318 if (args->arg_type == GTK_TYPE_STRING &&
319 param_ftype == GTK_TYPE_STRING)
320 GTK_VALUE_STRING (*params) = args->d.string_data;
321 else if (args->arg_type == GTK_TYPE_IDENTIFIER &&
322 (param_ftype == GTK_TYPE_ENUM ||
323 param_ftype == GTK_TYPE_FLAGS))
327 value = gtk_type_enum_find_value (params->type, args->d.string_data);
329 GTK_VALUE_ENUM (*params) = value->value;
355 gtk_binding_entry_activate (GtkBindingEntry *entry,
358 GtkBindingSignal *sig;
359 gboolean old_emission;
361 old_emission = entry->in_emission;
362 entry->in_emission = TRUE;
364 gtk_object_ref (object);
366 for (sig = entry->signals; sig; sig = sig->next)
370 GtkArg *params = NULL;
371 gchar *accelerator = NULL;
373 signal_id = gtk_signal_lookup (sig->signal_name, GTK_OBJECT_TYPE (object));
376 accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
377 g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
378 "could not find signal \"%s\" in the `%s' class ancestry",
379 entry->binding_set->set_name,
382 gtk_type_name (GTK_OBJECT_TYPE (object)));
383 g_free (accelerator);
387 g_signal_query (signal_id, &query);
388 if (query.n_params != sig->n_args ||
389 query.return_type != G_TYPE_NONE ||
390 !binding_compose_params (sig->args, &query, ¶ms))
392 accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
393 g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
394 "signature mismatch for signal \"%s\" in the `%s' class ancestry",
395 entry->binding_set->set_name,
398 gtk_type_name (GTK_OBJECT_TYPE (object)));
400 else if (!(query.signal_flags & GTK_RUN_ACTION))
402 accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
403 g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
404 "signal \"%s\" in the `%s' class ancestry cannot be used for action emissions",
405 entry->binding_set->set_name,
408 gtk_type_name (GTK_OBJECT_TYPE (object)));
410 g_free (accelerator);
414 gtk_signal_emitv (object, signal_id, params);
417 if (GTK_OBJECT_DESTROYED (object) || entry->destroyed)
421 gtk_object_unref (object);
423 entry->in_emission = old_emission;
424 if (entry->destroyed && !entry->in_emission)
425 binding_entry_free (entry);
429 gtk_binding_set_new (const gchar *set_name)
431 GtkBindingSet *binding_set;
433 g_return_val_if_fail (set_name != NULL, NULL);
435 binding_set = g_new (GtkBindingSet, 1);
436 binding_set->set_name = g_strdup (set_name);
437 binding_set->widget_path_pspecs = NULL;
438 binding_set->widget_class_pspecs = NULL;
439 binding_set->class_branch_pspecs = NULL;
440 binding_set->entries = NULL;
441 binding_set->current = NULL;
443 binding_set_list = g_slist_prepend (binding_set_list, binding_set);
449 gtk_binding_set_by_class (gpointer object_class)
451 GtkObjectClass *class = object_class;
452 GtkBindingSet* binding_set;
454 g_return_val_if_fail (GTK_IS_OBJECT_CLASS (class), NULL);
456 if (!key_id_class_binding_set)
457 key_id_class_binding_set = g_quark_from_static_string (key_class_binding_set);
459 binding_set = g_dataset_id_get_data (class, key_id_class_binding_set);
464 binding_set = gtk_binding_set_new (gtk_type_name (GTK_CLASS_TYPE (class)));
465 gtk_binding_set_add_path (binding_set,
467 gtk_type_name (GTK_CLASS_TYPE (class)),
469 g_dataset_id_set_data (class, key_id_class_binding_set, binding_set);
475 gtk_binding_set_find (const gchar *set_name)
479 g_return_val_if_fail (set_name != NULL, NULL);
481 for (slist = binding_set_list; slist; slist = slist->next)
483 GtkBindingSet *binding_set;
485 binding_set = slist->data;
486 if (g_str_equal (binding_set->set_name, (gpointer) set_name))
493 gtk_binding_set_activate (GtkBindingSet *binding_set,
498 GtkBindingEntry *entry;
500 g_return_val_if_fail (binding_set != NULL, FALSE);
501 g_return_val_if_fail (object != NULL, FALSE);
502 g_return_val_if_fail (GTK_IS_OBJECT (object), FALSE);
504 keyval = gdk_keyval_to_lower (keyval);
505 modifiers = modifiers & BINDING_MOD_MASK ();
507 if (!GTK_OBJECT_DESTROYED (object))
509 entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
512 gtk_binding_entry_activate (entry, object);
522 gtk_binding_entry_clear (GtkBindingSet *binding_set,
526 GtkBindingEntry *entry;
528 g_return_if_fail (binding_set != NULL);
530 keyval = gdk_keyval_to_lower (keyval);
531 modifiers = modifiers & BINDING_MOD_MASK ();
533 entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
535 binding_entry_destroy (entry);
537 entry = binding_entry_new (binding_set, keyval, modifiers);
541 gtk_binding_entry_remove (GtkBindingSet *binding_set,
545 GtkBindingEntry *entry;
547 g_return_if_fail (binding_set != NULL);
549 keyval = gdk_keyval_to_lower (keyval);
550 modifiers = modifiers & BINDING_MOD_MASK ();
552 entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
554 binding_entry_destroy (entry);
558 gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
561 const gchar *signal_name,
562 GSList *binding_args)
564 GtkBindingEntry *entry;
565 GtkBindingSignal *signal, **signal_p;
570 g_return_if_fail (binding_set != NULL);
571 g_return_if_fail (signal_name != NULL);
573 keyval = gdk_keyval_to_lower (keyval);
574 modifiers = modifiers & BINDING_MOD_MASK ();
576 signal = binding_signal_new (signal_name, g_slist_length (binding_args));
579 for (slist = binding_args; slist; slist = slist->next)
581 GtkBindingArg *tmp_arg;
583 tmp_arg = slist->data;
586 g_warning ("gtk_binding_entry_add_signall(): arg[%u] is `NULL'", n);
587 binding_signal_free (signal);
590 switch (GTK_FUNDAMENTAL_TYPE (tmp_arg->arg_type))
593 arg->arg_type = GTK_TYPE_LONG;
594 arg->d.long_data = tmp_arg->d.long_data;
596 case GTK_TYPE_DOUBLE:
597 arg->arg_type = GTK_TYPE_DOUBLE;
598 arg->d.double_data = tmp_arg->d.double_data;
600 case GTK_TYPE_STRING:
601 if (tmp_arg->arg_type != GTK_TYPE_IDENTIFIER)
602 arg->arg_type = GTK_TYPE_STRING;
604 arg->arg_type = GTK_TYPE_IDENTIFIER;
605 arg->d.string_data = g_strdup (tmp_arg->d.string_data);
606 if (!arg->d.string_data)
608 g_warning ("gtk_binding_entry_add_signall(): value of `string' arg[%u] is `NULL'", n);
609 binding_signal_free (signal);
614 g_warning ("gtk_binding_entry_add_signall(): unsupported type `%s' for arg[%u]",
615 gtk_type_name (arg->arg_type), n);
616 binding_signal_free (signal);
623 entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
626 gtk_binding_entry_add (binding_set, keyval, modifiers);
627 entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
629 signal_p = &entry->signals;
631 signal_p = &(*signal_p)->next;
636 gtk_binding_entry_add_signal (GtkBindingSet *binding_set,
639 const gchar *signal_name,
643 GSList *slist, *free_slist;
647 g_return_if_fail (binding_set != NULL);
648 g_return_if_fail (signal_name != NULL);
650 keyval = gdk_keyval_to_lower (keyval);
651 modifiers = modifiers & BINDING_MOD_MASK ();
653 va_start (args, n_args);
655 for (i = 0; i < n_args; i++)
659 arg = g_new0 (GtkBindingArg, 1);
660 slist = g_slist_prepend (slist, arg);
662 arg->arg_type = va_arg (args, GtkType);
663 switch (GTK_FUNDAMENTAL_TYPE (arg->arg_type))
665 /* for elaborated commenting about var args collection, take a look
666 * at gtk_arg_collect_value() in gtkargcollector.c
675 arg->arg_type = GTK_TYPE_LONG;
676 arg->d.long_data = va_arg (args, gint);
680 arg->arg_type = GTK_TYPE_LONG;
681 arg->d.long_data = va_arg (args, glong);
684 case GTK_TYPE_DOUBLE:
685 arg->arg_type = GTK_TYPE_DOUBLE;
686 arg->d.double_data = va_arg (args, gdouble);
688 case GTK_TYPE_STRING:
689 if (arg->arg_type != GTK_TYPE_IDENTIFIER)
690 arg->arg_type = GTK_TYPE_STRING;
691 arg->d.string_data = va_arg (args, gchar*);
692 if (!arg->d.string_data)
694 g_warning ("gtk_binding_entry_add_signal(): type `%s' arg[%u] is `NULL'",
695 gtk_type_name (arg->arg_type),
701 g_warning ("gtk_binding_entry_add_signal(): unsupported type `%s' for arg[%u]",
702 gtk_type_name (arg->arg_type), i);
709 if (i == n_args || i == 0)
711 slist = g_slist_reverse (slist);
712 gtk_binding_entry_add_signall (binding_set, keyval, modifiers, signal_name, slist);
718 g_free (slist->data);
721 g_slist_free (free_slist);
725 gtk_binding_set_add_path (GtkBindingSet *binding_set,
726 GtkPathType path_type,
727 const gchar *path_pattern,
728 GtkPathPriorityType priority)
731 GSList **slist_p, *slist;
732 static guint seq_id = 0;
734 g_return_if_fail (binding_set != NULL);
735 g_return_if_fail (path_pattern != NULL);
736 g_return_if_fail (priority <= GTK_PATH_PRIO_MASK);
738 priority &= GTK_PATH_PRIO_MASK;
742 case GTK_PATH_WIDGET:
743 slist_p = &binding_set->widget_path_pspecs;
745 case GTK_PATH_WIDGET_CLASS:
746 slist_p = &binding_set->widget_class_pspecs;
749 slist_p = &binding_set->class_branch_pspecs;
752 g_assert_not_reached ();
757 pspec = g_new (PatternSpec, 1);
758 pspec->pspec = g_pattern_spec_new (path_pattern);
759 pspec->seq_id = priority << 28;
760 pspec->user_data = binding_set;
765 PatternSpec *tmp_pspec;
767 tmp_pspec = slist->data;
770 if (g_pattern_spec_equal (tmp_pspec->pspec, pspec->pspec))
772 GtkPathPriorityType lprio = tmp_pspec->seq_id >> 28;
774 g_pattern_spec_free (pspec->pspec);
777 if (lprio < priority)
779 tmp_pspec->seq_id &= 0x0fffffff;
780 tmp_pspec->seq_id |= priority << 28;
787 pspec->seq_id |= seq_id++ & 0x0fffffff;
788 *slist_p = g_slist_prepend (*slist_p, pspec);
792 static inline gboolean
793 binding_match_activate (GSList *pspec_list,
797 const gchar *path_reversed)
801 for (slist = pspec_list; slist; slist = slist->next)
806 if (g_pattern_match (pspec->pspec, path_length, path, path_reversed))
808 GtkBindingSet *binding_set;
810 binding_set = pspec->user_data;
812 gtk_binding_entry_activate (binding_set->current, object);
822 gtk_binding_pattern_compare (gconstpointer new_pattern,
823 gconstpointer existing_pattern)
825 register const PatternSpec *np = new_pattern;
826 register const PatternSpec *ep = existing_pattern;
828 /* walk the list as long as the existing patterns have
832 return np->seq_id < ep->seq_id;
835 static inline GSList*
836 gtk_binding_entries_sort_patterns (GtkBindingEntry *entries,
844 register GtkBindingSet *binding_set;
845 GSList *slist = NULL;
847 binding_set = entries->binding_set;
848 binding_set->current = entries;
852 case GTK_PATH_WIDGET:
853 slist = binding_set->widget_path_pspecs;
855 case GTK_PATH_WIDGET_CLASS:
856 slist = binding_set->widget_class_pspecs;
859 slist = binding_set->class_branch_pspecs;
863 for (; slist; slist = slist->next)
868 patterns = g_slist_insert_sorted (patterns, pspec, gtk_binding_pattern_compare);
871 entries = entries->hash_next;
879 gtk_bindings_activate (GtkObject *object,
883 GtkBindingEntry *entries;
885 gboolean handled = FALSE;
887 g_return_val_if_fail (object != NULL, FALSE);
888 g_return_val_if_fail (GTK_IS_OBJECT (object), FALSE);
890 if (!GTK_IS_WIDGET (object) || GTK_OBJECT_DESTROYED (object))
893 widget = GTK_WIDGET (object);
895 keyval = gdk_keyval_to_lower (keyval);
896 modifiers = modifiers & BINDING_MOD_MASK ();
898 entries = binding_ht_lookup_list (keyval, modifiers);
906 gchar *path, *path_reversed;
909 gtk_widget_path (widget, &path_length, &path, &path_reversed);
910 patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_WIDGET);
911 handled = binding_match_activate (patterns, object, path_length, path, path_reversed);
912 g_slist_free (patterns);
914 g_free (path_reversed);
920 gchar *path, *path_reversed;
923 gtk_widget_class_path (widget, &path_length, &path, &path_reversed);
924 patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_WIDGET_CLASS);
925 handled = binding_match_activate (patterns, object, path_length, path, path_reversed);
926 g_slist_free (patterns);
928 g_free (path_reversed);
936 patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_CLASS);
937 class_type = GTK_OBJECT_TYPE (object);
938 while (class_type && !handled)
942 gchar *path_reversed;
944 path = gtk_type_name (class_type);
945 path_reversed = g_strdup (path);
946 g_strreverse (path_reversed);
947 path_length = strlen (path);
948 handled = binding_match_activate (patterns, object, path_length, path, path_reversed);
949 g_free (path_reversed);
951 class_type = gtk_type_parent (class_type);
953 g_slist_free (patterns);
960 gtk_binding_parse_signal (GScanner *scanner,
961 GtkBindingSet *binding_set,
966 guint expected_token = 0;
974 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
976 g_scanner_get_next_token (scanner);
977 if (scanner->token != G_TOKEN_STRING)
978 return G_TOKEN_STRING;
979 g_scanner_peek_next_token (scanner);
980 if (scanner->next_token != '(')
982 g_scanner_get_next_token (scanner);
985 signal = g_strdup (scanner->value.v_string);
986 g_scanner_get_next_token (scanner);
993 scanner->config->scan_symbols = FALSE;
997 expected_token = G_TOKEN_INT;
999 expected_token = ')';
1000 g_scanner_get_next_token (scanner);
1001 switch (scanner->token)
1009 arg = g_new (GtkBindingArg, 1);
1010 arg->arg_type = GTK_TYPE_DOUBLE;
1011 arg->d.double_data = scanner->value.v_float;
1014 arg->d.double_data = - arg->d.double_data;
1017 args = g_slist_prepend (args, arg);
1026 arg = g_new (GtkBindingArg, 1);
1027 arg->arg_type = GTK_TYPE_LONG;
1028 arg->d.long_data = scanner->value.v_int;
1031 arg->d.long_data = - arg->d.long_data;
1034 args = g_slist_prepend (args, arg);
1039 case G_TOKEN_STRING:
1040 if (need_arg && !negate)
1043 arg = g_new (GtkBindingArg, 1);
1044 arg->arg_type = GTK_TYPE_STRING;
1045 arg->d.string_data = g_strdup (scanner->value.v_string);
1046 args = g_slist_prepend (args, arg);
1051 case G_TOKEN_IDENTIFIER:
1052 if (need_arg && !negate)
1055 arg = g_new (GtkBindingArg, 1);
1056 arg->arg_type = GTK_TYPE_IDENTIFIER;
1057 arg->d.string_data = g_strdup (scanner->value.v_identifier);
1058 args = g_slist_prepend (args, arg);
1068 expected_token = G_TOKEN_INT;
1082 if (!(need_arg && seen_comma) && !negate)
1084 args = g_slist_reverse (args);
1085 gtk_binding_entry_add_signall (binding_set,
1090 expected_token = G_TOKEN_NONE;
1100 scanner->config->scan_symbols = TRUE;
1102 for (slist = args; slist; slist = slist->next)
1107 if (GTK_FUNDAMENTAL_TYPE (arg->arg_type) == GTK_TYPE_STRING)
1108 g_free (arg->d.string_data);
1111 g_slist_free (args);
1114 return expected_token;
1118 gtk_binding_parse_bind (GScanner *scanner,
1119 GtkBindingSet *binding_set)
1122 guint modifiers = 0;
1124 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1126 g_scanner_get_next_token (scanner);
1127 if (scanner->token != GTK_RC_TOKEN_BIND)
1128 return GTK_RC_TOKEN_BIND;
1129 g_scanner_get_next_token (scanner);
1130 if (scanner->token != G_TOKEN_STRING)
1131 return G_TOKEN_STRING;
1132 gtk_accelerator_parse (scanner->value.v_string, &keyval, &modifiers);
1133 modifiers &= BINDING_MOD_MASK ();
1135 return G_TOKEN_STRING;
1137 g_scanner_get_next_token (scanner);
1138 if (scanner->token != '{')
1141 gtk_binding_entry_clear (binding_set, keyval, modifiers);
1143 g_scanner_peek_next_token (scanner);
1144 while (scanner->next_token != '}')
1146 switch (scanner->next_token)
1148 guint expected_token;
1150 case G_TOKEN_STRING:
1151 expected_token = gtk_binding_parse_signal (scanner,
1155 if (expected_token != G_TOKEN_NONE)
1156 return expected_token;
1159 g_scanner_get_next_token (scanner);
1162 g_scanner_peek_next_token (scanner);
1164 g_scanner_get_next_token (scanner);
1166 return G_TOKEN_NONE;
1170 gtk_binding_parse_binding (GScanner *scanner)
1173 GtkBindingSet *binding_set;
1175 g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
1177 g_scanner_get_next_token (scanner);
1178 if (scanner->token != GTK_RC_TOKEN_BINDING)
1179 return GTK_RC_TOKEN_BINDING;
1180 g_scanner_get_next_token (scanner);
1181 if (scanner->token != G_TOKEN_STRING)
1182 return G_TOKEN_STRING;
1183 name = g_strdup (scanner->value.v_string);
1185 g_scanner_get_next_token (scanner);
1186 if (scanner->token != '{')
1189 return G_TOKEN_STRING;
1192 binding_set = gtk_binding_set_find (name);
1194 binding_set = gtk_binding_set_new (name);
1197 g_scanner_peek_next_token (scanner);
1198 while (scanner->next_token != '}')
1200 switch (scanner->next_token)
1202 guint expected_token;
1204 case GTK_RC_TOKEN_BIND:
1205 expected_token = gtk_binding_parse_bind (scanner, binding_set);
1206 if (expected_token != G_TOKEN_NONE)
1207 return expected_token;
1210 g_scanner_get_next_token (scanner);
1213 g_scanner_peek_next_token (scanner);
1215 g_scanner_get_next_token (scanner);
1217 return G_TOKEN_NONE;