diff options
Diffstat (limited to 'src/screen.c')
-rw-r--r-- | src/screen.c | 1062 |
1 files changed, 0 insertions, 1062 deletions
diff --git a/src/screen.c b/src/screen.c deleted file mode 100644 index 4619f41..0000000 --- a/src/screen.c +++ /dev/null @@ -1,1062 +0,0 @@ -#include <stdlib.h> -#include <string.h> - -#include "runes.h" -#include "parser.h" - -static void runes_screen_ensure_capacity(RunesTerm *t, int size); -static struct runes_row *runes_screen_row_at(RunesTerm *t, int row); -static struct runes_cell *runes_screen_cell_at(RunesTerm *t, int row, int col); -static void runes_screen_scroll_down(RunesTerm *t, int count); -static void runes_screen_scroll_up(RunesTerm *t, int count); -static int runes_screen_scroll_region_is_active(RunesTerm *t); -static int runes_screen_loc_is_between( - RunesTerm *t, struct runes_loc loc, - struct runes_loc start, struct runes_loc end); -static int runes_screen_row_max_col(RunesTerm *t, int row); - -void runes_screen_init(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->grid = calloc(1, sizeof(struct runes_grid)); - runes_parser_yylex_init_extra(t, &scr->scanner); -} - -void runes_screen_set_window_size(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - struct runes_loc old_size; - int i; - - old_size.row = scr->grid->max.row; - old_size.col = scr->grid->max.col; - - scr->grid->max.row = t->display.ypixel / t->display.fonty; - scr->grid->max.col = t->display.xpixel / t->display.fontx; - - if (scr->grid->max.row == 0) { - scr->grid->max.row = 1; - } - if (scr->grid->max.col == 0) { - scr->grid->max.col = 1; - } - - if (scr->grid->max.row == old_size.row && scr->grid->max.col == old_size.col) { - return; - } - - if (scr->grid->cur.row >= scr->grid->max.row) { - scr->grid->cur.row = scr->grid->max.row - 1; - } - if (scr->grid->cur.col > scr->grid->max.col) { - scr->grid->cur.col = scr->grid->max.col; - } - - runes_screen_ensure_capacity(t, scr->grid->max.row); - - for (i = 0; i < scr->grid->row_count; ++i) { - scr->grid->rows[i].cells = realloc( - scr->grid->rows[i].cells, - scr->grid->max.col * sizeof(struct runes_cell)); - if (old_size.col < scr->grid->max.col) { - memset( - &scr->grid->rows[i].cells[old_size.col], 0, - (scr->grid->max.col - old_size.col) * sizeof(struct runes_cell)); - } - } - - for (i = scr->grid->row_count; i < scr->grid->max.row; ++i) { - scr->grid->rows[i].cells = calloc( - scr->grid->max.col, sizeof(struct runes_cell)); - } - - if (scr->grid->row_count < scr->grid->max.row) { - scr->grid->row_count = scr->grid->max.row; - scr->grid->row_top = 0; - } - else { - scr->grid->row_top = scr->grid->row_count - scr->grid->max.row; - } - - scr->grid->scroll_top = 0; - scr->grid->scroll_bottom = scr->grid->max.row - 1; -} - -void runes_screen_process_string(RunesTerm *t, char *buf, size_t len) -{ - RunesScreen *scr = &t->scr; - int remaining; - - scr->state = runes_parser_yy_scan_bytes(buf, len, scr->scanner); - remaining = runes_parser_yylex(scr->scanner); - t->pty.remaininglen = remaining; - if (t->pty.remaininglen) { - memmove( - t->pty.readbuf, &buf[len - t->pty.remaininglen], - t->pty.remaininglen); - } - runes_parser_yy_delete_buffer(scr->state, scr->scanner); -} - -int runes_screen_loc_is_selected(RunesTerm *t, struct runes_loc loc) -{ - RunesScreen *scr = &t->scr; - struct runes_loc start = scr->grid->selection_start; - struct runes_loc end = scr->grid->selection_end; - - if (!scr->has_selection) { - return 0; - } - - if (loc.row == start.row) { - int start_max_col; - - start_max_col = runes_screen_row_max_col(t, start.row); - if (start.col > start_max_col) { - start.col = scr->grid->max.col; - } - } - - if (loc.row == end.row) { - int end_max_col; - - end_max_col = runes_screen_row_max_col(t, end.row); - if (end.col > end_max_col) { - end.col = scr->grid->max.col; - } - } - - return runes_screen_loc_is_between(t, loc, start, end); -} - -void runes_screen_get_string( - RunesTerm *t, struct runes_loc *start, struct runes_loc *end, - char **strp, size_t *lenp) -{ - RunesScreen *scr = &t->scr; - int row, col; - size_t capacity = 8; - - *lenp = 0; - - if (end->row < start->row || (end->row == start->row && end->col <= start->col)) { - return; - } - - *strp = malloc(capacity); - - for (row = start->row; row <= end->row; ++row) { - int start_col, end_col, max_col; - struct runes_row *grid_row = &scr->grid->rows[row]; - - max_col = runes_screen_row_max_col(t, row); - - if (row == start->row) { - if (start->col > max_col) { - start_col = scr->grid->max.col; - } - else { - start_col = start->col; - } - } - else { - start_col = 0; - } - - if (row == end->row) { - if (end->col > max_col) { - end_col = scr->grid->max.col; - } - else { - end_col = end->col; - } - } - else { - end_col = scr->grid->max.col; - } - - if (end_col > max_col) { - end_col = max_col; - } - - for (col = start_col; col < end_col; ++col) { - struct runes_cell *cell = &grid_row->cells[col]; - char *contents = cell->contents; - size_t len = cell->len; - - if (cell->len == 0) { - contents = " "; - len = 1; - } - - if (*lenp + len > capacity) { - capacity *= 1.5; - *strp = realloc(*strp, capacity); - } - memcpy(*strp + *lenp, contents, len); - *lenp += len; - } - - if ((row != end->row || end->col > max_col) && !grid_row->wrapped) { - if (*lenp + 1 > capacity) { - capacity *= 1.5; - *strp = realloc(*strp, capacity); - } - memcpy(*strp + *lenp, "\n", 1); - *lenp += 1; - } - } -} - -void runes_screen_audible_bell(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->audible_bell = 1; -} - -void runes_screen_visual_bell(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->visual_bell = 1; -} - -void runes_screen_show_string_ascii(RunesTerm *t, char *buf, size_t len) -{ - RunesScreen *scr = &t->scr; - size_t i; - int col = scr->grid->cur.col; - - for (i = 0; i < len; ++i) { - struct runes_cell *cell; - - if (col >= scr->grid->max.col) { - runes_screen_row_at(t, scr->grid->cur.row)->wrapped = 1; - runes_screen_move_to(t, scr->grid->cur.row + 1, 0); - col = 0; - } - cell = runes_screen_cell_at(t, scr->grid->cur.row, col++); - - cell->len = 1; - cell->contents[0] = buf[i]; - cell->attrs = scr->attrs; - cell->is_wide = 0; - } - runes_screen_move_to(t, scr->grid->cur.row, col); - - scr->dirty = 1; -} - -void runes_screen_show_string_utf8(RunesTerm *t, char *buf, size_t len) -{ - RunesScreen *scr = &t->scr; - char *c = buf, *next; - int col = scr->grid->cur.col; - - /* XXX need to detect combining characters and append them to the previous - * cell */ - while ((next = g_utf8_next_char(c))) { - gunichar uc; - struct runes_cell *cell = NULL; - int is_wide, is_combining; - GUnicodeType ctype; - - uc = g_utf8_get_char(c); - /* XXX handle zero width characters */ - is_wide = g_unichar_iswide(uc); - ctype = g_unichar_type(uc); - /* XXX should this also include spacing marks? */ - is_combining = ctype == G_UNICODE_ENCLOSING_MARK - || ctype == G_UNICODE_NON_SPACING_MARK; - - if (is_combining) { - if (col > 0) { - cell = runes_screen_cell_at( - t, scr->grid->cur.row, col - 1); - } - else if (scr->grid->cur.row > 0 && runes_screen_row_at(t, scr->grid->cur.row - 1)->wrapped) { - cell = runes_screen_cell_at( - t, scr->grid->cur.row - 1, scr->grid->max.col - 1); - } - - if (cell) { - char *normal; - - memcpy(cell->contents + cell->len, c, next - c); - cell->len += next - c; - /* some fonts have combined characters but can't handle - * combining characters, so try to fix that here */ - /* XXX it'd be nice if there was a way to do this that didn't - * require an allocation */ - normal = g_utf8_normalize( - cell->contents, cell->len, G_NORMALIZE_NFC); - memcpy(cell->contents, normal, cell->len); - free(normal); - } - } - else { - if (col + (is_wide ? 2 : 1) > scr->grid->max.col) { - runes_screen_row_at(t, scr->grid->cur.row)->wrapped = 1; - runes_screen_move_to(t, scr->grid->cur.row + 1, 0); - col = 0; - } - cell = runes_screen_cell_at(t, scr->grid->cur.row, col); - cell->is_wide = is_wide; - - cell->len = next - c; - memcpy(cell->contents, c, cell->len); - cell->attrs = scr->attrs; - - col += is_wide ? 2 : 1; - } - - c = next; - if ((size_t)(c - buf) >= len) { - break; - } - } - runes_screen_move_to(t, scr->grid->cur.row, col); - - scr->dirty = 1; -} - -void runes_screen_move_to(RunesTerm *t, int row, int col) -{ - RunesScreen *scr = &t->scr; - int top = scr->grid->scroll_top, bottom = scr->grid->scroll_bottom; - - if (row > bottom) { - runes_screen_scroll_down(t, row - bottom); - row = bottom; - } - else if (row < top) { - runes_screen_scroll_up(t, top - row); - row = top; - } - - if (col < 0) { - col = 0; - } - - if (col > scr->grid->max.col) { - col = scr->grid->max.col; - } - - scr->grid->cur.row = row; - scr->grid->cur.col = col; -} - -void runes_screen_clear_screen(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - int r; - - for (r = 0; r < scr->grid->max.row; ++r) { - struct runes_row *row; - - row = runes_screen_row_at(t, r); - memset(row->cells, 0, scr->grid->max.col * sizeof(struct runes_cell)); - row->wrapped = 0; - } - - scr->dirty = 1; -} - -void runes_screen_clear_screen_forward(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - struct runes_row *row; - int r; - - row = runes_screen_row_at(t, scr->grid->cur.row); - memset( - &row->cells[scr->grid->cur.col], 0, - (scr->grid->max.col - scr->grid->cur.col) * sizeof(struct runes_cell)); - row->wrapped = 0; - for (r = scr->grid->cur.row + 1; r < scr->grid->max.row; ++r) { - row = runes_screen_row_at(t, r); - memset(row->cells, 0, scr->grid->max.col * sizeof(struct runes_cell)); - row->wrapped = 0; - } - - scr->dirty = 1; -} - -void runes_screen_clear_screen_backward(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - struct runes_row *row; - int r; - - for (r = 0; r < scr->grid->cur.row - 1; ++r) { - row = runes_screen_row_at(t, r); - memset(row->cells, 0, scr->grid->max.col * sizeof(struct runes_cell)); - row->wrapped = 0; - } - row = runes_screen_row_at(t, scr->grid->cur.row); - memset(row->cells, 0, scr->grid->cur.col * sizeof(struct runes_cell)); - - scr->dirty = 1; -} - -void runes_screen_kill_line(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - struct runes_row *row; - - row = runes_screen_row_at(t, scr->grid->cur.row); - memset(row->cells, 0, scr->grid->max.col * sizeof(struct runes_cell)); - row->wrapped = 0; - - scr->dirty = 1; -} - -void runes_screen_kill_line_forward(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - struct runes_row *row; - - row = runes_screen_row_at(t, scr->grid->cur.row); - memset( - &row->cells[scr->grid->cur.col], 0, - (scr->grid->max.col - scr->grid->cur.col) * sizeof(struct runes_cell)); - row->wrapped = 0; - - scr->dirty = 1; -} - -void runes_screen_kill_line_backward(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - struct runes_row *row; - - row = runes_screen_row_at(t, scr->grid->cur.row); - memset(row->cells, 0, scr->grid->cur.col * sizeof(struct runes_cell)); - if (scr->grid->cur.row > 0) { - row = runes_screen_row_at(t, scr->grid->cur.row - 1); - row->wrapped = 0; - } - - scr->dirty = 1; -} - -void runes_screen_insert_characters(RunesTerm *t, int count) -{ - RunesScreen *scr = &t->scr; - struct runes_row *row; - - row = runes_screen_row_at(t, scr->grid->cur.row); - if (count >= scr->grid->max.col - scr->grid->cur.col) { - runes_screen_kill_line_forward(t); - } - else { - memmove( - &row->cells[scr->grid->cur.col + count], - &row->cells[scr->grid->cur.col], - (scr->grid->max.col - scr->grid->cur.col - count) * sizeof(struct runes_cell)); - memset( - &row->cells[scr->grid->cur.col], 0, - count * sizeof(struct runes_cell)); - row->wrapped = 0; - } - - scr->dirty = 1; -} - -void runes_screen_insert_lines(RunesTerm *t, int count) -{ - RunesScreen *scr = &t->scr; - - if (count >= scr->grid->max.row - scr->grid->cur.row) { - runes_screen_clear_screen_forward(t); - runes_screen_kill_line(t); - } - else { - struct runes_row *row; - int bottom = scr->grid->scroll_bottom + 1; - int i; - - for (i = bottom - count; i < bottom; ++i) { - row = runes_screen_row_at(t, i); - free(row->cells); - } - row = runes_screen_row_at(t, scr->grid->cur.row); - memmove( - row + count, row, - (bottom - scr->grid->cur.row - count) * sizeof(struct runes_row)); - memset(row, 0, count * sizeof(struct runes_row)); - for (i = scr->grid->cur.row; i < scr->grid->cur.row + count; ++i) { - row = runes_screen_row_at(t, i); - row->cells = calloc(scr->grid->max.col, sizeof(struct runes_cell)); - row->wrapped = 0; - } - } - - scr->dirty = 1; -} - -void runes_screen_delete_characters(RunesTerm *t, int count) -{ - RunesScreen *scr = &t->scr; - - if (count >= scr->grid->max.col - scr->grid->cur.col) { - runes_screen_kill_line_forward(t); - } - else { - struct runes_row *row; - - row = runes_screen_row_at(t, scr->grid->cur.row); - memmove( - &row->cells[scr->grid->cur.col], - &row->cells[scr->grid->cur.col + count], - (scr->grid->max.col - scr->grid->cur.col - count) * sizeof(struct runes_cell)); - memset( - &row->cells[scr->grid->max.col - count], 0, - count * sizeof(struct runes_cell)); - row->wrapped = 0; - } - - scr->dirty = 1; -} - -void runes_screen_delete_lines(RunesTerm *t, int count) -{ - RunesScreen *scr = &t->scr; - - if (count >= scr->grid->max.row - scr->grid->cur.row) { - runes_screen_clear_screen_forward(t); - runes_screen_kill_line(t); - } - else { - struct runes_row *row; - int bottom = scr->grid->scroll_bottom + 1; - int i; - - for (i = scr->grid->cur.row; i < scr->grid->cur.row + count; ++i) { - row = runes_screen_row_at(t, i); - free(row->cells); - } - row = runes_screen_row_at(t, scr->grid->cur.row); - memmove( - row, row + count, - (bottom - scr->grid->cur.row - count) * sizeof(struct runes_row)); - row = runes_screen_row_at(t, bottom - count); - memset(row, 0, count * sizeof(struct runes_row)); - for (i = bottom - count; i < bottom; ++i) { - row = runes_screen_row_at(t, i); - row->cells = calloc(scr->grid->max.col, sizeof(struct runes_cell)); - row->wrapped = 0; - } - } - - scr->dirty = 1; -} - -void runes_screen_set_scroll_region( - RunesTerm *t, int top, int bottom, int left, int right) -{ - RunesScreen *scr = &t->scr; - - if (left > 0 || right < scr->grid->max.col - 1) { - runes_warn("vertical scroll regions not yet implemented\n"); - } - - if (top > bottom) { - return; - } - - scr->grid->scroll_top = top < 0 - ? 0 - : top; - scr->grid->scroll_bottom = bottom >= scr->grid->max.row - ? scr->grid->max.row - 1 - : bottom; - - runes_screen_move_to(t, scr->grid->scroll_top, 0); -} - -void runes_screen_reset_text_attributes(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - memset(&scr->attrs, 0, sizeof(struct runes_cell_attrs)); -} - -void runes_screen_set_fg_color(RunesTerm *t, int idx) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.fgcolor.type = RUNES_COLOR_IDX; - scr->attrs.fgcolor.idx = idx; -} - -void runes_screen_set_fg_color_rgb( - RunesTerm *t, unsigned char r, unsigned char g, unsigned char b) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.fgcolor.type = RUNES_COLOR_RGB; - scr->attrs.fgcolor.r = r; - scr->attrs.fgcolor.g = g; - scr->attrs.fgcolor.b = b; -} - -void runes_screen_reset_fg_color(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.fgcolor.type = RUNES_COLOR_DEFAULT; -} - -void runes_screen_set_bg_color(RunesTerm *t, int idx) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.bgcolor.type = RUNES_COLOR_IDX; - scr->attrs.bgcolor.idx = idx; -} - -void runes_screen_set_bg_color_rgb( - RunesTerm *t, unsigned char r, unsigned char g, unsigned char b) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.bgcolor.type = RUNES_COLOR_RGB; - scr->attrs.bgcolor.r = r; - scr->attrs.bgcolor.g = g; - scr->attrs.bgcolor.b = b; -} - -void runes_screen_reset_bg_color(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.bgcolor.type = RUNES_COLOR_DEFAULT; -} - -void runes_screen_set_bold(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.bold = 1; -} - -void runes_screen_set_italic(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.italic = 1; -} - -void runes_screen_set_underline(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.underline = 1; -} - -void runes_screen_set_inverse(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.inverse = 1; -} - -void runes_screen_reset_bold(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.bold = 0; -} - -void runes_screen_reset_italic(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.italic = 0; -} - -void runes_screen_reset_underline(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.underline = 0; -} - -void runes_screen_reset_inverse(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->attrs.inverse = 0; -} - -void runes_screen_use_alternate_buffer(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - if (scr->alternate) { - return; - } - - scr->alternate = scr->grid; - scr->grid = calloc(1, sizeof(struct runes_grid)); - runes_screen_set_window_size(t); - - scr->dirty = 1; -} - -void runes_screen_use_normal_buffer(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - int i; - - if (!scr->alternate) { - return; - } - - for (i = 0; i < scr->grid->row_count; ++i) { - free(scr->grid->rows[i].cells); - } - free(scr->grid->rows); - free(scr->grid); - - scr->grid = scr->alternate; - scr->alternate = NULL; - - runes_screen_set_window_size(t); - - scr->dirty = 1; -} - -void runes_screen_save_cursor(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->grid->saved = scr->grid->cur; -} - -void runes_screen_restore_cursor(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->grid->cur = scr->grid->saved; -} - -void runes_screen_show_cursor(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->hide_cursor = 0; -} - -void runes_screen_hide_cursor(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->hide_cursor = 1; -} - -void runes_screen_set_application_keypad(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->application_keypad = 1; -} - -void runes_screen_reset_application_keypad(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->application_keypad = 0; -} - -void runes_screen_set_application_cursor(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->application_cursor = 1; -} - -void runes_screen_reset_application_cursor(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->application_cursor = 0; -} - -void runes_screen_set_mouse_reporting_press(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->mouse_reporting_press = 1; -} - -void runes_screen_reset_mouse_reporting_press(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->mouse_reporting_press = 0; -} - -void runes_screen_set_mouse_reporting_press_release(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->mouse_reporting_press_release = 1; -} - -void runes_screen_reset_mouse_reporting_press_release(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->mouse_reporting_press_release = 0; -} - -void runes_screen_set_bracketed_paste(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->bracketed_paste = 1; -} - -void runes_screen_reset_bracketed_paste(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - scr->bracketed_paste = 0; -} - -void runes_screen_set_window_title(RunesTerm *t, char *buf, size_t len) -{ - RunesScreen *scr = &t->scr; - - free(scr->title); - scr->title_len = len; - scr->title = malloc(scr->title_len); - memcpy(scr->title, buf, scr->title_len); - scr->update_title = 1; -} - -void runes_screen_set_icon_name(RunesTerm *t, char *buf, size_t len) -{ - RunesScreen *scr = &t->scr; - - free(scr->icon_name); - scr->icon_name_len = len; - scr->icon_name = malloc(scr->icon_name_len); - memcpy(scr->icon_name, buf, scr->icon_name_len); - scr->update_icon_name = 1; -} - -void runes_screen_cleanup(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - int i; - - for (i = 0; i < scr->grid->row_count; ++i) { - free(scr->grid->rows[i].cells); - } - free(scr->grid->rows); - free(scr->grid); - - free(scr->title); - free(scr->icon_name); - - runes_parser_yylex_destroy(scr->scanner); -} - -static void runes_screen_ensure_capacity(RunesTerm *t, int size) -{ - RunesScreen *scr = &t->scr; - int old_capacity = scr->grid->row_capacity; - - if (scr->grid->row_capacity >= size) { - return; - } - - if (scr->grid->row_capacity == 0) { - scr->grid->row_capacity = scr->grid->max.row; - } - - while (scr->grid->row_capacity < size) { - scr->grid->row_capacity *= 1.5; - } - - scr->grid->rows = realloc( - scr->grid->rows, scr->grid->row_capacity * sizeof(struct runes_row)); - memset( - &scr->grid->rows[old_capacity], 0, - (scr->grid->row_capacity - old_capacity) * sizeof(struct runes_row)); -} - -static struct runes_row *runes_screen_row_at(RunesTerm *t, int row) -{ - RunesScreen *scr = &t->scr; - - return &scr->grid->rows[row + scr->grid->row_top]; -} - -static struct runes_cell *runes_screen_cell_at(RunesTerm *t, int row, int col) -{ - RunesScreen *scr = &t->scr; - - return &scr->grid->rows[row + scr->grid->row_top].cells[col]; -} - -static void runes_screen_scroll_down(RunesTerm *t, int count) -{ - RunesScreen *scr = &t->scr; - struct runes_row *row; - int i; - - if (runes_screen_scroll_region_is_active(t) || scr->alternate) { - int bottom = scr->grid->scroll_bottom, top = scr->grid->scroll_top; - - if (bottom - top + 1 > count) { - for (i = 0; i < count; ++i) { - row = runes_screen_row_at(t, top + i); - free(row->cells); - } - row = runes_screen_row_at(t, top); - memmove( - row, row + count, - (bottom - top + 1 - count) * sizeof(struct runes_row)); - for (i = 0; i < count; ++i) { - row = runes_screen_row_at(t, bottom - i); - row->cells = calloc( - scr->grid->max.col, sizeof(struct runes_cell)); - row->wrapped = 0; - } - } - else { - for (i = 0; i < bottom - top + 1; ++i) { - row = runes_screen_row_at(t, top + i); - memset( - row->cells, 0, - scr->grid->max.col * sizeof(struct runes_cell)); - row->wrapped = 0; - } - } - } - else { - int scrollback = t->config.scrollback_length; - - if (scr->grid->row_count + count > scrollback) { - int overflow = scr->grid->row_count + count - scrollback; - - runes_screen_ensure_capacity(t, scrollback); - for (i = 0; i < overflow; ++i) { - free(scr->grid->rows[i].cells); - } - memmove( - &scr->grid->rows[0], &scr->grid->rows[overflow], - (scrollback - overflow) * sizeof(struct runes_row)); - for (i = scrollback - count; i < scrollback; ++i) { - scr->grid->rows[i].cells = calloc( - scr->grid->max.col, sizeof(struct runes_cell)); - } - scr->grid->row_count = scrollback; - scr->grid->row_top = scrollback - scr->grid->max.row; - } - else { - runes_screen_ensure_capacity(t, scr->grid->row_count + count); - for (i = 0; i < count; ++i) { - row = runes_screen_row_at(t, i + scr->grid->max.row); - row->cells = calloc( - scr->grid->max.col, sizeof(struct runes_cell)); - } - scr->grid->row_count += count; - scr->grid->row_top += count; - } - } - - scr->dirty = 1; -} - -static void runes_screen_scroll_up(RunesTerm *t, int count) -{ - RunesScreen *scr = &t->scr; - struct runes_row *row; - int bottom = scr->grid->scroll_bottom, top = scr->grid->scroll_top; - int i; - - if (bottom - top + 1 > count) { - for (i = 0; i < count; ++i) { - row = runes_screen_row_at(t, bottom - i); - free(row->cells); - } - row = runes_screen_row_at(t, top); - memmove( - row + count, row, - (bottom - top + 1 - count) * sizeof(struct runes_row)); - for (i = 0; i < count; ++i) { - row = runes_screen_row_at(t, top + i); - row->cells = calloc(scr->grid->max.col, sizeof(struct runes_cell)); - row->wrapped = 0; - } - } - else { - for (i = 0; i < bottom - top + 1; ++i) { - row = runes_screen_row_at(t, top + i); - memset( - row->cells, 0, scr->grid->max.col * sizeof(struct runes_cell)); - row->wrapped = 0; - } - } - - scr->dirty = 1; -} - -static int runes_screen_scroll_region_is_active(RunesTerm *t) -{ - RunesScreen *scr = &t->scr; - - return scr->grid->scroll_top != 0 - || scr->grid->scroll_bottom != scr->grid->max.row - 1; -} - -static int runes_screen_loc_is_between( - RunesTerm *t, struct runes_loc loc, - struct runes_loc start, struct runes_loc end) -{ - UNUSED(t); - - if (end.row < start.row || (end.row == start.row && end.col < start.col)) { - struct runes_loc tmp; - - tmp = start; - start = end; - end = tmp; - } - - if (loc.row < start.row || loc.row > end.row) { - return 0; - } - - if (loc.row == start.row && loc.col < start.col) { - return 0; - } - - if (loc.row == end.row && loc.col >= end.col) { - return 0; - } - - return 1; -} - -static int runes_screen_row_max_col(RunesTerm *t, int row) -{ - RunesScreen *scr = &t->scr; - struct runes_cell *cells = scr->grid->rows[row].cells; - int i, max = -1; - - for (i = 0; i < scr->grid->max.col; ++i) { - if (cells[i].len) { - max = i; - } - } - - return max + 1; -} |