Fix small typo
[gmpc.git] / src / mm-keys.c
blob59980efaf904edbccff8b0e753fe0a0504934355
1 /*
2 * Copyright (C) 2004-2007 Qball Cow <qball@sarine.nl>
3 * Borrowed from Lee Willis <lee@leewillis.co.uk> that
4 * Borrowed heavily from code by Jan Arne Petersen <jpetersen@uni-bonn.de>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
21 #include <config.h>
22 #ifdef ENABLE_MMKEYS
24 #include <stdio.h>
25 #include "mm-keys.h"
26 #include "eggcellrendererkeys.h"
28 static void mmkeys_class_init (MmKeysClass *klass);
29 static void mmkeys_init (MmKeys *object);
30 static void mmkeys_finalize (GObject *object);
32 static int grab_mmkey (int key_code, unsigned int mask, GdkWindow *root);
34 static GdkFilterReturn filter_mmkeys (GdkXEvent *xevent,
35 GdkEvent *event,
36 gpointer data);
38 #define FG_DEFAULT None
39 #define FG_ERROR "red"
41 /* Members of the treestore */
42 enum {
43 MM_STORE_KEYNAME = 0,
44 MM_STORE_INDEX,
45 MM_STORE_KEYCODE,
46 MM_STORE_MASK,
47 MM_STORE_KEYVAL,
48 MM_STORE_FOREGROUND,
49 MM_STORE_COUNT,
52 enum {
53 MM_PLAYPAUSE,
54 MM_NEXT,
55 MM_PREV,
56 MM_STOP,
57 MM_FASTFORWARD,
58 MM_FASTBACKWARD,
59 MM_REPEAT,
60 MM_RANDOM,
61 MM_RAISE,
62 MM_HIDE,
63 MM_TOGGLE_HIDDEN,
64 MM_VOLUME_UP,
65 MM_VOLUME_DOWN,
66 MM_SHOW_NOTIFICATION,
67 LAST_SIGNAL
70 char *keynames[LAST_SIGNAL] = {
71 N_("PlayPause"), /** MM_PLAYPAUSE */
72 N_("Next"), /** MM_NEXT*/
73 N_("Previous"), /** MM_PREV */
74 N_("Stop"), /** MM_STOP */
75 N_("Fast Forward"), /** MM_FASTFORWARD */
76 N_("Fast Backward"), /** MM_FASTBACKWARD */
77 N_("Repeat"), /** MM_REPEAT */
78 N_("Random"), /** MM_RANDOM */
79 N_("Raise window"), /** MM_RAISE */
80 N_("Hide window"), /** MM_HIDE */
81 N_("Toggle window"), /** MM_TOGGLE_HIDDEN */
82 N_("Volume Up"), /** MM_VOLUME_UP */
83 N_("Volume Down"), /** MM_VOLUME_DOWN */
84 N_("Show song"), /** MM_SHOW_NOTIFICATION */
85 };
87 static GObjectClass *parent_class;
88 static guint signals[LAST_SIGNAL];
89 static int keycodes[LAST_SIGNAL];
90 static unsigned int masks[LAST_SIGNAL];
91 static int keyerror[LAST_SIGNAL];
93 static GType type = 0;
95 static GType mmkeys_get_type (void)
97 if (!type) {
98 static const GTypeInfo info = {
99 sizeof (MmKeysClass),
100 NULL, /* base_init */
101 NULL, /* base_finalize */
102 (GClassInitFunc) mmkeys_class_init,
103 NULL, /* class_finalize */
104 NULL, /* class_data */
105 sizeof (MmKeys),
107 (GInstanceInitFunc) mmkeys_init,
110 type = g_type_register_static (G_TYPE_OBJECT, "MmKeys",&info, 0);
113 return type;
116 static void mmkeys_class_init (MmKeysClass *klass)
118 GObjectClass *object_class;
120 parent_class = g_type_class_peek_parent (klass);
121 object_class = (GObjectClass*) klass;
123 object_class->finalize = mmkeys_finalize;
125 signals[MM_PLAYPAUSE] =
126 g_signal_new ("mm_playpause",
127 G_TYPE_FROM_CLASS (klass),
128 G_SIGNAL_RUN_LAST,
130 NULL, NULL,
131 g_cclosure_marshal_VOID__INT,
132 G_TYPE_NONE, 1, G_TYPE_INT);
133 signals[MM_PREV] =
134 g_signal_new ("mm_prev",
135 G_TYPE_FROM_CLASS (klass),
136 G_SIGNAL_RUN_LAST,
138 NULL, NULL,
139 g_cclosure_marshal_VOID__INT,
140 G_TYPE_NONE, 1, G_TYPE_INT);
141 signals[MM_NEXT] =
142 g_signal_new ("mm_next",
143 G_TYPE_FROM_CLASS (klass),
144 G_SIGNAL_RUN_LAST,
146 NULL, NULL,
147 g_cclosure_marshal_VOID__INT,
148 G_TYPE_NONE, 1, G_TYPE_INT);
149 signals[MM_STOP] =
150 g_signal_new ("mm_stop",
151 G_TYPE_FROM_CLASS (klass),
152 G_SIGNAL_RUN_LAST,
154 NULL, NULL,
155 g_cclosure_marshal_VOID__INT,
156 G_TYPE_NONE, 1, G_TYPE_INT);
157 signals[MM_FASTFORWARD] =
158 g_signal_new ("mm_fastforward",
159 G_TYPE_FROM_CLASS (klass),
160 G_SIGNAL_RUN_LAST,
162 NULL, NULL,
163 g_cclosure_marshal_VOID__INT,
164 G_TYPE_NONE, 1, G_TYPE_INT);
165 signals[MM_FASTBACKWARD]=
166 g_signal_new ("mm_fastbackward",
167 G_TYPE_FROM_CLASS (klass),
168 G_SIGNAL_RUN_LAST,
170 NULL, NULL,
171 g_cclosure_marshal_VOID__INT,
172 G_TYPE_NONE, 1, G_TYPE_INT);
173 signals[MM_REPEAT]=
174 g_signal_new ("mm_repeat",
175 G_TYPE_FROM_CLASS (klass),
176 G_SIGNAL_RUN_LAST,
178 NULL, NULL,
179 g_cclosure_marshal_VOID__INT,
180 G_TYPE_NONE, 1, G_TYPE_INT);
181 signals[MM_RANDOM]=
182 g_signal_new ("mm_random",
183 G_TYPE_FROM_CLASS (klass),
184 G_SIGNAL_RUN_LAST,
186 NULL, NULL,
187 g_cclosure_marshal_VOID__INT,
188 G_TYPE_NONE, 1, G_TYPE_INT);
189 signals[MM_RAISE]=
190 g_signal_new ("mm_raise",
191 G_TYPE_FROM_CLASS (klass),
192 G_SIGNAL_RUN_LAST,
194 NULL, NULL,
195 g_cclosure_marshal_VOID__INT,
196 G_TYPE_NONE, 1, G_TYPE_INT);
197 signals[MM_HIDE]=
198 g_signal_new ("mm_hide",
199 G_TYPE_FROM_CLASS (klass),
200 G_SIGNAL_RUN_LAST,
202 NULL, NULL,
203 g_cclosure_marshal_VOID__INT,
204 G_TYPE_NONE, 1, G_TYPE_INT);
205 signals[MM_TOGGLE_HIDDEN]=
206 g_signal_new ("mm_toggle_hidden",
207 G_TYPE_FROM_CLASS (klass),
208 G_SIGNAL_RUN_LAST,
210 NULL, NULL,
211 g_cclosure_marshal_VOID__INT,
212 G_TYPE_NONE, 1, G_TYPE_INT);
213 signals[MM_VOLUME_UP] =
214 g_signal_new ("mm_volume_up",
215 G_TYPE_FROM_CLASS (klass),
216 G_SIGNAL_RUN_LAST,
218 NULL, NULL,
219 g_cclosure_marshal_VOID__INT,
220 G_TYPE_NONE, 1, G_TYPE_INT);
222 signals[MM_VOLUME_DOWN] =
223 g_signal_new ("mm_volume_down",
224 G_TYPE_FROM_CLASS (klass),
225 G_SIGNAL_RUN_LAST,
227 NULL, NULL,
228 g_cclosure_marshal_VOID__INT,
229 G_TYPE_NONE, 1, G_TYPE_INT);
230 signals[MM_SHOW_NOTIFICATION] =
231 g_signal_new ("mm_show_notification",
232 G_TYPE_FROM_CLASS (klass),
233 G_SIGNAL_RUN_LAST,
235 NULL, NULL,
236 g_cclosure_marshal_VOID__INT,
237 G_TYPE_NONE, 1, G_TYPE_INT);
240 static void mmkeys_finalize (GObject *object)
242 parent_class->finalize (G_OBJECT(object));
245 static void mmkeys_init (MmKeys *object)
247 GdkDisplay *display;
248 GdkScreen *screen;
249 GdkWindow *root;
250 guint i, j;
251 int keycode = 0;
252 int anyKeybindsFailed = FALSE;
253 int anyDuplicatesFound = FALSE;
255 display = gdk_display_get_default ();
258 /** Play Pause */
259 keycode = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPlay);
260 keycodes[MM_PLAYPAUSE] = cfg_get_single_value_as_int_with_default(config, "Keybindings", keynames[MM_PLAYPAUSE], keycode);
261 masks[MM_PLAYPAUSE] = cfg_get_single_value_as_int_with_default(config, "Keymasks", keynames[MM_PLAYPAUSE], 0);
263 * Previous
265 keycode = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPrev);
266 keycodes[MM_PREV] = cfg_get_single_value_as_int_with_default(config, "Keybindings", keynames[MM_PREV], keycode);
267 masks[MM_PREV] = cfg_get_single_value_as_int_with_default(config, "Keymasks", keynames[MM_PREV], 0);
269 * Next
271 keycode = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioNext);
272 keycodes[MM_NEXT] = cfg_get_single_value_as_int_with_default(config, "Keybindings", keynames[MM_NEXT], keycode);
273 masks[MM_NEXT] = cfg_get_single_value_as_int_with_default(config, "Keymasks", keynames[MM_NEXT], 0);
275 * Stop
277 keycode = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioStop);
278 keycodes[MM_STOP] = cfg_get_single_value_as_int_with_default(config, "Keybindings", keynames[MM_STOP], keycode);
279 masks[MM_STOP] = cfg_get_single_value_as_int_with_default(config, "Keymasks", keynames[MM_STOP], 0);
281 for(i=0;i<LAST_SIGNAL;i++)
283 keycodes[i] = cfg_get_single_value_as_int_with_default(config, "Keybindings", keynames[i], 0);
284 masks[i] = cfg_get_single_value_as_int_with_default(config, "Keymasks", keynames[i], 0);
285 keyerror[i] = FALSE;
286 /* Detect duplicates */
287 for(j=0;j<i;j++)
289 if (keycodes[i] != 0 &&
290 keycodes[i] == keycodes[j] &&
291 masks[i] == masks[j])
293 anyDuplicatesFound = TRUE;
294 keycodes[i] = 0;
295 masks[i] = 0;
296 keyerror[i] = TRUE;
297 cfg_set_single_value_as_int(config, "Keybindings", keynames[i], 0);
298 cfg_set_single_value_as_int(config, "Keymasks", keynames[i], 0);
303 for (i = 0; i < gdk_display_get_n_screens (display); i++) {
304 screen = gdk_display_get_screen (display, i);
305 if (screen != NULL) {
306 root = gdk_screen_get_root_window (screen);
308 for (j = 0; j < LAST_SIGNAL;j++) {
309 if (keycodes[j] > 0)
310 if( !grab_mmkey (keycodes[j], masks[j], root) )
312 keyerror[j] = TRUE;
313 anyKeybindsFailed = TRUE;
317 gdk_window_add_filter (root, filter_mmkeys, object);
321 if (anyKeybindsFailed)
323 GString *message = g_string_new (_("Could not grab the following multimedia keys:\n\n"));
324 for (i=0;i<LAST_SIGNAL;i++)
326 if (keyerror[i] && keycodes[i] != 0)
328 gchar *rawkeysym = egg_virtual_accelerator_name (
329 XKeycodeToKeysym(GDK_DISPLAY(), keycodes[i], 0),
330 keycodes[i], masks[i]);
331 gchar *keysym = g_markup_escape_text(rawkeysym, -1);
332 q_free (rawkeysym);
333 g_string_append_printf( message,
334 "\t%s: %s\n",
335 _(keynames[i]), keysym );
336 q_free (keysym);
339 g_string_append( message,
340 _("\nEnsure that your window manager (or other applications) have not already bound this key for some other function, then restart gmpc." ));
341 show_error_message (message->str, TRUE);
342 g_string_free (message, TRUE);
345 if (anyDuplicatesFound)
347 show_error_message(_("Duplicate mapping(s) detected\n\n"
348 "Some duplicate multimedia key mappings were detected, and disabled. Please revisit the preferences and ensure your settings are now correct."), TRUE );
352 MmKeys * mmkeys_new (void)
354 return MMKEYS (g_object_new (TYPE_MMKEYS, NULL));
358 static int grab_mmkey (int key_code, unsigned int mask, GdkWindow *root)
360 gdk_error_trap_push ();
362 XGrabKey (GDK_DISPLAY (), key_code,
363 mask,
364 GDK_WINDOW_XID (root), True,
365 GrabModeAsync, GrabModeAsync);
366 XGrabKey (GDK_DISPLAY (), key_code,
367 Mod2Mask | mask,
368 GDK_WINDOW_XID (root), True,
369 GrabModeAsync, GrabModeAsync);
370 XGrabKey (GDK_DISPLAY (), key_code,
371 Mod5Mask | mask,
372 GDK_WINDOW_XID (root), True,
373 GrabModeAsync, GrabModeAsync);
374 XGrabKey (GDK_DISPLAY (), key_code,
375 LockMask | mask,
376 GDK_WINDOW_XID (root), True,
377 GrabModeAsync, GrabModeAsync);
378 XGrabKey (GDK_DISPLAY (), key_code,
379 Mod2Mask | Mod5Mask | mask,
380 GDK_WINDOW_XID (root), True,
381 GrabModeAsync, GrabModeAsync);
382 XGrabKey (GDK_DISPLAY (), key_code,
383 Mod2Mask | LockMask | mask,
384 GDK_WINDOW_XID (root), True,
385 GrabModeAsync, GrabModeAsync);
386 XGrabKey (GDK_DISPLAY (), key_code,
387 Mod5Mask | LockMask | mask,
388 GDK_WINDOW_XID (root), True,
389 GrabModeAsync, GrabModeAsync);
390 XGrabKey (GDK_DISPLAY (), key_code,
391 Mod2Mask | Mod5Mask | LockMask | mask,
392 GDK_WINDOW_XID (root), True,
393 GrabModeAsync, GrabModeAsync);
395 gdk_flush ();
396 if (gdk_error_trap_pop ()) {
397 debug_printf (DEBUG_INFO, "Error grabbing key %d+%d, %p\n", key_code, mask, root);
398 return FALSE;
400 return TRUE;
403 static GdkFilterReturn filter_mmkeys (GdkXEvent *xevent, GdkEvent *event, gpointer data)
405 int i;
406 XEvent *xev;
407 XKeyEvent *key;
408 unsigned int keystate;
410 xev = (XEvent *) xevent;
411 if (xev->type != KeyPress) {
412 return GDK_FILTER_CONTINUE;
415 key = (XKeyEvent *) xevent;
416 keystate = key->state & ~(Mod2Mask | Mod5Mask | LockMask);
417 for(i=0; i < LAST_SIGNAL;i++)
419 if(keycodes[i] == key->keycode && masks[i] == keystate )
421 g_signal_emit (data, signals[i], 0, 0);
422 debug_printf(DEBUG_INFO, "%s pressed", keynames[i]);
423 return GDK_FILTER_REMOVE;
427 return GDK_FILTER_CONTINUE;
431 static void ungrab_mmkey (int key_code, int mask, GdkWindow *root)
433 gdk_error_trap_push ();
435 XUngrabKey (GDK_DISPLAY (), key_code,
436 mask,
437 GDK_WINDOW_XID (root));
438 XUngrabKey (GDK_DISPLAY (), key_code,
439 Mod2Mask | mask,
440 GDK_WINDOW_XID (root));
441 XUngrabKey (GDK_DISPLAY (), key_code,
442 Mod5Mask | mask,
443 GDK_WINDOW_XID (root));
444 XUngrabKey (GDK_DISPLAY (), key_code,
445 LockMask | mask,
446 GDK_WINDOW_XID (root));
447 XUngrabKey (GDK_DISPLAY (), key_code,
448 Mod2Mask | Mod5Mask | mask,
449 GDK_WINDOW_XID (root));
450 XUngrabKey (GDK_DISPLAY (), key_code,
451 Mod2Mask | LockMask | mask,
452 GDK_WINDOW_XID (root));
453 XUngrabKey (GDK_DISPLAY (), key_code,
454 Mod5Mask | LockMask | mask,
455 GDK_WINDOW_XID (root));
456 XUngrabKey (GDK_DISPLAY (), key_code,
457 Mod2Mask | Mod5Mask | LockMask | mask,
458 GDK_WINDOW_XID (root));
460 gdk_flush ();
461 if (gdk_error_trap_pop ()) {
462 debug_printf (DEBUG_INFO, "Error ungrabbing key %d+%d, %p\n", key_code, mask, root);
468 void grab_key(int key, int keycode, unsigned int mask)
470 GdkDisplay *display;
471 GdkScreen *screen;
472 GdkWindow *root;
473 guint i;
474 display = gdk_display_get_default ();
476 /* remove old key */
477 if(keycodes[key] > 0)
479 for (i = 0; i < gdk_display_get_n_screens (display); i++) {
480 screen = gdk_display_get_screen (display, i);
481 if (screen != NULL) {
482 root = gdk_screen_get_root_window (screen);
483 ungrab_mmkey (keycodes[key], masks[key], root);
487 keycodes[key] = 0;
488 masks[key] = 0;
489 keyerror[key] = FALSE;
490 if(keycode >0)
492 keycodes[key] = keycode;
493 masks[key] = mask;
495 for (i = 0; i < gdk_display_get_n_screens (display); i++) {
496 screen = gdk_display_get_screen (display, i);
497 if (screen != NULL) {
498 root = gdk_screen_get_root_window (screen);
499 if (!grab_mmkey (keycodes[key], masks[key], root))
501 /* Grab failed */
502 keyerror[key] = TRUE;
507 cfg_set_single_value_as_int(config,"Keybindings", keynames[key], keycodes[key]);
508 cfg_set_single_value_as_int(config,"Keymasks", keynames[key], masks[key]);
511 /*****
512 * Multimedia key plugin for config panel
514 void mmkeys_pref_destroy(GtkWidget *container);
515 void mmkeys_pref_construct(GtkWidget *container);
516 GladeXML *mmkeys_pref_xml = NULL;
518 gmpcPrefPlugin mmkeys_gpp = {
519 .construct = mmkeys_pref_construct,
520 .destroy = mmkeys_pref_destroy
523 gmpcPlugin mmkeys_plug =
525 . name = N_("Multimedia Keys"),
526 .version = {1,1,1},
527 .plugin_type = GMPC_INTERNALL,
528 .pref = &mmkeys_gpp /* preferences */
531 static void accel_cleared_callback(GtkCellRendererText *cell, const char *path_string, gpointer data)
533 GtkTreeModel *model = (GtkTreeModel *)data;
534 GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
535 GtkTreeIter iter;
536 int key;
538 gtk_tree_model_get_iter (model, &iter, path);
540 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
541 MM_STORE_KEYCODE, 0,
542 MM_STORE_MASK, 0,
543 MM_STORE_KEYVAL, 0,
544 MM_STORE_FOREGROUND, FG_DEFAULT,
545 -1);
546 gtk_tree_path_free (path);
547 gtk_tree_model_get(model, &iter, 1, &key, -1);
548 grab_key(key, 0, 0);
551 static void
552 accel_edited_callback (GtkCellRendererText *cell,
553 const char *path_string,
554 guint keyval,
555 GdkModifierType mask,
556 guint hardware_keycode,
557 gpointer data)
559 GtkTreeModel *model = (GtkTreeModel *)data;
560 GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
561 GtkTreeIter iter;
562 int key;
563 int i;
565 gtk_tree_model_get_iter (model, &iter, path);
567 debug_printf(DEBUG_INFO, "EggCellRenderKeys grabbed %d %u", mask, hardware_keycode );
568 if(hardware_keycode == 22)
570 hardware_keycode = 0;
573 gtk_tree_model_get(model, &iter, 1, &key, -1);
575 /* Check for duplicates */
576 for (i=0;i<LAST_SIGNAL;i++) {
577 if (i == key)
578 continue;
579 if (hardware_keycode != 0 &&
580 keycodes[i] == hardware_keycode &&
581 masks[i] == mask)
583 gchar *message;
584 gchar *rawkeysym = egg_virtual_accelerator_name (
585 XKeycodeToKeysym(GDK_DISPLAY(), hardware_keycode, 0),
586 hardware_keycode, mask);
587 gchar *keysym = g_markup_escape_text(rawkeysym, -1);
588 q_free (rawkeysym);
589 message = g_strdup_printf( _("<b>Duplicate mapping detected</b>\n\n"
590 "%s is already mapped to %s"),
591 keysym, _(keynames[i]) );
592 q_free (keysym);
593 show_error_message (message, TRUE);
594 q_free (message);
596 /* Clear the duplicate entry */
597 accel_cleared_callback(cell, path_string, data);
598 return;
602 grab_key(key, hardware_keycode, mask);
603 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
604 MM_STORE_KEYCODE, hardware_keycode,
605 MM_STORE_MASK, mask,
606 MM_STORE_KEYVAL, keyval,
607 MM_STORE_FOREGROUND, keyerror[key] ? FG_ERROR : FG_DEFAULT,
608 -1);
609 gtk_tree_path_free (path);
610 if( keyerror[key] )
612 gchar *message;
613 gchar *rawkeysym = egg_virtual_accelerator_name (
614 XKeycodeToKeysym(GDK_DISPLAY(), keycodes[key], 0),
615 keycodes[key], masks[key]);
616 gchar *keysym = g_markup_escape_text(rawkeysym, -1);
617 q_free (rawkeysym);
618 message = g_strdup_printf(
619 _("Could not grab multimedia key:\n\n"
620 "\t%s: %s\n\n"
621 "Ensure that your window manager (or other applications) have not already bound this key for some other function, then restart gmpc."),
622 _(keynames[key]), keysym );
623 q_free (keysym);
624 show_error_message (message, TRUE);
625 q_free (message);
636 void mmkeys_pref_destroy(GtkWidget *container)
638 if(mmkeys_pref_xml)
640 GtkWidget *vbox = glade_xml_get_widget(mmkeys_pref_xml, "mmkeys-vbox");
641 gtk_container_remove(GTK_CONTAINER(container),vbox);
642 g_object_unref(mmkeys_pref_xml);
643 mmkeys_pref_xml = NULL;
647 void mmkeys_pref_construct(GtkWidget *container)
649 gchar *path = gmpc_get_full_glade_path("gmpc.glade");
650 mmkeys_pref_xml = glade_xml_new(path, "mmkeys-vbox",NULL);
651 q_free(path);
652 if(mmkeys_pref_xml)
654 int i=0;
655 GtkWidget *vbox = glade_xml_get_widget(mmkeys_pref_xml, "mmkeys-vbox");
656 GtkTreeViewColumn *column = NULL;
657 GtkListStore *store = gtk_list_store_new(MM_STORE_COUNT,
658 G_TYPE_STRING, /* MM_STORE_KEYNAME */
659 G_TYPE_INT, /* MM_STORE_INDEX */
660 G_TYPE_UINT, /* MM_STORE_KEYCODE */
661 G_TYPE_UINT, /* MM_STORE_MASK */
662 G_TYPE_UINT, /* MM_STORE_KEYVAL */
663 G_TYPE_STRING /* MM_STORE_FOREGROUND */
665 GtkCellRenderer *rend =gtk_cell_renderer_text_new();
666 gtk_tree_view_set_model(GTK_TREE_VIEW (glade_xml_get_widget(mmkeys_pref_xml, "mmkeys-tree")), GTK_TREE_MODEL(store));
668 column = gtk_tree_view_column_new();
669 gtk_tree_view_column_pack_start(column, rend, TRUE);
670 gtk_tree_view_column_add_attribute(column, rend,
671 "text", MM_STORE_KEYNAME);
672 gtk_tree_view_column_set_title(column, _("Action"));
673 gtk_tree_view_append_column(GTK_TREE_VIEW (glade_xml_get_widget(mmkeys_pref_xml, "mmkeys-tree")), column);
675 rend = egg_cell_renderer_keys_new ();
676 column = gtk_tree_view_column_new ();
678 /* g_object_set (G_OBJECT (rend), "accel_mode", EGG_CELL_RENDERER_KEYS_MODE_X);*/
679 egg_cell_renderer_keys_set_accel_mode(EGG_CELL_RENDERER_KEYS(rend), EGG_CELL_RENDERER_KEYS_MODE_GTK);
680 g_object_set (G_OBJECT (rend), "editable", TRUE, NULL);
682 g_signal_connect (G_OBJECT (rend),
683 "accel_edited",
684 G_CALLBACK (accel_edited_callback),
685 store);
687 g_signal_connect (G_OBJECT (rend),
688 "accel_cleared",
689 G_CALLBACK (accel_cleared_callback),
690 store);
691 gtk_tree_view_column_pack_start (column, rend,
692 TRUE);
693 gtk_tree_view_column_set_title(column, _("Shortcut"));
694 gtk_tree_view_column_set_attributes (column, rend,
695 "keycode", MM_STORE_KEYCODE,
696 "accel_mask", MM_STORE_MASK,
697 "accel_key", MM_STORE_KEYVAL,
698 "foreground", MM_STORE_FOREGROUND,
699 NULL);
700 gtk_tree_view_append_column (GTK_TREE_VIEW (glade_xml_get_widget(mmkeys_pref_xml, "mmkeys-tree")), column);
702 gtk_container_add(GTK_CONTAINER(container),vbox);
703 for(i=0;i< LAST_SIGNAL;i++)
705 GtkTreeIter iter;
706 gtk_list_store_append(store, &iter);
707 gtk_list_store_set(store, &iter,
708 MM_STORE_KEYNAME, _(keynames[i]),
709 MM_STORE_INDEX, i,
710 MM_STORE_KEYCODE, keycodes[i],
711 MM_STORE_MASK, masks[i],
712 MM_STORE_KEYVAL, XKeycodeToKeysym(GDK_DISPLAY(), keycodes[i], 0),
713 MM_STORE_FOREGROUND, keyerror[i] ? FG_ERROR : FG_DEFAULT,
714 -1);
722 #endif