From 4a96b1a94e135617a1388b5b26040d774db2fc34 Mon Sep 17 00:00:00 2001 From: waker Date: Sun, 4 Nov 2012 19:26:19 +0100 Subject: switched to the new config format for global hotkeys --- plugins/hotkeys/Makefile.am | 2 +- plugins/hotkeys/hotkeys.c | 100 +++++++++++++++++++++++++++++------------ plugins/hotkeys/parser.c | 107 ++++++++++++++++++++++++++++++++++++++++++++ plugins/hotkeys/parser.h | 39 ++++++++++++++++ 4 files changed, 219 insertions(+), 29 deletions(-) create mode 100644 plugins/hotkeys/parser.c create mode 100644 plugins/hotkeys/parser.h (limited to 'plugins/hotkeys') 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 #include #include +#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 + + 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 . +*/ + +#include +#include +#include +#include +#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 + + 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 . +*/ +#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 -- cgit v1.2.3