summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Viktor Semykin <thesame.ml@gmail.com>2010-07-04 19:02:19 +0300
committerGravatar Viktor Semykin <thesame.ml@gmail.com>2010-07-04 19:02:19 +0300
commit5e64ac2297992c8cfe35233fc93585f7066a6faa (patch)
treeb8b181b60b65a0e39081b16f61834b61b8da09bd /plugins
parentffd1a10e7f34a0a9201297db12aadbf74d7c59c8 (diff)
added support of plugins actions for global hotkeys
Diffstat (limited to 'plugins')
-rw-r--r--plugins/gtkui/actions.c3
-rw-r--r--plugins/gtkui/plcommon.c14
-rw-r--r--plugins/hotkeys/hotkeys.c138
-rw-r--r--plugins/lastfm/lastfm.c8
-rw-r--r--plugins/shellexec/shellexec.c112
5 files changed, 226 insertions, 49 deletions
diff --git a/plugins/gtkui/actions.c b/plugins/gtkui/actions.c
index 0f07a4b0..96ee0085 100644
--- a/plugins/gtkui/actions.c
+++ b/plugins/gtkui/actions.c
@@ -30,7 +30,8 @@ static void
on_actionitem_activate (GtkMenuItem *menuitem,
DB_plugin_action_t *action)
{
- action->callback (NULL, action->data);
+// action->callback (NULL, action->data);
+ action->callback (action, NULL);
}
void
diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c
index 1a04dbfc..1600b848 100644
--- a/plugins/gtkui/plcommon.c
+++ b/plugins/gtkui/plcommon.c
@@ -353,7 +353,7 @@ actionitem_activate (GtkMenuItem *menuitem,
// Plugin can handle all tracks by itself
if (action->flags & DB_ACTION_CAN_MULTIPLE_TRACKS)
{
- action->callback (NULL, action->data);
+ action->callback (action, NULL);
return;
}
@@ -361,7 +361,7 @@ actionitem_activate (GtkMenuItem *menuitem,
if (0 == action->flags & DB_ACTION_ALLOW_MULTIPLE_TRACKS)
{
DB_playItem_t *it = deadbeef->pl_get_for_idx_and_iter (clicked_idx, PL_MAIN);
- action->callback (it, action->data);
+ action->callback (action, it);
deadbeef->pl_item_unref (it);
return;
}
@@ -370,7 +370,7 @@ actionitem_activate (GtkMenuItem *menuitem,
DB_playItem_t *it = deadbeef->pl_get_first (PL_MAIN);
while (it) {
if (deadbeef->pl_is_selected (it))
- action->callback (it, action->data);
+ action->callback (action, it);
DB_playItem_t *next = deadbeef->pl_get_next (it, PL_MAIN);
deadbeef->pl_item_unref (it);
it = next;
@@ -421,10 +421,10 @@ list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) {
gtk_container_add (GTK_CONTAINER (playlist_menu), remove2);
g_object_set_data (G_OBJECT (remove2), "ps", listview);
- remove_from_disk = gtk_menu_item_new_with_mnemonic (_("Remove from disk"));
- gtk_widget_show (remove_from_disk);
- gtk_container_add (GTK_CONTAINER (playlist_menu), remove_from_disk);
- g_object_set_data (G_OBJECT (remove_from_disk), "ps", listview);
+/* remove_from_disk = gtk_menu_item_new_with_mnemonic (_("Remove from disk"));*/
+/* gtk_widget_show (remove_from_disk);*/
+/* gtk_container_add (GTK_CONTAINER (playlist_menu), remove_from_disk);*/
+/* g_object_set_data (G_OBJECT (remove_from_disk), "ps", listview);*/
separator8 = gtk_separator_menu_item_new ();
gtk_widget_show (separator8);
diff --git a/plugins/hotkeys/hotkeys.c b/plugins/hotkeys/hotkeys.c
index 0fffdf0c..b201bfd4 100644
--- a/plugins/hotkeys/hotkeys.c
+++ b/plugins/hotkeys/hotkeys.c
@@ -25,8 +25,8 @@
#include "hotkeys.h"
#include "../../deadbeef.h"
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-#define trace(fmt,...)
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
static DB_hotkeys_plugin_t plugin;
static DB_functions_t *deadbeef;
@@ -48,23 +48,20 @@ static const xkey_t keys[] = {
#include "keysyms.inc"
};
-typedef void (*command_func_t) (void);
+//typedef void (*command_func_t) (void *command);
-typedef struct {
+typedef struct command_s {
int keycode;
int modifier;
- command_func_t func;
+ const char *action;
+ void (*func) (struct command_s *command);
} command_t;
+typedef void (*command_func_t) (command_t *command);
+
static command_t commands [MAX_COMMAND_COUNT];
static int command_count = 0;
-
-typedef struct {
- char* name;
- void (*func) (void);
-} known_command_t;
-
static int
get_keycode (Display *disp, const char* name, KeySym *syms, int first_kk, int last_kk, int ks_per_kk) {
int i, ks;
@@ -95,36 +92,139 @@ trim (char* s)
}
static void
-cmd_seek_fwd () {
+cmd_seek_fwd (void *unused) {
deadbeef->playback_set_pos (deadbeef->playback_get_pos () + 5);
}
static void
-cmd_seek_back () {
+cmd_seek_back (void *unused) {
deadbeef->playback_set_pos (deadbeef->playback_get_pos () - 5);
}
static void
-cmd_volume_up () {
+cmd_volume_up (void *unused) {
deadbeef->volume_set_db (deadbeef->volume_get_db () + 2);
}
static void
-cmd_volume_down () {
+cmd_volume_down (void *unused) {
deadbeef->volume_set_db (deadbeef->volume_get_db () - 2);
}
static void
-cmd_stop_after_current () {
+cmd_stop_after_current (void *unused) {
int var = deadbeef->conf_get_int ("playlist.stop_after_current", 0);
var = 1 - var;
deadbeef->conf_set_int ("playlist.stop_after_current", var);
deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0);
}
+/*
+ FIXME: This function has many common code with plcommon.c
+ and it does full traverse of playlist twice
+*/
+static void
+cmd_invoke_plugin_command (command_t *command)
+{
+ trace ("We're here to invoke %s\n", command->action);
+
+ DB_plugin_action_t *action = NULL;
+ DB_plugin_t **plugins = deadbeef->plug_get_list();
+ int i;
+
+ int selected_count = 0;
+ DB_playItem_t *pit = deadbeef->pl_get_first (PL_MAIN);
+ DB_playItem_t *selected = NULL;
+ while (pit) {
+ if (deadbeef->pl_is_selected (pit))
+ {
+ if (!selected)
+ selected = pit;
+ selected_count++;
+ }
+ DB_playItem_t *next = deadbeef->pl_get_next (pit, PL_MAIN);
+ deadbeef->pl_item_unref (pit);
+ pit = next;
+ }
+
+ for (i = 0; plugins[i]; i++)
+ {
+ if (!plugins[i]->get_actions)
+ continue;
+
+ DB_plugin_action_t *actions = plugins[i]->get_actions (selected);
+ DB_plugin_action_t *iter;
+ for (iter = actions; iter; iter = iter->next)
+ {
+ if (!iter->name)
+ continue;
+ if (0 == strcmp (iter->name, command->action))
+ {
+ action = iter;
+ break;
+ }
+ }
+ if (action)
+ break;
+ }
+ if (!action)
+ {
+ fprintf (stderr, "Hotkeys: action %s not found\n", command->action);
+ return;
+ }
+
+ if (action->flags & DB_ACTION_COMMON)
+ {
+ //Simply call common action
+ action->callback (action, NULL);
+ return;
+ }
+ //Now we're checking af action is applicable:
+
+ if (selected_count == 0)
+ {
+ fprintf (stderr, "No tracks selected\n");
+ return;
+ }
+ if ((selected_count == 1) && (0 == action->flags & DB_ACTION_SINGLE_TRACK))
+ {
+ fprintf (stderr, "Hotkeys: action %s not allowed for single track\n", action->name);
+ return;
+ }
+ if ((selected_count > 1) && (0 == action->flags & DB_ACTION_ALLOW_MULTIPLE_TRACKS))
+ {
+ fprintf (stderr, "Hotkeys: action %s not allowed for multiple tracks\n", action->name);
+ return;
+ }
+
+ //So, action is allowed, do it.
+
+ if (action->flags & DB_ACTION_CAN_MULTIPLE_TRACKS)
+ {
+ action->callback (action, NULL);
+ return;
+ }
+
+ pit = deadbeef->pl_get_first (PL_MAIN);
+ while (pit) {
+ if (deadbeef->pl_is_selected (pit))
+ {
+ action->callback (action, pit);
+ }
+ DB_playItem_t *next = deadbeef->pl_get_next (pit, PL_MAIN);
+ deadbeef->pl_item_unref (pit);
+ pit = next;
+ }
+}
+
static command_func_t
get_command (const char* command)
{
+ /*
+ These deadbeef functions don't take any parameters
+ but I assume we use cdecl convention so actual
+ parameters count doesn't matter.
+ */
if (!strcasecmp (command, "toggle_pause"))
return deadbeef->playback_pause;
@@ -158,7 +258,8 @@ get_command (const char* command)
else if (!strcasecmp (command, "toggle_stop_after_current"))
return cmd_stop_after_current;
- return NULL;
+ return cmd_invoke_plugin_command;
+// return NULL;
}
static int
@@ -248,6 +349,7 @@ read_config (Display *disp)
else {
command = trim (command);
cmd_entry->func = get_command (command);
+ cmd_entry->action = strdup (command);
if (!cmd_entry->func)
{
fprintf (stderr, "hotkeys: Unknown command <%s> while parsing %s %s\n", command, item->key, item->value);
@@ -355,7 +457,7 @@ hotkeys_event_loop (void *unused) {
(state == commands[ i ].modifier))
{
trace ("matches to commands[%d]!\n", i);
- commands[i].func ();
+ commands[i].func (&commands[i]);
break;
}
}
diff --git a/plugins/lastfm/lastfm.c b/plugins/lastfm/lastfm.c
index 82b2db91..c674a5fa 100644
--- a/plugins/lastfm/lastfm.c
+++ b/plugins/lastfm/lastfm.c
@@ -23,8 +23,8 @@
#include <curl/curl.h>
#include "../../deadbeef.h"
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-#define trace(fmt,...)
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
#define LFM_TESTMODE 0
#define LFM_IGNORE_RULES 0
@@ -825,7 +825,7 @@ lastfm_stop (void) {
}
static int
-lfm_action_lookup (DB_playItem_t *it, void *data)
+lfm_action_lookup (DB_plugin_action_t *action, DB_playItem_t *it)
{
const char *artist = deadbeef->pl_find_meta (it, "artist");
const char *title = deadbeef->pl_find_meta (it, "title");
@@ -857,6 +857,7 @@ lfm_action_love (DB_playItem_t *it, void *data)
static DB_plugin_action_t love_action = {
.title = "Love at Last.fm",
+ .name = "lfm_love",
.flags = DB_ACTION_SINGLE_TRACK,
.callback = lfm_action_love,
.next = NULL
@@ -864,6 +865,7 @@ static DB_plugin_action_t love_action = {
static DB_plugin_action_t lookup_action = {
.title = "Lookup at Last.fm",
+ .name = "lfm_lookup",
.flags = DB_ACTION_SINGLE_TRACK,
.callback = lfm_action_lookup,
.next = &love_action
diff --git a/plugins/shellexec/shellexec.c b/plugins/shellexec/shellexec.c
index 9141bf92..94cbffe5 100644
--- a/plugins/shellexec/shellexec.c
+++ b/plugins/shellexec/shellexec.c
@@ -27,7 +27,20 @@
static DB_misc_t plugin;
static DB_functions_t *deadbeef;
-static DB_plugin_action_t *actions;
+enum {
+ SHX_ACTION_LOCAL_ONLY = 1 << 0,
+ SHX_ACTION_REMOTE_ONLY = 1 << 1
+};
+
+typedef struct Shx_action_s
+{
+ DB_plugin_action_t parent;
+
+ const char *shcommand;
+ uint32_t shx_flags;
+} Shx_action_t;
+
+static Shx_action_t *actions;
DB_plugin_t *
shellexec_load (DB_functions_t *api) {
@@ -41,15 +54,16 @@ trim (char* s)
char *h, *t;
for (h = s; *h == ' ' || *h == '\t'; h++);
- for (t = s + strlen (s); *t == ' ' || *t == '\t'; t--);
- * (t+1) = 0;
+ for (t = s + strlen (s)-1; *t == ' ' || *t == '\t'; t--);
+ *(t+1) = 0;
return h;
}
static int
shell_quote (const char *source, char *dest)
{
- char *sp, *dp;
+ const char *sp;
+ char *dp;
for (sp = source, dp = dest; *sp; sp++, dp++)
{
@@ -82,7 +96,7 @@ shell_quote (const char *source, char *dest)
Output:
echo 'Blind Faith' - 'Can'\''t Find My Way Home' %a - %t
*/
-static const char*
+static char*
format_shell_command (DB_playItem_t *it, const char *format)
{
char *p;
@@ -149,9 +163,10 @@ format_shell_command (DB_playItem_t *it, const char *format)
}
static int
-shx_callback (DB_playItem_t *it, void *data)
+//shx_callback (DB_playItem_t *it, void *data)
+shx_callback (Shx_action_t *action, DB_playItem_t *it)
{
- const char *cmd = format_shell_command (it, data);
+ char *cmd = format_shell_command (it, action->shcommand);
printf ("%s\n", cmd);
system (cmd);
free (cmd);
@@ -159,8 +174,17 @@ shx_callback (DB_playItem_t *it, void *data)
}
static DB_plugin_action_t *
-shx_get_actions (DB_playItem_t *unused)
+shx_get_actions (DB_playItem_t *it)
{
+ Shx_action_t *action = actions;
+ for (action = actions; action; action = action->parent.next)
+ {
+ if (((action->shx_flags & SHX_ACTION_LOCAL_ONLY) && !deadbeef->is_local_file (it->fname)) ||
+ ((action->shx_flags & SHX_ACTION_REMOTE_ONLY) && deadbeef->is_local_file (it->fname)))
+ action->parent.flags |= DB_ACTION_DISABLED;
+ else
+ action->parent.flags &= ~DB_ACTION_DISABLED;
+ }
return actions;
}
@@ -168,35 +192,83 @@ static int
shx_start ()
{
actions = NULL;
- DB_plugin_action_t *prev = NULL;
+ Shx_action_t *prev = NULL;
DB_conf_item_t *item = deadbeef->conf_find ("shellexec.", NULL);
while (item)
{
size_t l = strlen (item->value) + 1;
char tmp[l];
+ char *tmpptr;
strcpy (tmp, item->value);
trace ("Shellexec: %s\n", tmp);
- char *semicolon = strchr (tmp, ':');
- if (!semicolon)
+ const char *command;
+ const char *title;
+ const char *name;
+ const char *flags;
+
+ char *semicolon;
+ int idx = 0;
+ tmpptr = tmp;
+ do
{
- fprintf (stdout, "Shellexec: wrong option <%s>\n", tmp);
+ semicolon = strchr (tmpptr, ':');
+ if (semicolon)
+ *semicolon = 0;
+
+ trace ("Shellexec: idx: %d, tmp: %s\n", idx, tmpptr);
+ switch (idx)
+ {
+ case 0: command = trim (tmpptr); break;
+ case 1: title = trim (tmpptr); break;
+ case 2: name = trim (tmpptr); break;
+ case 3: flags = trim (tmpptr); break;
+ }
+ if (semicolon)
+ tmpptr = semicolon + 1;
+ idx++;
+ }
+ while (semicolon);
+
+ if (idx < 2)
+ {
+ fprintf (stderr, "Shellexec: need at least command and title (%s)\n", item->value);
continue;
}
+ if (idx > 4)
+ {
+ fprintf (stderr, "Shellexec: too many parameters in configuration line (%s)\n", item->value);
+ continue;
+ }
+ Shx_action_t *action = calloc (sizeof (Shx_action_t), 1);
+
+ trace ("Shellexec: title <%s>, name <%s>, command <%s>, flags <%s>\n",
+ title,
+ name,
+ command,
+ flags);
+
+ action->parent.title = strdup (title);
+ action->parent.name = strdup (name);
+ action->shcommand = strdup (command);
+ action->parent.callback = shx_callback;
+ action->parent.flags = DB_ACTION_SINGLE_TRACK;
+ action->parent.next = NULL;
+
+ action->shx_flags = 0;
- *semicolon = 0;
+ if (strstr (flags, "local"))
+ action->shx_flags |= SHX_ACTION_LOCAL_ONLY;
- DB_plugin_action_t *action = calloc (sizeof (DB_plugin_action_t), 1);
+ if (strstr (flags, "remote"))
+ action->shx_flags |= SHX_ACTION_REMOTE_ONLY;
- action->title = strdup (trim (semicolon + 1));
- action->callback = shx_callback;
- action->data = strdup (trim (tmp));
- action->flags = DB_ACTION_SINGLE_TRACK | DB_ACTION_ALLOW_MULTIPLE_TRACKS;
- action->next = NULL;
+ if (0 == strstr (flags, "single"))
+ action->parent.flags |= DB_ACTION_ALLOW_MULTIPLE_TRACKS;
if (prev)
- prev->next = action;
+ prev->parent.next = action;
prev = action;
if (!actions)