diff options
author | Tim Janik <timj@gtk.org> | 1998-07-22 22:29:10 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 1998-07-22 22:29:10 +0000 |
commit | 8c56db61e364b474a162ff6e01597505d11f5213 (patch) | |
tree | 998b0d80a01818933c7486ea4525a8a1be207467 /gtk/gtkbindings.c | |
parent | 3ea4f70fa64fffcfca5c6cebc4952a7c6d6e77ae (diff) | |
download | gdk-pixbuf-8c56db61e364b474a162ff6e01597505d11f5213.tar.gz |
introduce testbindings on C-1 for buttons, to check out binding
Thu Jul 23 00:11:39 1998 Tim Janik <timj@gtk.org>
* gtk/testgtkrc: introduce testbindings on C-1 for buttons,
to check out binding priorities. someone should really write
gtkrc-mode for emacs.
* gtk/gtkwidget.c (gtk_widget_class_init): remove ugly bindings test.
* gtk/testgtk.c (main): and move it here ;). this test says something
on release of C-9. (this works only if the mouse pointer is on a
spinbutton and there is no focus widget).
* gtk/gtkrc.h:
* gtk/gtkrc.c:
export gtk_rc_parse_color, gtk_rc_parse_state and a new function
gtk_rc_parse_priority to parse path priority types.
export rc tokens.
feature binding parsing.
Wed Jul 22 23:41:17 1998 Tim Janik <timj@gtk.org>
* gtk/gtkbindings.h:
* gtk/gtkbindings.c: new function gtk_binding_parse_binding() to
feature binding parsing in rc files.
* gtk/gtkbindings.c (gtk_binding_set_new): bug fix.
* gtk/gtkbindings.c (gtk_binding_pattern_compare): bug fix, we used to
order the bindings with lowest priority first.
Diffstat (limited to 'gtk/gtkbindings.c')
-rw-r--r-- | gtk/gtkbindings.c | 287 |
1 files changed, 278 insertions, 9 deletions
diff --git a/gtk/gtkbindings.c b/gtk/gtkbindings.c index 12ed21c49..b991ca85c 100644 --- a/gtk/gtkbindings.c +++ b/gtk/gtkbindings.c @@ -25,6 +25,7 @@ #include "gtkbindings.h" #include "gtksignal.h" #include "gtkwidget.h" +#include "gtkrc.h" /* --- defines --- */ @@ -302,10 +303,12 @@ binding_compose_params (GtkBindingArg *args, valid = FALSE; break; case GTK_TYPE_STRING: - if (param_ftype == GTK_TYPE_STRING) + if (args->arg_type == GTK_TYPE_STRING && + param_ftype == GTK_TYPE_STRING) GTK_VALUE_STRING (*params) = args->d.string_data; - else if (param_ftype == GTK_TYPE_ENUM || - param_ftype == GTK_TYPE_FLAGS) + else if (args->arg_type == GTK_TYPE_IDENTIFIER && + (param_ftype == GTK_TYPE_ENUM || + param_ftype == GTK_TYPE_FLAGS)) { /* FIXME: we need identifier lookups here */ valid = FALSE; @@ -421,7 +424,7 @@ gtk_binding_set_new (const gchar *set_name) binding_set->entries = NULL; binding_set->current = NULL; - binding_set_list = g_slist_prepend (NULL, binding_set); + binding_set_list = g_slist_prepend (binding_set_list, binding_set); return binding_set; } @@ -790,13 +793,17 @@ binding_match_activate (GSList *pspec_list, } static gint -gtk_binding_pattern_compare (gconstpointer a, - gconstpointer b) +gtk_binding_pattern_compare (gconstpointer new_pattern, + gconstpointer existing_pattern) { - register const GtkPatternSpec *pa = a; - register const GtkPatternSpec *pb = b; + register const GtkPatternSpec *np = new_pattern; + register const GtkPatternSpec *ep = existing_pattern; - return pa->seq_id < pb->seq_id ? -1 : 1; + /* walk the list as long as the existing patterns have + * higher priorities. + */ + + return np->seq_id < ep->seq_id; } static inline GSList* @@ -1169,3 +1176,265 @@ gtk_pattern_spec_free_segs (GtkPatternSpec *pspec) g_free (pspec->pattern_reversed); pspec->pattern_reversed = NULL; } + +static guint +gtk_binding_parse_signal (GScanner *scanner, + GtkBindingSet *binding_set, + guint keyval, + guint 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 = GTK_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 = GTK_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 = GTK_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, + keyval, + modifiers, + signal, + args); + expected_token = G_TOKEN_NONE; + } + done = TRUE; + break; + default: + done = TRUE; + break; + } + } + while (!done); + scanner->config->scan_symbols = TRUE; + + for (slist = args; slist; slist = slist->next) + { + GtkBindingArg *arg; + + arg = slist->data; + if (GTK_FUNDAMENTAL_TYPE (arg->arg_type) == GTK_TYPE_STRING) + g_free (arg->d.string_data); + g_free (arg); + } + g_slist_free (args); + g_free (signal); + + return expected_token; +} + +static inline guint +gtk_binding_parse_bind (GScanner *scanner, + GtkBindingSet *binding_set) +{ + guint keyval = 0; + guint modifiers = 0; + + g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR); + + g_scanner_get_next_token (scanner); + if (scanner->token != GTK_RC_TOKEN_BIND) + return GTK_RC_TOKEN_BIND; + g_scanner_get_next_token (scanner); + if (scanner->token != G_TOKEN_STRING) + return G_TOKEN_STRING; + gtk_accelerator_parse (scanner->value.v_string, &keyval, &modifiers); + modifiers &= BINDING_MOD_MASK (); + if (keyval == 0) + return G_TOKEN_STRING; + + g_scanner_get_next_token (scanner); + if (scanner->token != '{') + return '{'; + + gtk_binding_entry_clear (binding_set, keyval, modifiers); + + g_scanner_peek_next_token (scanner); + while (scanner->next_token != '}') + { + switch (scanner->next_token) + { + guint expected_token; + + case G_TOKEN_STRING: + expected_token = gtk_binding_parse_signal (scanner, + binding_set, + keyval, + modifiers); + if (expected_token != G_TOKEN_NONE) + return expected_token; + break; + default: + g_scanner_get_next_token (scanner); + return '}'; + } + g_scanner_peek_next_token (scanner); + } + g_scanner_get_next_token (scanner); + + return G_TOKEN_NONE; +} + +guint +gtk_binding_parse_binding (GScanner *scanner) +{ + gchar *name; + GtkBindingSet *binding_set; + + g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR); + + g_scanner_get_next_token (scanner); + if (scanner->token != GTK_RC_TOKEN_BINDING) + return GTK_RC_TOKEN_BINDING; + g_scanner_get_next_token (scanner); + if (scanner->token != G_TOKEN_STRING) + return G_TOKEN_STRING; + name = g_strdup (scanner->value.v_string); + + g_scanner_get_next_token (scanner); + if (scanner->token != '{') + { + g_free (name); + return G_TOKEN_STRING; + } + + binding_set = gtk_binding_set_find (name); + if (!binding_set) + binding_set = gtk_binding_set_new (name); + g_free (name); + + g_scanner_peek_next_token (scanner); + while (scanner->next_token != '}') + { + switch (scanner->next_token) + { + guint expected_token; + + case GTK_RC_TOKEN_BIND: + expected_token = gtk_binding_parse_bind (scanner, binding_set); + if (expected_token != G_TOKEN_NONE) + return expected_token; + break; + default: + g_scanner_get_next_token (scanner); + return '}'; + } + g_scanner_peek_next_token (scanner); + } + g_scanner_get_next_token (scanner); + + return G_TOKEN_NONE; +} + |