static struct gui_window {
WINDOW *win;
- size_t cols;
- size_t lines;
} top, bot, sb, in, sep;
#define RINGBUFFER_SIZE 512
int color;
};
static struct ringbuffer *bot_win_rb;
-#define NUM_LINES(len) (1 + (len) / bot.cols)
static unsigned scroll_position;
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)
{
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);
}
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);
}
*/
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);
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;
*/
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;
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;
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++;
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);
{
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;
+ 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, top.cols);
+ wresize(top.win, top_lines, COLS);
mvwin(top.win, top_y, 0);
- wresize(sb.win, sb.lines, sb.cols);
+ wresize(sb.win, sb_lines, COLS);
mvwin(sb.win, sb_y, 0);
- wresize(sep.win, sep.lines, sep.cols);
+ wresize(sep.win, sep_lines, COLS);
mvwin(sep.win, sep_y, 0);
- wresize(bot.win, bot.lines, bot.cols);
+ wresize(bot.win, bot_lines, COLS);
mvwin(bot.win, bot_y, 0);
- wresize(in.win, in.lines, in.cols);
+ wresize(in.win, in_lines, 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);
+ 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);
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;
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;
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");
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();
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");
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);
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);
+ 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);
+ init_wins(top_lines + 1);
print_in_bar(COLOR_MSG, "increased top window");
}