tmus

TUI Music Player
git clone https://git.sinitax.com/sinitax/tmus
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

commit 4f3bfa23ed263e79db97d14032f569fa539ab9fc
parent 440e88cfbbc2f24ca0fa22c448d597e751d49dc2
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sat,  4 Feb 2023 15:37:00 +0100

Improve player status display

Diffstat:
Msrc/cmd.c | 36++++++++++++++++++------------------
Msrc/player.c | 10+++++-----
Msrc/player.h | 18++++++------------
Msrc/player_mpd.c | 71+++++++++++++++++++++++++++--------------------------------------------
Msrc/player_mplay.c | 79+++++++++++++++++++++++++++++++------------------------------------------------
Msrc/tui.c | 46+++++++++++++++++++++++-----------------------
Msrc/tui.h | 12++++++------
7 files changed, 116 insertions(+), 156 deletions(-)

diff --git a/src/cmd.c b/src/cmd.c @@ -41,11 +41,11 @@ void cmd_status_from_errno(int err) { if (err == EACCES || err == EPERM) - CMD_SET_STATUS("Missing permissions"); + USER_STATUS("Missing permissions"); else if (err == EEXIST) - CMD_SET_STATUS("Path already exists"); + USER_STATUS("Path already exists"); else - CMD_SET_STATUS("Unknown error"); + USER_STATUS("Unknown error"); } bool @@ -64,19 +64,19 @@ cmd_move(const char *name) tag = tag_find(name); if (!tag) { - CMD_SET_STATUS("Tag not found"); + USER_STATUS("Tag not found"); return false; } link = list_at(tracks_vis, track_nav.sel); if (!link) { - CMD_SET_STATUS("No track selected"); + USER_STATUS("No track selected"); return false; } track = tracks_vis_track(link); if (track->tag == tag) { - CMD_SET_STATUS("Same tag"); + USER_STATUS("Same tag"); return false; } @@ -98,32 +98,32 @@ cmd_copy(const char *name) tag = tag_find(name); if (!tag) { - CMD_SET_STATUS("Tag not found"); + USER_STATUS("Tag not found"); return false; } link = list_at(tracks_vis, track_nav.sel); if (!link) { - CMD_SET_STATUS("No track selected"); + USER_STATUS("No track selected"); return false; } track = tracks_vis_track(link); if (track->tag == tag) { - CMD_SET_STATUS("Same tag"); + USER_STATUS("Same tag"); return false; } newpath = aprintf("%s/%s", tag->fpath, track->name); if (path_exists(newpath)) { free(newpath); - CMD_SET_STATUS("File already exists"); + USER_STATUS("File already exists"); return false; } if (!dup_file(track->fpath, newpath)) { free(newpath); - CMD_SET_STATUS("Failed to copy track"); + USER_STATUS("Failed to copy track"); return false; } free(newpath); @@ -131,7 +131,7 @@ cmd_copy(const char *name) new = track_add(tag, track->name); if (!new) { rm_file(track->fpath); - CMD_SET_STATUS("Failed to copy track"); + USER_STATUS("Failed to copy track"); return false; } @@ -222,13 +222,13 @@ cmd_add_tag(const char *name) tag = tag_find(name); if (tag) { - CMD_SET_STATUS("Tag already exists"); + USER_STATUS("Tag already exists"); return false; } tag = tag_create(name); if (!tag) { - CMD_SET_STATUS("Failed to create tag"); + USER_STATUS("Failed to create tag"); return false; } @@ -248,13 +248,13 @@ cmd_rm_tag(const char *name) } else { tag = tag_find(name); if (!tag) { - CMD_SET_STATUS("No such tag"); + USER_STATUS("No such tag"); return false; } } if (!tag_rm(tag, true)) { - CMD_SET_STATUS("Failed to remove tag"); + USER_STATUS("Failed to remove tag"); return false; } @@ -269,7 +269,7 @@ cmd_rename(const char *name) struct tag *tag; if (!*name) { - CMD_SET_STATUS("Supply a name"); + USER_STATUS("Supply a name"); return false; } @@ -334,7 +334,7 @@ bool cmd_rerun(void) { if (!last_cmd || !last_args) { - CMD_SET_STATUS("No command to repeat"); + USER_STATUS("No command to repeat"); return false; } return last_cmd->func(last_args); diff --git a/src/player.c b/src/player.c @@ -120,20 +120,20 @@ player_prev(void) struct track *track; if (list_empty(&player.history)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; if (!player.track || !link_inuse(&player.track->link_hs)) { next = list_back(&player.history); } else if (LIST_INNER(player.track->link_hs.prev)) { next = player.track->link_hs.prev; } else { - return PLAYER_STATUS_ERR; + return PLAYER_ERR; } track = UPCAST(next, struct track, link_hs); player_play_track(track, false); - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -159,11 +159,11 @@ player_next(void) } player_play_track(next_track, new_entry); - return PLAYER_STATUS_OK; + return PLAYER_OK; clear: player_clear_track(); - return PLAYER_STATUS_ERR; + return PLAYER_ERR; } /* implemented by backend: diff --git a/src/player.h b/src/player.h @@ -3,21 +3,15 @@ #include "list.h" #include "util.h" -#define PLAYER_STATUS_INFO(...) \ - PLAYER_STATUS(PLAYER_STATUS_MSG_INFO, __VA_ARGS__) - -#define PLAYER_STATUS_ERR(...) \ - PLAYER_STATUS(PLAYER_STATUS_MSG_ERR, __VA_ARGS__) - -#define PLAYER_STATUS(lvl, ...) do { \ - player.status_lvl = (lvl); \ - if (player.status) free(player.status); \ - player.status = aprintf(__VA_ARGS__); \ +#define PLAYER_STATUS(...) do { \ + free(user_status); \ + user_status = aprintf("Player: " __VA_ARGS__); \ + user_status_uptime = 20; \ } while (0) enum { - PLAYER_STATUS_OK, - PLAYER_STATUS_ERR + PLAYER_OK, + PLAYER_ERR }; enum { diff --git a/src/player_mpd.c b/src/player_mpd.c @@ -30,26 +30,14 @@ struct mpd_player { struct player player; struct mpd_player mpd; -static void player_clear_status(void); - static bool mpd_handle_status(int status); static char *mpd_loaded_track_name(struct mpd_song *song); -void -player_clear_status(void) -{ - free(player.status); - player.status = NULL; - player.status_lvl = PLAYER_STATUS_MSG_NONE; -} - bool mpd_handle_status(int status) { const char *errstr; - player_clear_status(); - switch (status) { case MPD_ERROR_SERVER: case MPD_ERROR_ARGUMENT: @@ -57,7 +45,7 @@ mpd_handle_status(int status) ERRORX(SYSTEM, "Player failed to recover"); case MPD_ERROR_SYSTEM: errstr = mpd_connection_get_error_message(mpd.conn); - PLAYER_STATUS_ERR("ERR - %s", errstr); + PLAYER_STATUS("MPD ERR - %s", errstr); return false; case MPD_ERROR_CLOSED: ERRORX(SYSTEM, "Player connection abruptly closed"); @@ -101,9 +89,6 @@ player_init(void) player.time_pos = 0; player.time_end = 0; - - player.status = NULL; - player.status_lvl = PLAYER_STATUS_MSG_INFO; } void @@ -133,7 +118,7 @@ player_update(void) status = mpd_run_status(mpd.conn); if (!status) { - PLAYER_STATUS_ERR("MPD connection reset: %s", + PLAYER_STATUS("MPD connection reset: %s", mpd_connection_get_error_message(mpd.conn)); mpd_connection_free(mpd.conn); mpd.conn = NULL; @@ -158,7 +143,7 @@ player_update(void) * get status and track name again.. */ status = mpd_run_status(mpd.conn); if (!status) { - PLAYER_STATUS_ERR("MPD connection reset: %s", + PLAYER_STATUS("MPD connection reset: %s", mpd_connection_get_error_message(mpd.conn)); mpd_connection_free(mpd.conn); mpd.conn = NULL; @@ -214,15 +199,15 @@ player_play_track(struct track *track, bool new) status = mpd_run_clear(mpd.conn); if (!mpd_handle_status(status)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; status = mpd_run_add(mpd.conn, track->fpath); if (!mpd_handle_status(status)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; status = mpd_run_play(mpd.conn); if (!mpd_handle_status(status)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; /* add last track to history */ if (player.track && !link_inuse(&player.track->link_hs)) @@ -233,7 +218,7 @@ player_play_track(struct track *track, bool new) player.track = track; - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -245,9 +230,9 @@ player_clear_track(void) status = mpd_run_clear(mpd.conn); if (!mpd_handle_status(status)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -257,9 +242,9 @@ player_toggle_pause(void) status = mpd_run_toggle_pause(mpd.conn); if (!mpd_handle_status(status)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -269,9 +254,9 @@ player_pause(void) status = mpd_run_pause(mpd.conn, true); if (!mpd_handle_status(status)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -281,9 +266,9 @@ player_resume(void) status = mpd_run_pause(mpd.conn, false); if (!mpd_handle_status(status)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -293,9 +278,9 @@ player_play(void) status = mpd_run_play(mpd.conn); if (!mpd_handle_status(status)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -305,9 +290,9 @@ player_stop(void) status = mpd_run_stop(mpd.conn); if (!mpd_handle_status(status)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -315,20 +300,19 @@ player_seek(int sec) { int status; - player_clear_status(); if (!player.loaded || player.state == PLAYER_STATE_STOPPED) { - PLAYER_STATUS_ERR("No track loaded"); - return PLAYER_STATUS_ERR; + PLAYER_STATUS("No track loaded"); + return PLAYER_ERR; } status = mpd_run_seek_current(mpd.conn, sec, false); if (!mpd_handle_status(status)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; mpd.seek_delay = 7; player_pause(); - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -336,17 +320,16 @@ player_set_volume(unsigned int vol) { int status; - player_clear_status(); if (player.volume == -1) { - PLAYER_STATUS_ERR("Volume control not supported"); - return PLAYER_STATUS_ERR; + PLAYER_STATUS("Volume control not supported"); + return PLAYER_ERR; } status = mpd_run_set_volume(mpd.conn, vol); if (!mpd_handle_status(status)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; player.volume = vol; - return PLAYER_STATUS_OK; + return PLAYER_OK; } diff --git a/src/player_mplay.c b/src/player_mplay.c @@ -1,5 +1,6 @@ #include "player.h" +#include "tui.h" #include "data.h" #include "list.h" #include "util.h" @@ -15,6 +16,13 @@ #include <stdlib.h> #include <string.h> +#define MPLAY_STATUS(line) do { \ + free(user_status); \ + user_status = aprintf("Player: %s", \ + line ? line : "no response"); \ + user_status_uptime = 20; \ + } while (0) + struct mplay_player { FILE *stdin; FILE *stdout; @@ -26,13 +34,10 @@ struct mplay_player mplay; static void sigpipe_handler(int sig); -static bool mplay_alive(void); static void mplay_kill(void); static bool mplay_run(struct track *track); static char *mplay_readline(void); -static void player_clear_status(void); - void sigpipe_handler(int sig) { @@ -40,12 +45,6 @@ sigpipe_handler(int sig) } bool -mplay_alive(void) -{ - return player.loaded && !kill(mplay.pid, 0); -} - -bool mplay_run(struct track *track) { int output[2]; @@ -77,8 +76,10 @@ mplay_run(struct track *track) } else { close(0); close(1); + close(2); dup2(input[0], 0); dup2(output[1], 1); + dup2(output[1], 2); close(output[0]); close(output[1]); path = aprintf("%s/%s/%s", datadir, @@ -92,7 +93,7 @@ mplay_run(struct track *track) line = mplay_readline(); if (!line || strcmp(line, "+READY")) { mplay_kill(); - PLAYER_STATUS_ERR("Failed to start"); + MPLAY_STATUS(line); return false; } @@ -129,14 +130,6 @@ mplay_readline(void) } void -player_clear_status(void) -{ - free(player.status); - player.status = NULL; - player.status_lvl = PLAYER_STATUS_MSG_NONE; -} - -void player_init(void) { list_init(&player.playlist); @@ -156,9 +149,6 @@ player_init(void) player.time_pos = 0; player.time_end = 0; - player.status = NULL; - player.status_lvl = PLAYER_STATUS_MSG_INFO; - signal(SIGPIPE, sigpipe_handler); } @@ -169,7 +159,6 @@ player_deinit(void) list_clear(&player.queue); list_clear(&player.history); - free(player.status); free(player.track_name); mplay_kill(); @@ -181,12 +170,10 @@ player_update(void) bool queue_empty; char *tok, *line; - player_clear_status(); - if (!player.loaded) { queue_empty = list_empty(&player.queue); if (player.track && player.autoplay || !queue_empty) { - if (player_next() != PLAYER_STATUS_OK) + if (player_next() != PLAYER_OK) player_clear_track(); } else if (player.track) { player_clear_track(); @@ -199,7 +186,7 @@ player_update(void) line = mplay_readline(); if (!player.loaded) return; if (!line || strncmp(line, "+STATUS:", 8)) { - PLAYER_STATUS_ERR("Bad response"); + MPLAY_STATUS(line); return; } @@ -226,7 +213,7 @@ player_play_track(struct track *track, bool new) player_clear_track(); if (!mplay_run(track)) - return PLAYER_STATUS_ERR; + return PLAYER_ERR; /* new invocations are removed from history */ if (new) link_pop(&track->link_hs); @@ -235,7 +222,7 @@ player_play_track(struct track *track, bool new) player.time_pos = 0; player.time_end = 0; - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -247,7 +234,7 @@ player_clear_track(void) player.track = NULL; mplay_kill(); - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -258,11 +245,11 @@ player_toggle_pause(void) fprintf(mplay.stdin, "pause\n"); line = mplay_readline(); if (!line || strncmp(line, "+PAUSE:", 7)) { - PLAYER_STATUS_ERR("Bad response"); - return PLAYER_STATUS_ERR; + MPLAY_STATUS(line); + return PLAYER_ERR; } - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -271,7 +258,7 @@ player_pause(void) if (player.state != PLAYER_STATE_PAUSED) player_toggle_pause(); - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -280,13 +267,13 @@ player_resume(void) if (player.state != PLAYER_STATE_PLAYING) player_toggle_pause(); - return PLAYER_STATUS_OK; + return PLAYER_OK; } int player_play(void) { - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -294,7 +281,7 @@ player_stop(void) { player_clear_track(); - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -302,19 +289,17 @@ player_seek(int sec) { char *line; - player_clear_status(); - fprintf(mplay.stdin, "seek %i\n", sec); line = mplay_readline(); if (!line || strncmp(line, "+SEEK:", 6)) { - PLAYER_STATUS_ERR("Bad response"); - return PLAYER_STATUS_ERR; + MPLAY_STATUS(line); + return PLAYER_ERR; } player.time_pos = atoi(line + 7); player.time_end = MAX(player.time_pos, player.time_end); - return PLAYER_STATUS_OK; + return PLAYER_OK; } int @@ -322,22 +307,20 @@ player_set_volume(unsigned int vol) { char *line; - player_clear_status(); - if (player.volume == -1) { - PLAYER_STATUS_ERR("Volume control not supported"); - return PLAYER_STATUS_ERR; + PLAYER_STATUS("volume control not supported"); + return PLAYER_ERR; } fprintf(mplay.stdin, "vol %i\n", vol); line = mplay_readline(); if (!line || strncmp(line, "+VOLUME:", 8)) { - PLAYER_STATUS_ERR("Bad response"); - return PLAYER_STATUS_ERR; + MPLAY_STATUS(line); + return PLAYER_ERR; } player.volume = atoi(line + 9); - return PLAYER_STATUS_OK; + return PLAYER_OK; } diff --git a/src/tui.c b/src/tui.c @@ -129,8 +129,8 @@ int track_show_playlist; struct listnav tag_nav; struct listnav track_nav; -char *cmd_status; -int cmd_status_uptime; +char *user_status; +int user_status_uptime; void pane_title(struct pane *pane, bool highlight, const char *fmtstr, ...) @@ -554,10 +554,10 @@ delete_selected_track(void) if (!trash_tag || !strcmp(track->tag->name, "trash")) { if (!track_rm(track, true)) - CMD_SET_STATUS("Failed to remove track"); + USER_STATUS("Failed to remove track"); } else { if (!track_move(track, trash_tag)) - CMD_SET_STATUS("Failed to trash track"); + USER_STATUS("Failed to trash track"); } return true; @@ -707,10 +707,10 @@ run_cmd(const char *query) bool success, found; success = cmd_run(query, &found); - if (!success && !cmd_status) - CMD_SET_STATUS("FAIL"); - else if (success && !cmd_status) - CMD_SET_STATUS("OK"); + if (!success && !user_status) + USER_STATUS("FAIL"); + else if (success && !user_status) + USER_STATUS("OK"); return found; } @@ -831,19 +831,19 @@ cmd_pane_input(wint_t c) if (cmd_input_mode == IMODE_EXECUTE) { if (!run_cmd(history->sel->buf)) - CMD_SET_STATUS("No such command"); + USER_STATUS("No such command"); } else if (cmd_input_mode == IMODE_TRACK_PLAY) { if (!play_track(history->sel->buf)) - CMD_SET_STATUS("Failed to find track"); + USER_STATUS("Failed to find track"); } else if (cmd_input_mode == IMODE_TRACK_SELECT) { if (!seek_track_by_name(history->sel->buf)) - CMD_SET_STATUS("Failed to find track"); + USER_STATUS("Failed to find track"); } else if (cmd_input_mode == IMODE_TRACK_VIS_SELECT) { if (!seek_track_vis_by_name(history->sel->buf)) - CMD_SET_STATUS("Failed to find track in view"); + USER_STATUS("Failed to find track in view"); } else if (cmd_input_mode == IMODE_TAG_SELECT) { if (!seek_tag(history->sel->buf)) - CMD_SET_STATUS("Failed to find tag"); + USER_STATUS("Failed to find tag"); } history_submit(history); @@ -958,8 +958,8 @@ cmd_pane_vis(struct pane *pane, int sel) /* cmd and search input */ strbuf_clear(&line); - free(cmd_status); - cmd_status = NULL; + free(user_status); + user_status = NULL; cmd = history->sel; if (cmd != history->input) { @@ -986,14 +986,14 @@ cmd_pane_vis(struct pane *pane, int sel) ? cmd->buf[cmd->cur] : L' '); ATTR_OFF(pane->win, A_REVERSE); } - } else if (cmd_status && cmd_status_uptime) { - cmd_status_uptime--; + } else if (user_status && user_status_uptime) { + user_status_uptime--; strbuf_clear(&line); - strbuf_append(&line, " %s", cmd_status); + strbuf_append(&line, " %s", user_status); pane_writeln(pane, 2, line.buf); } else { - free(cmd_status); - cmd_status = NULL; + free(user_status); + user_status = NULL; } } @@ -1211,8 +1211,8 @@ tui_init(void) quit = 0; cmd_input_mode = IMODE_TRACK_SELECT; - cmd_status = NULL; - cmd_status_uptime = 0; + user_status = NULL; + user_status_uptime = 0; inputln_init(&completion_query); completion_reset = 1; @@ -1247,7 +1247,7 @@ tui_init(void) void tui_deinit(void) { - free(cmd_status); + free(user_status); inputln_deinit(&completion_query); diff --git a/src/tui.h b/src/tui.h @@ -6,10 +6,10 @@ #include <stdbool.h> -#define CMD_SET_STATUS(...) do { \ - free(cmd_status); \ - cmd_status_uptime = 10; \ - cmd_status = aprintf(__VA_ARGS__); \ +#define USER_STATUS(...) do { \ + free(user_status); \ + user_status = aprintf(__VA_ARGS__); \ + user_status_uptime = 10; \ } while (0) void tui_init(void); @@ -25,8 +25,8 @@ extern int track_show_playlist; extern struct listnav tag_nav; extern struct listnav track_nav; -extern char *cmd_status; -extern int cmd_status_uptime; +extern char *user_status; +extern int user_status_uptime; static inline bool tui_enabled(void)