source: trunk/third/bonobo/bonobo/bonobo-ui-sync-keys.c @ 15579

Revision 15579, 4.9 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15578, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2/*
3 * bonobo-ui-sync-keys.h: The Bonobo UI/XML sync engine for keys bits.
4 *
5 * Author:
6 *      Michael Meeks (michael@helixcode.com)
7 *
8 * Copyright 2000 Helix Code, Inc.
9 */
10
11#include <config.h>
12#include <stdlib.h>
13
14#include <bonobo/bonobo-ui-xml.h>
15#include <bonobo/bonobo-ui-util.h>
16#include <bonobo/bonobo-ui-engine.h>
17#include <bonobo/bonobo-ui-sync.h>
18#include <bonobo/bonobo-ui-sync-keys.h>
19
20static GtkObjectClass *parent_class = NULL;
21
22#define PARENT_TYPE bonobo_ui_sync_get_type ()
23
24#define BINDING_MOD_MASK()                              \
25        (gtk_accelerator_get_default_mod_mask () | GDK_RELEASE_MASK)
26
27typedef struct {
28        guint           key;
29        GdkModifierType mods;
30        BonoboUINode        *node;
31} Binding;
32
33static gboolean
34keybindings_free (gpointer key,
35                  gpointer value,
36                  gpointer user_data)
37{
38        g_free (key);
39
40        return TRUE;
41}
42
43/* Shamelessly stolen from gtkbindings.c */
44static guint
45keybinding_hash_fn (gconstpointer  key)
46{
47        register const Binding *e = key;
48        register guint h;
49
50        h = e->key;
51        h ^= e->mods;
52
53        return h;
54}
55
56static gint
57keybinding_compare_fn (gconstpointer a,
58                       gconstpointer b)
59{
60        register const Binding *ba = a;
61        register const Binding *bb = b;
62
63        return (ba->key == bb->key && ba->mods == bb->mods);
64}
65
66gint
67bonobo_ui_sync_keys_binding_handle (GtkWidget        *widget,
68                                    GdkEventKey      *event,
69                                    BonoboUISyncKeys *msync)
70{
71        Binding lookup, *binding;
72
73        lookup.key  = gdk_keyval_to_lower (event->keyval);
74        lookup.mods = event->state & BINDING_MOD_MASK ();
75
76        if (!(binding = g_hash_table_lookup (
77                msync->keybindings, &lookup)))
78
79                return FALSE;
80        else {
81                bonobo_ui_engine_emit_verb_on (
82                        msync->parent.engine, binding->node);
83
84                return TRUE;
85        }
86       
87        return FALSE;
88}
89
90static void
91impl_destroy (GtkObject *object)
92{
93        BonoboUISyncKeys *sync;
94
95        sync = BONOBO_UI_SYNC_KEYS (object);
96
97        g_hash_table_foreach_remove (sync->keybindings,
98                                     keybindings_free, NULL);
99        g_hash_table_destroy (sync->keybindings);
100        sync->keybindings = NULL;
101
102        parent_class->destroy (object);
103}
104
105static void
106update_keybindings (BonoboUISyncKeys *msync,
107                    BonoboUINode     *node)
108{
109        BonoboUINode    *l;
110        BonoboUIXmlData *data;
111
112        if (!bonobo_ui_engine_node_is_dirty (msync->parent.engine, node))
113                return;
114
115        data = bonobo_ui_xml_get_data (NULL, node);
116        g_return_if_fail (data != NULL);
117
118        if (!data->dirty)
119                return;
120
121        g_hash_table_foreach_remove (
122                msync->keybindings, keybindings_free, NULL);
123
124        for (l = bonobo_ui_node_children (node); l;
125             l = bonobo_ui_node_next (l)) {
126                guint           key;
127                GdkModifierType mods;
128                char           *name;
129                Binding        *binding;
130               
131                name = bonobo_ui_node_get_attr (l, "name");
132                if (!name)
133                        continue;
134               
135                bonobo_ui_util_accel_parse (name, &key, &mods);
136                bonobo_ui_node_free_string (name);
137
138                binding       = g_new0 (Binding, 1);
139                binding->mods = mods & BINDING_MOD_MASK ();
140                binding->key  = gdk_keyval_to_lower (key);
141                binding->node = l;
142
143                g_hash_table_insert (msync->keybindings, binding, binding);
144        }
145}
146
147static void
148impl_bonobo_ui_sync_keys_update_root (BonoboUISync *sync,
149                                      BonoboUINode *root)
150{
151        if (bonobo_ui_node_has_name (root, "keybindings"))
152                update_keybindings (BONOBO_UI_SYNC_KEYS (sync), root);
153}
154
155static void
156impl_bonobo_ui_sync_keys_stamp_root (BonoboUISync *sync)
157{
158        BonoboUINode *node;
159
160        node = bonobo_ui_engine_get_path (sync->engine, "/keybindings");
161
162        if (node)
163                bonobo_ui_engine_node_set_dirty (sync->engine, node, TRUE);
164}
165
166static gboolean
167impl_bonobo_ui_sync_keys_can_handle (BonoboUISync *sync,
168                                     BonoboUINode *node)
169{
170        return bonobo_ui_node_has_name (node, "keybindings");
171}
172
173/* We need to map the shell to the item */
174
175static void
176class_init (BonoboUISyncClass *sync_class)
177{
178        GtkObjectClass *object_class;
179
180        parent_class = gtk_type_class (BONOBO_TYPE_UI_SYNC);
181
182        object_class = GTK_OBJECT_CLASS (sync_class);
183        object_class->destroy  = impl_destroy;
184
185        sync_class->update_root   = impl_bonobo_ui_sync_keys_update_root;
186        sync_class->can_handle    = impl_bonobo_ui_sync_keys_can_handle;
187        sync_class->stamp_root    = impl_bonobo_ui_sync_keys_stamp_root;
188}
189
190static void
191init (BonoboUISyncKeys *msync)
192{
193        msync->keybindings = g_hash_table_new (
194                keybinding_hash_fn, keybinding_compare_fn);     
195}
196
197GtkType
198bonobo_ui_sync_keys_get_type (void)
199{
200        static GtkType type = 0;
201
202        if (type == 0) {
203                static const GtkTypeInfo info = {
204                        "BonoboUISyncKeys",
205                        sizeof (BonoboUISyncKeys),
206                        sizeof (BonoboUISyncKeysClass),
207                        (GtkClassInitFunc)  class_init,
208                        (GtkObjectInitFunc) init,
209                        /* reserved_1 */ NULL,
210                        /* reserved_2 */ NULL,
211                        (GtkClassInitFunc) NULL,
212                };
213
214                type = gtk_type_unique (PARENT_TYPE, &info);
215        }
216
217        return type;
218}
219
220BonoboUISync *
221bonobo_ui_sync_keys_new (BonoboUIEngine *engine)
222{
223        BonoboUISyncKeys *sync;
224
225        g_return_val_if_fail (BONOBO_IS_UI_ENGINE (engine), NULL);
226
227        sync = gtk_type_new (BONOBO_TYPE_UI_SYNC_KEYS);
228
229        return bonobo_ui_sync_construct (
230                BONOBO_UI_SYNC (sync), engine, FALSE, FALSE);
231}
Note: See TracBrowser for help on using the repository browser.