summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/gtkui/callbacks.c31
-rw-r--r--plugins/hotkeys/hotkeys.c58
2 files changed, 84 insertions, 5 deletions
diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c
index 17109be8..42635ac9 100644
--- a/plugins/gtkui/callbacks.c
+++ b/plugins/gtkui/callbacks.c
@@ -27,6 +27,7 @@
#include <assert.h>
#include <ctype.h>
#include <gdk/gdkkeysyms.h>
+#include <X11/Xlib.h>
#include "../../gettext.h"
#include "callbacks.h"
@@ -45,6 +46,7 @@
#include "eq.h"
#include "wingeom.h"
#include "widgets.h"
+#include "../hotkeys/hotkeys.h"
//#define trace(...) { fprintf (stderr, __VA_ARGS__); }
#define trace(fmt,...)
@@ -375,6 +377,35 @@ on_mainwin_key_press_event (GtkWidget *widget,
GdkEventKey *event,
gpointer user_data)
{
+ // local hotkeys
+ // first translate gdk modifiers into X11 constants
+ int mods = 0;
+ if (event->state & GDK_CONTROL_MASK) {
+ mods |= ControlMask;
+ }
+ if (event->state & GDK_MOD1_MASK) {
+ mods |= Mod1Mask;
+ }
+ if (event->state & GDK_SHIFT_MASK) {
+ mods |= ShiftMask;
+ }
+ if (event->state & GDK_MOD4_MASK) {
+ mods |= Mod4Mask;
+ }
+ trace ("keycode: %x, mods %x\n", event->keyval, mods);
+ DB_plugin_t *hkplug = deadbeef->plug_get_for_id ("hotkeys");
+ if (hkplug) {
+ int ctx;
+ DB_plugin_action_t *act = ((DB_hotkeys_plugin_t *)hkplug)->get_action_for_keycombo (event->keyval, mods, 0, &ctx);
+ if (act && act->callback) {
+ trace ("executing action %s in ctx %d\n", act->name, ctx);
+ act->callback (act, ctx);
+ return TRUE;
+ }
+ }
+
+
+
uint32_t maskedstate = (event->state &~ (GDK_LOCK_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | GDK_MOD5_MASK)) & 0xfff;
if ((maskedstate == GDK_MOD1_MASK || maskedstate == 0) && event->keyval == GDK_n) {
// button for that one is not in toolbar anymore, so handle it manually
diff --git a/plugins/hotkeys/hotkeys.c b/plugins/hotkeys/hotkeys.c
index 34ac1e1d..5c9e9419 100644
--- a/plugins/hotkeys/hotkeys.c
+++ b/plugins/hotkeys/hotkeys.c
@@ -41,11 +41,12 @@ static int need_reset = 0;
typedef struct {
const char *name;
KeySym keysym;
+ int keycode; // after mapping
} xkey_t;
-#define KEY(kname, kcode) { .name=kname, .keysym=kcode },
+#define KEY(kname, kcode) { .name=kname, .keysym=kcode},
-static const xkey_t keys[] = {
+static xkey_t keys[] = {
#include "keysyms.inc"
};
@@ -61,6 +62,22 @@ typedef struct command_s {
static command_t commands [MAX_COMMAND_COUNT];
static int command_count = 0;
+static void
+init_mapped_keycodes (Display *disp, KeySym *syms, int first_kk, int last_kk, int ks_per_kk) {
+ int i, ks;
+ for (i = 0; i < last_kk-first_kk; i++)
+ {
+ KeySym sym = * (syms + i*ks_per_kk);
+ for (ks = 0; keys[ks].name; ks++)
+ {
+ if (keys[ ks ].keysym == sym)
+ {
+ keys[ks].keycode = i+first_kk;
+ }
+ }
+ }
+}
+
static int
get_keycode (Display *disp, const char* name, KeySym *syms, int first_kk, int last_kk, int ks_per_kk) {
trace ("get_keycode %s\n", name);
@@ -441,6 +458,14 @@ hotkeys_connect (void) {
XSetErrorHandler (x_err_handler);
read_config (disp);
+
+ int ks_per_kk;
+ int first_kk, last_kk;
+ KeySym* syms;
+ XDisplayKeycodes (disp, &first_kk, &last_kk);
+ syms = XGetKeyboardMapping (disp, first_kk, last_kk - first_kk, &ks_per_kk);
+ init_mapped_keycodes (disp, syms, first_kk, last_kk, ks_per_kk);
+ XFree (syms);
XSync (disp, 0);
loop_tid = deadbeef->thread_start (hotkeys_event_loop, 0);
return 0;
@@ -470,8 +495,26 @@ hotkeys_get_name_for_keycode (int keycode) {
DB_plugin_action_t*
hotkeys_get_action_for_keycombo (int key, int mods, int isglobal, int *ctx) {
- for (int i = 0; i < command_count; i++) {
- if (commands[i].keycode == key && commands[i].modifier == mods && commands[i].isglobal == isglobal) {
+ int i;
+ // find mapped keycode
+ int keycode = 0;
+ for (i = 0; keys[i].name; i++) {
+ if (key == keys[i].keysym) {
+ keycode = keys[i].keycode;
+ break;
+ }
+ }
+ if (!keys[i].name) {
+ trace ("hotkeys: unknown keysym 0x%X\n", key);
+ return NULL;
+ }
+
+ trace ("hotkeys: keysym 0x%X mapped to 0x%X\n", key, keycode);
+
+
+ for (i = 0; i < command_count; i++) {
+ trace ("hotkeys: command %s keycode %x mods %x\n", commands[i].action->name, commands[i].keycode, commands[i].modifier);
+ if (commands[i].keycode == keycode && commands[i].modifier == mods && commands[i].isglobal == isglobal) {
*ctx = commands[i].ctx;
return commands[i].action;
}
@@ -677,7 +720,12 @@ static DB_hotkeys_plugin_t plugin = {
.misc.plugin.type = DB_PLUGIN_MISC,
.misc.plugin.id = "hotkeys",
.misc.plugin.name = "Global hotkeys support",
- .misc.plugin.descr = "Allows one to control player with global hotkeys",
+ .misc.plugin.descr =
+ "Allows one to control player with hotkeys\n"
+ "Changes in version 1.1\n"
+ " * adaptation to new deadbeef 0.6 plugin API\n"
+ " * added local hotkeys support\n"
+ ,
.misc.plugin.copyright =
"Copyright (C) 2009-2012 Alexey Yakovenko <waker@users.sourceforge.net>\n"
"Copyright (C) 2009-2011 Viktor Semykin <thesame.ml@gmail.com>\n"