summaryrefslogtreecommitdiff
path: root/plugins/hotkeys
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2012-11-04 19:26:19 +0100
committerGravatar waker <wakeroid@gmail.com>2012-11-04 19:26:19 +0100
commit4a96b1a94e135617a1388b5b26040d774db2fc34 (patch)
tree9667745bd82b7204455af936983e89c224bf9d1d /plugins/hotkeys
parent21dfe3e0b0f89e4f09d7f6bfa914ff7bd0d062bb (diff)
switched to the new config format for global hotkeys
Diffstat (limited to 'plugins/hotkeys')
-rw-r--r--plugins/hotkeys/Makefile.am2
-rw-r--r--plugins/hotkeys/hotkeys.c100
-rw-r--r--plugins/hotkeys/parser.c107
-rw-r--r--plugins/hotkeys/parser.h39
4 files changed, 219 insertions, 29 deletions
diff --git a/plugins/hotkeys/Makefile.am b/plugins/hotkeys/Makefile.am
index 79a9d642..3468f2bd 100644
--- a/plugins/hotkeys/Makefile.am
+++ b/plugins/hotkeys/Makefile.am
@@ -1,7 +1,7 @@
if HAVE_HOTKEYS
hotkeysdir = $(libdir)/$(PACKAGE)
pkglib_LTLIBRARIES = hotkeys.la
-hotkeys_la_SOURCES = hotkeys.c hotkeys.h
+hotkeys_la_SOURCES = hotkeys.c hotkeys.h parser.c parser.h
hotkeys_la_LDFLAGS = -module
EXTRA_hotkeys_la_SOURCES = keysyms.inc
diff --git a/plugins/hotkeys/hotkeys.c b/plugins/hotkeys/hotkeys.c
index 9c317120..f01c62ab 100644
--- a/plugins/hotkeys/hotkeys.c
+++ b/plugins/hotkeys/hotkeys.c
@@ -21,6 +21,7 @@
#include <unistd.h>
#include <X11/Xlib.h>
#include <ctype.h>
+#include "parser.h"
#include "hotkeys.h"
#include "../../deadbeef.h"
@@ -51,6 +52,7 @@ static const xkey_t keys[] = {
typedef struct command_s {
int keycode;
int modifier;
+ int ctx;
DB_plugin_action_t *action;
} command_t;
@@ -59,6 +61,7 @@ static int command_count = 0;
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);
int i, ks;
for (i = 0; i < last_kk-first_kk; i++)
@@ -186,6 +189,29 @@ get_action (const char* command)
return NULL;
}
+static DB_plugin_action_t *
+find_action_by_name (const char *command) {
+ // find action with this name, and add to list
+ DB_plugin_action_t *actions = NULL;
+ DB_plugin_t **plugins = deadbeef->plug_get_list ();
+ for (int i = 0; plugins[i]; i++) {
+ DB_plugin_t *p = plugins[i];
+ if (p->get_actions) {
+ actions = p->get_actions (NULL);
+ while (actions) {
+ if (actions->name && actions->title && !strcasecmp (actions->name, command)) {
+ break; // found
+ }
+ actions = actions->next;
+ }
+ if (actions) {
+ break;
+ }
+ }
+ }
+ return actions;
+}
+
static int
read_config (Display *disp)
{
@@ -196,7 +222,7 @@ read_config (Display *disp)
XDisplayKeycodes (disp, &first_kk, &last_kk);
syms = XGetKeyboardMapping (disp, first_kk, last_kk - first_kk, &ks_per_kk);
- DB_conf_item_t *item = deadbeef->conf_find ("hotkeys.", NULL);
+ DB_conf_item_t *item = deadbeef->conf_find ("hotkey.", NULL);
while (item) {
if (command_count == MAX_COMMAND_COUNT)
{
@@ -205,30 +231,55 @@ read_config (Display *disp)
}
command_t *cmd_entry = &commands[ command_count ];
- cmd_entry->modifier = 0;
- cmd_entry->keycode = 0;
-
- size_t l = strlen (item->value);
- char param[l+1];
- memcpy (param, item->value, l+1);
-
- char* colon = strchr (param, ':');
- if (!colon)
- {
- fprintf (stderr, "hotkeys: bad config option %s %s\n", item->key, item->value);
- continue;
+ memset (cmd_entry, 0, sizeof (command_t));
+
+ char token[MAX_TOKEN];
+ char keycombo[MAX_TOKEN];
+ int isglobal;
+ const char *script = item->value;
+ if ((script = gettoken (script, keycombo)) == 0) {
+ trace ("hotkeys: unexpected eol (keycombo)\n");
+ goto out;
+ }
+ if ((script = gettoken (script, token)) == 0) {
+ trace ("hotkeys: unexpected eol (ctx)\n");
+ goto out;
+ }
+ cmd_entry->ctx = atoi (token);
+ if (cmd_entry->ctx < 0 || cmd_entry->ctx >= DDB_ACTION_CTX_COUNT) {
+ trace ("hotkeys: invalid ctx %d\n");
+ goto out;
+ }
+ if ((script = gettoken (script, token)) == 0) {
+ trace ("hotkeys: unexpected eol (isglobal)\n");
+ goto out;
+ }
+ isglobal = atoi (token);
+ if (!isglobal) {
+ trace ("hotkeys: isglobal=0, skip\n");
+ goto out; // ignore non-global hotkeys
+ }
+ if ((script = gettoken (script, token)) == 0) {
+ trace ("hotkeys: unexpected eol (action)\n");
+ goto out;
+ }
+ cmd_entry->action = find_action_by_name (token);
+ if (!cmd_entry->action) {
+ trace ("hotkeys: action not found %s\n", token);
+ goto out;
}
- char* command = colon+1;
- *colon = 0;
+ // parse key combo
int done = 0;
char* p;
- char* space = param - 1;
+ char* space = keycombo;
do {
- p = space+1;
+ p = space;
space = strchr (p, ' ');
- if (space)
+ if (space) {
*space = 0;
+ space++;
+ }
else
done = 1;
@@ -270,18 +321,11 @@ read_config (Display *disp)
trace ("hotkeys: Key not found while parsing %s %s\n", item->key, item->value);
}
else {
- command = trim (command);
- cmd_entry->action = get_action (command);
- if (!cmd_entry->action)
- {
- trace ("hotkeys: Unknown command <%s> while parsing %s %s\n", command, item->key, item->value);
- }
- else {
- command_count++;
- }
+ command_count++;
}
}
- item = deadbeef->conf_find ("hotkeys.", item);
+out:
+ item = deadbeef->conf_find ("hotkey.", item);
}
XFree (syms);
int i;
diff --git a/plugins/hotkeys/parser.c b/plugins/hotkeys/parser.c
new file mode 100644
index 00000000..c49eeb72
--- /dev/null
+++ b/plugins/hotkeys/parser.c
@@ -0,0 +1,107 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2012 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include "parser.h"
+
+// very basic parser, ripped from psynth, optimized, and extended to support
+// quoted strings and extra special chars
+int parser_line;
+
+void
+parser_init (void) {
+ parser_line = 1;
+}
+
+const char *
+skipws (const char *p) {
+ while (*p <= ' ' && *p) {
+ if (*p == '\n') {
+ parser_line++;
+ }
+ p++;
+ }
+ if (!*p) {
+ return NULL;
+ }
+ return p;
+}
+
+const char *
+gettoken (const char *p, char *tok) {
+ const char *c;
+ assert (p);
+ assert (tok);
+ int n = MAX_TOKEN-1;
+ char specialchars[] = "{}();";
+ if (!(p = skipws (p))) {
+ return NULL;
+ }
+ if (*p == '"') {
+ p++;
+ c = p;
+ while (n > 0 && *c && *c != '"') {
+ if (*c == '\n') {
+ parser_line++;
+ }
+ *tok++ = *c++;
+ n--;
+ }
+ if (*c) {
+ c++;
+ }
+ *tok = 0;
+ return c;
+ }
+ if (strchr (specialchars, *p)) {
+ *tok = *p;
+ tok[1] = 0;
+ return p+1;
+ }
+ c = p;
+ while (n > 0 && *c > ' ' && !strchr (specialchars, *c)) {
+ *tok++ = *c++;
+ n--;
+ }
+ *tok = 0;
+ return c;
+}
+
+const char *
+gettoken_warn_eof (const char *p, char *tok) {
+ p = gettoken (p, tok);
+ if (!p) {
+ fprintf (stderr, "parser: unexpected eof at line %d", parser_line);
+ }
+ return p;
+}
+
+const char *
+gettoken_err_eof (const char *p, char *tok) {
+ p = gettoken (p, tok);
+ if (!p) {
+ fprintf (stderr, "parser: unexpected eof at line %d", parser_line);
+ exit (-1);
+ }
+ return p;
+}
+
+
diff --git a/plugins/hotkeys/parser.h b/plugins/hotkeys/parser.h
new file mode 100644
index 00000000..b0f95169
--- /dev/null
+++ b/plugins/hotkeys/parser.h
@@ -0,0 +1,39 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2012 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, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __PARSER_H
+#define __PARSER_H
+
+#define MAX_TOKEN 256
+extern int parser_line;
+
+void
+parser_init (void);
+
+const char *
+skipws (const char *p);
+
+const char *
+gettoken (const char *p, char *tok);
+
+const char *
+gettoken_warn_eof (const char *p, char *tok);
+
+const char *
+gettoken_err_eof (const char *p, char *tok);
+
+#endif