]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - gui.c
gui: Remove ->cols and ->lines of struct gui_window.
[paraslash.git] / gui.c
diff --git a/gui.c b/gui.c
index ead752096464a0519648a13d82a39fd64d9a7d1e..9cf950650090cc263b8395c09088f7ad0e3178fd 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -34,8 +34,6 @@ static int signal_pipe;
 
 static struct gui_window {
        WINDOW *win;
-       size_t cols;
-       size_t lines;
 } top, bot, sb, in, sep;
 
 #define RINGBUFFER_SIZE 512
@@ -45,7 +43,6 @@ struct rb_entry {
        int color;
 };
 static struct ringbuffer *bot_win_rb;
-#define NUM_LINES(len) (1 + (len) / bot.cols)
 
 static unsigned scroll_position;
 
@@ -203,6 +200,31 @@ static int find_cmd_byname(char *name)
        return -1;
 }
 
+/*
+ * Even though ncurses provides getmaxx and getmaxy, these functions/macros are
+ * not described in the XSI Curses standard.
+ */
+static int get_num_lines(struct gui_window *w)
+{
+       int lines;
+       __a_unused int cols; /* avoid "set but not used" warnings */
+
+       getmaxyx(w->win, lines, cols);
+       return lines;
+}
+
+static int get_num_cols(struct gui_window *w)
+{
+       __a_unused int lines; /* avoid "set but not used" warnings */
+       int cols;
+
+       getmaxyx(w->win, lines, cols);
+       return cols;
+}
+
+/** Number of lines of the window are occupied by an output line. */
+#define NUM_LINES(len) (1 + (len) / get_num_cols(&bot))
+
 /* isendwin() returns false before initscr() was called */
 static bool curses_active(void)
 {
@@ -354,7 +376,7 @@ __printf_2_3 static void print_in_bar(int color, const char *fmt,...)
        xvasprintf(&msg, fmt, ap);
        va_end(ap);
        wmove(in.win, 0, 0);
-       align_str(in.win, msg, in.cols, LEFT);
+       align_str(in.win, msg, get_num_cols(&in), LEFT);
        free(msg);
        wrefresh(in.win);
 }
@@ -365,7 +387,7 @@ static void print_status_bar(void)
 
        tmp = para_strdup("para_gui " PACKAGE_VERSION " (hit ? for help)");
        wmove(sb.win, 0, 0);
-       align_str(sb.win, tmp, sb.cols, CENTER);
+       align_str(sb.win, tmp, get_num_cols(&sb), CENTER);
        free(tmp);
 }
 
@@ -376,7 +398,8 @@ static void print_status_bar(void)
  */
 static int first_visible_rbe(unsigned *lines)
 {
-       int i;
+       int i, bot_lines = get_num_lines(&bot);
+
        *lines = 0;
        for (i = scroll_position; i < RINGBUFFER_SIZE; i++) {
                struct rb_entry *rbe = ringbuffer_get(bot_win_rb, i);
@@ -384,10 +407,10 @@ static int first_visible_rbe(unsigned *lines)
                if (!rbe)
                        return i - 1;
                rbe_lines = NUM_LINES(rbe->len);
-               if (rbe_lines > bot.lines)
+               if (rbe_lines > bot_lines)
                        return -1;
                *lines += rbe_lines;
-               if (*lines >= bot.lines)
+               if (*lines >= bot_lines)
                        return i;
        }
        return RINGBUFFER_SIZE - 1;
@@ -398,7 +421,7 @@ returns number of first visible rbe, *lines is the number of lines drawn.
  */
 static int draw_top_rbe(unsigned *lines)
 {
-       int ret, fvr = first_visible_rbe(lines);
+       int bot_cols, bot_lines, ret, fvr = first_visible_rbe(lines);
        struct rb_entry *rbe;
        size_t bytes_to_skip, cells_to_skip, width;
 
@@ -408,9 +431,10 @@ static int draw_top_rbe(unsigned *lines)
        rbe = ringbuffer_get(bot_win_rb, fvr);
        if (!rbe)
                return -1;
-       if (*lines > bot.lines) {
+       getmaxyx(bot.win, bot_lines, bot_cols);
+       if (*lines > bot_lines) {
                /* rbe is partially visible multi-line */
-               cells_to_skip = (*lines - bot.lines) * bot.cols;
+               cells_to_skip = (*lines - bot_lines) * bot_cols;
                ret = skip_cells(rbe->msg, cells_to_skip, &bytes_to_skip);
                if (ret < 0)
                        return ret;
@@ -430,14 +454,14 @@ static int draw_top_rbe(unsigned *lines)
 static void redraw_bot_win(void)
 {
        unsigned lines;
-       int i;
+       int i, bot_lines = get_num_lines(&bot);
 
        wmove(bot.win, 0, 0);
        wclear(bot.win);
        i = draw_top_rbe(&lines);
        if (i <= 0)
                goto out;
-       while (i > 0 && lines < bot.lines) {
+       while (i > 0 && lines < bot_lines) {
                struct rb_entry *rbe = ringbuffer_get(bot_win_rb, --i);
                if (!rbe) {
                        lines++;
@@ -564,75 +588,6 @@ __noreturn __printf_2_3 static void die(int exit_code, const char* fmt, ...)
        exit(exit_code);
 }
 
-/*
- * init all windows
- */
-static void init_wins(int top_lines)
-{
-       int top_y = 0, bot_y = top_lines + 1, sb_y = LINES - 2,
-               in_y = LINES - 1, sep_y = top_lines;
-
-       top.lines = top_lines;
-       bot.lines = LINES - top.lines - 3;
-       sb.lines = in.lines = sep.lines = 1;
-
-       top.cols = bot.cols = sb.cols = in.cols = sep.cols = COLS;
-
-       assume_default_colors(theme.default_fg, theme.default_bg);
-       if (top.win) {
-               wresize(top.win, top.lines, top.cols);
-               mvwin(top.win, top_y, 0);
-
-               wresize(sb.win, sb.lines, sb.cols);
-               mvwin(sb.win, sb_y, 0);
-
-               wresize(sep.win, sep.lines, sep.cols);
-               mvwin(sep.win, sep_y, 0);
-
-               wresize(bot.win, bot.lines, bot.cols);
-               mvwin(bot.win, bot_y, 0);
-
-               wresize(in.win, in.lines, in.cols);
-               mvwin(in.win, in_y, 0);
-       } else {
-               sep.win = newwin(sep.lines, sep.cols, sep_y, 0);
-               top.win = newwin(top.lines, top.cols, top_y, 0);
-               bot.win = newwin(bot.lines, bot.cols, bot_y, 0);
-               sb.win = newwin(sb.lines, sb.cols, sb_y, 0);
-               in.win = newwin(in.lines, in.cols, in_y, 0);
-               if (!top.win || !bot.win || !sb.win || !in.win || !sep.win)
-                       die(EXIT_FAILURE, "Error: Cannot create curses windows\n");
-               wclear(bot.win);
-               wclear(sb.win);
-               wclear(in.win);
-               scrollok(bot.win, 1);
-               wattron(sb.win, COLOR_PAIR(COLOR_STATUSBAR));
-               wattron(sep.win, COLOR_PAIR(COLOR_SEPARATOR));
-               wattron(bot.win, COLOR_PAIR(COLOR_BOT));
-               wattron(top.win, COLOR_PAIR(COLOR_TOP));
-               nodelay(top.win, 1);
-               nodelay(bot.win, 1);
-               nodelay(sb.win, 1);
-               nodelay(in.win, 0);
-
-               keypad(top.win, 1);
-               keypad(bot.win, 1);
-               keypad(sb.win, 1);
-               keypad(in.win, 1);
-       }
-       wmove(sep.win, 0, 0);
-       whline(sep.win, theme.sep_char, COLS);
-       wclear(top.win);
-       //wclear(bot.win);
-       wnoutrefresh(top.win);
-       wnoutrefresh(bot.win);
-       print_status_bar();
-       wnoutrefresh(sb.win);
-       wnoutrefresh(in.win);
-       wnoutrefresh(sep.win);
-       doupdate();
-}
-
 /*
  * Print stat item #i to curses window
  */
@@ -641,11 +596,12 @@ static void print_stat_item(int i)
        char *tmp;
        struct stat_item_data d = theme.data[i];
        char *c = stat_content[i];
+       int top_lines = get_num_lines(&top);
 
        if (!curses_active() || !d.len || !c)
                return;
        tmp = make_message("%s%s%s", d.prefix, c, d.postfix);
-       wmove(top.win, d.y * top.lines / 100, d.x * COLS / 100);
+       wmove(top.win, d.y * top_lines / 100, d.x * COLS / 100);
        wrefresh(top.win);
        wattron(top.win, COLOR_PAIR(i + 1));
        align_str(top.win, tmp, d.len * COLS / 100, d.align);
@@ -737,6 +693,72 @@ static void clear_all_items(void)
        }
 }
 
+/*
+ * init all windows
+ */
+static void init_wins(int top_lines)
+{
+       int top_y = 0, bot_y = top_lines + 1, sb_y = LINES - 2,
+               in_y = LINES - 1, sep_y = top_lines;
+       int bot_lines = LINES - top_lines - 3, sb_lines = 1, in_lines = 1,
+               sep_lines = 1;
+
+       assume_default_colors(theme.default_fg, theme.default_bg);
+       if (top.win) {
+               wresize(top.win, top_lines, COLS);
+               mvwin(top.win, top_y, 0);
+
+               wresize(sb.win, sb_lines, COLS);
+               mvwin(sb.win, sb_y, 0);
+
+               wresize(sep.win, sep_lines, COLS);
+               mvwin(sep.win, sep_y, 0);
+
+               wresize(bot.win, bot_lines, COLS);
+               mvwin(bot.win, bot_y, 0);
+
+               wresize(in.win, in_lines, COLS);
+               mvwin(in.win, in_y, 0);
+       } else {
+               sep.win = newwin(sep_lines, COLS, sep_y, 0);
+               top.win = newwin(top_lines, COLS, top_y, 0);
+               bot.win = newwin(bot_lines, COLS, bot_y, 0);
+               sb.win = newwin(sb_lines, COLS, sb_y, 0);
+               in.win = newwin(in_lines, COLS, in_y, 0);
+               if (!top.win || !bot.win || !sb.win || !in.win || !sep.win)
+                       die(EXIT_FAILURE, "Error: Cannot create curses windows\n");
+               wclear(bot.win);
+               wclear(sb.win);
+               wclear(in.win);
+               scrollok(bot.win, 1);
+               wattron(sb.win, COLOR_PAIR(COLOR_STATUSBAR));
+               wattron(sep.win, COLOR_PAIR(COLOR_SEPARATOR));
+               wattron(bot.win, COLOR_PAIR(COLOR_BOT));
+               wattron(top.win, COLOR_PAIR(COLOR_TOP));
+               nodelay(top.win, 1);
+               nodelay(bot.win, 1);
+               nodelay(sb.win, 1);
+               nodelay(in.win, 0);
+
+               keypad(top.win, 1);
+               keypad(bot.win, 1);
+               keypad(sb.win, 1);
+               keypad(in.win, 1);
+       }
+       wmove(sep.win, 0, 0);
+       whline(sep.win, theme.sep_char, COLS);
+       wclear(top.win);
+       print_all_items();
+       //wclear(bot.win);
+       wnoutrefresh(top.win);
+       wnoutrefresh(bot.win);
+       print_status_bar();
+       wnoutrefresh(sb.win);
+       wnoutrefresh(in.win);
+       wnoutrefresh(sep.win);
+       doupdate();
+}
+
 static void init_pair_or_die(short pair, short f, short b)
 {
        if (init_pair(pair, f, b) == ERR)
@@ -787,7 +809,6 @@ static void init_curses(void)
        init_colors_or_die();
        clear(); /* ignore non-fatal errors */
        init_wins(theme.top_lines_default);
-       print_all_items();
        // noecho(); /* don't echo input */
 }
 
@@ -1100,13 +1121,13 @@ static void print_scroll_msg(void)
 
 static void com_scroll_top(void)
 {
-       int i = RINGBUFFER_SIZE - 1;
+       int i = RINGBUFFER_SIZE - 1, bot_lines = get_num_lines(&bot);
        unsigned lines = 0;
 
        while (i > 0 && !ringbuffer_get(bot_win_rb, i))
                i--;
        /* i is oldest entry */
-       for (; lines < bot.lines && i >= 0; i--) {
+       for (; lines < bot_lines && i >= 0; i--) {
                struct rb_entry *rbe = ringbuffer_get(bot_win_rb, i);
                if (!rbe)
                        break;
@@ -1136,9 +1157,9 @@ static void com_cancel_scrolling(void)
 static void com_page_down(void)
 {
        unsigned lines = 0;
-       int i = scroll_position;
+       int i = scroll_position, bot_lines = get_num_lines(&bot);
 
-       while (lines < bot.lines && --i > 0) {
+       while (lines < bot_lines && --i > 0) {
                struct rb_entry *rbe = ringbuffer_get(bot_win_rb, i);
                if (!rbe)
                        break;
@@ -1156,7 +1177,7 @@ static void com_page_down(void)
 static void com_page_up(void)
 {
        unsigned lines;
-       int fvr = first_visible_rbe(&lines);
+       int fvr = first_visible_rbe(&lines), bot_lines = get_num_lines(&bot);
 
        if (fvr < 0 || fvr + 1 >= ringbuffer_filled(bot_win_rb)) {
                print_in_bar(COLOR_ERRMSG, "top of buffer is shown\n");
@@ -1165,7 +1186,7 @@ static void com_page_up(void)
        scroll_position = fvr + 1;
        for (; scroll_position > 0; scroll_position--) {
                first_visible_rbe(&lines);
-               if (lines == bot.lines)
+               if (lines == bot_lines)
                        break;
        }
        redraw_bot_win();
@@ -1175,7 +1196,7 @@ static void com_page_up(void)
 static void com_scroll_down(void)
 {
        struct rb_entry *rbe;
-       int rbe_lines;
+       int rbe_lines, bot_lines = get_num_lines(&bot);
 
        if (!scroll_position) {
                print_in_bar(COLOR_ERRMSG, "bottom of buffer is shown\n");
@@ -1185,7 +1206,7 @@ static void com_scroll_down(void)
        rbe = ringbuffer_get(bot_win_rb, scroll_position);
        rbe_lines = NUM_LINES(rbe->len);
        wscrl(bot.win, rbe_lines);
-       wmove(bot.win, bot.lines - rbe_lines, 0);
+       wmove(bot.win, bot_lines - rbe_lines, 0);
        wattron(bot.win, COLOR_PAIR(rbe->color));
        waddstr(bot.win, rbe->msg);
        wrefresh(bot.win);
@@ -1323,23 +1344,25 @@ static void com_help(void)
 
 static void com_shrink_top_win(void)
 {
-       if (top.lines <= theme.top_lines_min) {
+       int top_lines = get_num_lines(&top);
+
+       if (top_lines <= theme.top_lines_min) {
                PARA_WARNING_LOG("can not decrease top window\n");
                return;
        }
-       init_wins(top.lines - 1);
-       print_all_items();
+       init_wins(top_lines - 1);
        print_in_bar(COLOR_MSG, "%s", "decreased top window");
 }
 
 static void com_enlarge_top_win(void)
 {
-       if (bot.lines < 3) {
+       int top_lines = get_num_lines(&top), bot_lines = get_num_lines(&bot);
+
+       if (bot_lines < 3) {
                PARA_WARNING_LOG("can not increase top window\n");
                return;
        }
-       init_wins(top.lines + 1);
-       print_all_items();
+       init_wins(top_lines + 1);
        print_in_bar(COLOR_MSG, "increased top window");
 }