From: Andre Noll Date: Sun, 27 Feb 2011 22:19:51 +0000 (+0100) Subject: Merge branch 't/ogg_timining_fixes' X-Git-Tag: v0.4.6~27 X-Git-Url: http://git.tuebingen.mpg.de/?a=commitdiff_plain;h=dd98d31d017bbbe16bf6711e0343b267dd6cfe89;hp=f44d27b634fe4a26efc38de75e8b84524d156c4b;p=paraslash.git Merge branch 't/ogg_timining_fixes' --- diff --git a/NEWS b/NEWS index 149f4e40..dcc4393b 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ FEC group size. - aacdec error message cleanups - simplified color error handling + - para_gui: New option --theme to select a startup theme. Several + other improvements and fixes. -------------------------------------------- 0.4.5 (2010-12-17) "symmetric randomization" diff --git a/aac_afh.c b/aac_afh.c index 94b0f8b3..a53a757f 100644 --- a/aac_afh.c +++ b/aac_afh.c @@ -42,9 +42,9 @@ static int aac_find_stsz(unsigned char *buf, size_t buflen, off_t *skip) return -E_STSZ; } -static int atom_cmp(unsigned char *buf1, char *buf2) +static int atom_cmp(const unsigned char *buf1, const char *buf2) { - unsigned char *b2 = (unsigned char *)buf2; + const unsigned char *b2 = (unsigned char *)buf2; if (buf1[0] != b2[0]) return 1; diff --git a/alsa_write.c b/alsa_write.c index d6493418..ae3bbfba 100644 --- a/alsa_write.c +++ b/alsa_write.c @@ -231,10 +231,9 @@ again: if (!pad) { int32_t val; - pad = para_calloc(sizeof(*pad)); - wn->private_data = pad; if (bytes == 0) /* no data available */ return; + pad = para_calloc(sizeof(*pad)); get_btr_sample_rate(btrn, &val); pad->sample_rate = val; get_btr_channels(btrn, &val); @@ -245,8 +244,11 @@ again: PARA_INFO_LOG("%d channel(s), %dHz\n", pad->channels, pad->sample_rate); ret = alsa_init(pad, wn->conf); - if (ret < 0) + if (ret < 0) { + free(pad); goto err; + } + wn->private_data = pad; wn->min_iqs = pad->bytes_per_frame; goto again; } diff --git a/audiod.c b/audiod.c index 64ea8a51..8b17d95f 100644 --- a/audiod.c +++ b/audiod.c @@ -823,6 +823,14 @@ static int parse_receiver_args(void) ret = get_audio_format_num(arg); if (ret < 0) goto out; + /* + * If multiple receivers are given for this audio format, the + * last one wins and we have to free the previous receiver + * config here. Since we are iterating backwards, the winning + * receiver arg is in fact the first one given. + */ + if (afi[ret].receiver_conf) + afi[ret].receiver->free_config(afi[ret].receiver_conf); afi[ret].receiver_conf = check_receiver_arg(recv_arg, &receiver_num); if (!afi[ret].receiver_conf) { ret = -E_RECV_SYNTAX; @@ -830,9 +838,9 @@ static int parse_receiver_args(void) } afi[ret].receiver = &receivers[receiver_num]; } - /* use the first available receiver with no arguments - * for those audio formats for which no receiver - * was specified + /* + * Use the first available receiver with no arguments for those audio + * formats for which no receiver was specified. */ cmd = para_strdup(receivers[0].name); FOR_EACH_AUDIO_FORMAT(i) { diff --git a/configure.ac b/configure.ac index f47a56df..f3a2d133 100644 --- a/configure.ac +++ b/configure.ac @@ -31,12 +31,12 @@ AC_REPLACE_FNMATCH AC_HEADER_DIRENT AC_HEADER_STDC AC_HEADER_SYS_WAIT +AC_HEADER_STDBOOL AC_CHECK_HEADERS([arpa/inet.h ctype.h fcntl.h limits.h netdb.h netinet/in.h \ stdlib.h string.h sys/socket.h sys/time.h sys/timeb.h sys/un.h \ sys/ipc.h unistd.h utime.h stddef.h], [], [AC_MSG_ERROR([$ac_header not found])]) - # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE @@ -45,6 +45,7 @@ AC_TYPE_PID_T AC_TYPE_SIZE_T AC_HEADER_TIME AC_STRUCT_TM +AC_TYPE_INT8_T AC_TYPE_INT16_T AC_TYPE_INT32_T AC_TYPE_INT64_T @@ -75,7 +76,7 @@ AC_FUNC_LSTAT AC_CHECK_FUNCS([atexit dup2 memchr memmove memset \ regcomp select strchr strdup strerror strstr strtol uname \ fchdir gettimeofday localtime_r munmap strcasecmp strcspn \ - strncasecmp strrchr strspn alarm mkdir rmdir], [], + strncasecmp strrchr strspn alarm mkdir inet_ntoa socket], [], [AC_MSG_ERROR([function not found, cannot live without it])]) cmdline_dir="cmdline" @@ -735,7 +736,6 @@ AC_DEFINE_UNQUOTED(STATUS_ITEM_ARRAY, [$result], AC_DEFINE_UNQUOTED(SERVER_AUDIO_FORMATS, "$server_audio_formats", [formats supported by para_server and para_afh]) - AC_SUBST(executables, add_para($executables)) recv_objs="$recv_cmdline_objs $recv_errlist_objs" diff --git a/depend.sh b/depend.sh index aad45a3c..60d4eba6 100755 --- a/depend.sh +++ b/depend.sh @@ -19,4 +19,4 @@ shift LC_ALL=C gcc -MM -MG "$@" \ | sed -e "s@^\(.*\)\.o:@$object_dir/\1.d $object_dir/\1.o:@" \ - -e "s@[ ^]\([a-zA-Z0-9_]\+\.cmdline.h\)@ $cmdline_dir/\1@g" + -e "s@[ ^]\([a-zA-Z0-9_]\{1,\}\.cmdline.h\)@ $cmdline_dir/\1@g" diff --git a/fd.c b/fd.c index a0969e3e..6f9266f4 100644 --- a/fd.c +++ b/fd.c @@ -446,7 +446,7 @@ int para_chdir(const char *path) * \sa getcwd(3). * */ -int para_opendir(const char *dirname, DIR **dir, int *cwd) +static int para_opendir(const char *dirname, DIR **dir, int *cwd) { int ret; @@ -480,7 +480,7 @@ close_cwd: * * \return Standard. */ -int para_fchdir(int fd) +static int para_fchdir(int fd) { if (fchdir(fd) < 0) return -ERRNO_TO_PARA_ERROR(errno); diff --git a/fd.h b/fd.h index 436622f0..cc226b02 100644 --- a/fd.h +++ b/fd.h @@ -17,9 +17,7 @@ __must_check int para_fgets(char *line, int size, FILE *f); int para_mmap(size_t length, int prot, int flags, int fd, off_t offset, void *map); int para_open(const char *path, int flags, mode_t mode); -int para_opendir(const char *dirname, DIR **dir, int *cwd); int para_mkdir(const char *path, mode_t mode); -int para_fchdir(int fd); int para_chdir(const char *path); int mmap_full_file(const char *filename, int open_mode, void **map, size_t *size, int *fd_ptr); diff --git a/ggo/gui.m4 b/ggo/gui.m4 index 3f31dc1a..895229b2 100644 --- a/ggo/gui.m4 +++ b/ggo/gui.m4 @@ -1,9 +1,10 @@ include(header.m4) define(CURRENT_PROGRAM,para_gui) +define(DEFAULT_CONFIG_FILE,~/.paraslash/gui.conf) ######################### -section "general options" +section "General options" ######################### @@ -14,34 +15,53 @@ include(loglevel.m4) option "timeout" t #~~~~~~~~~~~~~~~~~ "set timeout" +int typestr = "milliseconds" +default = "30" +optional - int typestr="milliseconds" - default="30" - optional +option "theme" T +#~~~~~~~~~~~~~~~ +"select startup theme" +string typestr = "name" +optional +details = " + If this option is not given the default theme is used. + If the given name is not a valid theme name, the list of + available themes is printed and the program terminates. +" option "stat_cmd" s #~~~~~~~~~~~~~~~~~~ -"command to read server and audiod status -data from" +"command to read status items from" +string typestr = "command" +default = "para_audioc -- stat -p" +optional +details = " + In order to run para_gui on a host on which no para_audiod + is running (hence the default command does not work), the + command - string typestr="command" - default="para_audioc -- stat -p" - optional + para_client -- stat -p + + may be used. This command prints less information though. + In particular, no timing information about the current audio + file is printed. +" #--------------------------------- -section "mapping keys to commands" +section "Mapping keys to commands" #--------------------------------- option "key_map" k #~~~~~~~~~~~~~~~~~ +"Map key k to command c using mode m." -"Map key k to command c using mode m. Mode -may be d, x or p for display, external and -paraslash commands, respectively. Of course, -this option may be given multiple times, one -for each key mapping." - - string typestr="k:m:c" - optional - multiple +string typestr = "k:m:c" +optional +multiple +details = " + Mode may be d, x or p for display, external and paraslash + commands, respectively. Of course, this option may be given + multiple times, one for each key mapping. +" diff --git a/ggo/makefile b/ggo/makefile index d4f3a8cd..d5a1d645 100644 --- a/ggo/makefile +++ b/ggo/makefile @@ -29,6 +29,7 @@ $(cmdline_dir)/%_write.cmdline.h $(cmdline_dir)/%_write.cmdline.c: $(ggo_dir)/%_ --func-name $(subst _write.ggo,,$("); return buf; } + if (c == KEY_HOME) { + sprintf(buf, ""); + return buf; + } + if (c == KEY_END) { + sprintf(buf, ""); + return buf; + } if (c < 256 && c > -128 && iscntrl((unsigned char) c)) { if (c < 0) c += 256; @@ -635,14 +655,6 @@ static void init_wins(int top_lines) doupdate(); } -static void check_geometry(void) -{ - if (LINES < theme.lines_min || COLS < theme.cols_min) - msg_n_exit(EXIT_FAILURE, "Error: Terminal (%dx%d) too small" - " (need at least %dx%d)\n", COLS, LINES, - theme.cols_min, theme.lines_min); -} - /* * Print stat item #i to curses window */ @@ -747,53 +759,60 @@ static void clear_all_items(void) } } -static void init_colors(void) +static void init_pair_or_die(short pair, short f, short b) +{ + if (init_pair(pair, f, b) == ERR) + msg_n_exit(EXIT_FAILURE, "fatal: init_pair() failed\n"); +} + +static void init_colors_or_die(void) { int i; if (!has_colors()) - msg_n_exit(EXIT_FAILURE, "Error: No color term\n"); - start_color(); + msg_n_exit(EXIT_FAILURE, "fatal: No color term\n"); + if (start_color() == ERR) + msg_n_exit(EXIT_FAILURE, "fatal: failed to start colors\n"); FOR_EACH_STATUS_ITEM(i) if (theme.data[i].len) - init_pair(i + 1, theme.data[i].fg, theme.data[i].bg); - init_pair(COLOR_STATUSBAR, theme.sb_fg, theme.sb_bg); - init_pair(COLOR_COMMAND, theme.cmd_fg, theme.cmd_bg); - init_pair(COLOR_OUTPUT, theme.output_fg, theme.output_bg); - init_pair(COLOR_MSG, theme.msg_fg, theme.msg_bg); - init_pair(COLOR_ERRMSG, theme.err_msg_fg, theme.err_msg_bg); - init_pair(COLOR_WELCOME, theme.welcome_fg, theme.welcome_bg); - init_pair(COLOR_SEPARATOR, theme.sep_fg, theme.sep_bg); - init_pair(COLOR_TOP, theme.default_fg, theme.default_bg); - init_pair(COLOR_BOT, theme.default_fg, theme.default_bg); + init_pair_or_die(i + 1, theme.data[i].fg, + theme.data[i].bg); + init_pair_or_die(COLOR_STATUSBAR, theme.sb_fg, theme.sb_bg); + init_pair_or_die(COLOR_COMMAND, theme.cmd_fg, theme.cmd_bg); + init_pair_or_die(COLOR_OUTPUT, theme.output_fg, theme.output_bg); + init_pair_or_die(COLOR_MSG, theme.msg_fg, theme.msg_bg); + init_pair_or_die(COLOR_ERRMSG, theme.err_msg_fg, theme.err_msg_bg); + init_pair_or_die(COLOR_WELCOME, theme.welcome_fg, theme.welcome_bg); + init_pair_or_die(COLOR_SEPARATOR, theme.sep_fg, theme.sep_bg); + init_pair_or_die(COLOR_TOP, theme.default_fg, theme.default_bg); + init_pair_or_die(COLOR_BOT, theme.default_fg, theme.default_bg); } -/* - * (re-)initialize the curses library FIXME: Error checking - */ +/* (Re-)initialize the curses library. */ static void init_curses(void) { curses_active = 1; - if (top.win && refresh() == ERR) { /* refesh is really needed */ + if (top.win && refresh() == ERR) /* refesh is really needed */ msg_n_exit(EXIT_FAILURE, "refresh() failed\n"); - } - check_geometry(); + if (LINES < theme.lines_min || COLS < theme.cols_min) + msg_n_exit(EXIT_FAILURE, "Error: Terminal (%dx%d) too small" + " (need at least %dx%d)\n", COLS, LINES, + theme.cols_min, theme.lines_min); curs_set(0); /* make cursor invisible, ignore errors */ -// if (noraw() == ERR); -// msg_n_exit(EXIT_FAILURE, "can not place terminal out of " -// "raw mode\n"); - nonl(); /* tell curses not to do NL->CR/NL on output */ - noecho(); /* don't echo input */ - cbreak(); /* take input chars one at a time, no wait for \n */ - //reset_prog_mode(); - init_colors(); - clear(); + nonl(); /* do not NL->CR/NL on output, always returns OK */ + /* don't echo input */ + if (noecho() == ERR) + msg_n_exit(EXIT_FAILURE, "fatal: noecho() failed\n"); + /* take input chars one at a time, no wait for \n */ + if (cbreak() == ERR) + msg_n_exit(EXIT_FAILURE, "fatal: cbreak() failed\n"); + init_colors_or_die(); + clear(); /* ignore non-fatal errors */ init_wins(theme.top_lines_default); print_all_items(); - noecho(); /* don't echo input */ + // noecho(); /* don't echo input */ } - static void check_sigchld(void) { int ret; @@ -1097,6 +1116,41 @@ static void print_scroll_msg(void) filled - scroll_position, ringbuffer_filled(bot_win_rb)); } +static void com_scroll_top(void) +{ + int i = RINGBUFFER_SIZE - 1; + unsigned lines = 0; + + while (i > 0 && !ringbuffer_get(bot_win_rb, i)) + i--; + /* i is oldest entry */ + for (; lines < bot.lines && i >= 0; i--) { + struct rb_entry *rbe = ringbuffer_get(bot_win_rb, i); + if (!rbe) + break; + lines += NUM_LINES(strlen(rbe->msg)); + } + i++; + if (lines > 0 && scroll_position != i) { + scroll_position = i; + redraw_bot_win(); + print_scroll_msg(); + return; + } + print_in_bar(COLOR_ERRMSG, "top of buffer is shown\n"); +} + +static void com_cancel_scrolling(void) +{ + + if (scroll_position == 0) { + print_in_bar(COLOR_ERRMSG, "bottom of buffer is shown\n"); + return; + } + scroll_position = 0; + redraw_bot_win(); +} + static void com_page_down(void) { unsigned lines = 0; @@ -1228,7 +1282,8 @@ static void com_reread_conf(void) .override = 1, .initialize = 1, .check_required = 0, - .check_ambiguity = 0 + .check_ambiguity = 0, + .print_errors = 0, }; if (!cf) { @@ -1236,8 +1291,11 @@ static void com_reread_conf(void) return; } PARA_INFO_LOG("rereading command line options and config file"); - gui_cmdline_parser(_argc, _argv, &conf); - gui_cmdline_parser_config_file(cf, &conf, ¶ms); + gui_cmdline_parser_ext(_argc, _argv, &conf, ¶ms); + if (gui_cmdline_parser_config_file(cf, &conf, ¶ms) != 0) { + PARA_EMERG_LOG("errors in config file"); + finish(EXIT_FAILURE); + } PARA_NOTICE_LOG("config file reloaded"); if (check_key_map_args() < 0) finish(EXIT_FAILURE); @@ -1394,17 +1452,9 @@ int main(int argc, char *argv[]) _argc = argc; _argv = argv; - if (gui_cmdline_parser(argc, argv, &conf)) { - fprintf(stderr, "parse error while reading command line\n"); + if (gui_cmdline_parser(argc, argv, &conf) != 0) exit(EXIT_FAILURE); - } HANDLE_VERSION_FLAG("gui", conf); - init_theme(0, &theme); - top.lines = theme.top_lines_default; - if (check_key_map_args() < 0) { - fprintf(stderr, "invalid key map\n"); - exit(EXIT_FAILURE); - } cf = configfile_exists(); if (!cf && conf.config_file_given) { fprintf(stderr, "can not read config file %s\n", @@ -1416,15 +1466,19 @@ int main(int argc, char *argv[]) .override = 0, .initialize = 0, .check_required = 0, - .check_ambiguity = 0 + .check_ambiguity = 0, + .print_errors = 1, }; - gui_cmdline_parser_config_file(cf, &conf, ¶ms); + if (gui_cmdline_parser_config_file(cf, &conf, ¶ms) != 0) + exit(EXIT_FAILURE); } loglevel = get_loglevel_by_name(conf.loglevel_arg); if (check_key_map_args() < 0) { - fprintf(stderr, "invalid key map in config file\n"); + fprintf(stderr, "invalid key map\n"); exit(EXIT_FAILURE); } + init_theme_or_die(conf.theme_arg, &theme); + top.lines = theme.top_lines_default; setup_signal_handling(); bot_win_rb = ringbuffer_new(RINGBUFFER_SIZE); initscr(); /* needed only once, always successful */ diff --git a/gui.h b/gui.h index f8c6712b..aad20488 100644 --- a/gui.h +++ b/gui.h @@ -30,7 +30,7 @@ struct gui_theme { struct stat_item_data data[NUM_STAT_ITEMS]; }; -void init_theme(int i, struct gui_theme *); +void init_theme_or_die(const char *name, struct gui_theme *t); void next_theme(struct gui_theme *); void prev_theme(struct gui_theme *); #define LEFT 1 diff --git a/gui_theme.c b/gui_theme.c index ffb47d43..ffa5d792 100644 --- a/gui_theme.c +++ b/gui_theme.c @@ -4,19 +4,14 @@ * Licensed under the GPL v2. For licencing details see COPYING. */ +#include #include "para.h" #include "gui.h" #include -#define NUM_THEMES 2 - - -static int current_theme_num; - static void init_theme_simple(struct gui_theme *t) { struct stat_item_data *d = t->data; - t->name = "simple"; t->author = "Andre Noll"; t->lines_min = 5; t->top_lines_min = 2; @@ -72,7 +67,6 @@ static void init_theme_simple(struct gui_theme *t) static void init_theme_colorful_blackness(struct gui_theme *t) { struct stat_item_data *d = t->data; - t->name = "colorful blackness"; t->author = "Andre Noll"; /* minimal number of lines that is needed to display all * information provided by this theme @@ -363,24 +357,58 @@ static void init_theme_colorful_blackness(struct gui_theme *t) d[SI_DIRECTORY].len = 100; } -void init_theme(int num, struct gui_theme *t) +struct theme_description { + const char *name; + void (*init)(struct gui_theme *t); +}; + +struct theme_description themes[] = { + { + .name = "colorful blackness", + .init = init_theme_colorful_blackness, + }, + { + .name = "simple", + .init = init_theme_simple, + }, +}; + +#define NUM_THEMES (ARRAY_SIZE(themes)) + +static int current_theme_num; + +static void set_theme(int num, struct gui_theme *t) { int i; FOR_EACH_STATUS_ITEM(i) t->data[i].len = 0; + num %= NUM_THEMES; + t->name = themes[num].name; + themes[num].init(t); current_theme_num = num; +} - return (num % NUM_THEMES)? - init_theme_simple(t) : init_theme_colorful_blackness(t); +void init_theme_or_die(const char *name, struct gui_theme *t) +{ + int i; + + if (!name) + return set_theme(0, t); + for (i = 0; i < NUM_THEMES; i++) + if (strcmp(name, themes[i].name) == 0) + return set_theme(i, t); + fprintf(stderr, "Available themes:\n"); + for (i = 0; i < NUM_THEMES; i++) + fprintf(stderr, "\t%s\n", themes[i].name); + exit(EXIT_FAILURE); } void prev_theme(struct gui_theme *t) { - return init_theme(++current_theme_num, t); + return set_theme(++current_theme_num, t); } void next_theme(struct gui_theme *t) { - return init_theme(--current_theme_num, t); + return set_theme(--current_theme_num, t); } - diff --git a/oss_write.c b/oss_write.c index df9608a8..70a58203 100644 --- a/oss_write.c +++ b/oss_write.c @@ -88,7 +88,6 @@ static int oss_init(struct writer_node *wn, unsigned sample_rate, struct oss_write_args_info *conf = wn->conf; struct private_oss_write_data *powd = para_calloc(sizeof(*powd)); - wn->private_data = powd; PARA_INFO_LOG("opening %s\n", conf->device_arg); ret = para_open(conf->device_arg, O_WRONLY, 0); if (ret < 0) @@ -149,6 +148,7 @@ static int oss_init(struct writer_node *wn, unsigned sample_rate, sample_rate); } wn->min_iqs = powd->bytes_per_frame; + wn->private_data = powd; return 1; err: close(powd->fd); diff --git a/web/gitweb_header.html.in b/web/gitweb_header.html.in index 44f8847d..d1338276 100644 --- a/web/gitweb_header.html.in +++ b/web/gitweb_header.html.in @@ -2,9 +2,7 @@ - paraslash - + paraslash @@ -16,16 +14,16 @@ - + Home

News

Features

Download

Screenshots

- Changes

+ Changes

Documentation

License

Contact

Credits

- + diff --git a/web/header.html b/web/header.html index 7d56f631..464db042 100644 --- a/web/header.html +++ b/web/header.html @@ -29,7 +29,7 @@
Features
Download
Screenshots -
Changes +
Changes
Documentation
License
Contact diff --git a/web/header2.html b/web/header2.html index c438108d..c8de7afd 100644 --- a/web/header2.html +++ b/web/header2.html @@ -29,7 +29,7 @@
Features
Download
Screenshots -
Changes +
Changes
Documentation
License
Contact diff --git a/web/images/git-logo.png b/web/images/git-logo.png new file mode 100644 index 00000000..16ae8d53 Binary files /dev/null and b/web/images/git-logo.png differ diff --git a/write.c b/write.c index dda1b705..2ea9d213 100644 --- a/write.c +++ b/write.c @@ -216,6 +216,7 @@ out: w->close(wn); btr_free_node(wn->btrn); + w->free_config(wn->conf); free(wn->conf); } free(wns);