summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/gtkui/callbacks.c1
-rw-r--r--plugins/gtkui/callbacks.h4
-rw-r--r--plugins/gtkui/deadbeef.glade12
-rw-r--r--plugins/gtkui/interface.c7
-rw-r--r--plugins/gtkui/prefwin.c112
-rw-r--r--plugins/hotkeys/hotkeys.c82
-rw-r--r--plugins/hotkeys/hotkeys.h30
-rw-r--r--plugins/hotkeys/keysyms.inc2
8 files changed, 210 insertions, 40 deletions
diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c
index 369e9749..410e67e9 100644
--- a/plugins/gtkui/callbacks.c
+++ b/plugins/gtkui/callbacks.c
@@ -987,3 +987,4 @@ on_mainwin_realize (GtkWidget *widget,
gtkui_init_theme_colors ();
}
+
diff --git a/plugins/gtkui/callbacks.h b/plugins/gtkui/callbacks.h
index 83139073..9abca77b 100644
--- a/plugins/gtkui/callbacks.h
+++ b/plugins/gtkui/callbacks.h
@@ -765,3 +765,7 @@ on_color_selected_text_color_set (GtkColorButton *colorbutton,
void
on_disable_playlist_theming_toggled (GtkToggleButton *togglebutton,
gpointer user_data);
+
+void
+on_addhotkey_activate (GtkButton *button,
+ gpointer user_data);
diff --git a/plugins/gtkui/deadbeef.glade b/plugins/gtkui/deadbeef.glade
index 85cf6cd6..3e9ca696 100644
--- a/plugins/gtkui/deadbeef.glade
+++ b/plugins/gtkui/deadbeef.glade
@@ -3955,6 +3955,18 @@ SOCKS5_HOSTNAME</property>
<property name="focus_on_click">True</property>
</widget>
</child>
+
+ <child>
+ <widget class="GtkButton" id="applyhotkeys">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Apply</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ </child>
</widget>
<packing>
<property name="padding">0</property>
diff --git a/plugins/gtkui/interface.c b/plugins/gtkui/interface.c
index cb33ff83..2f9534bf 100644
--- a/plugins/gtkui/interface.c
+++ b/plugins/gtkui/interface.c
@@ -1604,6 +1604,7 @@ create_prefwin (void)
GtkWidget *hbuttonbox3;
GtkWidget *addhotkey;
GtkWidget *removehotkey;
+ GtkWidget *applyhotkeys;
GtkWidget *label66;
GtkWidget *dialog_action_area2;
GtkWidget *closebutton1;
@@ -2080,6 +2081,11 @@ create_prefwin (void)
gtk_container_add (GTK_CONTAINER (hbuttonbox3), removehotkey);
GTK_WIDGET_SET_FLAGS (removehotkey, GTK_CAN_DEFAULT);
+ applyhotkeys = gtk_button_new_with_mnemonic ("Apply");
+ gtk_widget_show (applyhotkeys);
+ gtk_container_add (GTK_CONTAINER (hbuttonbox3), applyhotkeys);
+ GTK_WIDGET_SET_FLAGS (applyhotkeys, GTK_CAN_DEFAULT);
+
label66 = gtk_label_new ("Global Hotkeys");
gtk_widget_show (label66);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 5), label66);
@@ -2250,6 +2256,7 @@ create_prefwin (void)
GLADE_HOOKUP_OBJECT (prefwin, hbuttonbox3, "hbuttonbox3");
GLADE_HOOKUP_OBJECT (prefwin, addhotkey, "addhotkey");
GLADE_HOOKUP_OBJECT (prefwin, removehotkey, "removehotkey");
+ GLADE_HOOKUP_OBJECT (prefwin, applyhotkeys, "applyhotkeys");
GLADE_HOOKUP_OBJECT (prefwin, label66, "label66");
GLADE_HOOKUP_OBJECT_NO_REF (prefwin, dialog_action_area2, "dialog_action_area2");
GLADE_HOOKUP_OBJECT (prefwin, closebutton1, "closebutton1");
diff --git a/plugins/gtkui/prefwin.c b/plugins/gtkui/prefwin.c
index 00c53515..efb407a3 100644
--- a/plugins/gtkui/prefwin.c
+++ b/plugins/gtkui/prefwin.c
@@ -24,6 +24,9 @@
#include "interface.h"
#include "callbacks.h"
#include "drawing.h"
+#include "../hotkeys/hotkeys.h"
+
+#pragma GCC optimize("O0")
static GtkWidget *prefwin;
@@ -96,6 +99,9 @@ preferences_fill_soundcards (void) {
void
on_hk_slot_edited (GtkCellRendererText *renderer, gchar *path, gchar *new_text, gpointer user_data) {
+ if (!new_text || !new_text[0]) {
+ return;
+ }
GtkListStore *store = GTK_LIST_STORE (user_data);
GtkTreePath *treepath = gtk_tree_path_new_from_string (path);
GtkTreeIter iter;
@@ -120,16 +126,87 @@ on_hk_binding_edited (GtkCellRendererAccel *accel, gchar *path, guint accel_key,
if (accel_mods & GDK_CONTROL_MASK) {
strcat (new_value, "Ctrl ");
}
- if (accel_mods & GDK_MOD4_MASK) {
+ if (accel_mods & GDK_SUPER_MASK) {
strcat (new_value, "Super ");
}
- if (accel_mods & GDK_META_MASK) {
+ if (accel_mods & GDK_MOD1_MASK) {
strcat (new_value, "Alt ");
}
- char key[2] = {accel_key, 0};
- strcat (new_value, key);
- gtk_list_store_set (store, &iter, 1, new_value, -1);
+ // find key name from hotkeys plugin
+ DB_plugin_t **plugs = deadbeef->plug_get_list ();
+ int i;
+ for (i = 0; plugs[i]; i++) {
+ if (plugs[i]->id && !strcmp (plugs[i]->id, "hotkeys")) {
+ const char *name = ((DB_hotkeys_plugin_t *)plugs[i])->get_name_for_keycode (accel_key);
+ strcat (new_value, name);
+ gtk_list_store_set (store, &iter, 1, new_value, -1);
+ break;
+ }
+ }
+// if (!plugs[i]) {
+// return;
+// }
+}
+
+void
+on_addhotkey_clicked (GtkButton *button, gpointer user_data) {
+ GtkListStore *store = GTK_LIST_STORE (user_data);
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, "toggle_pause", 1, "", -1);
+}
+
+void
+on_removehotkey_clicked (GtkButton *button, gpointer user_data) {
+ GtkTreeView *tree = GTK_TREE_VIEW (user_data);
+ GtkTreeModel *model = gtk_tree_view_get_model (tree);
+ if (model) {
+ GtkTreeSelection *sel = gtk_tree_view_get_selection (tree);
+ if (sel) {
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (sel, NULL, &iter)) {
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ }
+ }
+ }
+}
+
+static gboolean
+add_hotkey_to_config (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) {
+ int *counter = (int *)data;
+ GValue key = {0,}, value = {0,};
+// g_value_init (&key, G_TYPE_STRING);
+// g_value_init (&value, G_TYPE_STRING);
+ gtk_tree_model_get_value (model, iter, 0, &key);
+ gtk_tree_model_get_value (model, iter, 1, &value);
+ const char *skey = g_value_get_string (&key);
+ const char *svalue = g_value_get_string (&value);
+
+ char conf_name[100];
+ char conf_value[100];
+ snprintf (conf_name, sizeof (conf_name), "hotkeys.key%d", *counter);
+ (*counter)++;
+ snprintf (conf_value, sizeof (conf_value), "%s: %s", svalue, skey);
+ deadbeef->conf_set_str (conf_name, conf_value);
+}
+
+void
+on_applyhotkeys_clicked (GtkButton *button, gpointer user_data) {
+ DB_plugin_t **plugs = deadbeef->plug_get_list ();
+ int i;
+ for (i = 0; plugs[i]; i++) {
+ if (plugs[i]->id && !strcmp (plugs[i]->id, "hotkeys")) {
+ // rebuild config
+ deadbeef->conf_remove_items ("hotkeys.key");
+ int counter = 1;
+ GtkTreeModel *model = GTK_TREE_MODEL (user_data);
+ gtk_tree_model_foreach (model, add_hotkey_to_config, &counter);
+
+ ((DB_hotkeys_plugin_t *)plugs[i])->reset ();
+ break;
+ }
+ }
}
void
@@ -277,16 +354,17 @@ on_preferences_activate (GtkMenuItem *menuitem,
// model for hotkey slots
const char *slots[] = {
- "Toggle pause",
- "Play",
- "Prev",
- "Next",
- "Random",
- "Seek forward",
- "Seek backward",
- "Volume up",
- "Volume down",
- "Toggle stop after current",
+ "toggle_pause",
+ "play",
+ "prev",
+ "next",
+ "stop",
+ "play_random",
+ "seek_fwd",
+ "seek_back",
+ "volume_up",
+ "volume_down",
+ "toggle_stop_after_current",
NULL
};
GtkListStore *slots_store = gtk_list_store_new (1, G_TYPE_STRING);
@@ -345,6 +423,10 @@ on_preferences_activate (GtkMenuItem *menuitem,
}
gtk_tree_view_set_model (hktree, GTK_TREE_MODEL (hkstore));
+ g_signal_connect ((gpointer)lookup_widget (prefwin, "addhotkey"), "clicked", G_CALLBACK (on_addhotkey_clicked), hkstore);
+ g_signal_connect ((gpointer)lookup_widget (prefwin, "removehotkey"), "clicked", G_CALLBACK (on_removehotkey_clicked), hktree);
+ g_signal_connect ((gpointer)lookup_widget (prefwin, "applyhotkeys"), "clicked", G_CALLBACK (on_applyhotkeys_clicked), hkstore);
+
gtk_dialog_run (GTK_DIALOG (prefwin));
gtk_widget_destroy (prefwin);
prefwin = NULL;
diff --git a/plugins/hotkeys/hotkeys.c b/plugins/hotkeys/hotkeys.c
index 622fc5fb..959dbd30 100644
--- a/plugins/hotkeys/hotkeys.c
+++ b/plugins/hotkeys/hotkeys.c
@@ -22,13 +22,15 @@
#include <X11/Xlib.h>
#include <ctype.h>
+#include "hotkeys.h"
#include "../../deadbeef.h"
-static DB_misc_t plugin;
+static DB_hotkeys_plugin_t plugin;
static DB_functions_t *deadbeef;
static int finished;
static Display *disp;
static intptr_t loop_tid;
+static int need_reset = 0;
#define MAX_COMMAND_COUNT 256
@@ -67,7 +69,7 @@ get_keycode (Display *disp, const char* name, KeySym *syms, int first_kk, int la
for (i = 0; i < last_kk-first_kk; i++)
{
KeySym sym = * (syms + i*ks_per_kk);
- for (ks = 0; ks < sizeof (keys) / sizeof (xkey_t); ks++)
+ for (ks = 0; keys[ks].name; ks++)
{
if ( (keys[ ks ].keysym == sym) && (0 == strcmp (name, keys[ ks ].name)))
{
@@ -257,6 +259,12 @@ read_config (Display *disp)
item = deadbeef->conf_find ("hotkeys.", item);
}
XFree (syms);
+ int i;
+ // need to grab it here to prevent gdk_x_error from being called while we're
+ // doing it on other thread
+ for (i = 0; i < command_count; i++) {
+ XGrabKey (disp, commands[i].keycode, commands[i].modifier, DefaultRootWindow (disp), False, GrabModeAsync, GrabModeAsync);
+ }
}
DB_plugin_t *
@@ -271,11 +279,29 @@ cleanup () {
XCloseDisplay (disp);
}
+static int
+x_err_handler (Display *d, XErrorEvent *evt) {
+ char buffer[1024];
+ XGetErrorText (d, evt->error_code, buffer, sizeof (buffer));
+ fprintf (stderr, "hotkeys: xlib error: %s\n", buffer);
+}
+
static void
hotkeys_event_loop (void *unused) {
int i;
while (!finished) {
+ if (need_reset) {
+ XSetErrorHandler (x_err_handler);
+ for (int i = 0; i < command_count; i++) {
+ XUngrabKey (disp, commands[i].keycode, commands[i].modifier, DefaultRootWindow (disp));
+ }
+ memset (commands, 0, sizeof (commands));
+ command_count = 0;
+ read_config (disp);
+ need_reset = 0;
+ }
+
XEvent event;
while (XPending (disp))
{
@@ -297,13 +323,6 @@ hotkeys_event_loop (void *unused) {
}
static int
-x_err_handler (Display *d, XErrorEvent *evt) {
- char buffer[1024];
- XGetErrorText (d, evt->error_code, buffer, sizeof (buffer));
- fprintf (stderr, "hotkeys: xlib error: %s\n", buffer);
-}
-
-static int
hotkeys_start (void) {
finished = 0;
loop_tid = 0;
@@ -316,12 +335,6 @@ hotkeys_start (void) {
XSetErrorHandler (x_err_handler);
read_config (disp);
- int i;
- // need to grab it here to prevent gdk_x_error from being called while we're
- // doing it on other thread
- for (i = 0; i < command_count; i++) {
- XGrabKey (disp, commands[i].keycode, commands[i].modifier, DefaultRootWindow (disp), False, GrabModeAsync, GrabModeAsync);
- }
XSync (disp, 0);
if (command_count > 0) {
loop_tid = deadbeef->thread_start (hotkeys_event_loop, 0);
@@ -340,16 +353,35 @@ hotkeys_stop (void) {
}
}
+const char *
+hotkeys_get_name_for_keycode (int keycode) {
+ for (int i = 0; keys[i].name; i++) {
+ if (keycode == keys[i].keysym) {
+ return keys[i].name;
+ }
+ }
+ return NULL;
+}
+
+void
+hotkeys_reset (void) {
+ need_reset = 1;
+}
+
// define plugin interface
-static DB_misc_t plugin = {
- DB_PLUGIN_SET_API_VERSION
- .plugin.type = DB_PLUGIN_MISC,
- .plugin.name = "Global hotkeys support",
- .plugin.descr = "Allows to control player with global hotkeys",
- .plugin.author = "Viktor Semykin",
- .plugin.email = "thesame.ml@gmail.com",
- .plugin.website = "http://deadbeef.sf.net",
- .plugin.start = hotkeys_start,
- .plugin.stop = hotkeys_stop
+static DB_hotkeys_plugin_t plugin = {
+ .misc.plugin.api_vmajor = DB_API_VERSION_MAJOR,
+ .misc.plugin.api_vminor = DB_API_VERSION_MINOR,
+ .misc.plugin.type = DB_PLUGIN_MISC,
+ .misc.plugin.id = "hotkeys",
+ .misc.plugin.name = "Global hotkeys support",
+ .misc.plugin.descr = "Allows to control player with global hotkeys",
+ .misc.plugin.author = "Viktor Semykin",
+ .misc.plugin.email = "thesame.ml@gmail.com",
+ .misc.plugin.website = "http://deadbeef.sf.net",
+ .misc.plugin.start = hotkeys_start,
+ .misc.plugin.stop = hotkeys_stop,
+ .get_name_for_keycode = hotkeys_get_name_for_keycode,
+ .reset = hotkeys_reset,
};
diff --git a/plugins/hotkeys/hotkeys.h b/plugins/hotkeys/hotkeys.h
new file mode 100644
index 00000000..f520aa41
--- /dev/null
+++ b/plugins/hotkeys/hotkeys.h
@@ -0,0 +1,30 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __HOTKEYS_H
+#define __HOTKEYS_H
+
+#include "../../deadbeef.h"
+
+typedef struct DB_hotkeys_plugin_s {
+ DB_misc_t misc;
+ const char *(*get_name_for_keycode) (int keycode);
+ void (*reset) (void);
+} DB_hotkeys_plugin_t;
+
+#endif
diff --git a/plugins/hotkeys/keysyms.inc b/plugins/hotkeys/keysyms.inc
index af164fef..1f66304b 100644
--- a/plugins/hotkeys/keysyms.inc
+++ b/plugins/hotkeys/keysyms.inc
@@ -2189,3 +2189,5 @@ KEY("XF86Ungrab", 0x1008FE20)
KEY("XF86ClearGrab", 0x1008FE21)
KEY("XF86Next_VMode", 0x1008FE22)
KEY("XF86Prev_VMode", 0x1008FE23)
+
+KEY(NULL, 0)