diff options
author | Viktor Semykin <thesame.ml@gmail.com> | 2010-07-04 19:02:19 +0300 |
---|---|---|
committer | Viktor Semykin <thesame.ml@gmail.com> | 2010-07-04 19:02:19 +0300 |
commit | 5e64ac2297992c8cfe35233fc93585f7066a6faa (patch) | |
tree | b8b181b60b65a0e39081b16f61834b61b8da09bd /plugins | |
parent | ffd1a10e7f34a0a9201297db12aadbf74d7c59c8 (diff) |
added support of plugins actions for global hotkeys
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/gtkui/actions.c | 3 | ||||
-rw-r--r-- | plugins/gtkui/plcommon.c | 14 | ||||
-rw-r--r-- | plugins/hotkeys/hotkeys.c | 138 | ||||
-rw-r--r-- | plugins/lastfm/lastfm.c | 8 | ||||
-rw-r--r-- | plugins/shellexec/shellexec.c | 112 |
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) |