Mercurial > pidgin
annotate finch/libgnt/gntbindable.c @ 18239:726f5e9fd606
I'm sure we'll eventually do something here. Until then ...
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Sat, 23 Jun 2007 06:23:15 +0000 |
parents | 1cedd520cd18 |
children | 3ee6ea8a66f8 fd01bac27b79 |
rev | line source |
---|---|
18049
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
1 /** |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
2 * GNT - The GLib Ncurses Toolkit |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
3 * |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
4 * GNT is the legal property of its developers, whose names are too numerous |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
5 * to list here. Please refer to the COPYRIGHT file distributed with this |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
6 * source distribution. |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
7 * |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
8 * This library is free software; you can redistribute it and/or modify |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
9 * it under the terms of the GNU General Public License as published by |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
10 * the Free Software Foundation; either version 2 of the License, or |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
11 * (at your option) any later version. |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
12 * |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
13 * This program is distributed in the hope that it will be useful, |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
16 * GNU General Public License for more details. |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
17 * |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
18 * You should have received a copy of the GNU General Public License |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
19 * along with this program; if not, write to the Free Software |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
21 */ |
1cedd520cd18
Doxygen skeleton and license info for gnt files.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
15817
diff
changeset
|
22 |
15817 | 23 #include "gntbindable.h" |
24 #include "gntstyle.h" | |
25 #include "gnt.h" | |
26 #include "gntutils.h" | |
27 | |
28 static GObjectClass *parent_class = NULL; | |
29 | |
30 static void | |
31 gnt_bindable_class_init(GntBindableClass *klass) | |
32 { | |
33 parent_class = g_type_class_peek_parent(klass); | |
34 | |
35 klass->actions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, | |
36 (GDestroyNotify)gnt_bindable_action_free); | |
37 klass->bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, | |
38 (GDestroyNotify)gnt_bindable_action_param_free); | |
39 | |
40 gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); | |
41 GNTDEBUG; | |
42 } | |
43 | |
44 static gpointer | |
45 bindable_clone(GntBindableAction *action) | |
46 { | |
47 GntBindableAction *ret = g_new0(GntBindableAction, 1); | |
48 ret->name = g_strdup(action->name); | |
49 ret->u = action->u; | |
50 return ret; | |
51 } | |
52 | |
53 static gpointer | |
54 binding_clone(GntBindableActionParam *param) | |
55 { | |
56 GntBindableActionParam *p = g_new0(GntBindableActionParam, 1); | |
57 p->list = g_list_copy(param->list); | |
58 p->action = param->action; | |
59 return p; | |
60 } | |
61 | |
62 static void | |
63 duplicate_hashes(GntBindableClass *klass) | |
64 { | |
65 /* Duplicate the bindings from parent class */ | |
66 if (klass->actions) { | |
67 klass->actions = g_hash_table_duplicate(klass->actions, g_str_hash, | |
68 g_str_equal, g_free, (GDestroyNotify)gnt_bindable_action_free, | |
69 (GDupFunc)g_strdup, (GDupFunc)bindable_clone); | |
70 klass->bindings = g_hash_table_duplicate(klass->bindings, g_str_hash, | |
71 g_str_equal, g_free, (GDestroyNotify)gnt_bindable_action_param_free, | |
72 (GDupFunc)g_strdup, (GDupFunc)binding_clone); | |
73 } else { | |
74 klass->actions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, | |
75 (GDestroyNotify)gnt_bindable_action_free); | |
76 klass->bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, | |
77 (GDestroyNotify)gnt_bindable_action_param_free); | |
78 } | |
79 | |
80 GNTDEBUG; | |
81 } | |
82 | |
83 /****************************************************************************** | |
84 * GntBindable API | |
85 *****************************************************************************/ | |
86 GType | |
87 gnt_bindable_get_gtype(void) | |
88 { | |
89 static GType type = 0; | |
90 | |
91 if(type == 0) { | |
92 static const GTypeInfo info = { | |
93 sizeof(GntBindableClass), | |
94 (GBaseInitFunc)duplicate_hashes, /* base_init */ | |
95 NULL, /* base_finalize */ | |
96 (GClassInitFunc)gnt_bindable_class_init, | |
97 NULL, | |
98 NULL, /* class_data */ | |
99 sizeof(GntBindable), | |
100 0, /* n_preallocs */ | |
101 NULL, /* instance_init */ | |
102 NULL /* value_table */ | |
103 }; | |
104 | |
105 type = g_type_register_static(G_TYPE_OBJECT, | |
106 "GntBindable", | |
107 &info, G_TYPE_FLAG_ABSTRACT); | |
108 } | |
109 | |
110 return type; | |
111 } | |
112 | |
113 /** | |
114 * Key Remaps | |
115 */ | |
116 const char * | |
117 gnt_bindable_remap_keys(GntBindable *bindable, const char *text) | |
118 { | |
119 const char *remap = NULL; | |
120 GType type = G_OBJECT_TYPE(bindable); | |
121 GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bindable)); | |
122 | |
123 if (klass->remaps == NULL) | |
124 { | |
125 klass->remaps = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
126 gnt_styles_get_keyremaps(type, klass->remaps); | |
127 } | |
128 | |
129 remap = g_hash_table_lookup(klass->remaps, text); | |
130 | |
131 return (remap ? remap : text); | |
132 } | |
133 | |
134 /** | |
135 * Actions and Bindings | |
136 */ | |
137 gboolean | |
138 gnt_bindable_perform_action_named(GntBindable *bindable, const char *name, ...) | |
139 { | |
140 GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bindable)); | |
141 GList *list = NULL; | |
142 va_list args; | |
143 GntBindableAction *action; | |
144 void *p; | |
145 | |
146 va_start(args, name); | |
147 while ((p = va_arg(args, void *)) != NULL) | |
148 list = g_list_append(list, p); | |
149 va_end(args); | |
150 | |
151 action = g_hash_table_lookup(klass->actions, name); | |
152 if (action && action->u.action) { | |
153 return action->u.action(bindable, list); | |
154 } | |
155 return FALSE; | |
156 } | |
157 | |
158 gboolean | |
159 gnt_bindable_perform_action_key(GntBindable *bindable, const char *keys) | |
160 { | |
161 GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bindable)); | |
162 GntBindableActionParam *param = g_hash_table_lookup(klass->bindings, keys); | |
163 | |
164 if (param && param->action) { | |
165 if (param->list) | |
166 return param->action->u.action(bindable, param->list); | |
167 else | |
168 return param->action->u.action_noparam(bindable); | |
169 } | |
170 return FALSE; | |
171 } | |
172 | |
173 static void | |
174 register_binding(GntBindableClass *klass, const char *name, const char *trigger, GList *list) | |
175 { | |
176 GntBindableActionParam *param; | |
177 GntBindableAction *action; | |
178 | |
179 if (name == NULL || *name == '\0') { | |
180 g_hash_table_remove(klass->bindings, (char*)trigger); | |
181 gnt_keys_del_combination(trigger); | |
182 return; | |
183 } | |
184 | |
185 action = g_hash_table_lookup(klass->actions, name); | |
186 if (!action) { | |
187 g_printerr("GntWidget: Invalid action name %s for %s\n", | |
188 name, g_type_name(G_OBJECT_CLASS_TYPE(klass))); | |
189 if (list) | |
190 g_list_free(list); | |
191 return; | |
192 } | |
193 | |
194 param = g_new0(GntBindableActionParam, 1); | |
195 param->action = action; | |
196 param->list = list; | |
197 g_hash_table_replace(klass->bindings, g_strdup(trigger), param); | |
198 gnt_keys_add_combination(trigger); | |
199 } | |
200 | |
201 void gnt_bindable_register_binding(GntBindableClass *klass, const char *name, | |
202 const char *trigger, ...) | |
203 { | |
204 GList *list = NULL; | |
205 va_list args; | |
206 void *data; | |
207 | |
208 va_start(args, trigger); | |
209 while ((data = va_arg(args, void *))) { | |
210 list = g_list_append(list, data); | |
211 } | |
212 va_end(args); | |
213 | |
214 register_binding(klass, name, trigger, list); | |
215 } | |
216 | |
217 void gnt_bindable_class_register_action(GntBindableClass *klass, const char *name, | |
218 GntBindableActionCallback callback, const char *trigger, ...) | |
219 { | |
220 void *data; | |
221 va_list args; | |
222 GntBindableAction *action = g_new0(GntBindableAction, 1); | |
223 GList *list; | |
224 | |
225 action->name = g_strdup(name); | |
226 action->u.action = callback; | |
227 | |
228 g_hash_table_replace(klass->actions, g_strdup(name), action); | |
229 | |
230 if (trigger && *trigger) { | |
231 list = NULL; | |
232 va_start(args, trigger); | |
233 while ((data = va_arg(args, void *))) { | |
234 list = g_list_append(list, data); | |
235 } | |
236 va_end(args); | |
237 | |
238 register_binding(klass, name, trigger, list); | |
239 } | |
240 } | |
241 | |
242 void gnt_bindable_action_free(GntBindableAction *action) | |
243 { | |
244 g_free(action->name); | |
245 g_free(action); | |
246 } | |
247 | |
248 void gnt_bindable_action_param_free(GntBindableActionParam *param) | |
249 { | |
250 g_list_free(param->list); /* XXX: There may be a leak here for string parameters */ | |
251 g_free(param); | |
252 } | |
253 | |
254 |