X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=gui.c;h=1498426a8922e11726280f9c7cbecb6f49058174;hb=44d40c0c021b65cbfa88466b34054d0fcbcc2a45;hp=fa1538b0d63f3db2ca8be6497aa0ce797d3a89a1;hpb=ffb2eaa90429f6d5c3d369509efcdf91c5463dad;p=paraslash.git diff --git a/gui.c b/gui.c index fa1538b0..1498426a 100644 --- a/gui.c +++ b/gui.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1998-2010 Andre Noll + * Copyright (C) 1998-2011 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -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 = "", + .name = "scroll_top", + .description = "scroll to top of buffer", + .handler = com_scroll_top + }, { + .key = "", + .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, ""); 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; @@ -294,9 +314,9 @@ static int align_str(WINDOW* win, char *str, unsigned int len, str[len] = '\0'; num = 0; } - /* replace newlines by spaces */ + /* replace control characters by spaces */ for (i = 0; i < len && str[i]; i++) { - if (str[i] == '\n') + if (str[i] == '\n' || str[i] == '\r' || str[i] == '\f') str[i] = ' '; } if (align == LEFT) { @@ -768,24 +788,17 @@ static void init_colors(void) init_pair(COLOR_BOT, theme.default_fg, theme.default_bg); } -/* - * (re-)initialize the curses library FIXME: Error checking - */ +/* (Re-)initialize the curses library. FIXME: Error checking. */ 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(); 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(); init_wins(theme.top_lines_default); @@ -793,7 +806,6 @@ static void init_curses(void) noecho(); /* don't echo input */ } - static void check_sigchld(void) { int ret; @@ -902,7 +914,13 @@ static int open_stat_pipe(void) if (init) init = 0; else - sleep(1); + /* + * Sleep a bit to avoid a busy loop. As the call to sleep() may + * be interrupted by SIGCHLD, we simply wait until the call + * succeeds. + */ + while (sleep(2)) + ; /* nothing */ ret = para_exec_cmdline_pid(&pid, conf.stat_cmd_arg, fds); if (ret < 0) return ret; @@ -1091,6 +1109,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; @@ -1222,7 +1275,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) { @@ -1230,8 +1284,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); @@ -1388,17 +1445,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", @@ -1410,15 +1459,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 */