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;
-}