X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=gui.c;h=54fc9db98bd91ad836eb79288d42927eadcb1fcf;hp=fb70dd830a2f6233b3a3463c3098656d7ed6fd64;hb=761d9bd95a6601c0b3be6591a6b6672b755e1fbe;hpb=14e6890c756529c73a95cf1fb3648a6a7c3344d7 diff --git a/gui.c b/gui.c index fb70dd83..54fc9db9 100644 --- a/gui.c +++ b/gui.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "gui.cmdline.h" @@ -22,6 +23,7 @@ #include "list.h" #include "sched.h" #include "signal.h" +#include "ggo.h" #include "version.h" /** define the array of error lists needed by para_gui */ @@ -292,7 +294,7 @@ static char *configfile_exists(void) static void add_spaces(WINDOW* win, unsigned int num) { char space[] = " "; - unsigned sz = sizeof(space); + unsigned sz = sizeof(space) - 1; /* number of spaces */ while (num >= sz) { waddstr(win, space); @@ -312,11 +314,18 @@ static void add_spaces(WINDOW* win, unsigned int num) static int align_str(WINDOW* win, char *str, unsigned int len, unsigned int align) { - int i, num; /* of spaces */ + int ret, i, num; /* of spaces */ + size_t width; if (!win || !str) - return -1; - num = len - strlen(str); + return 0; + ret = strwidth(str, &width); + if (ret < 0) { + PARA_ERROR_LOG("%s\n", para_strerror(-ret)); + width = 0; + str[0] = '\0'; + } + num = len - width; if (num < 0) { str[len] = '\0'; num = 0; @@ -398,11 +407,14 @@ static int first_visible_rbe(unsigned *lines) return RINGBUFFER_SIZE - 1; } +/* +returns number of first visible rbe, *lines is the number of lines drawn. + */ static int draw_top_rbe(unsigned *lines) { - unsigned len; - int offset, fvr = first_visible_rbe(lines); + int ret, fvr = first_visible_rbe(lines); struct rb_entry *rbe; + size_t bytes_to_skip, cells_to_skip, width; if (fvr < 0) return -1; @@ -410,16 +422,22 @@ static int draw_top_rbe(unsigned *lines) rbe = ringbuffer_get(bot_win_rb, fvr); if (!rbe) return -1; - len = strlen(rbe->msg); if (*lines > bot.lines) { - /* first rbe is only partially visible */ - offset = (*lines - bot.lines) * bot.cols; - assert(offset <= len); - } else - offset = 0; + /* rbe is partially visible multi-line */ + cells_to_skip = (*lines - bot.lines) * bot.cols; + ret = skip_cells(rbe->msg, cells_to_skip, &bytes_to_skip); + if (ret < 0) + return ret; + ret = strwidth(rbe->msg + bytes_to_skip, &width); + if (ret < 0) + return ret; + } else { + bytes_to_skip = 0; + width = rbe->len; + } wattron(bot.win, COLOR_PAIR(rbe->color)); - waddstr(bot.win, rbe->msg + offset); - *lines = NUM_LINES(len - offset); + waddstr(bot.win, rbe->msg + bytes_to_skip); + *lines = NUM_LINES(width); return fvr; } @@ -451,10 +469,15 @@ out: static void rb_add_entry(int color, char *msg) { - struct rb_entry *old, *new = para_malloc(sizeof(struct rb_entry)); + struct rb_entry *old, *new; int x, y; + size_t len; + + if (strwidth(msg, &len) < 0) + return; + new = para_malloc(sizeof(struct rb_entry)); new->color = color; - new->len = strlen(msg); + new->len = len; new->msg = msg; old = ringbuffer_add(bot_win_rb, new); // fprintf(stderr, "added: %s\n", new->msg); @@ -503,7 +526,7 @@ static int add_output_line(char *line, void *data) static int loglevel; -__printf_2_3 void curses_log(int ll, const char *fmt,...) +static __printf_2_3 void curses_log(int ll, const char *fmt,...) { int color; char *msg; @@ -582,8 +605,8 @@ static void print_welcome(void) { if (loglevel > LL_NOTICE) return; - outputf(COLOR_WELCOME, "Welcome to para_gui " PACKAGE_VERSION - " \"" CODENAME "\". Theme: %s", theme.name); + outputf(COLOR_WELCOME, "Welcome to %s. Theme: %s", + version_single_line("gui"), theme.name); wclrtoeol(bot.win); } @@ -982,6 +1005,7 @@ static int do_select(int mode) char command_buf[2][COMMAND_BUF_SIZE] = {"", ""}; int cbo[2] = {0, 0}; /* command buf offsets */ struct timeval tv; + unsigned flags[2] = {0, 0}; /* for for_each_line() */ repeat: tv.tv_sec = conf.timeout_arg / 1000; @@ -1019,21 +1043,25 @@ repeat: COMMAND_BUF_SIZE - 1 - cbo[i], &rfds, &sz); cbo[i] += sz; sz = cbo[i]; - cbo[i] = for_each_line(command_buf[i], cbo[i], + cbo[i] = for_each_line(flags[i], command_buf[i], cbo[i], add_output_line, &i); - if (sz != cbo[i]) + if (sz != cbo[i]) { /* at least one line found */ wrefresh(bot.win); + flags[i] = 0; + } if (ret < 0) { PARA_NOTICE_LOG("closing command fd %d: %s", i, para_strerror(-ret)); close(command_fds[i]); command_fds[i] = -1; + flags[i] = 0; if (command_fds[!i] < 0) /* both fds closed */ return 0; } if (cbo[i] == COMMAND_BUF_SIZE - 1) { PARA_NOTICE_LOG("discarding overlong line"); cbo[i] = 0; + flags[i] = FELF_DISCARD_FIRST; } } } @@ -1171,7 +1199,7 @@ static void com_scroll_top(void) struct rb_entry *rbe = ringbuffer_get(bot_win_rb, i); if (!rbe) break; - lines += NUM_LINES(strlen(rbe->msg)); + lines += NUM_LINES(rbe->len); } i++; if (lines > 0 && scroll_position != i) { @@ -1202,7 +1230,7 @@ static void com_page_down(void) struct rb_entry *rbe = ringbuffer_get(bot_win_rb, i); if (!rbe) break; - lines += NUM_LINES(strlen(rbe->msg)); + lines += NUM_LINES(rbe->len); } if (lines) { scroll_position = i; @@ -1335,10 +1363,7 @@ static void com_reread_conf(void) } PARA_INFO_LOG("rereading command line options and config file"); 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); - } + gui_cmdline_parser_config_file(cf, &conf, ¶ms); PARA_NOTICE_LOG("config file reloaded"); if (check_key_map_args() < 0) finish(EXIT_FAILURE); @@ -1407,8 +1432,7 @@ static void com_enlarge_top_win(void) static void com_version(void) { - print_in_bar(COLOR_MSG, "para_gui " PACKAGE_VERSION " \"" - CODENAME "\""); + print_in_bar(COLOR_MSG, "%s", version_single_line("gui")); } __noreturn static void com_quit(void) @@ -1487,6 +1511,15 @@ static void handle_command(int c) km_keyname(c)); } +__noreturn static void print_help_and_die(void) +{ + struct ggo_help h = DEFINE_GGO_HELP(gui); + bool d = conf.detailed_help_given; + + ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS); + exit(0); +} + int main(int argc, char *argv[]) { int ret; @@ -1496,7 +1529,10 @@ int main(int argc, char *argv[]) _argv = argv; gui_cmdline_parser(argc, argv, &conf); /* exits on errors */ - HANDLE_VERSION_FLAG("gui", conf); + loglevel = get_loglevel_by_name(conf.loglevel_arg); + version_handle_flag("gui", conf.version_given); + if (conf.help_given || conf.detailed_help_given) + print_help_and_die(); cf = configfile_exists(); if (!cf && conf.config_file_given) { fprintf(stderr, "can not read config file %s\n", @@ -1511,10 +1547,9 @@ int main(int argc, char *argv[]) .check_ambiguity = 0, .print_errors = 1, }; - if (gui_cmdline_parser_config_file(cf, &conf, ¶ms) != 0) - exit(EXIT_FAILURE); + gui_cmdline_parser_config_file(cf, &conf, ¶ms); + loglevel = get_loglevel_by_name(conf.loglevel_arg); } - loglevel = get_loglevel_by_name(conf.loglevel_arg); if (check_key_map_args() < 0) { fprintf(stderr, "invalid key map\n"); exit(EXIT_FAILURE); @@ -1523,6 +1558,7 @@ int main(int argc, char *argv[]) top.lines = theme.top_lines_default; setup_signal_handling(); bot_win_rb = ringbuffer_new(RINGBUFFER_SIZE); + setlocale(LC_CTYPE, ""); initscr(); /* needed only once, always successful */ init_curses(); print_welcome();