From b7943d6760d31ccb951f3b518fdad5a2ee6e9e5b Mon Sep 17 00:00:00 2001 From: waker Date: Mon, 5 Nov 2012 22:18:48 +0100 Subject: local hotkeys support --- plugins/gtkui/callbacks.c | 31 +++++++++++++++++++++++++ plugins/hotkeys/hotkeys.c | 58 +++++++++++++++++++++++++++++++++++++++++++---- 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 #include #include +#include #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 \n" "Copyright (C) 2009-2011 Viktor Semykin \n" -- cgit v1.2.3