Mercurial > audlegacy-plugins
diff src/hotkey/plugin.c @ 2330:0be42d832217
Splitted core/gui/grabbing sources; Fixed memory leak when closing configuration dialog.
| author | Sascha Hlusiak <contact@saschahlusiak.de> |
|---|---|
| date | Sun, 20 Jan 2008 14:52:44 +0100 |
| parents | 515f9c741a5c |
| children | ad45d65e9ae7 |
line wrap: on
line diff
--- a/src/hotkey/plugin.c Tue Jan 15 12:35:54 2008 +0200 +++ b/src/hotkey/plugin.c Sun Jan 20 14:52:44 2008 +0100 @@ -1,4 +1,3 @@ -/* -*- Mode: C; indent-tabs: t; c-basic-offset: 9; tab-width: 9 -*- */ /* * This file is part of audacious-hotkey plugin for audacious * @@ -37,112 +36,37 @@ #include <config.h> #include <stdio.h> -#include <stdlib.h> -#include <X11/Xlib.h> -#include <X11/keysym.h> #include <X11/XF86keysym.h> -#include <gtk/gtk.h> #include <gdk/gdkx.h> -#include <gdk/gdkkeysyms.h> #include <audacious/plugin.h> #include <audacious/auddrct.h> #include <audacious/configdb.h> #include <audacious/i18n.h> -/* for audacious_info_dialog () */ -#include <audacious/util.h> +#include "plugin.h" +#include "gui.h" +#include "grab.h" /* func defs */ -void x_display_init (void); -static void get_offending_modifiers (Display * dpy); static void init (void); -static void grab_keys (); -static void ungrab_keys (); -static gboolean handle_keyevent(int keycode, int state, int type); -static gboolean setup_filter(); -static void release_filter(); - -static void load_config (void); -static void save_config (void); -static void configure (void); -static void clear_keyboard (GtkWidget *widget, gpointer data); - -void cancel_callback (GtkWidget *widget, gpointer data); -void ok_callback (GtkWidget *widget, gpointer data); -static void about (void); static void cleanup (void); -#define TYPE_KEY 0 -#define TYPE_MOUSE 1 - -typedef struct { - gint key, mask; - gint type; -} HotkeyConfiguration; - -typedef struct { - gint vol_increment; - 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; -} PluginConfig; - -PluginConfig plugin_cfg; - -static Display *xdisplay = NULL; -static Window x_root_window = 0; -static gint grabbed = 0; +/* global vars */ +static PluginConfig plugin_cfg; static gboolean loaded = FALSE; -static unsigned int numlock_mask = 0; -static unsigned int scrolllock_mask = 0; -static unsigned int capslock_mask = 0; -typedef struct { - GtkWidget *keytext; - HotkeyConfiguration hotkey; -} KeyControls; - -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; - static GeneralPlugin audacioushotkey = { .description = "Global Hotkey", .init = init, - .about = about, - .configure = configure, + .about = show_about, + .configure = show_configure, .cleanup = cleanup }; @@ -151,67 +75,26 @@ +PluginConfig* get_config(void) +{ + return &plugin_cfg; +} + + /* * plugin activated */ static void init (void) { - x_display_init ( ); setup_filter(); load_config ( ); - grab_keys (); + grab_keys ( ); loaded = TRUE; } -/* check X display */ -void x_display_init (void) -{ - if (xdisplay != NULL) return; - xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); - x_root_window = GDK_WINDOW_XID(gdk_get_default_root_window()); - get_offending_modifiers(xdisplay); -} - -/* Taken from xbindkeys */ -static void get_offending_modifiers (Display * dpy) -{ - int i; - XModifierKeymap *modmap; - KeyCode nlock, slock; - static int mask_table[8] = { - ShiftMask, LockMask, ControlMask, Mod1Mask, - Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask - }; - - nlock = XKeysymToKeycode (dpy, XK_Num_Lock); - slock = XKeysymToKeycode (dpy, XK_Scroll_Lock); - - /* - * Find out the masks for the NumLock and ScrollLock modifiers, - * so that we can bind the grabs for when they are enabled too. - */ - modmap = XGetModifierMapping (dpy); - - if (modmap != NULL && modmap->max_keypermod > 0) - { - for (i = 0; i < 8 * modmap->max_keypermod; i++) - { - if (modmap->modifiermap[i] == nlock && nlock != 0) - numlock_mask = mask_table[i / modmap->max_keypermod]; - else if (modmap->modifiermap[i] == slock && slock != 0) - scrolllock_mask = mask_table[i / modmap->max_keypermod]; - } - } - - capslock_mask = LockMask; - - if (modmap) - XFreeModifiermap (modmap); -} - /* handle keys */ -static gboolean handle_keyevent (int keycode, int state, int type) +gboolean handle_keyevent (int keycode, int state, int type) { gint current_volume, old_volume; static gint volume_static = 0; @@ -232,8 +115,6 @@ mute = TRUE; } - state &= ~(scrolllock_mask | numlock_mask | capslock_mask); - /* mute the playback */ if ((keycode == plugin_cfg.mute.key) && (state == plugin_cfg.mute.mask) && (type == plugin_cfg.mute.type)) { @@ -390,64 +271,17 @@ return FALSE; } -static GdkFilterReturn -gdk_filter(GdkXEvent *xevent, - GdkEvent *event, - gpointer data) -{ - switch (((XEvent*)xevent)->type) - { - case KeyPress: - { - XKeyEvent *keyevent = (XKeyEvent*)xevent; - if (handle_keyevent(keyevent->keycode, keyevent->state, TYPE_KEY)) - return GDK_FILTER_REMOVE; - break; - } - case ButtonPress: - { - XButtonEvent *buttonevent = (XButtonEvent*)xevent; - if (handle_keyevent(buttonevent->button, buttonevent->state, TYPE_MOUSE)) - return GDK_FILTER_REMOVE; - break; - } - default: - return -1; - } - - return GDK_FILTER_CONTINUE; -} - -static gboolean -setup_filter() -{ - gdk_window_add_filter(gdk_get_default_root_window(), - gdk_filter, - NULL); - - return TRUE; -} - -static void release_filter() -{ - gdk_window_remove_filter(gdk_get_default_root_window(), - gdk_filter, - NULL); -} - /* load plugin configuration */ -static void load_config (void) +void load_config (void) { ConfigDb *cfdb; - if (xdisplay == NULL) x_display_init(); - /* default volume level */ plugin_cfg.vol_increment = 4; plugin_cfg.vol_decrement = 4; #define load_key(hotkey,default) \ - plugin_cfg.hotkey.key = (default)?(XKeysymToKeycode(xdisplay, (default))):0; \ + 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); \ @@ -476,7 +310,7 @@ } /* save plugin configuration */ -static void save_config (void) +void save_config (void) { ConfigDb *cfdb; @@ -505,633 +339,6 @@ aud_cfg_db_close (cfdb); } -static int x11_error_handler (Display *dpy, XErrorEvent *error) -{ - return 0; -} - -/* grab required keys */ -static void grab_key(HotkeyConfiguration hotkey) -{ - unsigned int modifier = hotkey.mask & ~(numlock_mask | capslock_mask | scrolllock_mask); - - if (hotkey.key == 0) return; - - if (hotkey.type == TYPE_KEY) - { - 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, - x_root_window, - False, GrabModeAsync, GrabModeAsync); - - if (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, - x_root_window, - False, GrabModeAsync, GrabModeAsync); - - if (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, - x_root_window, - False, GrabModeAsync, GrabModeAsync); - - if (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, - modifier | numlock_mask | capslock_mask | scrolllock_mask, - x_root_window, False, GrabModeAsync, - GrabModeAsync); - } - if (hotkey.type == TYPE_MOUSE) - { - 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, - x_root_window, - False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); - - if (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, - x_root_window, - False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); - - if (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, - x_root_window, - False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); - - if (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, - modifier | numlock_mask | capslock_mask | scrolllock_mask, - x_root_window, False, ButtonPressMask, GrabModeAsync, - GrabModeAsync, None, None); - } -} - -static void grab_keys () -{ - if (grabbed) return; - if (xdisplay == NULL) x_display_init(); - - XErrorHandler old_handler = 0; - - XSync(xdisplay, False); - old_handler = XSetErrorHandler (x11_error_handler); - - grab_key(plugin_cfg.mute); - grab_key(plugin_cfg.vol_up); - grab_key(plugin_cfg.vol_down); - grab_key(plugin_cfg.play); - grab_key(plugin_cfg.pause); - grab_key(plugin_cfg.stop); - grab_key(plugin_cfg.prev_track); - grab_key(plugin_cfg.next_track); - grab_key(plugin_cfg.jump_to_file); - grab_key(plugin_cfg.forward); - grab_key(plugin_cfg.backward); - grab_key(plugin_cfg.toggle_win); - grab_key(plugin_cfg.show_aosd); - - XSync(xdisplay, False); - XSetErrorHandler (old_handler); - - grabbed = 1; -} -/* - * plugin init end - */ - -static void set_keytext (GtkWidget *entry, gint key, gint mask, gint type) -{ - gchar *text = NULL; - - if (key == 0 && mask == 0) - { - text = g_strdup(_("(none)")); - } else { - static char *modifier_string[] = { "Control", "Shift", "Alt", "Mod2", "Mod3", "Super", "Mod5" }; - static unsigned int modifiers[] = { ControlMask, ShiftMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; - gchar *strings[9]; - gchar *keytext = NULL; - int i, j; - if (type == TYPE_KEY) - { - KeySym keysym; - keysym = XKeycodeToKeysym(xdisplay, key, 0); - if (keysym == 0 || keysym == NoSymbol) - { - keytext = g_strdup_printf("#%d", key); - } else { - keytext = g_strdup(XKeysymToString(keysym)); - } - } - if (type == TYPE_MOUSE) - { - keytext = g_strdup_printf("Button%d", key); - } - - for (i = 0, j=0; j<7; j++) - { - if (mask & modifiers[j]) - strings[i++] = modifier_string[j]; - } - if (key != 0) strings[i++] = keytext; - strings[i] = NULL; - - text = g_strjoinv(" + ", strings); - g_free(keytext); - } - - gtk_entry_set_text(GTK_ENTRY(entry), text); - gtk_editable_set_position(GTK_EDITABLE(entry), -1); - if (text) g_free(text); -} - -static gboolean -on_entry_key_press_event(GtkWidget * widget, - GdkEventKey * event, - gpointer user_data) -{ - KeyControls *controls = (KeyControls*) user_data; - int is_mod; - int mod; - - if (event->keyval == GDK_Tab) return FALSE; - - mod = 0; - is_mod = 0; - - if ((event->state & GDK_CONTROL_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R)))) - mod |= ControlMask; - - if ((event->state & GDK_MOD1_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Alt_L || event->keyval == GDK_Alt_R)))) - mod |= Mod1Mask; - - if ((event->state & GDK_SHIFT_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R)))) - mod |= ShiftMask; - - if ((event->state & GDK_MOD5_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_ISO_Level3_Shift)))) - mod |= Mod5Mask; - - if ((event->state & GDK_MOD4_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Super_L || event->keyval == GDK_Super_R)))) - mod |= Mod4Mask; - - if (!is_mod) { - controls->hotkey.key = event->hardware_keycode; - controls->hotkey.mask = mod; - controls->hotkey.type = TYPE_KEY; - } else controls->hotkey.key = 0; - - set_keytext(controls->keytext, is_mod ? 0 : event->hardware_keycode, mod, TYPE_KEY); - return TRUE; -} - -static gboolean -on_entry_key_release_event(GtkWidget * widget, - GdkEventKey * event, - gpointer user_data) -{ - KeyControls *controls = (KeyControls*) user_data; - if (controls->hotkey.key == 0) { - controls->hotkey.mask = 0; - return TRUE; - } - set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); - return TRUE; -} - -static gboolean -on_entry_button_press_event(GtkWidget * widget, - GdkEventButton * event, - gpointer user_data) -{ - KeyControls *controls = (KeyControls*) user_data; - int mod; - - if (!gtk_widget_is_focus(widget)) return FALSE; - - mod = 0; - if (event->state & GDK_CONTROL_MASK) - mod |= ControlMask; - - if (event->state & GDK_MOD1_MASK) - mod |= Mod1Mask; - - if (event->state & GDK_SHIFT_MASK) - mod |= ShiftMask; - - if (event->state & GDK_MOD5_MASK) - mod |= Mod5Mask; - - if (event->state & GDK_MOD4_MASK) - mod |= Mod4Mask; - - if ((event->button <= 3) && (mod == 0)) - { - GtkWidget* dialog; - GtkResponseType response; - dialog = gtk_message_dialog_new (GTK_WINDOW(gtk_widget_get_toplevel(widget)), - GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_YES_NO, - _("It is not recommended to bind the primary mouse buttons without modificators.\n\n" - "Do you want to continue?")); - gtk_window_set_title(GTK_WINDOW(dialog), _("Binding mouse buttons")); - response = gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy (dialog); - if (response != GTK_RESPONSE_YES) return TRUE; - } - - controls->hotkey.key = event->button; - controls->hotkey.mask = mod; - controls->hotkey.type = TYPE_MOUSE; - set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); - return TRUE; -} - -static gboolean -on_entry_scroll_event(GtkWidget * widget, - GdkEventScroll * event, - gpointer user_data) -{ - KeyControls *controls = (KeyControls*) user_data; - int mod; - - if (!gtk_widget_is_focus(widget)) return FALSE; - - mod = 0; - if (event->state & GDK_CONTROL_MASK) - mod |= ControlMask; - - if (event->state & GDK_MOD1_MASK) - mod |= Mod1Mask; - - if (event->state & GDK_SHIFT_MASK) - mod |= ShiftMask; - - if (event->state & GDK_MOD5_MASK) - mod |= Mod5Mask; - - if (event->state & GDK_MOD4_MASK) - mod |= Mod4Mask; - - if (event->direction == GDK_SCROLL_UP) - controls->hotkey.key = 4; - else if (event->direction == GDK_SCROLL_DOWN) - controls->hotkey.key = 5; - else if (event->direction == GDK_SCROLL_LEFT) - controls->hotkey.key = 6; - else if (event->direction == GDK_SCROLL_RIGHT) - controls->hotkey.key = 7; - else return FALSE; - - controls->hotkey.mask = mod; - controls->hotkey.type = TYPE_MOUSE; - set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type); - return TRUE; -} - -static void add_event_controls(GtkWidget *table, - KeyControls *controls, - int row, - char* descr, - char* tooltip, - HotkeyConfiguration hotkey) -{ - GtkWidget *label; - GtkWidget *button; - - controls->hotkey.key = hotkey.key; - controls->hotkey.mask = hotkey.mask; - controls->hotkey.type = hotkey.type; - if (controls->hotkey.key == 0) - controls->hotkey.mask = 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->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); - 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", - G_CALLBACK(on_entry_key_release_event), controls); - g_signal_connect((gpointer)controls->keytext, "button_press_event", - G_CALLBACK(on_entry_button_press_event), controls); - 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", - 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); - } -} - -/* configuration window */ -static void configure (void) -{ - ConfigurationControls *controls; - GtkWidget *window; - GtkWidget *main_vbox, *vbox; - GtkWidget *hbox; - GtkWidget *alignment; - GtkWidget *frame; - GtkWidget *label; - GtkWidget *image; - GtkWidget *table; - GtkWidget *button_box, *button; - - if (!xdisplay) x_display_init(); - - load_config ( ); - - 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_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_resizable (GTK_WINDOW (window), FALSE); - gtk_container_set_border_width (GTK_CONTAINER (window), 5); - - main_vbox = gtk_vbox_new (FALSE, 4); - gtk_container_add (GTK_CONTAINER (window), main_vbox); - - alignment = gtk_alignment_new (0.5, 0.5, 1, 1); - gtk_box_pack_start (GTK_BOX (main_vbox), alignment, FALSE, TRUE, 0); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 4, 0, 0, 0); - hbox = gtk_hbox_new (FALSE, 2); - 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.")); - 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>")); - 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 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); - - - 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); - - - 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); - - 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); - - button_box = gtk_hbutton_box_new ( ); - gtk_box_pack_start (GTK_BOX (main_vbox), button_box, FALSE, TRUE, 6); - 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); - - 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); - - gtk_widget_show_all (GTK_WIDGET (window)); -} -/* configuration window end */ - -static void about (void) -{ - static GtkWidget *dialog; - - dialog = audacious_info_dialog (_("About Global Hotkey Plugin"), - _("Global Hotkey Plugin\n" - "Control the player with global key combinations or multimedia keys.\n\n" - "Copyright (C) 2007-2008 Sascha Hlusiak <contact@saschahlusiak.de>\n\n" - "Contributers include:\n" - "Copyright (C) 2006-2007 Vladimir Paskov <vlado.paskov@gmail.com>\n" - "Copyright (C) 2000-2002 Ville Syrjälä <syrjala@sci.fi>\n" - " Bryn Davies <curious@ihug.com.au>\n" - " Jonathan A. Davis <davis@jdhouse.org>\n" - " Jeremy Tan <nsx@nsx.homeip.net>\n\n" - ), - _("OK"), TRUE, NULL, NULL); - - gtk_signal_connect(GTK_OBJECT(dialog), "destroy", - GTK_SIGNAL_FUNC(gtk_widget_destroyed), &dialog); -} - -/* Clear keys */ -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); -} - -void cancel_callback (GtkWidget *widget, gpointer data) -{ - if (loaded) - { - grab_keys (); - } - if (data) g_free(data); - - gtk_widget_destroy (gtk_widget_get_toplevel (GTK_WIDGET (widget))); -} - -void ok_callback (GtkWidget *widget, gpointer data) -{ - ConfigurationControls *controls= (ConfigurationControls*)data; - - 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; - - save_config ( ); - - if (loaded) - { - grab_keys (); - } - - if (data) g_free(data); - - gtk_widget_destroy (gtk_widget_get_toplevel (GTK_WIDGET (widget))); -} - -/* - * plugin cleanup - */ static void cleanup (void) { if (!loaded) return; @@ -1140,97 +347,7 @@ loaded = FALSE; } -/* grab required keys */ -static void ungrab_key(HotkeyConfiguration hotkey) +gboolean is_loaded (void) { - unsigned int modifier = hotkey.mask & ~(numlock_mask | capslock_mask | scrolllock_mask); - - if (hotkey.key == 0) return; - - if (hotkey.type == TYPE_KEY) - { - 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); - - if (capslock_mask) - XUngrabKey (xdisplay, hotkey.key, modifier | capslock_mask, x_root_window); - - if (scrolllock_mask) - 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); - - if (numlock_mask && scrolllock_mask) - 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); - - if (numlock_mask && capslock_mask && scrolllock_mask) - XUngrabKey (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window); - } - if (hotkey.type == TYPE_MOUSE) - { - 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); - - if (capslock_mask) - XUngrabButton (xdisplay, hotkey.key, modifier | capslock_mask, x_root_window); - - if (scrolllock_mask) - 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); - - if (numlock_mask && scrolllock_mask) - 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); - - if (numlock_mask && capslock_mask && scrolllock_mask) - XUngrabButton (xdisplay, hotkey.key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window); - } + return loaded; } - -static void ungrab_keys () -{ - XErrorHandler old_handler = 0; - - if (!grabbed) return; - if (!xdisplay) return; - - XSync(xdisplay, False); - old_handler = XSetErrorHandler (x11_error_handler); - - ungrab_key(plugin_cfg.mute); - ungrab_key(plugin_cfg.vol_up); - ungrab_key(plugin_cfg.vol_down); - ungrab_key(plugin_cfg.play); - ungrab_key(plugin_cfg.pause); - ungrab_key(plugin_cfg.stop); - ungrab_key(plugin_cfg.prev_track); - ungrab_key(plugin_cfg.next_track); - ungrab_key(plugin_cfg.jump_to_file); - ungrab_key(plugin_cfg.forward); - ungrab_key(plugin_cfg.backward); - ungrab_key(plugin_cfg.toggle_win); - ungrab_key(plugin_cfg.show_aosd); - - XSync(xdisplay, False); - XSetErrorHandler (old_handler); - - grabbed = 0; -}
