From 4706da9316fd721f4ca1971dcfb4efa1cea2683f Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 1 Mar 2016 16:09:55 +0100 Subject: [PATCH] Make the windowing system width aware --- src/fe-text/mainwindows.c | 7 ++- src/fe-text/mainwindows.h | 1 + src/fe-text/statusbar-items.c | 16 +++-- src/fe-text/term-terminfo.c | 53 ++++++++-------- src/fe-text/term.h | 2 +- src/fe-text/terminfo-core.c | 110 ---------------------------------- src/fe-text/terminfo-core.h | 3 +- src/fe-text/textbuffer-view.c | 27 +++------ 8 files changed, 54 insertions(+), 165 deletions(-) diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index 5f58c25f..bc1fad71 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -39,13 +39,14 @@ int screen_reserved_top, screen_reserved_bottom; static int old_screen_width, old_screen_height; #define mainwindow_create_screen(window) \ - term_window_create(0, \ + term_window_create((window)->first_column, \ (window)->first_line + (window)->statusbar_lines_top, \ (window)->width, \ (window)->height - (window)->statusbar_lines) #define mainwindow_set_screen_size(window) \ - term_window_move((window)->screen_win, 0, \ + term_window_move((window)->screen_win, \ + (window)->first_column, \ (window)->first_line + (window)->statusbar_lines_top, \ (window)->width, \ (window)->height - (window)->statusbar_lines); @@ -186,6 +187,8 @@ MAIN_WINDOW_REC *mainwindow_create(void) rec = g_new0(MAIN_WINDOW_REC, 1); rec->dirty = TRUE; rec->width = term_width; + rec->first_column = 0; + rec->last_column = rec->first_column + rec->width; if (mainwindows == NULL) { active_mainwin = rec; diff --git a/src/fe-text/mainwindows.h b/src/fe-text/mainwindows.h index 1bca333d..9d07063f 100644 --- a/src/fe-text/mainwindows.h +++ b/src/fe-text/mainwindows.h @@ -16,6 +16,7 @@ typedef struct { int sticky_windows; /* number of sticky windows */ int first_line, last_line; /* first/last line used by this window (0..x) (includes statusbars) */ + int first_column, last_column; int width, height; /* width/height of the window (includes statusbars) */ GSList *statusbars; diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index e3e0c2a6..fb6da8b8 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -404,13 +404,21 @@ static void item_input(SBAR_ITEM_REC *item, int get_size_only) } if (get_size_only) { - item->min_size = 2+term_width/10; - item->max_size = term_width; + WINDOW_REC *window; + + window = active_win; + if (item->bar->parent_window != NULL) + window = item->bar->parent_window->active; + + const int max_width = (window != NULL) ? window->width : term_width; + + item->min_size = 2 + max_width / 10; + item->max_size = max_width; + return; } - gui_entry_move(rec, item->xpos, item->bar->real_ypos, - item->size); + gui_entry_move(rec, item->xpos, item->bar->real_ypos, item->size); gui_entry_redraw(rec); /* FIXME: this is only necessary with ^L.. */ } diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 3582b9e4..e39468af 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -274,27 +274,26 @@ void term_window_clear(TERM_WINDOW *window) int y; terminfo_set_normal(); - if (window->y == 0 && window->height == term_height) { + + /* Clear the whole terminal if there's an only window */ + if (window->x == 0 && window->width == term_width && + window->y == 0 && window->height == term_height) { term_clear(); - } else { - for (y = 0; y < window->height; y++) { - term_move(window, 0, y); - term_clrtoeol(window); - } + return; + } + + for (y = 0; y < window->height; y++) { + term_move(window, window->x, y); + term_clrtoeol(window); } } -/* Scroll window up/down */ -void term_window_scroll(TERM_WINDOW *window, int count) +void term_get_window_size(TERM_WINDOW *window, int *width, int *height) { - int y; - - terminfo_scroll(window->y, window->y+window->height-1, count); - term_move_reset(vcx, vcy); - - /* set the newly scrolled area dirty */ - for (y = 0; (window->y+y) < term_height && y < window->height; y++) - term_lines_empty[window->y+y] = FALSE; + if (width != NULL) + *width = window->width; + if (height != NULL) + *height = window->height; } inline static int term_putchar(int c) @@ -441,14 +440,14 @@ void term_set_color(TERM_WINDOW *window, int col) void term_move(TERM_WINDOW *window, int x, int y) { if (x >= 0 && y >= 0) { - vcmove = TRUE; - vcx = x+window->x; - vcy = y+window->y; + vcmove = TRUE; + vcx = x + window->x; + vcy = y + window->y; - if (vcx >= term_width) - vcx = term_width-1; - if (vcy >= term_height) - vcy = term_height-1; + if (vcx >= term_width) + vcx = term_width-1; + if (vcy >= term_height) + vcy = term_height-1; } } @@ -558,16 +557,18 @@ void term_clrtoeol(TERM_WINDOW *window) { /* clrtoeol() doesn't necessarily understand colors */ if (last_fg == -1 && last_bg == -1 && - (last_attrs & (ATTR_UNDERLINE|ATTR_REVERSE|ATTR_ITALIC)) == 0) { + (last_attrs & (ATTR_UNDERLINE|ATTR_REVERSE|ATTR_ITALIC)) == 0 && + window->width == term_width) + { if (!term_lines_empty[vcy]) { if (vcmove) term_move_real(); terminfo_clrtoeol(); if (vcx == 0) term_lines_empty[vcy] = TRUE; } - } else if (vcx < term_width) { + } else if (vcx < window->width) { /* we'll need to fill the line ourself. */ if (vcmove) term_move_real(); - terminfo_repeat(' ', term_width-vcx); + terminfo_repeat(' ', window->width - vcx); terminfo_move(vcx, vcy); term_lines_empty[vcy] = FALSE; } diff --git a/src/fe-text/term.h b/src/fe-text/term.h index 5f0a799e..c51bd59a 100644 --- a/src/fe-text/term.h +++ b/src/fe-text/term.h @@ -70,7 +70,6 @@ void term_window_move(TERM_WINDOW *window, int x, int y, /* Clear window */ void term_window_clear(TERM_WINDOW *window); /* Scroll window up/down */ -void term_window_scroll(TERM_WINDOW *window, int count); #ifdef TERM_TRUECOLOR #define term_set_color(window, col) term_set_color2(window, (col) &~(ATTR_FGCOLOR24|ATTR_BGCOLOR24), UINT_MAX, UINT_MAX) @@ -87,6 +86,7 @@ int term_addstr(TERM_WINDOW *window, const char *str); void term_clrtoeol(TERM_WINDOW *window); void term_move_cursor(int x, int y); +void term_get_window_size(TERM_WINDOW *window, int *width, int *height); void term_refresh_freeze(void); void term_refresh_thaw(void); diff --git a/src/fe-text/terminfo-core.c b/src/fe-text/terminfo-core.c index 60927f1a..5d428f7f 100644 --- a/src/fe-text/terminfo-core.c +++ b/src/fe-text/terminfo-core.c @@ -66,14 +66,11 @@ static TERMINFO_REC tcaps[] = { { "cnorm", "ve", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_cnorm) }, /* Scrolling */ - { "csr", "cs", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_csr) }, { "wind", "wi", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_wind) }, { "ri", "sr", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_ri) }, { "rin", "SR", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_rin) }, { "ind", "sf", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_ind) }, { "indn", "SF", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_indn) }, - { "il", "AL", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_il) }, - { "il1", "al", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_il1) }, { "dl", "DL", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_dl) }, { "dl1", "dl", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_dl1) }, @@ -165,99 +162,6 @@ static void _set_cursor_visible(TERM_REC *term, int set) tput(tparm(set ? term->TI_cnorm : term->TI_civis)); } -#define scroll_region_setup(term, y1, y2) \ - if ((term)->TI_csr != NULL) \ - tput(tparm((term)->TI_csr, y1, y2)); \ - else if ((term)->TI_wind != NULL) \ - tput(tparm((term)->TI_wind, y1, y2, 0, (term)->width-1)); - -/* Scroll (change_scroll_region+parm_rindex+parm_index / csr+rin+indn) */ -static void _scroll_region(TERM_REC *term, int y1, int y2, int count) -{ - /* setup the scrolling region to wanted area */ - scroll_region_setup(term, y1, y2); - - term->move(term, 0, y1); - if (count > 0) { - term->move(term, 0, y2); - tput(tparm(term->TI_indn, count, count)); - } else if (count < 0) { - term->move(term, 0, y1); - tput(tparm(term->TI_rin, -count, -count)); - } - - /* reset the scrolling region to full screen */ - scroll_region_setup(term, 0, term->height-1); -} - -/* Scroll (change_scroll_region+scroll_reverse+scroll_forward / csr+ri+ind) */ -static void _scroll_region_1(TERM_REC *term, int y1, int y2, int count) -{ - int i; - - /* setup the scrolling region to wanted area */ - scroll_region_setup(term, y1, y2); - - if (count > 0) { - term->move(term, 0, y2); - for (i = 0; i < count; i++) - tput(tparm(term->TI_ind)); - } else if (count < 0) { - term->move(term, 0, y1); - for (i = count; i < 0; i++) - tput(tparm(term->TI_ri)); - } - - /* reset the scrolling region to full screen */ - scroll_region_setup(term, 0, term->height-1); -} - -/* Scroll (parm_insert_line+parm_delete_line / il+dl) */ -static void _scroll_line(TERM_REC *term, int y1, int y2, int count) -{ - /* setup the scrolling region to wanted area - - this might not necessarily work with il/dl, but at least it - looks better if it does */ - scroll_region_setup(term, y1, y2); - - if (count > 0) { - term->move(term, 0, y1); - tput(tparm(term->TI_dl, count, count)); - term->move(term, 0, y2-count+1); - tput(tparm(term->TI_il, count, count)); - } else if (count < 0) { - term->move(term, 0, y2+count+1); - tput(tparm(term->TI_dl, -count, -count)); - term->move(term, 0, y1); - tput(tparm(term->TI_il, -count, -count)); - } - - /* reset the scrolling region to full screen */ - scroll_region_setup(term, 0, term->height-1); -} - -/* Scroll (insert_line+delete_line / il1+dl1) */ -static void _scroll_line_1(TERM_REC *term, int y1, int y2, int count) -{ - int i; - - if (count > 0) { - term->move(term, 0, y1); - for (i = 0; i < count; i++) - tput(tparm(term->TI_dl1)); - term->move(term, 0, y2-count+1); - for (i = 0; i < count; i++) - tput(tparm(term->TI_il1)); - } else if (count < 0) { - term->move(term, 0, y2+count+1); - for (i = count; i < 0; i++) - tput(tparm(term->TI_dl1)); - term->move(term, 0, y1); - for (i = count; i < 0; i++) - tput(tparm(term->TI_il1)); - } -} - /* Clear screen (clear_screen / clear) */ static void _clear_screen(TERM_REC *term) { @@ -599,20 +503,6 @@ static int term_setup(TERM_REC *term) term->set_cursor_visible = term->TI_civis && term->TI_cnorm ? _set_cursor_visible : _ignore_parm; - /* Scrolling */ - if ((term->TI_csr || term->TI_wind) && term->TI_rin && term->TI_indn) - term->scroll = _scroll_region; - else if (term->TI_il && term->TI_dl) - term->scroll = _scroll_line; - else if ((term->TI_csr || term->TI_wind) && term->TI_ri && term->TI_ind) - term->scroll = _scroll_region_1; - else if (term->scroll == NULL && (term->TI_il1 && term->TI_dl1)) - term->scroll = _scroll_line_1; - else if (term->scroll == NULL) { - fprintf(stderr, "Terminal doesn't support scrolling\n"); - return 0; - } - /* Clearing screen */ if (term->TI_clear) term->clear = _clear_screen; diff --git a/src/fe-text/terminfo-core.h b/src/fe-text/terminfo-core.h index 21398791..4f99a2e3 100644 --- a/src/fe-text/terminfo-core.h +++ b/src/fe-text/terminfo-core.h @@ -6,7 +6,6 @@ #define terminfo_move(x, y) current_term->move(current_term, x, y) #define terminfo_move_relative(oldx, oldy, x, y) current_term->move_relative(current_term, oldx, oldy, x, y) #define terminfo_set_cursor_visible(set) current_term->set_cursor_visible(current_term, set) -#define terminfo_scroll(y1, y2, count) current_term->scroll(current_term, y1, y2, count) #define terminfo_clear() current_term->clear(current_term) #define terminfo_clrtoeol() current_term->clrtoeol(current_term) #define terminfo_repeat(chr, count) current_term->repeat(current_term, chr, count) @@ -28,7 +27,7 @@ struct _TERM_REC { void (*move)(TERM_REC *term, int x, int y); void (*move_relative)(TERM_REC *term, int oldx, int oldy, int x, int y); void (*set_cursor_visible)(TERM_REC *term, int set); - void (*scroll)(TERM_REC *term, int y1, int y2, int count); + void (*scroll)(TERM_REC *term, int x1, int y1, int x2, int y2, int count); void (*clear)(TERM_REC *term); void (*clrtoeol)(TERM_REC *term); diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index e2e3707b..09299d74 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -396,6 +396,7 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, #ifdef TERM_TRUECOLOR unsigned int fg24, bg24; #endif + int window_width; if (view->dirty) /* don't bother drawing anything - redraw is coming */ return 0; @@ -404,6 +405,8 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, if (subline >= cache->count) return 0; + term_get_window_size(view->window, &window_width, NULL); + color = ATTR_RESET; need_move = TRUE; need_clrtoeol = FALSE; xpos = drawcount = 0; first = TRUE; @@ -411,7 +414,7 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, subline == 0 ? line->text : cache->lines[subline-1].start; for (;;) { if (text == text_newline) { - if (need_clrtoeol && xpos < term_width) { + if (need_clrtoeol && xpos < window_width) { term_set_color(view->window, ATTR_RESET); term_clrtoeol(view->window); } @@ -510,7 +513,7 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, } xpos += char_width; - if (xpos <= term_width) { + if (xpos <= window_width) { if (unichar_isprint(chr)) { if (view->utf8) term_add_unichar(view->window, chr); @@ -527,7 +530,7 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, text = end; } - if (need_clrtoeol && xpos < term_width) { + if (need_clrtoeol && xpos < window_width) { term_set_color(view->window, ATTR_RESET); term_clrtoeol(view->window); } @@ -813,23 +816,7 @@ static int view_scroll(TEXT_BUFFER_VIEW_REC *view, LINE_REC **lines, } if (scroll_visible && realcount != 0 && view->window != NULL) { - if (realcount <= -view->height || realcount >= view->height) { - /* scrolled more than screenful, redraw the - whole view */ - textbuffer_view_redraw(view); - } else { - term_set_color(view->window, ATTR_RESET); - term_window_scroll(view->window, realcount); - - if (draw_nonclean) { - if (realcount < 0) - view_draw_top(view, -realcount, TRUE); - else - view_draw_bottom(view, realcount); - } - - term_refresh(view->window); - } + textbuffer_view_redraw(view); } return realcount >= 0 ? realcount : -realcount;