]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 't/ogg_timining_fixes'
authorAndre Noll <maan@systemlinux.org>
Sun, 27 Feb 2011 22:19:51 +0000 (23:19 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 27 Feb 2011 22:19:51 +0000 (23:19 +0100)
19 files changed:
NEWS
aac_afh.c
alsa_write.c
audiod.c
configure.ac
depend.sh
fd.c
fd.h
ggo/gui.m4
ggo/makefile
gui.c
gui.h
gui_theme.c
oss_write.c
web/gitweb_header.html.in
web/header.html
web/header2.html
web/images/git-logo.png [new file with mode: 0644]
write.c

diff --git a/NEWS b/NEWS
index 149f4e40c51bc1e3af24ece46ea2ef0808a17f0d..dcc4393b517df293c8eb90344d6471af48dab833 100644 (file)
--- 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"
index 94b0f8b34cdb69787c86ae2dd333d7a3b1914e84..a53a757fd89777720cf5dafca5589ccad3117216 100644 (file)
--- 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;
index d649341837d3284f7aaf9b1fc83ab22f217826b6..ae3bbfbab60c82ab26311c00b1d0389a7544ec5c 100644 (file)
@@ -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;
        }
index 64ea8a51efeeb13cb65f86d1ea417120679ff2f4..8b17d95fba692db0b2dd9126226cb8fb2cb682d5 100644 (file)
--- 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) {
index f47a56df0c96f71d68e19b3655aa017925536a83..f3a2d1333f457f2cae6c313456a7fe295a479279 100644 (file)
@@ -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"
index aad45a3c8d4ff8f6882893683fd8763ac4970c9f..60d4eba6b8fc22ca5d0431444ec65d7cb2c74ab2 100755 (executable)
--- 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 a0969e3e651a92983682f29f1ca375b214a6447a..6f9266f47a56cd8dee3e99b8651d12a89bb4069b 100644 (file)
--- 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 436622f0ef994791abe9d1e3f3cd3adacb08d92a..cc226b029d3035b30f9ae0ccb95a36ffff210ecd 100644 (file)
--- 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);
index 3f31dc1a202ee0eb61d5b8373531b6a80234a6a6..895229b22f8ef68cf7fa143c525eb90310c75a79 100644 (file)
@@ -1,9 +1,10 @@
 include(header.m4)
 define(CURRENT_PROGRAM,para_gui)
+define(DEFAULT_CONFIG_FILE,~/.paraslash/gui.conf)
 
 <qu>
 #########################
-section "general options"
+section "General options"
 #########################
 </qu>
 
@@ -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.
+"
 </qu>
index d4f3a8cd2d212b281aff3c4282bb9e497a3c3297..d5a1d645cd79db1b177e2f46cd67dbffe765cecf 100644 (file)
@@ -29,6 +29,7 @@ $(cmdline_dir)/%_write.cmdline.h $(cmdline_dir)/%_write.cmdline.c: $(ggo_dir)/%_
                --func-name $(subst _write.ggo,,$(<F))_cmdline_parser < $<
 
 define ggo-opts
+$(if $(filter gui,$(*F)), --no-handle-error) \
 $(if $(filter recv filter write audiod,$(*F)), --no-handle-help) \
 $(if $(filter afh,$(*F)), --unamed-opts=audio_file) \
 $(if $(filter client audioc,$(*F)), --unamed-opts=command) \
diff --git a/gui.c b/gui.c
index 8e70dd93b4d3a5d3d7b35a3c7ec65723d7639f24..eba1e2a59331564a40677a123d1220dc9120c059 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -109,6 +109,8 @@ static void com_scroll_up(void);
 static void com_scroll_down(void);
 static void com_page_up(void);
 static void com_page_down(void);
+static void com_cancel_scrolling(void);
+static void com_scroll_top(void);
 
 static struct gui_command command_list[] = {
        {
@@ -186,6 +188,16 @@ static struct gui_command command_list[] = {
                .name = "page_down",
                .description = "scroll down one page",
                .handler = com_page_down
+       }, {
+               .key = "<home>",
+               .name = "scroll_top",
+               .description = "scroll to top of buffer",
+               .handler = com_scroll_top
+       }, {
+               .key = "<end>",
+               .name = "cancel_scroll",
+               .description = "deactivate scroll mode",
+               .handler = com_cancel_scrolling
        }, {
                .handler = NULL
        }
@@ -230,6 +242,14 @@ static char *km_keyname(int c)
                sprintf(buf, "<ppage>");
                return buf;
        }
+       if (c == KEY_HOME) {
+               sprintf(buf, "<home>");
+               return buf;
+       }
+       if (c == KEY_END) {
+               sprintf(buf, "<end>");
+               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, &params);
+       gui_cmdline_parser_ext(_argc, _argv, &conf, &params);
+       if (gui_cmdline_parser_config_file(cf, &conf, &params) != 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, &params);
+               if (gui_cmdline_parser_config_file(cf, &conf, &params) != 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 f8c6712b4d6870003cac507ed429dec47abdeca7..aad2048874468f9bf18ef10d1b18b3303747b91f 100644 (file)
--- 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
index ffb47d43302773f838f1fc6d0e6ca4958b2e871b..ffa5d792ee199f16e5bb26c5e6557054520f8e5c 100644 (file)
@@ -4,19 +4,14 @@
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
 
+#include <stdbool.h>
 #include "para.h"
 #include "gui.h"
 #include <curses.h>
 
-#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);
 }
-
index df9608a8c6a2bbb9b3787df76ce8ec7931604e16..70a58203db8a2f2e3eca5cfc12506334ed7133da 100644 (file)
@@ -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);
index 44f8847d7ec33a2b9d35a11bdfd85bbdaa85c9a5..d1338276b7ebe9e5a67d1c3dff4fa102a6658926 100644 (file)
@@ -2,9 +2,7 @@
 <tr>
        <td>
                        <a title="paraslash homepage" href="/">
-                       <img src="@web_root@/paraslash.png" alt="paraslash"
-                               border="0">
-                       </img>
+                       <img src="@web_root@/paraslash.png" alt="paraslash"/>
                        </a>
        </td>
        <td>
        </td>
 </tr>
 <tr>
-       <td valign="TOP">
+       <td valign="top">
                <a href="@web_root@/index.html">Home</a><br></br>
                <a href="@web_root@/NEWS.html">News</a><br></br>
                <a href="@web_root@/FEATURES.html">Features</a><br></br>
                <a href="@web_root@/download.html">Download</a><br></br>
                <a href="@web_root@/screenshots.html">Screenshots</a><br></br>
-               <a href="/gitweb/gitweb.cgi?p=.git;a=shortlog">Changes</a><br></br>
+               <a href="/gitweb/gitweb.cgi?p=.git;a=summary">Changes</a><br></br>
                <a href="@web_root@/documentation.html">Documentation</a><br></br>
                <a href="@web_root@/license.html">License</a><br></br>
                <a href="@web_root@/contact.html">Contact</a><br></br>
                <a href="@web_root@/CREDITS.html">Credits</a><br></br>
        </td>
-       <td Valign="TOP">
+       <td valign="top">
index 7d56f6313aed03bb5959a36543eefbf875ac09ab..464db04233601128b7299ccc56aa3630c64968cc 100644 (file)
@@ -29,7 +29,7 @@
                        <br><a href="FEATURES.html">Features</a>
                        <br><a href="download.html">Download</a>
                        <br><a href="screenshots.html">Screenshots</a>
-                       <br><a href="/gitweb/gitweb.cgi?p=.git;a=shortlog">Changes</a>
+                       <br><a href="/gitweb/gitweb.cgi?p=.git;a=summary">Changes</a>
                        <br><a href="documentation.html">Documentation</a>
                        <br><a href="license.html">License</a>
                        <br><a href="contact.html">Contact</a>
index c438108d886f830f57378e70604946a24c0498d1..c8de7afd8647d4291f2adea92ae6b528777b201e 100644 (file)
@@ -29,7 +29,7 @@
                        <br><a href="../../FEATURES.html">Features</a>
                        <br><a href="../../download.html">Download</a>
                        <br><a href="../../screenshots.html">Screenshots</a>
-                       <br><a href="../../gitweb/gitweb.cgi?p=.git;a=shortlog">Changes</a>
+                       <br><a href="../../gitweb/gitweb.cgi?p=.git;a=summary">Changes</a>
                        <br><a href="../../documentation.html">Documentation</a>
                        <br><a href="../../license.html">License</a>
                        <br><a href="../../contact.html">Contact</a>
diff --git a/web/images/git-logo.png b/web/images/git-logo.png
new file mode 100644 (file)
index 0000000..16ae8d5
Binary files /dev/null and b/web/images/git-logo.png differ
diff --git a/write.c b/write.c
index dda1b705c19151000dd08098f99d2b9d4c71f11c..2ea9d2132bee5f64224f3f9d635af8f83777a33e 100644 (file)
--- 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);