X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=gui.c;h=5b44819c05afc074fadca3a5a7d5c1ece9fe8b8f;hp=c335250fee77daccc61868963e6135a220337610;hb=d96c06ff93493c125b9f4d36655e77d7029ca309;hpb=8d7bdabd22ed7750086ca660754d8d881dae3832 diff --git a/gui.c b/gui.c index c335250f..5b44819c 100644 --- a/gui.c +++ b/gui.c @@ -1,20 +1,22 @@ /* - * Copyright (C) 1998-2008 Andre Noll + * Copyright (C) 1998-2009 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ -/** \file gui.c ncurses-based interface for paraslash */ +/** \file gui.c Curses-based interface for paraslash. */ +#include #include #include #include +#include + #include "gui.cmdline.h" #include "para.h" #include "gui.h" -#include +#include "string.h" #include "ringbuffer.h" -#include "gui_common.h" #include "fd.h" #include "error.h" #include "list.h" @@ -29,8 +31,6 @@ static char *stat_content[NUM_STAT_ITEMS]; static int signal_pipe; -static void finish(int sig); - static struct win_data { WINDOW *win; NCURSES_SIZE_T begx; @@ -45,7 +45,7 @@ struct rb_entry { size_t len; int color; }; -struct ringbuffer *bot_win_rb; +static struct ringbuffer *bot_win_rb; #define NUM_LINES(len) (1 + (len) / bot.cols) static unsigned scroll_position; @@ -91,8 +91,8 @@ struct stat_item { static struct gui_theme theme; -int _argc; -char **_argv; +static int _argc; +static char **_argv; static void com_help(void); static void com_reread_conf(void); @@ -110,7 +110,7 @@ static void com_scroll_down(void); static void com_page_up(void); static void com_page_down(void); -struct gui_command command_list[] = { +static struct gui_command command_list[] = { { .key = "?", .name = "help", @@ -191,6 +191,20 @@ struct gui_command command_list[] = { } }; +static int para_open_audiod_pipe(char *cmd) +{ + int fds[3] = {0, 1, 0}; + pid_t pid; + int ret = para_exec_cmdline_pid(&pid, cmd, fds); + if (ret < 0) + return ret; + ret = mark_fd_nonblocking(fds[1]); + if (ret > 0) + return fds[1]; + close(fds[1]); + return ret; +} + static int find_cmd_byname(char *name) { int i; @@ -282,20 +296,23 @@ static void add_spaces(WINDOW* win, unsigned int num) * print aligned string to curses window. This function always prints * exactly len chars. */ -static int align_str(WINDOW* win, const char *string, unsigned int len, +static int align_str(WINDOW* win, char *str, unsigned int len, unsigned int align) { - int num; /* of spaces */ - char *str; + int i, num; /* of spaces */ - if (!win || !string) + if (!win || !str) return -1; - num = len - strlen(string); - str = para_strdup(string); + num = len - strlen(str); if (num < 0) { str[len] = '\0'; num = 0; } + /* replace newlines by spaces */ + for (i = 0; i < len && str[i]; i++) { + if (str[i] == '\n') + str[i] = ' '; + } if (align == LEFT) { waddstr(win, str); add_spaces(win, num); @@ -307,7 +324,6 @@ static int align_str(WINDOW* win, const char *string, unsigned int len, waddstr(win, str[0]? str: ""); add_spaces(win, num - num / 2); } - free(str); return 1; } @@ -330,10 +346,14 @@ __printf_2_3 static void print_in_bar(int color, const char *fmt,...) */ static void print_status_bar(void) { + char *tmp; + if (!curses_active) return; + tmp = para_strdup(STANDARD_STATUS_BAR); wmove(sb.win, 0, 0); - align_str(sb.win, STANDARD_STATUS_BAR, sb.cols, CENTER); + align_str(sb.win, tmp, sb.cols, CENTER); + free(tmp); wrefresh(sb.win); } @@ -459,17 +479,19 @@ static int add_output_line(char *line, __a_unused void *data) return 1; } -void para_log(int ll, const char *fmt,...) +static int loglevel; + +__printf_2_3 void para_log(int ll, const char *fmt,...) { int color; char *msg; - if (ll < conf.loglevel_arg || !curses_active) + if (ll < loglevel || !curses_active) return; switch (ll) { - case DEBUG: - case INFO: - case NOTICE: + case LL_DEBUG: + case LL_INFO: + case LL_NOTICE: color = COLOR_MSG; break; default: @@ -489,13 +511,12 @@ static void setup_signal_handling(void) para_install_sighandler(SIGCHLD); para_install_sighandler(SIGWINCH); para_install_sighandler(SIGUSR1); -// signal(SIGPIPE, SIG_IGN); - signal(SIGHUP, SIG_IGN); + para_sigaction(SIGHUP, SIG_IGN); } -static void do_exit(int ret) +__noreturn static void do_exit(int ret) { - signal(SIGTERM, SIG_IGN); + para_sigaction(SIGTERM, SIG_IGN); kill(0, SIGTERM); exit(ret); } @@ -509,7 +530,7 @@ static void shutdown_curses(void) endwin(); } -static void finish(int ret) +__noreturn static void finish(int ret) { shutdown_curses(); do_exit(ret); @@ -518,7 +539,7 @@ static void finish(int ret) /* * exit curses and print given message to stdout/stderr */ -__printf_2_3 static void msg_n_exit(int ret, const char* fmt, ...) +__noreturn __printf_2_3 static void msg_n_exit(int ret, const char* fmt, ...) { va_list argp; FILE *outfd = ret? stderr: stdout; @@ -532,8 +553,7 @@ __printf_2_3 static void msg_n_exit(int ret, const char* fmt, ...) static void print_welcome(void) { - int ll = conf.loglevel_arg; - if (ll > NOTICE) + if (loglevel > LL_NOTICE) return; outputf(COLOR_WELCOME, "Welcome to para_gui " PACKAGE_VERSION " \"" CODENAME "\". Theme: %s", theme.name); @@ -657,6 +677,63 @@ static void print_stat_item(int i) wrefresh(top.win); } +static int update_item(int item_num, char *buf) +{ + char **c = stat_content + item_num; + + free(*c); + if (buf && buf[0]) + goto dup; + switch (item_num) { + case SI_ARTIST: + *c = para_strdup("(artist tag not set)"); + goto print; + case SI_TITLE: + *c = para_strdup("(title tag not set)"); + goto print; + case SI_YEAR: + *c = para_strdup("????"); + goto print; + case SI_ALBUM: + *c = para_strdup("(album tag not set)"); + goto print; + case SI_COMMENT: + *c = para_strdup("(comment tag not set)"); + goto print; + } +dup: + *c = para_strdup(buf); +print: + print_stat_item(item_num); + return 1; +} + +static int read_audiod_pipe(int fd) +{ + static char *buf; + static int bufsize, loaded; + int ret; + + if (loaded >= bufsize) { + if (bufsize > 1000 * 1000) { + loaded = 0; + return 0; + } + bufsize += bufsize + 1000; + buf = para_realloc(buf, bufsize); + } + assert(loaded < bufsize); + ret = read(fd, buf + loaded, bufsize - loaded); + if (ret <= 0) + return ret; + loaded += ret; + ret = for_each_stat_item(buf, loaded, update_item); + if (ret < 0) + return ret; + loaded = ret; + return 1; +} + static void print_all_items(void) { int i; @@ -739,26 +816,6 @@ reap_next_child: goto reap_next_child; } -/* - * print status line if line starts with known command. - */ -static int check_stat_line(char *line, __a_unused void *data) -{ - int i; - -// PARA_INFO_LOG("%s: checking: %s\n", __func__, line); - i = stat_line_valid(line); - if (i >= 0) { - line += strlen(status_item_list[i]) + 1; - if (*line == ' ') - line++; - free(stat_content[i]); - stat_content[i] = para_strdup(line); - print_stat_item(i); - } - return 1; -} - /* * This sucker modifies its first argument. *handler and *arg are * pointers to 0-terminated strings (inside line). Crap. @@ -828,13 +885,13 @@ static void handle_signal(int sig) } return; case SIGINT: - PARA_WARNING_LOG("%s", "caught SIGINT, reset"); - /* Nothing to do. SIGINT killed our child, para_client stat. - * This get noticed by do_select which resets everything + PARA_WARNING_LOG("caught SIGINT, reset"); + /* Nothing to do. SIGINT killed our child which gets noticed + * by do_select and resets everything. */ return; case SIGUSR1: - PARA_NOTICE_LOG("%s", "got SIGUSR1, rereading configuration"); + PARA_NOTICE_LOG("got SIGUSR1, rereading configuration"); com_reread_conf(); return; case SIGCHLD: @@ -865,7 +922,7 @@ static int open_audiod_pipe(void) * when any key is pressed. * * EXTERNAL_MODE: Check only signal pipe. Used when an external command - * is running. During that thime curses is disabled. Returns when + * is running. During that time curses is disabled. Returns when * cmd_pid == 0. */ static int do_select(int mode) @@ -916,7 +973,7 @@ repeat: } } if (audiod_pipe >= 0 && FD_ISSET(audiod_pipe, &rfds)) - if (read_audiod_pipe(audiod_pipe, check_stat_line) <= 0) { + if (read_audiod_pipe(audiod_pipe) <= 0) { close(audiod_pipe); audiod_pipe = -1; clear_all_items(); @@ -976,9 +1033,9 @@ static int send_output(void) return ret; } if (do_select(COMMAND_MODE) >= 0) - PARA_INFO_LOG("%s", "command complete"); + PARA_INFO_LOG("command complete"); else - PARA_NOTICE_LOG("%s", "command aborted"); + PARA_NOTICE_LOG("command aborted"); print_in_bar(COLOR_MSG, " "); return 1; } @@ -1061,13 +1118,14 @@ static void com_page_up(void) { unsigned lines; int fvr = first_visible_rbe(&lines); + if (fvr < 0 || fvr + 1 >= ringbuffer_filled(bot_win_rb)) { print_in_bar(COLOR_ERRMSG, "top of buffer is shown\n"); return; } scroll_position = fvr + 1; for (; scroll_position > 0; scroll_position--) { - fvr = first_visible_rbe(&lines); + first_visible_rbe(&lines); if (lines == bot.lines) break; } @@ -1138,24 +1196,24 @@ err_out: static void com_ll_decr(void) { - if (conf.loglevel_arg <= DEBUG) { + if (loglevel <= LL_DEBUG) { print_in_bar(COLOR_ERRMSG, "loglevel already at maximal verbosity\n"); return; } - conf.loglevel_arg--; - print_in_bar(COLOR_MSG, "loglevel set to %d\n", conf.loglevel_arg); + loglevel--; + print_in_bar(COLOR_MSG, "loglevel set to %d\n", loglevel); } static void com_ll_incr(void) { - if (conf.loglevel_arg >= EMERG) { + if (loglevel >= LL_EMERG) { print_in_bar(COLOR_ERRMSG, - "loglevel already at miminal verbosity\n"); + "loglevel already at minimal verbosity\n"); return; } - conf.loglevel_arg++; - print_in_bar(COLOR_MSG, "loglevel set to %d\n", conf.loglevel_arg); + loglevel++; + print_in_bar(COLOR_MSG, "loglevel set to %d\n", loglevel); } /* @@ -1172,13 +1230,13 @@ static void com_reread_conf(void) }; if (!cf) { - PARA_WARNING_LOG("%s", "there is no configuration to read"); + PARA_WARNING_LOG("there is no configuration to read"); return; } - PARA_INFO_LOG("%s", "rereading command line options and config file"); + PARA_INFO_LOG("rereading command line options and config file"); gui_cmdline_parser(_argc, _argv, &conf); gui_cmdline_parser_config_file(cf, &conf, ¶ms); - PARA_NOTICE_LOG("%s", "config file reloaded"); + PARA_NOTICE_LOG("config file reloaded"); if (check_key_map_args() < 0) finish(EXIT_FAILURE); } @@ -1223,7 +1281,7 @@ static void com_help(void) static void com_shrink_top_win(void) { if (top.lines <= theme.top_lines_min) { - PARA_WARNING_LOG("%s", "can not decrease top window"); + PARA_WARNING_LOG("can not decrease top window"); return; } init_wins(top.lines - 1); @@ -1235,7 +1293,7 @@ static void com_shrink_top_win(void) static void com_enlarge_top_win(void) { if (bot.lines < 3) { - PARA_WARNING_LOG("%s", "can not increase top window"); + PARA_WARNING_LOG("can not increase top window"); return; } init_wins(top.lines + 1); @@ -1250,7 +1308,7 @@ static void com_version(void) CODENAME "\""); } -static void com_quit(void) +__noreturn static void com_quit(void) { finish(0); } @@ -1361,6 +1419,7 @@ int main(int argc, char *argv[]) }; gui_cmdline_parser_config_file(cf, &conf, ¶ms); } + loglevel = get_loglevel_by_name(conf.loglevel_arg); if (check_key_map_args() < 0) { fprintf(stderr, "invalid key map in config file\n"); exit(EXIT_FAILURE);