Commit Diff
Commit:
a913de2162216a16a67cd8cf5ae0371c258aefc7
Date:
Thu Feb 17 15:41:02 2022
UTC
Message:
add `jump' subcommand to play the first matching
--- amused.c
+++ amused.c
@@ -394,6 +394,42 @@ main_play_song(const char *song)
imsg_compose_event(iev_player, IMSG_PLAY, 0, 0, fd,
path, sizeof(path));
return 1;
+}
+
+void
+main_playlist_jump(struct imsgev *iev, struct imsg *imsg)
+{
+ size_t datalen;
+ char arg[PATH_MAX];
+ const char *song;
+
+ datalen = IMSG_DATA_SIZE(*imsg);
+ if (datalen != sizeof(arg)) {
+ main_senderr(iev, "wrong size");
+ return;
+ }
+
+ memcpy(arg, imsg->data, sizeof(arg));
+ if (arg[sizeof(arg)-1] != '\0') {
+ main_senderr(iev, "data corrupted");
+ return;
+ }
+
+ song = playlist_jump(arg);
+ if (song == NULL) {
+ main_senderr(iev, "not found");
+ return;
+ }
+
+ main_send_player(IMSG_STOP, -1, NULL, 0);
+ if (!main_play_song(song)) {
+ main_senderr(iev, "can't play");
+ playlist_dropcurrent();
+ main_playlist_advance();
+ return;
+ }
+
+ main_send_status(iev);
}
void
--- amused.h
+++ amused.h
@@ -34,7 +34,7 @@ enum imsg_type {
IMSG_EOF,
IMSG_ERR,
- IMSG_CTL_PLAY,
+ IMSG_CTL_PLAY, /* with optional filename */
IMSG_CTL_TOGGLE_PLAY,
IMSG_CTL_PAUSE,
IMSG_CTL_STOP,
@@ -44,6 +44,7 @@ enum imsg_type {
IMSG_CTL_STATUS,
IMSG_CTL_NEXT,
IMSG_CTL_PREV,
+ IMSG_CTL_JUMP,
IMSG_CTL_BEGIN,
IMSG_CTL_ADD, /* path to a file */
@@ -73,6 +74,7 @@ enum actions {
PREV,
NEXT,
LOAD,
+ JUMP,
};
struct ctl_command;
@@ -106,6 +108,7 @@ void main_playlist_resume(void);
int imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
pid_t, int, const void *, uint16_t);
int main_send_player(uint16_t, int, const void *, uint16_t);
+void main_playlist_jump(struct imsgev *, struct imsg *);
void main_playlist_resume(void);
void main_playlist_advance(void);
void main_playlist_previous(void);
--- control.c
+++ control.c
@@ -323,6 +323,9 @@ control_dispatch_imsg(int fd, short event, void *bula)
main_send_player(IMSG_STOP, -1, NULL, 0);
main_playlist_previous();
break;
+ case IMSG_CTL_JUMP:
+ main_playlist_jump(&c->iev, &imsg);
+ break;
case IMSG_CTL_BEGIN:
if (control_state.tx != -1) {
main_senderr(&c->iev, "locked");
--- ctl.c
+++ ctl.c
@@ -43,6 +43,7 @@ int ctl_load(struct parse_result *, int, char **);
int ctl_add(struct parse_result *, int, char **);
int ctl_show(struct parse_result *, int, char **);
int ctl_load(struct parse_result *, int, char **);
+int ctl_jump(struct parse_result *, int, char **);
struct ctl_command ctl_commands[] = {
{ "play", PLAY, ctl_noarg, "" },
@@ -57,6 +58,7 @@ struct ctl_command ctl_commands[] = {
{ "next", NEXT, ctl_noarg, "" },
{ "prev", PREV, ctl_noarg, "" },
{ "load", LOAD, ctl_load, "[file]", 1 },
+ { "jump", JUMP, ctl_jump, "pattern" },
{ NULL },
};
@@ -136,6 +138,17 @@ enqueue_tracks(char **files)
}
return enq == 0;
+}
+
+static int
+jump_req(const char *arg)
+{
+ char path[PATH_MAX];
+
+ memset(path, 0, sizeof(path));
+ strlcpy(path, arg, sizeof(path));
+ imsg_compose(ibuf, IMSG_CTL_JUMP, 0, 0, -1, path, sizeof(path));
+ return 0;
}
static void
@@ -374,6 +387,10 @@ ctlaction(struct parse_result *res)
case LOAD:
done = 0;
imsg_compose(ibuf, IMSG_CTL_BEGIN, 0, 0, -1, NULL, 0);
+ break;
+ case JUMP:
+ done = 0;
+ ret = jump_req(res->file);
break;
case NONE:
/* action not expected */
@@ -411,6 +428,7 @@ ctlaction(struct parse_result *res)
case STATUS:
case NEXT:
case PREV:
+ case JUMP:
done = show_status(&imsg, &ret);
break;
case LOAD:
@@ -484,6 +502,23 @@ static int
return ctlaction(res);
}
+int
+ctl_jump(struct parse_result *res, int argc, char **argv)
+{
+ int ch;
+
+ while ((ch = getopt(argc, argv, "")) != -1)
+ ctl_usage(res->ctl);
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ ctl_usage(res->ctl);
+
+ res->file = argv[0];
+ return ctlaction(res);
+}
+
static int
sockconn(void)
{
--- playlist.c
+++ playlist.c
@@ -14,6 +14,9 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/types.h>
+
+#include <regex.h>
#include <stdlib.h>
#include <syslog.h>
@@ -160,3 +163,26 @@ playlist_dropcurrent(void)
playlist.songs[playlist.len] = NULL;
}
+
+const char *
+playlist_jump(const char *arg)
+{
+ size_t i;
+ regex_t re;
+
+ if (regcomp(&re, arg, REG_ICASE | REG_NOSUB) != 0)
+ return NULL;
+
+ for (i = 0; i < playlist.len; ++i) {
+ if (regexec(&re, playlist.songs[i], 0, NULL, 0) == 0)
+ break;
+ }
+ regfree(&re);
+
+ if (i == playlist.len)
+ return NULL;
+
+ play_state = STATE_PLAYING;
+ play_off = i;
+ return playlist.songs[i];
+}
--- playlist.h
+++ playlist.h
@@ -46,5 +46,6 @@ void playlist_dropcurrent(void);
void playlist_free(struct playlist *);
void playlist_truncate(void);
void playlist_dropcurrent(void);
+const char *playlist_jump(const char *);
#endif
Omar Polo