Mercurial > audlegacy-plugins
changeset 2336:ad45d65e9ae7
Hotkey Plugin: Complete GUI rework. Ability to use more than one binding for the same action.
author | Sascha Hlusiak <contact@saschahlusiak.de> |
---|---|
date | Wed, 23 Jan 2008 19:37:05 +0100 |
parents | 6b9d5a8b509e |
children | 107c1fed3d92 |
files | src/hotkey/grab.c src/hotkey/gui.c src/hotkey/plugin.c src/hotkey/plugin.h |
diffstat | 4 files changed, 548 insertions(+), 326 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotkey/grab.c Wed Jan 23 14:12:02 2008 +0100 +++ b/src/hotkey/grab.c Wed Jan 23 19:37:05 2008 +0100 @@ -93,96 +93,96 @@ } /* grab required keys */ -static void grab_key(HotkeyConfiguration hotkey, Display *xdisplay, Window x_root_window) +static void grab_key(const HotkeyConfiguration *hotkey, Display *xdisplay, Window x_root_window) { - unsigned int modifier = hotkey.mask & ~(numlock_mask | capslock_mask | scrolllock_mask); + unsigned int modifier = hotkey->mask & ~(numlock_mask | capslock_mask | scrolllock_mask); - if (hotkey.key == 0) return; + if (hotkey->key == 0) return; - if (hotkey.type == TYPE_KEY) + if (hotkey->type == TYPE_KEY) { - XGrabKey (xdisplay, hotkey.key, modifier, x_root_window, + XGrabKey (xdisplay, hotkey->key, modifier, x_root_window, False, GrabModeAsync, GrabModeAsync); if (modifier == AnyModifier) return; if (numlock_mask) - XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask, + XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (capslock_mask) - XGrabKey (xdisplay, hotkey.key, modifier | capslock_mask, + XGrabKey (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (scrolllock_mask) - XGrabKey (xdisplay, hotkey.key, modifier | scrolllock_mask, + XGrabKey (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (numlock_mask && capslock_mask) - XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask, + XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (numlock_mask && scrolllock_mask) - XGrabKey (xdisplay, hotkey.key, modifier | numlock_mask | scrolllock_mask, + XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (capslock_mask && scrolllock_mask) - XGrabKey (xdisplay, hotkey.key, modifier | capslock_mask | scrolllock_mask, + XGrabKey (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (numlock_mask && capslock_mask && scrolllock_mask) - XGrabKey (xdisplay, hotkey.key, + XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); } - if (hotkey.type == TYPE_MOUSE) + if (hotkey->type == TYPE_MOUSE) { - XGrabButton (xdisplay, hotkey.key, modifier, x_root_window, + XGrabButton (xdisplay, hotkey->key, modifier, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (modifier == AnyModifier) return; if (numlock_mask) - XGrabButton (xdisplay, hotkey.key, modifier | numlock_mask, + XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (capslock_mask) - XGrabButton (xdisplay, hotkey.key, modifier | capslock_mask, + XGrabButton (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (scrolllock_mask) - XGrabButton (xdisplay, hotkey.key, modifier | scrolllock_mask, + XGrabButton (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (numlock_mask && capslock_mask) - XGrabButton (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask, + XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (numlock_mask && scrolllock_mask) - XGrabButton (xdisplay, hotkey.key, modifier | numlock_mask | scrolllock_mask, + XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (capslock_mask && scrolllock_mask) - XGrabButton (xdisplay, hotkey.key, modifier | capslock_mask | scrolllock_mask, + XGrabButton (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (numlock_mask && capslock_mask && scrolllock_mask) - XGrabButton (xdisplay, hotkey.key, + XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); @@ -194,6 +194,7 @@ Display* xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); Window x_root_window = GDK_WINDOW_XID(gdk_get_default_root_window()); PluginConfig* plugin_cfg = get_config(); + HotkeyConfiguration *hotkey; XErrorHandler old_handler = 0; if (grabbed) return; @@ -203,21 +204,13 @@ old_handler = XSetErrorHandler (x11_error_handler); get_offending_modifiers(xdisplay); + hotkey = &(plugin_cfg->first); + while (hotkey) + { + grab_key(hotkey, xdisplay, x_root_window); + hotkey = hotkey->next; + } - grab_key(plugin_cfg->mute, xdisplay, x_root_window); - grab_key(plugin_cfg->vol_up, xdisplay, x_root_window); - grab_key(plugin_cfg->vol_down, xdisplay, x_root_window); - grab_key(plugin_cfg->play, xdisplay, x_root_window); - grab_key(plugin_cfg->pause, xdisplay, x_root_window); - grab_key(plugin_cfg->stop, xdisplay, x_root_window); - grab_key(plugin_cfg->prev_track, xdisplay, x_root_window); - grab_key(plugin_cfg->next_track, xdisplay, x_root_window); - grab_key(plugin_cfg->jump_to_file, xdisplay, x_root_window); - grab_key(plugin_cfg->forward, xdisplay, x_root_window); - grab_key(plugin_cfg->backward, xdisplay, x_root_window); - grab_key(plugin_cfg->toggle_win, xdisplay, x_root_window); - grab_key(plugin_cfg->show_aosd, xdisplay, x_root_window); - XSync(xdisplay, False); XSetErrorHandler (old_handler); @@ -227,67 +220,67 @@ /* grab required keys */ -static void ungrab_key(HotkeyConfiguration hotkey, Display* xdisplay, Window x_root_window) +static void ungrab_key(HotkeyConfiguration *hotkey, Display* xdisplay, Window x_root_window) { - unsigned int modifier = hotkey.mask & ~(numlock_mask | capslock_mask | scrolllock_mask); + unsigned int modifier = hotkey->mask & ~(numlock_mask | capslock_mask | scrolllock_mask); - if (hotkey.key == 0) return; + if (hotkey->key == 0) return; - if (hotkey.type == TYPE_KEY) + if (hotkey->type == TYPE_KEY) { - XUngrabKey (xdisplay, hotkey.key, modifier, x_root_window); + XUngrabKey (xdisplay, hotkey->key, modifier, x_root_window); if (modifier == AnyModifier) return; if (numlock_mask) - XUngrabKey (xdisplay, hotkey.key, modifier | numlock_mask, x_root_window); + XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window); if (capslock_mask) - XUngrabKey (xdisplay, hotkey.key, modifier | capslock_mask, x_root_window); + XUngrabKey (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window); if (scrolllock_mask) - XUngrabKey (xdisplay, hotkey.key, modifier | scrolllock_mask, x_root_window); + XUngrabKey (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window); if (numlock_mask && capslock_mask) - XUngrabKey (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask, x_root_window); + XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window); if (numlock_mask && scrolllock_mask) - XUngrabKey (xdisplay, hotkey.key, modifier | numlock_mask | scrolllock_mask, x_root_window); + XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window); if (capslock_mask && scrolllock_mask) - XUngrabKey (xdisplay, hotkey.key, modifier | capslock_mask | scrolllock_mask, x_root_window); + XUngrabKey (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window); if (numlock_mask && capslock_mask && scrolllock_mask) - XUngrabKey (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window); + XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window); } - if (hotkey.type == TYPE_MOUSE) + if (hotkey->type == TYPE_MOUSE) { - XUngrabButton (xdisplay, hotkey.key, modifier, x_root_window); + XUngrabButton (xdisplay, hotkey->key, modifier, x_root_window); if (modifier == AnyModifier) return; if (numlock_mask) - XUngrabButton (xdisplay, hotkey.key, modifier | numlock_mask, x_root_window); + XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window); if (capslock_mask) - XUngrabButton (xdisplay, hotkey.key, modifier | capslock_mask, x_root_window); + XUngrabButton (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window); if (scrolllock_mask) - XUngrabButton (xdisplay, hotkey.key, modifier | scrolllock_mask, x_root_window); + XUngrabButton (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window); if (numlock_mask && capslock_mask) - XUngrabButton (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask, x_root_window); + XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window); if (numlock_mask && scrolllock_mask) - XUngrabButton (xdisplay, hotkey.key, modifier | numlock_mask | scrolllock_mask, x_root_window); + XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window); if (capslock_mask && scrolllock_mask) - XUngrabButton (xdisplay, hotkey.key, modifier | capslock_mask | scrolllock_mask, x_root_window); + XUngrabButton (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window); if (numlock_mask && capslock_mask && scrolllock_mask) - XUngrabButton (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window); + XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window); } } @@ -297,6 +290,7 @@ Display* xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); Window x_root_window = GDK_WINDOW_XID(gdk_get_default_root_window()); PluginConfig* plugin_cfg = get_config(); + HotkeyConfiguration *hotkey; if (!grabbed) return; if (!xdisplay) return; @@ -306,20 +300,13 @@ get_offending_modifiers(xdisplay); - ungrab_key(plugin_cfg->mute, xdisplay, x_root_window); - ungrab_key(plugin_cfg->vol_up, xdisplay, x_root_window); - ungrab_key(plugin_cfg->vol_down, xdisplay, x_root_window); - ungrab_key(plugin_cfg->play, xdisplay, x_root_window); - ungrab_key(plugin_cfg->pause, xdisplay, x_root_window); - ungrab_key(plugin_cfg->stop, xdisplay, x_root_window); - ungrab_key(plugin_cfg->prev_track, xdisplay, x_root_window); - ungrab_key(plugin_cfg->next_track, xdisplay, x_root_window); - ungrab_key(plugin_cfg->jump_to_file, xdisplay, x_root_window); - ungrab_key(plugin_cfg->forward, xdisplay, x_root_window); - ungrab_key(plugin_cfg->backward, xdisplay, x_root_window); - ungrab_key(plugin_cfg->toggle_win, xdisplay, x_root_window); - ungrab_key(plugin_cfg->show_aosd, xdisplay, x_root_window); - + hotkey = &(plugin_cfg->first); + while (hotkey) + { + ungrab_key(hotkey, xdisplay, x_root_window); + hotkey = hotkey->next; + } + XSync(xdisplay, False); XSetErrorHandler (old_handler); @@ -332,20 +319,45 @@ GdkEvent *event, gpointer data) { + HotkeyConfiguration *hotkey; + hotkey = &(get_config()->first); switch (((XEvent*)xevent)->type) { case KeyPress: { XKeyEvent *keyevent = (XKeyEvent*)xevent; - if (handle_keyevent(keyevent->keycode, keyevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask), TYPE_KEY)) - return GDK_FILTER_REMOVE; + while (hotkey) + { + if ((hotkey->key == keyevent->keycode) && + (hotkey->mask == (keyevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) && + (hotkey->type == TYPE_KEY)) + { + if (handle_keyevent(hotkey->event)) + return GDK_FILTER_REMOVE; + break; + } + + hotkey = hotkey->next; + } break; } case ButtonPress: { XButtonEvent *buttonevent = (XButtonEvent*)xevent; - if (handle_keyevent(buttonevent->button, buttonevent->state, TYPE_MOUSE)) - return GDK_FILTER_REMOVE; + while (hotkey) + { + if ((hotkey->key == buttonevent->button) && + (hotkey->mask == (buttonevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) && + (hotkey->type == TYPE_MOUSE)) + { + if (handle_keyevent(hotkey->event)) + return GDK_FILTER_REMOVE; + break; + } + + hotkey = hotkey->next; + } + break; } default:
--- a/src/hotkey/gui.c Wed Jan 23 14:12:02 2008 +0100 +++ b/src/hotkey/gui.c Wed Jan 23 19:37:05 2008 +0100 @@ -46,36 +46,41 @@ #include "gui.h" #include "grab.h" - -typedef struct { +typedef struct _KeyControls { GtkWidget *keytext; - HotkeyConfiguration hotkey; -} KeyControls; + GtkWidget *table; + GtkWidget *button; + GtkWidget *combobox; -typedef struct { - KeyControls play; - KeyControls stop; - KeyControls pause; - KeyControls prev_track; - KeyControls next_track; - KeyControls vol_up; - KeyControls vol_down; - KeyControls mute; - KeyControls jump_to_file; - KeyControls forward; - KeyControls backward; - KeyControls toggle_win; - KeyControls show_aosd; -} ConfigurationControls; - + HotkeyConfiguration hotkey; + struct _KeyControls *next, *prev, *first; +} KeyControls; static void clear_keyboard (GtkWidget *widget, gpointer data); +static void add_callback (GtkWidget *widget, gpointer data); static void cancel_callback (GtkWidget *widget, gpointer data); static void destroy_callback (GtkWidget *widget, gpointer data); static void ok_callback (GtkWidget *widget, gpointer data); +static gchar* event_desc[EVENT_MAX] = { + [EVENT_PREV_TRACK] = N_("Previous Track"), + [EVENT_PLAY] = N_("Play"), + [EVENT_PAUSE] = N_("Pause/Resume"), + [EVENT_STOP] = N_("Stop"), + [EVENT_NEXT_TRACK] = N_("Next Track"), + [EVENT_FORWARD] = N_("Forward 5 Seconds"), + [EVENT_BACKWARD] = N_("Rewind 5 Seconds"), + [EVENT_MUTE] = N_("Mute"), + [EVENT_VOL_UP] = N_("Volume Up"), + [EVENT_VOL_DOWN] = N_("Volume Down"), + [EVENT_JUMP_TO_FILE] = N_("Jump to File"), + [EVENT_TOGGLE_WIN] = N_("Toggle Player Windows"), + [EVENT_SHOW_AOSD] = N_("Show On-Screen-Display") +}; + + static void set_keytext (GtkWidget *entry, gint key, gint mask, gint type) { gchar *text = NULL; @@ -132,6 +137,15 @@ int mod; if (event->keyval == GDK_Tab) return FALSE; + if (event->keyval == GDK_Escape && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE; + if (event->keyval == GDK_Return && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE; + if (event->keyval == GDK_ISO_Left_Tab) + { + set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); + return FALSE; + } + if (event->keyval == GDK_Up && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE; + if (event->keyval == GDK_Down && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE; mod = 0; is_mod = 0; @@ -155,7 +169,10 @@ controls->hotkey.key = event->hardware_keycode; controls->hotkey.mask = mod; controls->hotkey.type = TYPE_KEY; - } else controls->hotkey.key = 0; + if (controls->next == NULL) + add_callback (NULL, (gpointer) controls); + else gtk_widget_grab_focus(GTK_WIDGET(controls->next->keytext)); + } set_keytext(controls->keytext, is_mod ? 0 : event->hardware_keycode, mod, TYPE_KEY); return TRUE; @@ -167,11 +184,9 @@ gpointer user_data) { KeyControls *controls = (KeyControls*) user_data; - if (controls->hotkey.key == 0) { - controls->hotkey.mask = 0; - return TRUE; - } + if (!gtk_widget_is_focus(widget)) return FALSE; set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); + return TRUE; } @@ -221,6 +236,9 @@ controls->hotkey.mask = mod; controls->hotkey.type = TYPE_MOUSE; set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); + if (controls->next == NULL) + add_callback (NULL, (gpointer) controls); + return TRUE; } @@ -263,37 +281,58 @@ controls->hotkey.mask = mod; controls->hotkey.type = TYPE_MOUSE; set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); + if (controls->next == NULL) + add_callback (NULL, (gpointer) controls); return TRUE; } -static void add_event_controls(GtkWidget *table, - KeyControls *controls, +KeyControls* add_event_controls(KeyControls* list, + GtkWidget *table, int row, - char* descr, - char* tooltip, - HotkeyConfiguration hotkey) + HotkeyConfiguration *hotkey) { - GtkWidget *label; - GtkWidget *button; + KeyControls *controls; + int i; + + controls = (KeyControls*) g_malloc(sizeof(KeyControls)); + controls->next = NULL; + controls->prev = list; + controls->first = list->first; + controls->table = table; + list->next = controls; - controls->hotkey.key = hotkey.key; - controls->hotkey.mask = hotkey.mask; - controls->hotkey.type = hotkey.type; - if (controls->hotkey.key == 0) + if (hotkey) + { + controls->hotkey.key = hotkey->key; + controls->hotkey.mask = hotkey->mask; + controls->hotkey.type = hotkey->type; + controls->hotkey.event = hotkey->event; + if (controls->hotkey.key == 0) + controls->hotkey.mask = 0; + } else { + controls->hotkey.key = 0; controls->hotkey.mask = 0; + controls->hotkey.type = TYPE_KEY; + controls->hotkey.event = 0; + } - label = gtk_label_new (_(descr)); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1, - (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - gtk_misc_set_padding (GTK_MISC (label), 3, 3); - + controls->combobox = gtk_combo_box_new_text(); + for (i=0;i<EVENT_MAX;i++) + { + gtk_combo_box_append_text( GTK_COMBO_BOX(controls->combobox), event_desc[i] ); + } + gtk_combo_box_set_active( GTK_COMBO_BOX(controls->combobox), controls->hotkey.event); + gtk_table_attach (GTK_TABLE (table), controls->combobox, 0, 1, row, row+1, + (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), (GtkAttachOptions) (GTK_EXPAND), 0, 0); + + controls->keytext = gtk_entry_new (); gtk_table_attach (GTK_TABLE (table), controls->keytext, 1, 2, row, row+1, (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), (GtkAttachOptions) (GTK_EXPAND), 0, 0); gtk_entry_set_editable (GTK_ENTRY (controls->keytext), FALSE); - set_keytext(controls->keytext, hotkey.key, hotkey.mask, hotkey.type); + + set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); g_signal_connect((gpointer)controls->keytext, "key_press_event", G_CALLBACK(on_entry_key_press_event), controls); g_signal_connect((gpointer)controls->keytext, "key_release_event", @@ -303,25 +342,23 @@ g_signal_connect((gpointer)controls->keytext, "scroll_event", G_CALLBACK(on_entry_scroll_event), controls); - button = gtk_button_new_with_label (_("None")); - gtk_table_attach (GTK_TABLE (table), button, 2, 3, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); - g_signal_connect (G_OBJECT (button), "clicked", + + controls->button = gtk_button_new(); + gtk_button_set_image( GTK_BUTTON(controls->button), + gtk_image_new_from_stock( GTK_STOCK_DELETE , GTK_ICON_SIZE_BUTTON)); + gtk_table_attach (GTK_TABLE (table), controls->button, 2, 3, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); + g_signal_connect (G_OBJECT (controls->button), "clicked", G_CALLBACK (clear_keyboard), controls); - if (tooltip != NULL) { - GtkTooltips *tip = gtk_tooltips_new(); - gtk_tooltips_set_tip(tip, controls->keytext, tooltip, NULL); - gtk_tooltips_set_tip(tip, button, tooltip, NULL); - gtk_tooltips_set_tip(tip, label, tooltip, NULL); - } + gtk_widget_grab_focus(GTK_WIDGET(controls->keytext)); + return controls; } void show_configure () { - ConfigurationControls *controls; + KeyControls *first_controls, *current_controls; GtkWidget *window; - GtkWidget *main_vbox, *vbox; - GtkWidget *hbox; + GtkWidget *main_vbox, *hbox; GtkWidget *alignment; GtkWidget *frame; GtkWidget *label; @@ -329,6 +366,8 @@ GtkWidget *table; GtkWidget *button_box, *button; PluginConfig* plugin_cfg; + HotkeyConfiguration *hotkey, temphotkey; + int i; load_config ( ); @@ -336,19 +375,11 @@ ungrab_keys(); - controls = (ConfigurationControls*)g_malloc(sizeof(ConfigurationControls)); - if (!controls) - { - printf ("Faild to allocate memory for ConfigurationControls structure!\n" - "Aborting!"); - return; - } - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), _("Global Hotkey Plugin Configuration")); - gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER_ALWAYS); + gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER); gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_resizable (GTK_WINDOW (window), FALSE); + gtk_window_set_resizable (GTK_WINDOW (window), TRUE); gtk_container_set_border_width (GTK_CONTAINER (window), 5); main_vbox = gtk_vbox_new (FALSE, 4); @@ -361,156 +392,215 @@ gtk_container_add (GTK_CONTAINER (alignment), hbox); image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0); - label = gtk_label_new (_("Press a key combination inside a text field.")); + label = gtk_label_new (_("Press a key combination inside a text field.\nYou can also bind mouse buttons.")); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), _("<b>Playback:</b>")); + gtk_label_set_markup (GTK_LABEL (label), _("Hotkeys:")); frame = gtk_frame_new (NULL); gtk_frame_set_label_widget (GTK_FRAME (frame), label); - gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); - alignment = gtk_alignment_new (0.5, 0.5, 1, 1); + alignment = gtk_alignment_new (0, 0, 1, 0); gtk_container_add (GTK_CONTAINER (frame), alignment); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 3, 3, 3, 3); - vbox = gtk_vbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (alignment), vbox); + + table = gtk_table_new (1, 3, FALSE); + gtk_container_add (GTK_CONTAINER (alignment), table); + + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_table_set_row_spacings (GTK_TABLE (table), 0); + label = gtk_label_new (NULL); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0); gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER); gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); gtk_label_set_markup (GTK_LABEL (label), - _("<i>Configure keys which controls Audacious playback.</i>")); - table = gtk_table_new (4, 3, FALSE); - gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0); - gtk_table_set_col_spacings (GTK_TABLE (table), 2); - gtk_table_set_row_spacings (GTK_TABLE (table), 2); - - /* prev track */ - add_event_controls(table, &controls->prev_track, 0, _("Previous Track:"), NULL, - plugin_cfg->prev_track); - - add_event_controls(table, &controls->play, 1, _("Play:"), NULL, - plugin_cfg->play); - - add_event_controls(table, &controls->pause, 2, _("Pause/Resume:"), NULL, - plugin_cfg->pause); - - add_event_controls(table, &controls->stop, 3, _("Stop:"), NULL, - plugin_cfg->stop); - - add_event_controls(table, &controls->next_track, 4, _("Next Track:"), NULL, - plugin_cfg->next_track); - - add_event_controls(table, &controls->forward, 5, _("Forward 5 sec.:"), NULL, - plugin_cfg->forward); - - add_event_controls(table, &controls->backward, 6, _("Rewind 5 sec.:"), NULL, - plugin_cfg->backward); - + _("<b>Action:</b>")); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), (GtkAttachOptions) (GTK_EXPAND), 0, 0); label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), _("<b>Volume Control:</b>")); - frame = gtk_frame_new (NULL); - gtk_frame_set_label_widget (GTK_FRAME (frame), label); - gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, TRUE, 0); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); - alignment = gtk_alignment_new (0.5, 0.5, 1, 1); - gtk_container_add (GTK_CONTAINER (frame), alignment); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 3, 3, 3, 3); - vbox = gtk_vbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (alignment), vbox); - label = gtk_label_new (NULL); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0); gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER); gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); gtk_label_set_markup (GTK_LABEL (label), - _("<i>Configure keys which controls music volume.</i>")); - table = gtk_table_new (3, 3, FALSE); - gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0); - gtk_table_set_col_spacings (GTK_TABLE (table), 2); - gtk_table_set_row_spacings (GTK_TABLE (table), 2); - - add_event_controls(table, &controls->mute, 0, _("Mute:"),NULL, - plugin_cfg->mute); - - add_event_controls(table, &controls->vol_up, 1, _("Volume Up:"), NULL, - plugin_cfg->vol_up); - - add_event_controls(table, &controls->vol_down, 2, _("Volume Down:"), NULL, - plugin_cfg->vol_down); + _("<b>Key Binding:</b>")); + gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), (GtkAttachOptions) (GTK_EXPAND), 0, 0); - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), _("<b>Player:</b>")); - frame = gtk_frame_new (NULL); - gtk_frame_set_label_widget (GTK_FRAME (frame), label); - gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, TRUE, 0); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); - alignment = gtk_alignment_new (0.5, 0.5, 1, 1); - gtk_container_add (GTK_CONTAINER (frame), alignment); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 3, 3, 3, 3); - vbox = gtk_vbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (alignment), vbox); - label = gtk_label_new (NULL); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0); - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - gtk_label_set_markup (GTK_LABEL (label), - _("<i>Configure keys which control the player.</i>")); - table = gtk_table_new (3, 3, FALSE); - gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0); - gtk_table_set_col_spacings (GTK_TABLE (table), 2); - gtk_table_set_row_spacings (GTK_TABLE (table), 2); + hotkey = &(plugin_cfg->first); + i = 1; + first_controls = (KeyControls*) g_malloc(sizeof(KeyControls)); + first_controls->next = NULL; + first_controls->prev = NULL; + first_controls->table = table; + first_controls->button = NULL; + first_controls->combobox = NULL; + first_controls->keytext = NULL; + first_controls->first = first_controls; + first_controls->hotkey.key = 0; + first_controls->hotkey.mask = 0; + first_controls->hotkey.event = 0; + first_controls->hotkey.type = TYPE_KEY; + current_controls = first_controls; + if (hotkey -> key != 0) + { + while (hotkey) + { + current_controls = add_event_controls(current_controls, table, i, hotkey); + hotkey = hotkey->next; + i++; + } + } + temphotkey.key = 0; + temphotkey.mask = 0; + temphotkey.type = TYPE_KEY; + if (current_controls != first_controls) + temphotkey.event = current_controls->hotkey.event+1; + else temphotkey.event = 0; + if (temphotkey.event >= EVENT_MAX) temphotkey.event = 0; + add_event_controls(current_controls, table, i, &temphotkey); - add_event_controls(table, &controls->jump_to_file, 0, _("Jump to File:"), NULL, - plugin_cfg->jump_to_file); + - add_event_controls(table, &controls->toggle_win, 1, _("Toggle Player Windows:"), NULL, - plugin_cfg->toggle_win); - - add_event_controls(table, &controls->show_aosd, 2, _("Show On-Screen-Display:"), - _("For this, the Audacious OSD plugin must be activated."), - plugin_cfg->show_aosd); + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0); button_box = gtk_hbutton_box_new ( ); - gtk_box_pack_start (GTK_BOX (main_vbox), button_box, FALSE, TRUE, 6); + gtk_box_pack_start (GTK_BOX (hbox), button_box, FALSE, TRUE, 0); + gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), GTK_BUTTONBOX_START); + gtk_box_set_spacing (GTK_BOX (button_box), 4); + + button = gtk_button_new_from_stock (GTK_STOCK_ADD); + gtk_container_add (GTK_CONTAINER (button_box), button); + g_signal_connect (G_OBJECT (button), "clicked", + G_CALLBACK (add_callback), first_controls); + + button_box = gtk_hbutton_box_new ( ); + gtk_box_pack_start (GTK_BOX (hbox), button_box, TRUE, TRUE, 0); gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), GTK_BUTTONBOX_END); gtk_box_set_spacing (GTK_BOX (button_box), 4); - + button = gtk_button_new_from_stock (GTK_STOCK_CANCEL); gtk_container_add (GTK_CONTAINER (button_box), button); g_signal_connect (G_OBJECT (button), "clicked", - G_CALLBACK (cancel_callback), controls); - + G_CALLBACK (cancel_callback), NULL); + button = gtk_button_new_from_stock (GTK_STOCK_OK); gtk_container_add (GTK_CONTAINER (button_box), button); g_signal_connect (G_OBJECT (button), "clicked", - G_CALLBACK (ok_callback), controls); + G_CALLBACK (ok_callback), first_controls); g_signal_connect (G_OBJECT (window), "destroy", - G_CALLBACK (destroy_callback), controls); + G_CALLBACK (destroy_callback), first_controls); gtk_widget_show_all (GTK_WIDGET (window)); } static void clear_keyboard (GtkWidget *widget, gpointer data) { - KeyControls *spins = (KeyControls*)data; - spins->hotkey.key = 0; - spins->hotkey.mask = 0; - spins->hotkey.type = TYPE_KEY; - set_keytext(spins->keytext, 0, 0, TYPE_KEY); + KeyControls *controls= (KeyControls*)data; + if ((controls->next == NULL) && (controls->prev->keytext == NULL)) + { + controls->hotkey.key = 0; + controls->hotkey.mask = 0; + controls->hotkey.type = TYPE_KEY; + set_keytext(controls->keytext, 0, 0, TYPE_KEY); + gtk_combo_box_set_active( GTK_COMBO_BOX(controls->combobox), 0); + return; + } + + if (controls->prev) + { + KeyControls* c; + GtkWidget* table; + int row; + + gtk_widget_destroy(GTK_WIDGET(controls->button)); + gtk_widget_destroy(GTK_WIDGET(controls->keytext)); + gtk_widget_destroy(GTK_WIDGET(controls->combobox)); + + row=0; + c = controls->first; + while (c) { + if (c == controls) break; + row++; + c = c->next; + } + c = controls->next; + controls->prev->next = controls->next; + if (controls->next) + controls->next->prev = controls->prev; + g_free(controls); + if (c) table = c->table; else table = NULL; + while (c) + { + g_object_ref(c->combobox); + g_object_ref(c->keytext); + g_object_ref(c->button); + + gtk_container_remove( GTK_CONTAINER(c->table) , c->combobox); + gtk_container_remove( GTK_CONTAINER(c->table) , c->keytext); + gtk_container_remove( GTK_CONTAINER(c->table) , c->button); + + gtk_table_attach (GTK_TABLE (c->table), c->combobox, 0, 1, row, row+1, + (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), (GtkAttachOptions) (GTK_EXPAND), 0, 0); + gtk_table_attach (GTK_TABLE (c->table), c->keytext, 1, 2, row, row+1, + (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), (GtkAttachOptions) (GTK_EXPAND), 0, 0); + gtk_table_attach (GTK_TABLE (c->table), c->button, 2, 3, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); + + g_object_unref(c->combobox); + g_object_unref(c->keytext); + g_object_unref(c->button); + + c = c->next; + row++; + } + if (table) + gtk_widget_show_all (GTK_WIDGET (table)); + + return; + } +} + +void add_callback (GtkWidget *widget, gpointer data) +{ + KeyControls* controls = (KeyControls*)data; + HotkeyConfiguration temphotkey; + int count; + if (controls == NULL) return; + if ((controls->next == NULL)&&(controls->hotkey.event+1 == EVENT_MAX)) return; + controls = controls->first; + if (controls == NULL) return; + count = 1; + while (controls->next) { + controls = controls->next; + count = count + 1; + } + temphotkey.key = 0; + temphotkey.mask = 0; + temphotkey.type = TYPE_KEY; + temphotkey.event = controls->hotkey.event+1; + if (temphotkey.event >= EVENT_MAX) temphotkey.event = 0; + gtk_table_resize(GTK_TABLE(controls->table), count, 3); + add_event_controls(controls, controls->table, count, &temphotkey); + gtk_widget_show_all (GTK_WIDGET (controls->table)); } void destroy_callback (GtkWidget *widget, gpointer data) { + KeyControls* controls = (KeyControls*)data; if (is_loaded()) { grab_keys (); } - if (data) g_free(data); + while (controls) { + KeyControls *old; + old = controls; + controls = controls->next; + g_free(old); + } } void cancel_callback (GtkWidget *widget, gpointer data) @@ -520,23 +610,42 @@ void ok_callback (GtkWidget *widget, gpointer data) { - ConfigurationControls *controls= (ConfigurationControls*)data; + KeyControls *controls = (KeyControls*)data; PluginConfig* plugin_cfg = get_config(); + HotkeyConfiguration *hotkey; + + hotkey = &(plugin_cfg->first); + hotkey = hotkey->next; + while (hotkey) + { + HotkeyConfiguration * old; + old = hotkey; + hotkey = hotkey->next; + free(old); + } + plugin_cfg->first.next = NULL; + plugin_cfg->first.key = 0; + plugin_cfg->first.event = 0; + plugin_cfg->first.mask = 0; - plugin_cfg->play = controls->play.hotkey; - plugin_cfg->pause = controls->pause.hotkey; - plugin_cfg->stop= controls->stop.hotkey; - plugin_cfg->prev_track= controls->prev_track.hotkey; - plugin_cfg->next_track = controls->next_track.hotkey; - plugin_cfg->forward = controls->forward.hotkey; - plugin_cfg->backward = controls->backward.hotkey; - plugin_cfg->vol_up= controls->vol_up.hotkey; - plugin_cfg->vol_down = controls->vol_down.hotkey; - plugin_cfg->mute = controls->mute.hotkey; - plugin_cfg->jump_to_file= controls->jump_to_file.hotkey; - plugin_cfg->toggle_win = controls->toggle_win.hotkey; - plugin_cfg->show_aosd = controls->show_aosd.hotkey; - + hotkey = &(plugin_cfg->first); + while (controls) + { + if (controls->hotkey.key) { + if (hotkey->key) { + hotkey->next = (HotkeyConfiguration*) + malloc(sizeof (HotkeyConfiguration)); + hotkey = hotkey->next; + hotkey->next = NULL; + } + hotkey->key = controls->hotkey.key; + hotkey->mask = controls->hotkey.mask; + hotkey->event = gtk_combo_box_get_active( GTK_COMBO_BOX(controls->combobox) ); + hotkey->type = controls->hotkey.type; + } + controls = controls->next; + } + save_config ( ); gtk_widget_destroy (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
--- a/src/hotkey/plugin.c Wed Jan 23 14:12:02 2008 +0100 +++ b/src/hotkey/plugin.c Wed Jan 23 19:37:05 2008 +0100 @@ -94,7 +94,7 @@ } /* handle keys */ -gboolean handle_keyevent (int keycode, int state, int type) +gboolean handle_keyevent (EVENT event) { gint current_volume, old_volume; static gint volume_static = 0; @@ -116,7 +116,7 @@ } /* mute the playback */ - if ((keycode == plugin_cfg.mute.key) && (state == plugin_cfg.mute.mask) && (type == plugin_cfg.mute.type)) + if (event == EVENT_MUTE) { if (!mute) { @@ -131,7 +131,7 @@ } /* decreace volume */ - if ((keycode == plugin_cfg.vol_down.key) && (state == plugin_cfg.vol_down.mask) && (type == plugin_cfg.vol_down.type)) + if (event == EVENT_VOL_DOWN) { if (mute) { @@ -155,7 +155,7 @@ } /* increase volume */ - if ((keycode == plugin_cfg.vol_up.key) && (state == plugin_cfg.vol_up.mask) && (type == plugin_cfg.vol_up.type)) + if (event == EVENT_VOL_UP) { if (mute) { @@ -179,14 +179,14 @@ } /* play */ - if ((keycode == plugin_cfg.play.key) && (state == plugin_cfg.play.mask) && (type == plugin_cfg.play.type)) + if (event == EVENT_PLAY) { audacious_drct_play (); return TRUE; } /* pause */ - if ((keycode == plugin_cfg.pause.key) && (state == plugin_cfg.pause.mask) && (type == plugin_cfg.pause.type)) + if (event == EVENT_PAUSE) { if (!play) audacious_drct_play (); else audacious_drct_pause (); @@ -195,28 +195,28 @@ } /* stop */ - if ((keycode == plugin_cfg.stop.key) && (state == plugin_cfg.stop.mask) && (type == plugin_cfg.stop.type)) + if (event == EVENT_STOP) { audacious_drct_stop (); return TRUE; } /* prev track */ - if ((keycode == plugin_cfg.prev_track.key) && (state == plugin_cfg.prev_track.mask) && (type == plugin_cfg.prev_track.type)) + if (event == EVENT_PREV_TRACK) { audacious_drct_playlist_prev (); return TRUE; } /* next track */ - if ((keycode == plugin_cfg.next_track.key) && (state == plugin_cfg.next_track.mask) && (type == plugin_cfg.next_track.type)) + if (event == EVENT_NEXT_TRACK) { audacious_drct_playlist_next (); return TRUE; } /* forward */ - if ((keycode == plugin_cfg.forward.key) && (state == plugin_cfg.forward.mask) && (type == plugin_cfg.forward.type)) + if (event == EVENT_FORWARD) { gint time = audacious_drct_get_output_time(); time += 5000; /* Jump 5s into future */ @@ -225,7 +225,7 @@ } /* backward */ - if ((keycode == plugin_cfg.backward.key) && (state == plugin_cfg.backward.mask) && (type == plugin_cfg.backward.type)) + if (event == EVENT_BACKWARD) { gint time = audacious_drct_get_output_time(); if (time > 5000) time -= 5000; /* Jump 5s back */ @@ -235,14 +235,14 @@ } /* Open Jump-To-File dialog */ - if ((keycode == plugin_cfg.jump_to_file.key) && (state == plugin_cfg.jump_to_file.mask) && (type == plugin_cfg.jump_to_file.type)) + if (event == EVENT_JUMP_TO_FILE) { audacious_drct_show_jtf_box(); return TRUE; } /* Toggle Windows */ - if ((keycode == plugin_cfg.toggle_win.key) && (state == plugin_cfg.toggle_win.mask) && (type == plugin_cfg.toggle_win.type)) + if (event == EVENT_TOGGLE_WIN) { static gboolean is_main, is_eq, is_pl; is_main = audacious_drct_main_win_is_visible(); @@ -262,7 +262,7 @@ } /* Show OSD through AOSD plugin*/ - if ((keycode == plugin_cfg.show_aosd.key) && (state == plugin_cfg.show_aosd.mask) && (type == plugin_cfg.show_aosd.type)) + if (event == EVENT_SHOW_AOSD) { aud_hook_call("aosd toggle", NULL); return TRUE; @@ -271,40 +271,106 @@ return FALSE; } +void add_hotkey(HotkeyConfiguration** pphotkey, KeySym keysym, gint mask, gint type, EVENT event) +{ + KeyCode keycode; + HotkeyConfiguration *photkey; + if (keysym == 0) return; + if (pphotkey == NULL) return; + photkey = *pphotkey; + if (photkey == NULL) return; + keycode = XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), keysym); + if (keycode == 0) return; + if (photkey->key) { + photkey->next = (HotkeyConfiguration*) + malloc(sizeof (HotkeyConfiguration)); + photkey = photkey->next; + *pphotkey = photkey; + photkey->next = NULL; + } + photkey->key = (gint)keycode; + photkey->mask = mask; + photkey->event = event; + photkey->type = type; +} + +void load_defaults (void) +{ + HotkeyConfiguration* hotkey; + + hotkey = &(plugin_cfg.first); + + add_hotkey(&hotkey, XF86XK_AudioPrev, 0, TYPE_KEY, EVENT_PREV_TRACK); + add_hotkey(&hotkey, XF86XK_AudioPlay, 0, TYPE_KEY, EVENT_PLAY); + add_hotkey(&hotkey, XF86XK_AudioPause, 0, TYPE_KEY, EVENT_PAUSE); + add_hotkey(&hotkey, XF86XK_AudioStop, 0, TYPE_KEY, EVENT_STOP); + add_hotkey(&hotkey, XF86XK_AudioNext, 0, TYPE_KEY, EVENT_NEXT_TRACK); + +/* add_hotkey(&hotkey, XF86XK_AudioRewind, 0, TYPE_KEY, EVENT_BACKWARD); */ + + add_hotkey(&hotkey, XF86XK_AudioMute, 0, TYPE_KEY, EVENT_MUTE); + add_hotkey(&hotkey, XF86XK_AudioRaiseVolume, 0, TYPE_KEY, EVENT_VOL_UP); + add_hotkey(&hotkey, XF86XK_AudioLowerVolume, 0, TYPE_KEY, EVENT_VOL_DOWN); + +/* add_hotkey(&hotkey, XF86XK_AudioMedia, 0, TYPE_KEY, EVENT_JUMP_TO_FILE); + add_hotkey(&hotkey, XF86XK_Music, 0, TYPE_KEY, EVENT_TOGGLE_WIN); */ +} + /* load plugin configuration */ void load_config (void) { ConfigDb *cfdb; + HotkeyConfiguration *hotkey; + int i,max; /* default volume level */ plugin_cfg.vol_increment = 4; plugin_cfg.vol_decrement = 4; -#define load_key(hotkey,default) \ - plugin_cfg.hotkey.key = (default)?(XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), (default))):0; \ - plugin_cfg.hotkey.mask = 0; \ - plugin_cfg.hotkey.type = TYPE_KEY; \ - aud_cfg_db_get_int (cfdb, "globalHotkey", #hotkey, &plugin_cfg.hotkey.key); \ - aud_cfg_db_get_int (cfdb, "globalHotkey", #hotkey "_mask", &plugin_cfg.hotkey.mask); \ - aud_cfg_db_get_int (cfdb, "globalHotkey", #hotkey "_type", &plugin_cfg.hotkey.type); - - /* open configuration database */ cfdb = aud_cfg_db_open ( ); + hotkey = &(plugin_cfg.first); + hotkey->next = NULL; + hotkey->key = 0; + hotkey->mask = 0; + hotkey->event = 0; + hotkey->type = TYPE_KEY; + max = 0; + aud_cfg_db_get_int (cfdb, "globalHotkey", "NumHotkeys", &max); + if (max == 0) + load_defaults(); + else for (i=0; i<max; i++) + { + gchar *text = NULL; + gint value; + if (hotkey->key) { + hotkey->next = (HotkeyConfiguration*) + malloc(sizeof (HotkeyConfiguration)); + hotkey = hotkey->next; + hotkey->next = NULL; + hotkey->key = 0; + hotkey->mask = 0; + hotkey->event = 0; + hotkey->type = TYPE_KEY; + } + text = g_strdup_printf("Hotkey_%d_key", i); + aud_cfg_db_get_int (cfdb, "globalHotkey", text, &(hotkey->key)); + g_free(text); - load_key(mute, XF86XK_AudioMute); - load_key(vol_down, XF86XK_AudioLowerVolume); - load_key(vol_up, XF86XK_AudioRaiseVolume); - load_key(play, XF86XK_AudioPlay); - load_key(pause, XF86XK_AudioPause); - load_key(stop, XF86XK_AudioStop); - load_key(prev_track, XF86XK_AudioPrev); - load_key(next_track, XF86XK_AudioNext); - load_key(jump_to_file, XF86XK_AudioMedia); - load_key(toggle_win, 0); - load_key(forward, 0); - load_key(backward, XF86XK_AudioRewind); - load_key(show_aosd, 0); + text = g_strdup_printf("Hotkey_%d_mask", i); + aud_cfg_db_get_int (cfdb, "globalHotkey", text, &(hotkey->mask)); + g_free(text); + + text = g_strdup_printf("Hotkey_%d_type", i); + aud_cfg_db_get_int (cfdb, "globalHotkey", text, &(hotkey->type)); + g_free(text); + + text = g_strdup_printf("Hotkey_%d_event", i); + value = (gint)hotkey->event; + aud_cfg_db_get_int (cfdb, "globalHotkey", text, &value); + hotkey->event = (EVENT) value; + g_free(text); + } aud_cfg_db_close (cfdb); } @@ -313,37 +379,60 @@ void save_config (void) { ConfigDb *cfdb; + int max; + HotkeyConfiguration *hotkey; -#define save_key(hotkey) \ - aud_cfg_db_set_int (cfdb, "globalHotkey", #hotkey, plugin_cfg.hotkey.key); \ - aud_cfg_db_set_int (cfdb, "globalHotkey", #hotkey "_mask", plugin_cfg.hotkey.mask); \ - aud_cfg_db_set_int (cfdb, "globalHotkey", #hotkey "_type", plugin_cfg.hotkey.type); - /* open configuration database */ cfdb = aud_cfg_db_open ( ); - - save_key(mute); - save_key(vol_up); - save_key(vol_down); - save_key(play); - save_key(pause); - save_key(stop); - save_key(prev_track); - save_key(next_track); - save_key(jump_to_file); - save_key(forward); - save_key(backward); - save_key(toggle_win); - save_key(show_aosd); + hotkey = &(plugin_cfg.first); + max = 0; + while (hotkey) { + gchar *text = NULL; + if (hotkey->key) { + text = g_strdup_printf("Hotkey_%d_key", max); + aud_cfg_db_set_int (cfdb, "globalHotkey", text, hotkey->key); + g_free(text); + + text = g_strdup_printf("Hotkey_%d_mask", max); + aud_cfg_db_set_int (cfdb, "globalHotkey", text, hotkey->mask); + g_free(text); + + text = g_strdup_printf("Hotkey_%d_type", max); + aud_cfg_db_set_int (cfdb, "globalHotkey", text, hotkey->type); + g_free(text); + + text = g_strdup_printf("Hotkey_%d_event", max); + aud_cfg_db_set_int (cfdb, "globalHotkey", text, hotkey->event); + g_free(text); + max++; + } + + hotkey = hotkey->next; + } + aud_cfg_db_set_int (cfdb, "globalHotkey", "NumHotkeys", max); aud_cfg_db_close (cfdb); } static void cleanup (void) { + HotkeyConfiguration* hotkey; if (!loaded) return; ungrab_keys (); release_filter(); + hotkey = &(plugin_cfg.first); + hotkey = hotkey->next; + while (hotkey) + { + HotkeyConfiguration * old; + old = hotkey; + hotkey = hotkey->next; + free(old); + } + plugin_cfg.first.next = NULL; + plugin_cfg.first.key = 0; + plugin_cfg.first.event = 0; + plugin_cfg.first.mask = 0; loaded = FALSE; }
--- a/src/hotkey/plugin.h Wed Jan 23 14:12:02 2008 +0100 +++ b/src/hotkey/plugin.h Wed Jan 23 19:37:05 2008 +0100 @@ -6,9 +6,31 @@ #define TYPE_KEY 0 #define TYPE_MOUSE 1 -typedef struct { +typedef enum { + EVENT_PREV_TRACK = 0, + EVENT_PLAY, + EVENT_PAUSE, + EVENT_STOP, + EVENT_NEXT_TRACK, + + EVENT_FORWARD, + EVENT_BACKWARD, + EVENT_MUTE, + EVENT_VOL_UP, + EVENT_VOL_DOWN, + EVENT_JUMP_TO_FILE, + EVENT_TOGGLE_WIN, + EVENT_SHOW_AOSD, + + EVENT_MAX +} EVENT; + + +typedef struct _HotkeyConfiguration { gint key, mask; gint type; + EVENT event; + struct _HotkeyConfiguration *next; } HotkeyConfiguration; typedef struct { @@ -16,25 +38,15 @@ gint vol_decrement; /* keyboard */ - HotkeyConfiguration mute; - HotkeyConfiguration vol_down; - HotkeyConfiguration vol_up; - HotkeyConfiguration play; - HotkeyConfiguration stop; - HotkeyConfiguration pause; - HotkeyConfiguration prev_track; - HotkeyConfiguration next_track; - HotkeyConfiguration jump_to_file; - HotkeyConfiguration toggle_win; - HotkeyConfiguration forward; - HotkeyConfiguration backward; - HotkeyConfiguration show_aosd; + HotkeyConfiguration first; } PluginConfig; + + void load_config (void); void save_config (void); PluginConfig* get_config(void); gboolean is_loaded (void); -gboolean handle_keyevent(int keycode, int state, int type); +gboolean handle_keyevent(EVENT event); #endif