commit a913de2162216a16a67cd8cf5ae0371c258aefc7 from: Omar Polo date: Thu Feb 17 15:41:02 2022 UTC add `jump' subcommand to play the first matching commit - ec1fb0c7bde7316b21c4facdcd43af92792487b5 commit + a913de2162216a16a67cd8cf5ae0371c258aefc7 blob - 476254da7d3a25f7d19e3ceb0c90614e124764b3 blob + ad0bcba8dcef709152df7faf1fa2044a5c32b124 --- 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 blob - a4afe1c5043cbec97e4d0b7c29aeec7c54574e29 blob + c0f29c807bdaa15952bf65eeb7b355086edbdfe6 --- 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 imsg_event_add(struct imsgev *iev); 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); blob - 05a74efc2f6861eeb0eb8cc63e7826fb5e560538 blob + a84579341527eb8607efab9ae3b3f48a15889d8d --- 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"); blob - cfa495be900127654257412b4d990727e73e85c0 blob + 6b25d9f3fed4ffd7e513feca47370059a1f94a09 --- ctl.c +++ ctl.c @@ -43,6 +43,7 @@ int ctl_noarg(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 @@ ctl_load(struct parse_result *res, int argc, char **ar 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) { blob - f1a771837bb39ce5572ea229ebd85a682fb4e768 blob + 686e14fa39f3bb2032527d4639aef0424ce8813c --- playlist.c +++ playlist.c @@ -14,6 +14,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + +#include #include #include @@ -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]; +} blob - a4fed13615d9a6b02734aa8c8573c5c71c0ff642 blob + 95978a15a59fdabc77eff797ba19b27535c9d8e1 --- playlist.h +++ playlist.h @@ -46,5 +46,6 @@ void playlist_reset(void); void playlist_free(struct playlist *); void playlist_truncate(void); void playlist_dropcurrent(void); +const char *playlist_jump(const char *); #endif