* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#include "config.h"
#include <string.h>
#include <stdarg.h>
#include <gdkkeysyms.h>
+
#include "gtkbindings.h"
#include "gtkkeyhash.h"
-#include "gtksignal.h"
#include "gtkwidget.h"
#include "gtkrc.h"
+#include "gtkalias.h"
/* --- defines --- */
/* --- structures --- */
typedef struct {
+ GtkPathType type;
GPatternSpec *pspec;
- gpointer user_data;
- guint seq_id;
+ GSList *path;
+ gpointer user_data;
+ guint seq_id;
} PatternSpec;
static GHashTable *binding_entry_hash_table = NULL;
static GSList *binding_key_hashes = NULL;
static GSList *binding_set_list = NULL;
-static const gchar *key_class_binding_set = "gtk-class-binding-set";
+static const gchar key_class_binding_set[] = "gtk-class-binding-set";
static GQuark key_id_class_binding_set = 0;
/* --- functions --- */
+static void
+pattern_spec_free (PatternSpec *pspec)
+{
+ _gtk_rc_free_widget_class_path (pspec->path);
+ if (pspec->pspec)
+ g_pattern_spec_free (pspec->pspec);
+ g_free (pspec);
+}
+
static GtkBindingSignal*
binding_signal_new (const gchar *signal_name,
guint n_args)
{
GtkBindingSignal *signal;
-
- signal = g_new (GtkBindingSignal, 1);
+
+ signal = (GtkBindingSignal *) g_slice_alloc0 (sizeof (GtkBindingSignal) + n_args * sizeof (GtkBindingArg));
signal->next = NULL;
- signal->signal_name = g_strdup (signal_name);
+ signal->signal_name = (gchar *)g_intern_string (signal_name);
signal->n_args = n_args;
- signal->args = g_new0 (GtkBindingArg, n_args);
+ signal->args = (GtkBindingArg *)(signal + 1);
return signal;
}
for (i = 0; i < sig->n_args; i++)
{
- if (GTK_FUNDAMENTAL_TYPE (sig->args[i].arg_type) == GTK_TYPE_STRING)
+ if (G_TYPE_FUNDAMENTAL (sig->args[i].arg_type) == G_TYPE_STRING)
g_free (sig->args[i].d.string_data);
}
- g_free (sig->args);
- g_free (sig->signal_name);
- g_free (sig);
+ g_slice_free1 (sizeof (GtkBindingSignal) + sig->n_args * sizeof (GtkBindingArg), sig);
}
static guint
entry->binding_set = binding_set,
entry->destroyed = FALSE;
entry->in_emission = FALSE;
+ entry->marks_unbound = FALSE;
entry->signals = NULL;
entry->set_next = binding_set->entries;
g_value_init (&tmp_value, G_TYPE_DOUBLE);
g_value_set_double (&tmp_value, args->d.double_data);
break;
- case G_TYPE_LONG:
+ case G_TYPE_LONG:
g_value_init (&tmp_value, G_TYPE_LONG);
g_value_set_long (&tmp_value, args->d.long_data);
break;
- case G_TYPE_STRING:
+ case G_TYPE_STRING:
/* gtk_rc_parse_flags/enum() has fancier parsing for this; we can't call
* that since we don't have a GParamSpec, so just do something simple
*/
sig->signal_name,
g_type_name (G_OBJECT_TYPE (object)));
}
- else if (!(query.signal_flags & GTK_RUN_ACTION))
+ else if (!(query.signal_flags & G_SIGNAL_ACTION))
{
accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
return handled;
}
+/**
+ * gtk_binding_set_new:
+ * @set_name: unique name of this binding set
+ *
+ * GTK+ maintains a global list of binding sets. Each binding set has
+ * a unique name which needs to be specified upon creation.
+ *
+ * Return value: new binding set
+ */
GtkBindingSet*
-gtk_binding_set_new (const gchar *set_name)
+gtk_binding_set_new (const gchar *set_name)
{
GtkBindingSet *binding_set;
g_return_val_if_fail (set_name != NULL, NULL);
binding_set = g_new (GtkBindingSet, 1);
- binding_set->set_name = g_strdup (set_name);
+ binding_set->set_name = (gchar *) g_intern_string (set_name);
binding_set->widget_path_pspecs = NULL;
binding_set->widget_class_pspecs = NULL;
binding_set->class_branch_pspecs = NULL;
binding_set->entries = NULL;
binding_set->current = NULL;
+ binding_set->parsed = FALSE;
binding_set_list = g_slist_prepend (binding_set_list, binding_set);
return binding_set;
}
+/**
+ * gtk_binding_set_by_class:
+ * @object_class: a valid #GtkObject class
+ *
+ * This function returns the binding set named after the type name of
+ * the passed in class structure. New binding sets are created on
+ * demand by this function.
+ *
+ * Return value: the binding set corresponding to @object_class
+ */
GtkBindingSet*
gtk_binding_set_by_class (gpointer object_class)
{
if (binding_set)
return binding_set;
- binding_set = gtk_binding_set_new (gtk_type_name (GTK_CLASS_TYPE (class)));
+ binding_set = gtk_binding_set_new (g_type_name (G_OBJECT_CLASS_TYPE (class)));
gtk_binding_set_add_path (binding_set,
GTK_PATH_CLASS,
- gtk_type_name (GTK_CLASS_TYPE (class)),
+ g_type_name (G_OBJECT_CLASS_TYPE (class)),
GTK_PATH_PRIO_GTK);
g_dataset_id_set_data (class, key_id_class_binding_set, binding_set);
return binding_set;
}
+/**
+ * gtk_binding_set_find:
+ * @set_name: unique binding set name
+ *
+ * Find a binding set by its globally unique name. The @set_name can
+ * either be a name used for gtk_binding_set_new() or the type name of
+ * a class used in gtk_binding_set_by_class().
+ *
+ * Return value: %NULL or the specified binding set
+ */
GtkBindingSet*
-gtk_binding_set_find (const gchar *set_name)
+gtk_binding_set_find (const gchar *set_name)
{
GSList *slist;
return NULL;
}
+/**
+ * gtk_binding_set_activate:
+ * @binding_set: a #GtkBindingSet set to activate
+ * @keyval: key value of the binding
+ * @modifiers: key modifier of the binding
+ * @object: object to activate when binding found
+ *
+ * Find a key binding matching @keyval and @modifiers within
+ * @binding_set and activate the binding on @object.
+ *
+ * Return value: %TRUE if a binding was found and activated
+ */
gboolean
gtk_binding_set_activate (GtkBindingSet *binding_set,
guint keyval,
return FALSE;
}
+static void
+gtk_binding_entry_clear_internal (GtkBindingSet *binding_set,
+ guint keyval,
+ GdkModifierType modifiers)
+{
+ GtkBindingEntry *entry;
+
+ keyval = gdk_keyval_to_lower (keyval);
+ modifiers = modifiers & BINDING_MOD_MASK ();
+
+ entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
+ if (entry)
+ binding_entry_destroy (entry);
+
+ entry = binding_entry_new (binding_set, keyval, modifiers);
+}
+
+/**
+ * gtk_binding_entry_skip:
+ * @binding_set: a #GtkBindingSet to skip an entry of
+ * @keyval: key value of binding to skip
+ * @modifiers: key modifier of binding to skip
+ *
+ * Install a binding on @binding_set which causes key lookups
+ * to be aborted, to prevent bindings from lower priority sets
+ * to be activated.
+ *
+ * Since: 2.12
+ */
void
-gtk_binding_entry_clear (GtkBindingSet *binding_set,
- guint keyval,
- GdkModifierType modifiers)
+gtk_binding_entry_skip (GtkBindingSet *binding_set,
+ guint keyval,
+ GdkModifierType modifiers)
{
GtkBindingEntry *entry;
-
+
g_return_if_fail (binding_set != NULL);
-
+
keyval = gdk_keyval_to_lower (keyval);
modifiers = modifiers & BINDING_MOD_MASK ();
-
+
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
if (entry)
binding_entry_destroy (entry);
entry = binding_entry_new (binding_set, keyval, modifiers);
+ entry->marks_unbound = TRUE;
}
+/**
+ * gtk_binding_entry_remove:
+ * @binding_set: a #GtkBindingSet to remove an entry of
+ * @keyval: key value of binding to remove
+ * @modifiers: key modifier of binding to remove
+ *
+ * Remove a binding previously installed via
+ * gtk_binding_entry_add_signal() on @binding_set.
+ */
void
gtk_binding_entry_remove (GtkBindingSet *binding_set,
guint keyval,
binding_entry_destroy (entry);
}
+/**
+ * gtk_binding_entry_add_signall:
+ * @binding_set: a #GtkBindingSet to add a signal to
+ * @keyval: key value
+ * @modifiers: key modifier
+ * @signal_name: signal name to be bound
+ * @binding_args: list of #GtkBindingArg signal arguments
+ *
+ * Override or install a new key binding for @keyval with @modifiers on
+ * @binding_set.
+ */
void
gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
- guint keyval,
- GdkModifierType modifiers,
- const gchar *signal_name,
- GSList *binding_args)
+ guint keyval,
+ GdkModifierType modifiers,
+ const gchar *signal_name,
+ GSList *binding_args)
+{
+ _gtk_binding_entry_add_signall (binding_set,
+ keyval, modifiers,
+ signal_name, binding_args);
+}
+
+void
+_gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
+ guint keyval,
+ GdkModifierType modifiers,
+ const gchar *signal_name,
+ GSList *binding_args)
{
GtkBindingEntry *entry;
GtkBindingSignal *signal, **signal_p;
binding_signal_free (signal);
return;
}
- switch (GTK_FUNDAMENTAL_TYPE (tmp_arg->arg_type))
+ switch (G_TYPE_FUNDAMENTAL (tmp_arg->arg_type))
{
- case GTK_TYPE_LONG:
- arg->arg_type = GTK_TYPE_LONG;
+ case G_TYPE_LONG:
+ arg->arg_type = G_TYPE_LONG;
arg->d.long_data = tmp_arg->d.long_data;
break;
- case GTK_TYPE_DOUBLE:
- arg->arg_type = GTK_TYPE_DOUBLE;
+ case G_TYPE_DOUBLE:
+ arg->arg_type = G_TYPE_DOUBLE;
arg->d.double_data = tmp_arg->d.double_data;
break;
- case GTK_TYPE_STRING:
+ case G_TYPE_STRING:
if (tmp_arg->arg_type != GTK_TYPE_IDENTIFIER)
- arg->arg_type = GTK_TYPE_STRING;
+ arg->arg_type = G_TYPE_STRING;
else
arg->arg_type = GTK_TYPE_IDENTIFIER;
arg->d.string_data = g_strdup (tmp_arg->d.string_data);
break;
default:
g_warning ("gtk_binding_entry_add_signall(): unsupported type `%s' for arg[%u]",
- gtk_type_name (arg->arg_type), n);
+ g_type_name (arg->arg_type), n);
binding_signal_free (signal);
return;
}
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
if (!entry)
{
- gtk_binding_entry_add (binding_set, keyval, modifiers);
+ gtk_binding_entry_clear_internal (binding_set, keyval, modifiers);
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
}
signal_p = &entry->signals;
*signal_p = signal;
}
+/**
+ * gtk_binding_entry_add_signal:
+ * @binding_set: a #GtkBindingSet to install an entry for
+ * @keyval: key value of binding to install
+ * @modifiers: key modifier of binding to install
+ * @signal_name: signal to execute upon activation
+ * @n_args: number of arguments to @signal_name
+ * @Varargs: arguments to @signal_name
+ *
+ * Override or install a new key binding for @keyval with @modifiers on
+ * @binding_set. When the binding is activated, @signal_name will be
+ * emitted on the target widget, with @n_args @Varargs used as
+ * arguments.
+ */
void
gtk_binding_entry_add_signal (GtkBindingSet *binding_set,
guint keyval,
g_return_if_fail (binding_set != NULL);
g_return_if_fail (signal_name != NULL);
- keyval = gdk_keyval_to_lower (keyval);
- modifiers = modifiers & BINDING_MOD_MASK ();
-
va_start (args, n_args);
slist = NULL;
for (i = 0; i < n_args; i++)
{
GtkBindingArg *arg;
- arg = g_new0 (GtkBindingArg, 1);
+ arg = g_slice_new0 (GtkBindingArg);
slist = g_slist_prepend (slist, arg);
- arg->arg_type = va_arg (args, GtkType);
- switch (GTK_FUNDAMENTAL_TYPE (arg->arg_type))
+ arg->arg_type = va_arg (args, GType);
+ switch (G_TYPE_FUNDAMENTAL (arg->arg_type))
{
- /* for elaborated commenting about var args collection, take a look
- * at gtk_arg_collect_value() in gtkargcollector.c
- */
- case GTK_TYPE_CHAR:
- case GTK_TYPE_UCHAR:
- case GTK_TYPE_INT:
- case GTK_TYPE_UINT:
- case GTK_TYPE_BOOL:
- case GTK_TYPE_ENUM:
- case GTK_TYPE_FLAGS:
- arg->arg_type = GTK_TYPE_LONG;
+ case G_TYPE_CHAR:
+ case G_TYPE_UCHAR:
+ case G_TYPE_INT:
+ case G_TYPE_UINT:
+ case G_TYPE_BOOLEAN:
+ case G_TYPE_ENUM:
+ case G_TYPE_FLAGS:
+ arg->arg_type = G_TYPE_LONG;
arg->d.long_data = va_arg (args, gint);
break;
- case GTK_TYPE_LONG:
- case GTK_TYPE_ULONG:
- arg->arg_type = GTK_TYPE_LONG;
+ case G_TYPE_LONG:
+ case G_TYPE_ULONG:
+ arg->arg_type = G_TYPE_LONG;
arg->d.long_data = va_arg (args, glong);
break;
- case GTK_TYPE_FLOAT:
- case GTK_TYPE_DOUBLE:
- arg->arg_type = GTK_TYPE_DOUBLE;
+ case G_TYPE_FLOAT:
+ case G_TYPE_DOUBLE:
+ arg->arg_type = G_TYPE_DOUBLE;
arg->d.double_data = va_arg (args, gdouble);
break;
- case GTK_TYPE_STRING:
+ case G_TYPE_STRING:
if (arg->arg_type != GTK_TYPE_IDENTIFIER)
- arg->arg_type = GTK_TYPE_STRING;
+ arg->arg_type = G_TYPE_STRING;
arg->d.string_data = va_arg (args, gchar*);
if (!arg->d.string_data)
{
g_warning ("gtk_binding_entry_add_signal(): type `%s' arg[%u] is `NULL'",
- gtk_type_name (arg->arg_type),
+ g_type_name (arg->arg_type),
i);
i += n_args + 1;
}
break;
default:
g_warning ("gtk_binding_entry_add_signal(): unsupported type `%s' for arg[%u]",
- gtk_type_name (arg->arg_type), i);
+ g_type_name (arg->arg_type), i);
i += n_args + 1;
break;
}
if (i == n_args || i == 0)
{
slist = g_slist_reverse (slist);
- gtk_binding_entry_add_signall (binding_set, keyval, modifiers, signal_name, slist);
+ _gtk_binding_entry_add_signall (binding_set, keyval, modifiers, signal_name, slist);
}
free_slist = slist;
while (slist)
{
- g_free (slist->data);
+ g_slice_free (GtkBindingArg, slist->data);
slist = slist->next;
}
g_slist_free (free_slist);
}
+/**
+ * gtk_binding_set_add_path:
+ * @binding_set: a #GtkBindingSet to add a path to
+ * @path_type: path type the pattern applies to
+ * @path_pattern: the actual match pattern
+ * @priority: binding priority
+ *
+ * This function is used internally by the GtkRC parsing mechanism to
+ * assign match patterns to #GtkBindingSet structures.
+ */
void
gtk_binding_set_add_path (GtkBindingSet *binding_set,
GtkPathType path_type,
}
pspec = g_new (PatternSpec, 1);
- pspec->pspec = g_pattern_spec_new (path_pattern);
+ pspec->type = path_type;
+ if (path_type == GTK_PATH_WIDGET_CLASS)
+ {
+ pspec->pspec = NULL;
+ pspec->path = _gtk_rc_parse_widget_class_path (path_pattern);
+ }
+ else
+ {
+ pspec->pspec = g_pattern_spec_new (path_pattern);
+ pspec->path = NULL;
+ }
+
pspec->seq_id = priority << 28;
pspec->user_data = binding_set;
{
GtkPathPriorityType lprio = tmp_pspec->seq_id >> 28;
- g_pattern_spec_free (pspec->pspec);
- g_free (pspec);
+ pattern_spec_free (pspec);
pspec = NULL;
if (lprio < priority)
{
binding_match_activate (GSList *pspec_list,
GtkObject *object,
guint path_length,
- const gchar *path,
- const gchar *path_reversed)
+ gchar *path,
+ gchar *path_reversed,
+ gboolean *unbound)
{
GSList *slist;
+ *unbound = FALSE;
+
for (slist = pspec_list; slist; slist = slist->next)
{
PatternSpec *pspec;
+ GtkBindingSet *binding_set;
+ binding_set = NULL;
pspec = slist->data;
- if (g_pattern_match (pspec->pspec, path_length, path, path_reversed))
- {
- GtkBindingSet *binding_set;
-
- binding_set = pspec->user_data;
-
- if (gtk_binding_entry_activate (binding_set->current, object))
- return TRUE;
- }
+
+ if (pspec->type == GTK_PATH_WIDGET_CLASS)
+ {
+ if (_gtk_rc_match_widget_class (pspec->path, path_length, path, path_reversed))
+ binding_set = pspec->user_data;
+ }
+ else
+ {
+ if (g_pattern_match (pspec->pspec, path_length, path, path_reversed))
+ binding_set = pspec->user_data;
+ }
+
+ if (binding_set)
+ {
+ if (binding_set->current->marks_unbound)
+ {
+ *unbound = TRUE;
+ return FALSE;
+ }
+
+ if (gtk_binding_entry_activate (binding_set->current, object))
+ return TRUE;
+ }
}
return FALSE;
gboolean is_release)
{
GSList *patterns;
+ GSList *tmp_list;
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;
continue;
binding_set = entry->binding_set;
+
+ if (binding_set->current)
+ continue;
binding_set->current = entry;
switch (path_id)
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);
+ 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);
+ 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;
- GtkType class_type;
-
+ GType class_type;
+ gboolean unbound = FALSE;
+
patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_CLASS, is_release);
- class_type = GTK_OBJECT_TYPE (object);
+ class_type = G_TYPE_FROM_INSTANCE (object);
while (class_type && !handled)
{
guint path_length;
- const gchar *path;
+ gchar *path;
gchar *path_reversed;
-
- path = gtk_type_name (class_type);
+
+ 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);
+ handled = binding_match_activate (patterns, object, path_length, path, path_reversed, &unbound);
+ g_free (path);
g_free (path_reversed);
- class_type = gtk_type_parent (class_type);
+ 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)
+gtk_bindings_activate (GtkObject *object,
+ guint keyval,
+ GdkModifierType modifiers)
{
GSList *entries = NULL;
+ GdkDisplay *display;
GtkKeyHash *key_hash;
gboolean handled = FALSE;
gboolean is_release;
if (!GTK_IS_WIDGET (object))
return FALSE;
- is_release = (BINDING_MOD_MASK () & GDK_RELEASE_MASK) != 0;
+ is_release = (modifiers & GDK_RELEASE_MASK) != 0;
modifiers = modifiers & BINDING_MOD_MASK () & ~GDK_RELEASE_MASK;
- key_hash = binding_key_hash_for_keymap (gdk_keymap_get_default ());
+ 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);
}
/**
- * _gtk_bindings_activate_event:
+ * gtk_bindings_activate_event:
* @object: a #GtkObject (generally must be a widget)
* @event: a #GdkEventKey
*
* @event, and if one was found, activate it.
*
* Return value: %TRUE if a matching key binding was found
- **/
+ *
+ * Since: 2.4
+ */
gboolean
-_gtk_bindings_activate_event (GtkObject *object,
- GdkEventKey *event)
+gtk_bindings_activate_event (GtkObject *object,
+ GdkEventKey *event)
{
GSList *entries = NULL;
+ GdkDisplay *display;
GtkKeyHash *key_hash;
gboolean handled = FALSE;
if (!GTK_IS_WIDGET (object))
return FALSE;
- key_hash = binding_key_hash_for_keymap (gdk_keymap_get_default ());
+ 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->state,
+ BINDING_MOD_MASK () & ~GDK_RELEASE_MASK,
event->group);
handled = gtk_bindings_activate_list (object, entries,
{
need_arg = FALSE;
arg = g_new (GtkBindingArg, 1);
- arg->arg_type = GTK_TYPE_DOUBLE;
+ arg->arg_type = G_TYPE_DOUBLE;
arg->d.double_data = scanner->value.v_float;
if (negate)
{
{
need_arg = FALSE;
arg = g_new (GtkBindingArg, 1);
- arg->arg_type = GTK_TYPE_LONG;
+ arg->arg_type = G_TYPE_LONG;
arg->d.long_data = scanner->value.v_int;
if (negate)
{
{
need_arg = FALSE;
arg = g_new (GtkBindingArg, 1);
- arg->arg_type = GTK_TYPE_STRING;
+ arg->arg_type = G_TYPE_STRING;
arg->d.string_data = g_strdup (scanner->value.v_string);
args = g_slist_prepend (args, arg);
}
if (!(need_arg && seen_comma) && !negate)
{
args = g_slist_reverse (args);
- gtk_binding_entry_add_signall (binding_set,
- keyval,
- modifiers,
- signal,
- args);
+ _gtk_binding_entry_add_signall (binding_set,
+ keyval,
+ modifiers,
+ signal,
+ args);
expected_token = G_TOKEN_NONE;
}
done = TRUE;
GtkBindingArg *arg;
arg = slist->data;
- if (GTK_FUNDAMENTAL_TYPE (arg->arg_type) == GTK_TYPE_STRING)
+ if (G_TYPE_FUNDAMENTAL (arg->arg_type) == G_TYPE_STRING)
g_free (arg->d.string_data);
g_free (arg);
}
{
guint keyval = 0;
GdkModifierType modifiers = 0;
+ gboolean unbind = FALSE;
g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
g_scanner_get_next_token (scanner);
- if (scanner->token != GTK_RC_TOKEN_BIND)
+ if (scanner->token != GTK_RC_TOKEN_BIND &&
+ scanner->token != GTK_RC_TOKEN_UNBIND)
return GTK_RC_TOKEN_BIND;
+ unbind = scanner->token == GTK_RC_TOKEN_UNBIND;
g_scanner_get_next_token (scanner);
if (scanner->token != G_TOKEN_STRING)
return G_TOKEN_STRING;
if (keyval == 0)
return G_TOKEN_STRING;
+ if (unbind)
+ {
+ gtk_binding_entry_skip (binding_set, keyval, modifiers);
+ return G_TOKEN_NONE;
+ }
+
g_scanner_get_next_token (scanner);
+
if (scanner->token != '{')
return '{';
- gtk_binding_entry_clear (binding_set, keyval, modifiers);
-
+ gtk_binding_entry_clear_internal (binding_set, keyval, modifiers);
+
g_scanner_peek_next_token (scanner);
while (scanner->next_token != '}')
{
}
guint
-gtk_binding_parse_binding (GScanner *scanner)
+_gtk_binding_parse_binding (GScanner *scanner)
{
gchar *name;
GtkBindingSet *binding_set;
guint expected_token;
case GTK_RC_TOKEN_BIND:
+ case GTK_RC_TOKEN_UNBIND:
expected_token = gtk_binding_parse_bind (scanner, binding_set);
if (expected_token != G_TOKEN_NONE)
return expected_token;
pspec = slist->data;
- g_pattern_spec_free (pspec->pspec);
- g_free (pspec);
+ pattern_spec_free (pspec);
}
g_slist_free (pattern_specs);
free_pattern_specs (binding_set->widget_class_pspecs);
free_pattern_specs (binding_set->class_branch_pspecs);
- g_free (binding_set->set_name);
g_free (binding_set);
}
/**
* _gtk_binding_reset_parsed:
*
- * Removing all binding sets that were added by
- * gtk_binding_parse_binding()
- **/
+ * Remove all binding sets that were added by gtk_binding_parse_binding().
+ */
void
_gtk_binding_reset_parsed (void)
{
slist = next;
}
}
+
+#define __GTK_BINDINGS_C__
+#include "gtkaliasdef.c"