From f72add79bdc4b72a54fb72e512d3a15263e7484c Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Fri, 25 Apr 2014 00:04:06 -0400 Subject: start refactoring to draw parsed text to an intermediary data structure --- Makefile | 6 + src/display.c | 581 +++++++----------------------------------------------- src/display.h | 37 +--- src/parser.c | 184 ++++++++--------- src/parser.h | 338 ++++++++++++++++++++++++++++++- src/parser.l | 181 ++++++++--------- src/pty-unix.c | 6 +- src/runes.h | 4 +- src/screen.c | 369 ++++++++++++++++++++++++++++++++++ src/screen.h | 128 ++++++++++++ src/term.c | 1 + src/term.h | 48 ++--- src/window-xlib.c | 19 +- 13 files changed, 1102 insertions(+), 800 deletions(-) create mode 100644 src/screen.c create mode 100644 src/screen.h diff --git a/Makefile b/Makefile index 866ed58..5b3933e 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ OBJ = $(BUILD)runes.o \ $(BUILD)display.o \ $(BUILD)term.o \ $(BUILD)parser.o \ + $(BUILD)screen.o \ $(BUILD)config.o \ $(BUILD)window-xlib.o \ $(BUILD)pty-unix.o @@ -27,9 +28,14 @@ $(BUILD)%.o: $(SRC)%.c @$(MAKEDEPEND) -o $(<:$(SRC)%.c=$(BUILD).%.d) $< $(CC) $(ALLCFLAGS) -c -o $@ $< +$(SRC)screen.c: $(SRC)parser.h + $(SRC)%.c: $(SRC)%.l $(LEX) -o $@ $< +$(SRC)%.h: $(SRC)%.l + $(LEX) --header-file=$(<:.l=.h) -o /dev/null $< + clean: rm -f $(OUT) $(OBJ) $(OBJ:$(BUILD)%.o=$(BUILD).%.d) @rmdir -p $(BUILD) > /dev/null 2>&1 diff --git a/src/display.c b/src/display.c index dc2b00f..b0d380a 100644 --- a/src/display.c +++ b/src/display.c @@ -3,24 +3,20 @@ #include "runes.h" -static cairo_pattern_t *runes_display_get_fgcolor(RunesTerm *t); -static cairo_pattern_t *runes_display_get_bgcolor(RunesTerm *t); static void runes_display_recalculate_font_metrics(RunesTerm *t); -static void runes_display_position_cursor(RunesTerm *t, cairo_t *cr); +static void runes_display_draw_cell(RunesTerm *t, int row, int col); static void runes_display_paint_rectangle( RunesTerm *t, cairo_t *cr, cairo_pattern_t *pattern, - int x, int y, int width, int height); -static void runes_display_scroll_up(RunesTerm *t, int rows); -static void runes_display_scroll_down(RunesTerm *t, int rows); + int row, int col, int width, int height); +static void runes_display_draw_glyph( + RunesTerm *t, cairo_t *cr, cairo_pattern_t *pattern, char *buf, size_t len, + int row, int col); void runes_display_init(RunesTerm *t) { runes_display_recalculate_font_metrics(t); t->cursorcolor = cairo_pattern_create_rgba(0.0, 1.0, 0.0, 0.5); - - t->fgcolor = -1; - t->bgcolor = -1; } void runes_display_set_window_size(RunesTerm *t) @@ -38,11 +34,11 @@ void runes_display_set_window_size(RunesTerm *t) t->xpixel = width; t->ypixel = height; - t->rows = t->ypixel / t->fonty; - t->cols = t->xpixel / t->fontx; + t->scr.max.row = t->ypixel / t->fonty; + t->scr.max.col = t->xpixel / t->fontx; - t->scroll_top = 0; - t->scroll_bottom = t->rows - 1; + t->scr.scroll_top = 0; + t->scr.scroll_bottom = t->scr.max.row - 1; old_cr = t->cr; @@ -55,7 +51,6 @@ void runes_display_set_window_size(RunesTerm *t) CAIRO_FORMAT_RGB24, t->xpixel, t->ypixel); t->cr = cairo_create(surface); cairo_surface_destroy(surface); - cairo_set_source(t->cr, runes_display_get_fgcolor(t)); if (t->layout) { pango_cairo_update_layout(t->cr, t->layout); } @@ -92,428 +87,19 @@ void runes_display_set_window_size(RunesTerm *t) } runes_pty_backend_set_window_size(t); - runes_display_position_cursor(t, t->cr); -} - -void runes_display_focus_in(RunesTerm *t) -{ - t->unfocused = 0; -} - -void runes_display_focus_out(RunesTerm *t) -{ - t->unfocused = 1; -} - -void runes_display_move_to(RunesTerm *t, int row, int col) -{ - t->row = row; - t->col = col; - - if (row > t->scroll_bottom) { - runes_display_scroll_down(t, row - t->scroll_bottom); - t->row = t->scroll_bottom; - } - else if (row < t->scroll_top) { - runes_display_scroll_up(t, t->scroll_top - row); - t->row = t->scroll_top; - } - - runes_display_position_cursor(t, t->cr); } -void runes_display_show_string_ascii(RunesTerm *t, char *buf, size_t len) +void runes_display_draw_screen(RunesTerm *t) { - if (len) { - int remaining = len, space_in_row = t->cols - t->col; - - do { - int to_write = remaining > space_in_row ? space_in_row : remaining; - - runes_display_paint_rectangle( - t, t->cr, runes_display_get_bgcolor(t), - t->col, t->row, to_write, 1); - - pango_layout_set_text(t->layout, buf, to_write); - pango_cairo_update_layout(t->cr, t->layout); - pango_cairo_show_layout(t->cr, t->layout); - - buf += to_write; - remaining -= to_write; - space_in_row = t->cols; - if (remaining) { - runes_display_move_to(t, t->row + 1, 0); - } - else { - t->col += len; - runes_display_position_cursor(t, t->cr); - } - } while (remaining > 0); - } -} + int r, c; -/* XXX this is gross and kind of slow, but i can't find a better way to do it. - * i need to be able to convert the string into clusters before laying it out, - * since i'm not going to be using the full layout anyway, but the only way i - * can see to do that is with pango_get_log_attrs, which only returns character - * (not byte) offsets, so i have to reparse the utf8 myself once i get the - * results. not ideal. */ -void runes_display_show_string_utf8(RunesTerm *t, char *buf, size_t len) -{ - size_t i, pos, char_len; - PangoLogAttr *attrs; - - char_len = g_utf8_strlen(buf, len); - attrs = malloc(sizeof(PangoLogAttr) * (char_len + 1)); - pango_get_log_attrs(buf, len, -1, NULL, attrs, char_len + 1); - - pos = 0; - for (i = 1; i < char_len + 1; ++i) { - if (attrs[i].is_cursor_position) { - char *startpos, *c; - size_t cluster_len; - char width = 1; - - startpos = g_utf8_offset_to_pointer(buf, pos); - cluster_len = g_utf8_offset_to_pointer(buf, i) - startpos; - - for (c = startpos; - (size_t)(c - startpos) < cluster_len; - c = g_utf8_next_char(c)) { - if (g_unichar_iswide(g_utf8_get_char(c))) { - width = 2; - } - } - - runes_display_paint_rectangle( - t, t->cr, runes_display_get_bgcolor(t), - t->col, t->row, width, 1); - - pango_layout_set_text(t->layout, startpos, cluster_len); - pango_cairo_update_layout(t->cr, t->layout); - pango_cairo_show_layout(t->cr, t->layout); - - if (t->col + width >= t->cols) { - runes_display_move_to(t, t->row + 1, 0); - } - else { - runes_display_move_to(t, t->row, t->col + width); - } - pos = i; + /* XXX quite inefficient */ + for (r = 0; r < t->scr.max.row; ++r) { + for (c = 0; c < t->scr.max.col; ++c) { + runes_display_draw_cell(t, r, c); } } - - free(attrs); -} - -void runes_display_clear_screen(RunesTerm *t) -{ - runes_display_paint_rectangle( - t, t->cr, t->bgdefault, 0, 0, t->cols, t->rows); -} - -void runes_display_clear_screen_forward(RunesTerm *t) -{ - runes_display_kill_line_forward(t); - runes_display_paint_rectangle( - t, t->cr, t->bgdefault, 0, t->row, t->cols, t->rows - t->row); -} - -void runes_display_kill_line_forward(RunesTerm *t) -{ - runes_display_paint_rectangle( - t, t->cr, t->bgdefault, t->col, t->row, t->cols - t->col, 1); -} - -void runes_display_kill_line_backward(RunesTerm *t) -{ - runes_display_paint_rectangle( - t, t->cr, t->bgdefault, 0, t->row, t->col, 1); -} - -void runes_display_insert_lines(RunesTerm *t, int count) -{ - cairo_pattern_t *pattern; - cairo_matrix_t matrix; - - cairo_save(t->cr); - cairo_push_group(t->cr); - pattern = cairo_pattern_create_for_surface(cairo_get_target(t->cr)); - cairo_matrix_init_translate(&matrix, 0.0, -count * t->fonty); - cairo_pattern_set_matrix(pattern, &matrix); - runes_display_paint_rectangle( - t, t->cr, pattern, - 0, t->row + count, t->cols, t->scroll_bottom + 1 - t->row - count); - cairo_pattern_destroy(pattern); - cairo_pop_group_to_source(t->cr); - cairo_paint(t->cr); - runes_display_paint_rectangle( - t, t->cr, t->bgdefault, 0, t->row, t->cols, count); - cairo_restore(t->cr); -} - -void runes_display_insert_characters(RunesTerm *t, int count) -{ - cairo_pattern_t *pattern; - cairo_matrix_t matrix; - - cairo_save(t->cr); - cairo_push_group(t->cr); - pattern = cairo_pattern_create_for_surface(cairo_get_target(t->cr)); - cairo_matrix_init_translate(&matrix, -count * t->fontx, 0.0); - cairo_pattern_set_matrix(pattern, &matrix); - runes_display_paint_rectangle( - t, t->cr, pattern, - t->col + count, t->row, t->cols - t->col - count, 1); - cairo_pattern_destroy(pattern); - cairo_pop_group_to_source(t->cr); - cairo_paint(t->cr); - runes_display_paint_rectangle( - t, t->cr, t->bgdefault, t->col, t->row, count, 1); - cairo_restore(t->cr); -} - -void runes_display_delete_lines(RunesTerm *t, int count) -{ - cairo_pattern_t *pattern; - cairo_matrix_t matrix; - - cairo_save(t->cr); - cairo_push_group(t->cr); - pattern = cairo_pattern_create_for_surface(cairo_get_target(t->cr)); - cairo_matrix_init_translate(&matrix, 0.0, count * t->fonty); - cairo_pattern_set_matrix(pattern, &matrix); - runes_display_paint_rectangle( - t, t->cr, pattern, - 0, t->row, t->cols, t->scroll_bottom + 1 - t->row - count); - cairo_pattern_destroy(pattern); - cairo_pop_group_to_source(t->cr); - cairo_paint(t->cr); - runes_display_paint_rectangle( - t, t->cr, t->bgdefault, - 0, t->scroll_bottom + 1 - count, t->cols, count); - cairo_restore(t->cr); -} - -void runes_display_delete_characters(RunesTerm *t, int count) -{ - cairo_pattern_t *pattern; - cairo_matrix_t matrix; - - cairo_save(t->cr); - cairo_push_group(t->cr); - pattern = cairo_pattern_create_for_surface(cairo_get_target(t->cr)); - cairo_matrix_init_translate(&matrix, count * t->fontx, 0.0); - cairo_pattern_set_matrix(pattern, &matrix); - runes_display_paint_rectangle( - t, t->cr, pattern, t->col, t->row, t->cols - t->col - count, 1); - cairo_pattern_destroy(pattern); - cairo_pop_group_to_source(t->cr); - cairo_paint(t->cr); - runes_display_paint_rectangle( - t, t->cr, t->bgdefault, t->cols - count, t->row, count, 1); - cairo_restore(t->cr); -} - -void runes_display_reset_text_attributes(RunesTerm *t) -{ - runes_display_reset_fg_color(t); - runes_display_reset_bg_color(t); - runes_display_reset_bold(t); - runes_display_reset_italic(t); - runes_display_reset_underline(t); - runes_display_reset_inverse(t); -} - -void runes_display_set_bold(RunesTerm *t) -{ - PangoAttrList *attrs; - - attrs = pango_layout_get_attributes(t->layout); - if (t->bold_is_bold) { - pango_attr_list_change( - attrs, pango_attr_weight_new(PANGO_WEIGHT_BOLD)); - } - t->bold = 1; - cairo_set_source(t->cr, runes_display_get_fgcolor(t)); -} - -void runes_display_reset_bold(RunesTerm *t) -{ - PangoAttrList *attrs; - - attrs = pango_layout_get_attributes(t->layout); - if (t->bold_is_bold) { - pango_attr_list_change( - attrs, pango_attr_weight_new(PANGO_WEIGHT_NORMAL)); - } - t->bold = 0; - cairo_set_source(t->cr, runes_display_get_fgcolor(t)); -} - -void runes_display_set_italic(RunesTerm *t) -{ - PangoAttrList *attrs; - - attrs = pango_layout_get_attributes(t->layout); - pango_attr_list_change(attrs, pango_attr_style_new(PANGO_STYLE_ITALIC)); -} - -void runes_display_reset_italic(RunesTerm *t) -{ - PangoAttrList *attrs; - - attrs = pango_layout_get_attributes(t->layout); - pango_attr_list_change(attrs, pango_attr_style_new(PANGO_STYLE_NORMAL)); -} - -void runes_display_set_underline(RunesTerm *t) -{ - PangoAttrList *attrs; - - attrs = pango_layout_get_attributes(t->layout); - pango_attr_list_change( - attrs, pango_attr_underline_new(PANGO_UNDERLINE_SINGLE)); -} - -void runes_display_reset_underline(RunesTerm *t) -{ - PangoAttrList *attrs; - - attrs = pango_layout_get_attributes(t->layout); - pango_attr_list_change( - attrs, pango_attr_underline_new(PANGO_UNDERLINE_NONE)); -} - -void runes_display_set_inverse(RunesTerm *t) -{ - t->inverse = 1; - cairo_set_source(t->cr, runes_display_get_fgcolor(t)); -} - -void runes_display_reset_inverse(RunesTerm *t) -{ - t->inverse = 0; - cairo_set_source(t->cr, runes_display_get_fgcolor(t)); -} - -void runes_display_set_fg_color(RunesTerm *t, int color) -{ - t->fgcolor = color; - cairo_set_source(t->cr, runes_display_get_fgcolor(t)); -} - -void runes_display_set_fg_color_rgb(RunesTerm *t, int r, int g, int b) -{ - t->fgcolor = -2; - if (t->fgcustom) { - cairo_pattern_destroy(t->fgcustom); - } - t->fgcustom = cairo_pattern_create_rgb( - (double)r / 255.0, (double)g / 255.0, (double)b / 255.0); - cairo_set_source(t->cr, runes_display_get_fgcolor(t)); -} - -void runes_display_reset_fg_color(RunesTerm *t) -{ - runes_display_set_fg_color(t, -1); -} - -void runes_display_set_bg_color(RunesTerm *t, int color) -{ - t->bgcolor = color; - cairo_set_source(t->cr, runes_display_get_fgcolor(t)); -} - -void runes_display_set_bg_color_rgb(RunesTerm *t, int r, int g, int b) -{ - t->bgcolor = -2; - if (t->bgcustom) { - cairo_pattern_destroy(t->bgcustom); - } - t->bgcustom = cairo_pattern_create_rgb( - (double)r / 255.0, (double)g / 255.0, (double)b / 255.0); - cairo_set_source(t->cr, runes_display_get_fgcolor(t)); -} - -void runes_display_reset_bg_color(RunesTerm *t) -{ - runes_display_set_bg_color(t, -1); -} - -void runes_display_show_cursor(RunesTerm *t) -{ - t->hide_cursor = 0; -} - -void runes_display_hide_cursor(RunesTerm *t) -{ - t->hide_cursor = 1; -} - -void runes_display_save_cursor(RunesTerm *t) -{ - t->saved_row = t->row; - t->saved_col = t->col; - /* XXX do other stuff here? */ -} - -void runes_display_restore_cursor(RunesTerm *t) -{ - t->row = t->saved_row; - t->col = t->saved_col; -} - -void runes_display_use_alternate_buffer(RunesTerm *t) -{ - if (t->alternate_cr) { - return; - } - - runes_display_save_cursor(t); - t->alternate_cr = t->cr; - t->cr = NULL; - t->xpixel = -1; - t->ypixel = -1; - runes_display_set_window_size(t); -} - -void runes_display_use_normal_buffer(RunesTerm *t) -{ - if (!t->alternate_cr) { - return; - } - - runes_display_restore_cursor(t); - cairo_destroy(t->cr); - t->cr = t->alternate_cr; - t->alternate_cr = NULL; - t->xpixel = -1; - t->ypixel = -1; - runes_display_set_window_size(t); -} - -void runes_display_set_scroll_region( - RunesTerm *t, int top, int bottom, int left, int right) -{ - top = top < 0 ? 0 : top; - bottom = bottom > t->rows - 1 ? t->rows - 1 : bottom; - left = left < 0 ? 0 : left; - right = right > t->cols - 1 ? t->cols - 1 : right; - - if (left != 0 || right != t->cols - 1) { - fprintf(stderr, "vertical scroll regions not yet supported\n"); - } - - if (top >= bottom || left >= right) { - t->scroll_top = 0; - t->scroll_bottom = t->rows - 1; - return; - } - - t->scroll_top = top; - t->scroll_bottom = bottom; - runes_display_move_to(t, t->scroll_top, 0); + runes_window_backend_request_flush(t); } void runes_display_cleanup(RunesTerm *t) @@ -529,45 +115,6 @@ void runes_display_cleanup(RunesTerm *t) cairo_destroy(t->cr); } -static cairo_pattern_t *runes_display_get_fgcolor(RunesTerm *t) -{ - int color = t->inverse ? t->bgcolor : t->fgcolor; - - if (t->inverse && t->bgcolor == t->fgcolor) { - return t->bgdefault; - } - else if (color == -2) { - return t->inverse ? t->bgcustom : t->fgcustom; - } - else if (color == -1) { - return t->inverse ? t->bgdefault : t->fgdefault; - } - else if (t->bold_is_bright && t->bold && color < 8) { - return t->colors[color + 8]; - } - else { - return t->colors[color]; - } -} - -static cairo_pattern_t *runes_display_get_bgcolor(RunesTerm *t) -{ - int color = t->inverse ? t->fgcolor : t->bgcolor; - - if (t->inverse && t->bgcolor == t->fgcolor) { - return t->fgdefault; - } - else if (color == -2) { - return t->inverse ? t->bgcustom : t->fgcustom; - } - else if (color == -1) { - return t->inverse ? t->fgdefault : t->bgdefault; - } - else { - return t->colors[color]; - } -} - static void runes_display_recalculate_font_metrics(RunesTerm *t) { PangoFontDescription *desc; @@ -601,63 +148,69 @@ static void runes_display_recalculate_font_metrics(RunesTerm *t) } } -static void runes_display_position_cursor(RunesTerm *t, cairo_t *cr) +static void runes_display_draw_cell(RunesTerm *t, int row, int col) { - cairo_move_to(cr, t->col * t->fontx, t->row * t->fonty); + struct runes_cell *cell = &t->scr.rows[row].cells[col]; + cairo_pattern_t *bg = NULL, *fg = NULL; + + switch (cell->bgcolor.type) { + case RUNES_COLOR_DEFAULT: + bg = t->bgdefault; + break; + case RUNES_COLOR_IDX: + bg = t->colors[cell->bgcolor.idx]; + break; + case RUNES_COLOR_RGB: + /* XXX */ + fprintf(stderr, "rgb colors nyi\n"); + break; + } + + switch (cell->fgcolor.type) { + case RUNES_COLOR_DEFAULT: + fg = t->fgdefault; + break; + case RUNES_COLOR_IDX: + fg = t->colors[cell->fgcolor.idx]; + break; + case RUNES_COLOR_RGB: + /* XXX */ + fprintf(stderr, "rgb colors nyi\n"); + break; + } + + if (bg) { + runes_display_paint_rectangle(t, t->cr, bg, row, col, 1, 1); + } + + if (cell->len) { + runes_display_draw_glyph( + t, t->cr, fg, cell->contents, cell->len, row, col); + } } static void runes_display_paint_rectangle( RunesTerm *t, cairo_t *cr, cairo_pattern_t *pattern, - int x, int y, int width, int height) + int row, int col, int width, int height) { cairo_save(cr); cairo_set_source(cr, pattern); cairo_rectangle( - cr, x * t->fontx, y * t->fonty, width * t->fontx, height * t->fonty); + cr, col * t->fontx, row * t->fonty, + width * t->fontx, height * t->fonty); cairo_fill(cr); cairo_restore(cr); - runes_display_position_cursor(t, t->cr); -} - -static void runes_display_scroll_up(RunesTerm *t, int rows) -{ - cairo_pattern_t *pattern; - cairo_matrix_t matrix; - - cairo_save(t->cr); - cairo_push_group(t->cr); - pattern = cairo_pattern_create_for_surface(cairo_get_target(t->cr)); - cairo_matrix_init_translate(&matrix, 0.0, -rows * t->fonty); - cairo_pattern_set_matrix(pattern, &matrix); - runes_display_paint_rectangle( - t, t->cr, pattern, - 0, t->scroll_top + rows, - t->cols, t->scroll_bottom - t->scroll_top + 1 - rows); - cairo_pattern_destroy(pattern); - cairo_pop_group_to_source(t->cr); - cairo_paint(t->cr); - runes_display_paint_rectangle( - t, t->cr, t->bgdefault, 0, t->scroll_top, t->cols, rows); - cairo_restore(t->cr); } -static void runes_display_scroll_down(RunesTerm *t, int rows) +static void runes_display_draw_glyph( + RunesTerm *t, cairo_t *cr, cairo_pattern_t *pattern, char *buf, size_t len, + int row, int col) { - cairo_pattern_t *pattern; - cairo_matrix_t matrix; - - cairo_save(t->cr); - cairo_push_group(t->cr); - pattern = cairo_pattern_create_for_surface(cairo_get_target(t->cr)); - cairo_matrix_init_translate(&matrix, 0.0, rows * t->fonty); - cairo_pattern_set_matrix(pattern, &matrix); - runes_display_paint_rectangle( - t, t->cr, pattern, - 0, t->scroll_top, t->cols, t->scroll_bottom - t->scroll_top); - cairo_pattern_destroy(pattern); - cairo_pop_group_to_source(t->cr); - cairo_paint(t->cr); - runes_display_paint_rectangle( - t, t->cr, t->bgdefault, 0, t->scroll_bottom + 1 - rows, t->cols, rows); - cairo_restore(t->cr); + cairo_save(cr); + cairo_move_to(cr, col * t->fontx, row * t->fonty); + cairo_set_source(cr, pattern); + pango_layout_set_text(t->layout, buf, len); + pango_cairo_update_layout(t->cr, t->layout); + pango_cairo_show_layout(t->cr, t->layout); + cairo_restore(cr); } diff --git a/src/display.h b/src/display.h index 74f3713..d1a895b 100644 --- a/src/display.h +++ b/src/display.h @@ -3,42 +3,7 @@ void runes_display_init(RunesTerm *t); void runes_display_set_window_size(RunesTerm *t); -void runes_display_focus_in(RunesTerm *t); -void runes_display_focus_out(RunesTerm *t); -void runes_display_move_to(RunesTerm *t, int row, int col); -void runes_display_show_string_ascii(RunesTerm *t, char *buf, size_t len); -void runes_display_show_string_utf8(RunesTerm *t, char *buf, size_t len); -void runes_display_clear_screen(RunesTerm *t); -void runes_display_clear_screen_forward(RunesTerm *t); -void runes_display_kill_line_forward(RunesTerm *t); -void runes_display_kill_line_backward(RunesTerm *t); -void runes_display_insert_lines(RunesTerm *t, int count); -void runes_display_insert_characters(RunesTerm *t, int count); -void runes_display_delete_lines(RunesTerm *t, int count); -void runes_display_delete_characters(RunesTerm *t, int count); -void runes_display_reset_text_attributes(RunesTerm *t); -void runes_display_set_bold(RunesTerm *t); -void runes_display_reset_bold(RunesTerm *t); -void runes_display_set_italic(RunesTerm *t); -void runes_display_reset_italic(RunesTerm *t); -void runes_display_set_underline(RunesTerm *t); -void runes_display_reset_underline(RunesTerm *t); -void runes_display_set_inverse(RunesTerm *t); -void runes_display_reset_inverse(RunesTerm *t); -void runes_display_set_fg_color(RunesTerm *t, int color); -void runes_display_set_fg_color_rgb(RunesTerm *t, int r, int g, int b); -void runes_display_reset_fg_color(RunesTerm *t); -void runes_display_set_bg_color(RunesTerm *t, int color); -void runes_display_set_bg_color_rgb(RunesTerm *t, int r, int g, int b); -void runes_display_reset_bg_color(RunesTerm *t); -void runes_display_show_cursor(RunesTerm *t); -void runes_display_hide_cursor(RunesTerm *t); -void runes_display_save_cursor(RunesTerm *t); -void runes_display_restore_cursor(RunesTerm *t); -void runes_display_use_alternate_buffer(RunesTerm *t); -void runes_display_use_normal_buffer(RunesTerm *t); -void runes_display_set_scroll_region( - RunesTerm *t, int top, int bottom, int left, int right); +void runes_display_draw_screen(RunesTerm *t); void runes_display_cleanup(RunesTerm *t); #endif diff --git a/src/parser.c b/src/parser.c index 8651128..b9978a0 100644 --- a/src/parser.c +++ b/src/parser.c @@ -2361,99 +2361,80 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -void runes_parser_process_string(RunesTerm *t, char *buf, size_t len) -{ - YY_BUFFER_STATE state; - yyscan_t scanner; - int remaining; - - /* XXX this will break if buf ends with a partial escape sequence or utf8 - * character. we need to detect that and not consume the entire input in - * that case */ - runes_parser_yylex_init_extra(t,&scanner); - state = runes_parser_yy_scan_bytes(buf, len, scanner); - while ((remaining = runes_parser_yylex(scanner)) == -1); - t->remaininglen = remaining; - if (t->remaininglen) { - memmove(t->readbuf, &buf[len - t->remaininglen], t->remaininglen); - } - runes_parser_yy_delete_buffer(state, scanner); - runes_parser_yylex_destroy(scanner); -} - static void runes_parser_handle_bel(RunesTerm *t) { if (t->audible_bell) { - runes_window_backend_request_audible_bell(t); + runes_screen_audible_bell(t); } else { - runes_window_backend_request_visual_bell(t); + runes_screen_visual_bell(t); } } static void runes_parser_handle_bs(RunesTerm *t) { - runes_display_move_to(t, t->row, t->col - 1); + runes_screen_move_to(t, t->scr.cur.row, t->scr.cur.col - 1); } static void runes_parser_handle_tab(RunesTerm *t) { - runes_display_move_to(t, t->row, t->col - (t->col % 8) + 8); + runes_screen_move_to( + t, t->scr.cur.row, t->scr.cur.col - (t->scr.cur.col % 8) + 8); } static void runes_parser_handle_lf(RunesTerm *t) { - runes_display_move_to(t, t->row + 1, t->col); + runes_screen_move_to(t, t->scr.cur.row + 1, t->scr.cur.col); } static void runes_parser_handle_cr(RunesTerm *t) { - runes_display_move_to(t, t->row, 0); + runes_screen_move_to(t, t->scr.cur.row, 0); } static void runes_parser_handle_deckpam(RunesTerm *t) { - t->application_keypad = 1; + runes_screen_set_application_keypad(t); } static void runes_parser_handle_deckpnm(RunesTerm *t) { - t->application_keypad = 0; + runes_screen_reset_application_keypad(t); } static void runes_parser_handle_ri(RunesTerm *t) { - runes_display_move_to(t, t->row - 1, t->col); + runes_screen_move_to(t, t->scr.cur.row - 1, t->scr.cur.col); } static void runes_parser_handle_ris(RunesTerm *t) { - runes_display_use_normal_buffer(t); - runes_display_set_scroll_region(t, 0, t->rows - 1, 0, t->cols - 1); - runes_display_clear_screen(t); - runes_display_save_cursor(t); - runes_display_reset_text_attributes(t); - runes_display_show_cursor(t); - - t->application_keypad = 0; - t->application_cursor = 0; - t->mouse_reporting_press = 0; - t->mouse_reporting_press_release = 0; + runes_screen_use_normal_buffer(t); + runes_screen_set_scroll_region( + t, 0, t->scr.max.row - 1, 0, t->scr.max.col - 1); + runes_screen_clear_screen(t); + runes_screen_save_cursor(t); + runes_screen_reset_text_attributes(t); + runes_screen_show_cursor(t); + runes_screen_reset_application_keypad(t); + runes_screen_reset_application_cursor(t); + runes_screen_reset_mouse_reporting_press(t); + runes_screen_reset_mouse_reporting_press_release(t); } static void runes_parser_handle_vb(RunesTerm *t) { - runes_window_backend_request_visual_bell(t); + runes_screen_visual_bell(t); } static void runes_parser_handle_decsc(RunesTerm *t) { - runes_display_save_cursor(t); + runes_screen_save_cursor(t); } static void runes_parser_handle_decrc(RunesTerm *t) { - runes_display_restore_cursor(t); + runes_screen_restore_cursor(t); } static void runes_parser_extract_csi_params( @@ -2506,7 +2487,7 @@ static void runes_parser_handle_ich(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_insert_characters(t, params[0]); + runes_screen_insert_characters(t, params[0]); } static void runes_parser_handle_cuu(RunesTerm *t, char *buf, size_t len) @@ -2514,7 +2495,7 @@ static void runes_parser_handle_cuu(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_move_to(t, t->row - params[0], t->col); + runes_screen_move_to(t, t->scr.cur.row - params[0], t->scr.cur.col); } static void runes_parser_handle_cud(RunesTerm *t, char *buf, size_t len) @@ -2522,7 +2503,7 @@ static void runes_parser_handle_cud(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_move_to(t, t->row + params[0], t->col); + runes_screen_move_to(t, t->scr.cur.row + params[0], t->scr.cur.col); } static void runes_parser_handle_cuf(RunesTerm *t, char *buf, size_t len) @@ -2530,7 +2511,7 @@ static void runes_parser_handle_cuf(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_move_to(t, t->row, t->col + params[0]); + runes_screen_move_to(t, t->scr.cur.row, t->scr.cur.col + params[0]); } static void runes_parser_handle_cub(RunesTerm *t, char *buf, size_t len) @@ -2538,7 +2519,7 @@ static void runes_parser_handle_cub(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_move_to(t, t->row, t->col - params[0]); + runes_screen_move_to(t, t->scr.cur.row, t->scr.cur.col - params[0]); } static void runes_parser_handle_cup(RunesTerm *t, char *buf, size_t len) @@ -2552,7 +2533,7 @@ static void runes_parser_handle_cup(RunesTerm *t, char *buf, size_t len) if (params[1] == 0) { params[1] = 1; } - runes_display_move_to(t, params[0] - 1, params[1] - 1); + runes_screen_move_to(t, params[0] - 1, params[1] - 1); } static void runes_parser_handle_ed(RunesTerm *t, char *buf, size_t len) @@ -2562,14 +2543,13 @@ static void runes_parser_handle_ed(RunesTerm *t, char *buf, size_t len) runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); switch (params[0]) { case 0: - runes_display_clear_screen_forward(t); + runes_screen_clear_screen_forward(t); break; case 1: - /* XXX */ - fprintf(stderr, "unhandled ED parameter 1\n"); + runes_screen_clear_screen_backward(t); break; case 2: - runes_display_clear_screen(t); + runes_screen_clear_screen(t); break; default: fprintf(stderr, "unknown ED parameter %d\n", params[0]); @@ -2584,14 +2564,13 @@ static void runes_parser_handle_el(RunesTerm *t, char *buf, size_t len) runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); switch (params[0]) { case 0: - runes_display_kill_line_forward(t); + runes_screen_kill_line_forward(t); break; case 1: - runes_display_kill_line_backward(t); + runes_screen_kill_line_backward(t); break; case 2: - runes_display_kill_line_forward(t); - runes_display_kill_line_backward(t); + runes_screen_kill_line(t); break; default: fprintf(stderr, "unknown EL parameter %d\n", params[0]); @@ -2604,8 +2583,8 @@ static void runes_parser_handle_il(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_insert_lines(t, params[0]); - runes_display_move_to(t, t->row, 0); + runes_screen_insert_lines(t, params[0]); + runes_screen_move_to(t, t->scr.cur.row, 0); } static void runes_parser_handle_dl(RunesTerm *t, char *buf, size_t len) @@ -2613,8 +2592,8 @@ static void runes_parser_handle_dl(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_delete_lines(t, params[0]); - runes_display_move_to(t, t->row, 0); + runes_screen_delete_lines(t, params[0]); + runes_screen_move_to(t, t->scr.cur.row, 0); } static void runes_parser_handle_dch(RunesTerm *t, char *buf, size_t len) @@ -2622,7 +2601,7 @@ static void runes_parser_handle_dch(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_delete_characters(t, params[0]); + runes_screen_delete_characters(t, params[0]); } static void runes_parser_handle_sm(RunesTerm *t, char *buf, size_t len) @@ -2648,20 +2627,20 @@ static void runes_parser_handle_sm(RunesTerm *t, char *buf, size_t len) case '?': switch (params[i]) { case 1: - t->application_cursor = 1; + runes_screen_set_application_cursor(t); break; case 9: - t->mouse_reporting_press = 1; + runes_screen_set_mouse_reporting_press(t); break; case 25: - runes_display_show_cursor(t); + runes_screen_show_cursor(t); break; case 1000: - t->mouse_reporting_press_release = 1; + runes_screen_set_mouse_reporting_press_release(t); break; case 47: case 1049: - runes_display_use_alternate_buffer(t); + runes_screen_use_alternate_buffer(t); break; default: fprintf( @@ -2702,20 +2681,20 @@ static void runes_parser_handle_rm(RunesTerm *t, char *buf, size_t len) case '?': switch (params[i]) { case 1: - t->application_cursor = 0; + runes_screen_set_application_cursor(t); break; case 9: - t->mouse_reporting_press = 0; + runes_screen_set_mouse_reporting_press(t); break; case 25: - runes_display_hide_cursor(t); + runes_screen_hide_cursor(t); break; case 1000: - t->mouse_reporting_press_release = 0; + runes_screen_set_mouse_reporting_press_release(t); break; case 47: case 1049: - runes_display_use_normal_buffer(t); + runes_screen_use_normal_buffer(t); break; default: fprintf( @@ -2744,35 +2723,35 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) for (i = 0; i < nparams; ++i) { switch (params[i]) { case 0: - runes_display_reset_text_attributes(t); + runes_screen_reset_text_attributes(t); break; case 1: - runes_display_set_bold(t); + runes_screen_set_bold(t); break; case 3: - runes_display_set_italic(t); + runes_screen_set_italic(t); break; case 4: - runes_display_set_underline(t); + runes_screen_set_underline(t); break; case 7: - runes_display_set_inverse(t); + runes_screen_set_inverse(t); break; case 22: - runes_display_reset_bold(t); + runes_screen_reset_bold(t); break; case 23: - runes_display_reset_italic(t); + runes_screen_reset_italic(t); break; case 24: - runes_display_reset_underline(t); + runes_screen_reset_underline(t); break; case 27: - runes_display_reset_inverse(t); + runes_screen_reset_inverse(t); break; case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: - runes_display_set_fg_color(t, params[i] - 30); + runes_screen_set_fg_color(t, params[i] - 30); break; case 38: { i++; @@ -2793,7 +2772,7 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) params[i - 4], params[i - 3]); break; } - runes_display_set_fg_color_rgb( + runes_screen_set_fg_color_rgb( t, params[i - 2], params[i - 1], params[i]); break; case 5: @@ -2805,7 +2784,7 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) params[i - 2], params[i - 1]); break; } - runes_display_set_fg_color(t, params[i]); + runes_screen_set_fg_color(t, params[i]); break; default: i++; @@ -2817,11 +2796,11 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) break; } case 39: - runes_display_reset_fg_color(t); + runes_screen_reset_fg_color(t); break; case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: - runes_display_set_bg_color(t, params[i] - 40); + runes_screen_set_bg_color(t, params[i] - 40); break; case 48: { i++; @@ -2842,7 +2821,7 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) params[i - 4], params[i - 3]); break; } - runes_display_set_bg_color_rgb( + runes_screen_set_bg_color_rgb( t, params[i - 2], params[i - 1], params[i]); break; case 5: @@ -2854,7 +2833,7 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) params[i - 2], params[i - 1]); break; } - runes_display_set_bg_color(t, params[i]); + runes_screen_set_bg_color(t, params[i]); break; default: i++; @@ -2866,15 +2845,15 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) break; } case 49: - runes_display_reset_bg_color(t); + runes_screen_reset_bg_color(t); break; case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 97: - runes_display_set_fg_color(t, params[i] - 82); + runes_screen_set_fg_color(t, params[i] - 82); break; case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: - runes_display_set_bg_color(t, params[i] - 92); + runes_screen_set_bg_color(t, params[i] - 92); break; default: fprintf(stderr, "unknown SGR parameter: %d\n", params[i]); @@ -2885,12 +2864,13 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) static void runes_parser_handle_csr(RunesTerm *t, char *buf, size_t len) { - int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1, t->rows, 1, t->cols }; + int params[RUNES_PARSER_CSI_MAX_PARAMS] = { + 1, t->scr.max.row, 1, t->scr.max.col }; int nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_set_scroll_region( + runes_screen_set_scroll_region( t, params[0] - 1, params[1] - 1, params[2] - 1, params[3] - 1); } @@ -2902,7 +2882,7 @@ static void runes_parser_handle_decsed(RunesTerm *t, char *buf, size_t len) switch (params[0]) { case 0: /* XXX not quite correct */ - runes_display_clear_screen_forward(t); + runes_screen_clear_screen_forward(t); break; case 1: /* XXX */ @@ -2910,7 +2890,7 @@ static void runes_parser_handle_decsed(RunesTerm *t, char *buf, size_t len) break; case 2: /* XXX not quite correct */ - runes_display_clear_screen(t); + runes_screen_clear_screen(t); break; default: fprintf(stderr, "unknown DECSED parameter %d\n", params[0]); @@ -2926,7 +2906,7 @@ static void runes_parser_handle_decsel(RunesTerm *t, char *buf, size_t len) switch (params[0]) { case 0: /* XXX not quite correct */ - runes_display_kill_line_forward(t); + runes_screen_kill_line_forward(t); break; case 1: /* XXX */ @@ -2944,28 +2924,28 @@ static void runes_parser_handle_decsel(RunesTerm *t, char *buf, size_t len) static void runes_parser_handle_osc0(RunesTerm *t, char *buf, size_t len) { - runes_window_backend_set_icon_name(t, buf + 4, len - 5); - runes_window_backend_set_window_title(t, buf + 4, len - 5); + runes_screen_set_icon_name(t, buf + 4, len - 5); + runes_screen_set_window_title(t, buf + 4, len - 5); } static void runes_parser_handle_osc1(RunesTerm *t, char *buf, size_t len) { - runes_window_backend_set_icon_name(t, buf + 4, len - 5); + runes_screen_set_icon_name(t, buf + 4, len - 5); } static void runes_parser_handle_osc2(RunesTerm *t, char *buf, size_t len) { - runes_window_backend_set_window_title(t, buf + 4, len - 5); + runes_screen_set_window_title(t, buf + 4, len - 5); } static void runes_parser_handle_ascii(RunesTerm *t, char *text, size_t len) { - runes_display_show_string_ascii(t, text, len); + runes_screen_show_string_ascii(t, text, len); } static void runes_parser_handle_text(RunesTerm *t, char *text, size_t len) { - runes_display_show_string_utf8(t, text, len); + runes_screen_show_string_utf8(t, text, len); } /* XXX these are copied from the generated file so that I can add the UNUSED diff --git a/src/parser.h b/src/parser.h index ea449a8..95a67cd 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,6 +1,338 @@ -#ifndef _RUNES_PARSER_H -#define _RUNES_PARSER_H +#ifndef runes_parser_yyHEADER_H +#define runes_parser_yyHEADER_H 1 +#define runes_parser_yyIN_HEADER 1 -void runes_parser_process_string(RunesTerm *t, char *buf, size_t len); +#line 6 "src/parser.h" +#line 8 "src/parser.h" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 39 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 #endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +void runes_parser_yyrestart (FILE *input_file ,yyscan_t yyscanner ); +void runes_parser_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE runes_parser_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void runes_parser_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void runes_parser_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void runes_parser_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void runes_parser_yypop_buffer_state (yyscan_t yyscanner ); + +YY_BUFFER_STATE runes_parser_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE runes_parser_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE runes_parser_yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); + +void *runes_parser_yyalloc (yy_size_t ,yyscan_t yyscanner ); +void *runes_parser_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void runes_parser_yyfree (void * ,yyscan_t yyscanner ); + +/* Begin user sect3 */ + +#define runes_parser_yywrap(yyscanner) 1 +#define YY_SKIP_YYWRAP + +#define yytext_ptr yytext_r + +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define INITIAL 0 + +#endif + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#define YY_EXTRA_TYPE RunesTerm * + +int runes_parser_yylex_init (yyscan_t* scanner); + +int runes_parser_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int runes_parser_yylex_destroy (yyscan_t yyscanner ); + +int runes_parser_yyget_debug (yyscan_t yyscanner ); + +void runes_parser_yyset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE runes_parser_yyget_extra (yyscan_t yyscanner ); + +void runes_parser_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *runes_parser_yyget_in (yyscan_t yyscanner ); + +void runes_parser_yyset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *runes_parser_yyget_out (yyscan_t yyscanner ); + +void runes_parser_yyset_out (FILE * out_str ,yyscan_t yyscanner ); + +yy_size_t runes_parser_yyget_leng (yyscan_t yyscanner ); + +char *runes_parser_yyget_text (yyscan_t yyscanner ); + +int runes_parser_yyget_lineno (yyscan_t yyscanner ); + +void runes_parser_yyset_lineno (int line_number ,yyscan_t yyscanner ); + +int runes_parser_yyget_column (yyscan_t yyscanner ); + +void runes_parser_yyset_column (int column_no ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int runes_parser_yywrap (yyscan_t yyscanner ); +#else +extern int runes_parser_yywrap (yyscan_t yyscanner ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int runes_parser_yylex (yyscan_t yyscanner); + +#define YY_DECL int runes_parser_yylex (yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +#line 232 "src/parser.l" + + +#line 337 "src/parser.h" +#undef runes_parser_yyIN_HEADER +#endif /* runes_parser_yyHEADER_H */ diff --git a/src/parser.l b/src/parser.l index 2a2e94c..f2682c8 100644 --- a/src/parser.l +++ b/src/parser.l @@ -231,96 +231,80 @@ static void runes_parser_handle_text(RunesTerm *t, char *text, size_t len); %% -void runes_parser_process_string(RunesTerm *t, char *buf, size_t len) -{ - YY_BUFFER_STATE state; - yyscan_t scanner; - int remaining; - - yylex_init_extra(t, &scanner); - state = runes_parser_yy_scan_bytes(buf, len, scanner); - while ((remaining = runes_parser_yylex(scanner)) == -1); - t->remaininglen = remaining; - if (t->remaininglen) { - memmove(t->readbuf, &buf[len - t->remaininglen], t->remaininglen); - } - runes_parser_yy_delete_buffer(state, scanner); - yylex_destroy(scanner); -} - static void runes_parser_handle_bel(RunesTerm *t) { if (t->audible_bell) { - runes_window_backend_request_audible_bell(t); + runes_screen_audible_bell(t); } else { - runes_window_backend_request_visual_bell(t); + runes_screen_visual_bell(t); } } static void runes_parser_handle_bs(RunesTerm *t) { - runes_display_move_to(t, t->row, t->col - 1); + runes_screen_move_to(t, t->scr.cur.row, t->scr.cur.col - 1); } static void runes_parser_handle_tab(RunesTerm *t) { - runes_display_move_to(t, t->row, t->col - (t->col % 8) + 8); + runes_screen_move_to( + t, t->scr.cur.row, t->scr.cur.col - (t->scr.cur.col % 8) + 8); } static void runes_parser_handle_lf(RunesTerm *t) { - runes_display_move_to(t, t->row + 1, t->col); + runes_screen_move_to(t, t->scr.cur.row + 1, t->scr.cur.col); } static void runes_parser_handle_cr(RunesTerm *t) { - runes_display_move_to(t, t->row, 0); + runes_screen_move_to(t, t->scr.cur.row, 0); } static void runes_parser_handle_deckpam(RunesTerm *t) { - t->application_keypad = 1; + runes_screen_set_application_keypad(t); } static void runes_parser_handle_deckpnm(RunesTerm *t) { - t->application_keypad = 0; + runes_screen_reset_application_keypad(t); } static void runes_parser_handle_ri(RunesTerm *t) { - runes_display_move_to(t, t->row - 1, t->col); + runes_screen_move_to(t, t->scr.cur.row - 1, t->scr.cur.col); } static void runes_parser_handle_ris(RunesTerm *t) { - runes_display_use_normal_buffer(t); - runes_display_set_scroll_region(t, 0, t->rows - 1, 0, t->cols - 1); - runes_display_clear_screen(t); - runes_display_save_cursor(t); - runes_display_reset_text_attributes(t); - runes_display_show_cursor(t); - - t->application_keypad = 0; - t->application_cursor = 0; - t->mouse_reporting_press = 0; - t->mouse_reporting_press_release = 0; + runes_screen_use_normal_buffer(t); + runes_screen_set_scroll_region( + t, 0, t->scr.max.row - 1, 0, t->scr.max.col - 1); + runes_screen_clear_screen(t); + runes_screen_save_cursor(t); + runes_screen_reset_text_attributes(t); + runes_screen_show_cursor(t); + runes_screen_reset_application_keypad(t); + runes_screen_reset_application_cursor(t); + runes_screen_reset_mouse_reporting_press(t); + runes_screen_reset_mouse_reporting_press_release(t); } static void runes_parser_handle_vb(RunesTerm *t) { - runes_window_backend_request_visual_bell(t); + runes_screen_visual_bell(t); } static void runes_parser_handle_decsc(RunesTerm *t) { - runes_display_save_cursor(t); + runes_screen_save_cursor(t); } static void runes_parser_handle_decrc(RunesTerm *t) { - runes_display_restore_cursor(t); + runes_screen_restore_cursor(t); } static void runes_parser_extract_csi_params( @@ -373,7 +357,7 @@ static void runes_parser_handle_ich(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_insert_characters(t, params[0]); + runes_screen_insert_characters(t, params[0]); } static void runes_parser_handle_cuu(RunesTerm *t, char *buf, size_t len) @@ -381,7 +365,7 @@ static void runes_parser_handle_cuu(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_move_to(t, t->row - params[0], t->col); + runes_screen_move_to(t, t->scr.cur.row - params[0], t->scr.cur.col); } static void runes_parser_handle_cud(RunesTerm *t, char *buf, size_t len) @@ -389,7 +373,7 @@ static void runes_parser_handle_cud(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_move_to(t, t->row + params[0], t->col); + runes_screen_move_to(t, t->scr.cur.row + params[0], t->scr.cur.col); } static void runes_parser_handle_cuf(RunesTerm *t, char *buf, size_t len) @@ -397,7 +381,7 @@ static void runes_parser_handle_cuf(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_move_to(t, t->row, t->col + params[0]); + runes_screen_move_to(t, t->scr.cur.row, t->scr.cur.col + params[0]); } static void runes_parser_handle_cub(RunesTerm *t, char *buf, size_t len) @@ -405,7 +389,7 @@ static void runes_parser_handle_cub(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_move_to(t, t->row, t->col - params[0]); + runes_screen_move_to(t, t->scr.cur.row, t->scr.cur.col - params[0]); } static void runes_parser_handle_cup(RunesTerm *t, char *buf, size_t len) @@ -419,7 +403,7 @@ static void runes_parser_handle_cup(RunesTerm *t, char *buf, size_t len) if (params[1] == 0) { params[1] = 1; } - runes_display_move_to(t, params[0] - 1, params[1] - 1); + runes_screen_move_to(t, params[0] - 1, params[1] - 1); } static void runes_parser_handle_ed(RunesTerm *t, char *buf, size_t len) @@ -429,14 +413,13 @@ static void runes_parser_handle_ed(RunesTerm *t, char *buf, size_t len) runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); switch (params[0]) { case 0: - runes_display_clear_screen_forward(t); + runes_screen_clear_screen_forward(t); break; case 1: - /* XXX */ - fprintf(stderr, "unhandled ED parameter 1\n"); + runes_screen_clear_screen_backward(t); break; case 2: - runes_display_clear_screen(t); + runes_screen_clear_screen(t); break; default: fprintf(stderr, "unknown ED parameter %d\n", params[0]); @@ -451,14 +434,13 @@ static void runes_parser_handle_el(RunesTerm *t, char *buf, size_t len) runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); switch (params[0]) { case 0: - runes_display_kill_line_forward(t); + runes_screen_kill_line_forward(t); break; case 1: - runes_display_kill_line_backward(t); + runes_screen_kill_line_backward(t); break; case 2: - runes_display_kill_line_forward(t); - runes_display_kill_line_backward(t); + runes_screen_kill_line(t); break; default: fprintf(stderr, "unknown EL parameter %d\n", params[0]); @@ -471,8 +453,8 @@ static void runes_parser_handle_il(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_insert_lines(t, params[0]); - runes_display_move_to(t, t->row, 0); + runes_screen_insert_lines(t, params[0]); + runes_screen_move_to(t, t->scr.cur.row, 0); } static void runes_parser_handle_dl(RunesTerm *t, char *buf, size_t len) @@ -480,8 +462,8 @@ static void runes_parser_handle_dl(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_delete_lines(t, params[0]); - runes_display_move_to(t, t->row, 0); + runes_screen_delete_lines(t, params[0]); + runes_screen_move_to(t, t->scr.cur.row, 0); } static void runes_parser_handle_dch(RunesTerm *t, char *buf, size_t len) @@ -489,7 +471,7 @@ static void runes_parser_handle_dch(RunesTerm *t, char *buf, size_t len) int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1 }, nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_delete_characters(t, params[0]); + runes_screen_delete_characters(t, params[0]); } static void runes_parser_handle_sm(RunesTerm *t, char *buf, size_t len) @@ -515,20 +497,20 @@ static void runes_parser_handle_sm(RunesTerm *t, char *buf, size_t len) case '?': switch (params[i]) { case 1: - t->application_cursor = 1; + runes_screen_set_application_cursor(t); break; case 9: - t->mouse_reporting_press = 1; + runes_screen_set_mouse_reporting_press(t); break; case 25: - runes_display_show_cursor(t); + runes_screen_show_cursor(t); break; case 1000: - t->mouse_reporting_press_release = 1; + runes_screen_set_mouse_reporting_press_release(t); break; case 47: case 1049: - runes_display_use_alternate_buffer(t); + runes_screen_use_alternate_buffer(t); break; default: fprintf( @@ -569,20 +551,20 @@ static void runes_parser_handle_rm(RunesTerm *t, char *buf, size_t len) case '?': switch (params[i]) { case 1: - t->application_cursor = 0; + runes_screen_set_application_cursor(t); break; case 9: - t->mouse_reporting_press = 0; + runes_screen_set_mouse_reporting_press(t); break; case 25: - runes_display_hide_cursor(t); + runes_screen_hide_cursor(t); break; case 1000: - t->mouse_reporting_press_release = 0; + runes_screen_set_mouse_reporting_press_release(t); break; case 47: case 1049: - runes_display_use_normal_buffer(t); + runes_screen_use_normal_buffer(t); break; default: fprintf( @@ -611,35 +593,35 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) for (i = 0; i < nparams; ++i) { switch (params[i]) { case 0: - runes_display_reset_text_attributes(t); + runes_screen_reset_text_attributes(t); break; case 1: - runes_display_set_bold(t); + runes_screen_set_bold(t); break; case 3: - runes_display_set_italic(t); + runes_screen_set_italic(t); break; case 4: - runes_display_set_underline(t); + runes_screen_set_underline(t); break; case 7: - runes_display_set_inverse(t); + runes_screen_set_inverse(t); break; case 22: - runes_display_reset_bold(t); + runes_screen_reset_bold(t); break; case 23: - runes_display_reset_italic(t); + runes_screen_reset_italic(t); break; case 24: - runes_display_reset_underline(t); + runes_screen_reset_underline(t); break; case 27: - runes_display_reset_inverse(t); + runes_screen_reset_inverse(t); break; case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: - runes_display_set_fg_color(t, params[i] - 30); + runes_screen_set_fg_color(t, params[i] - 30); break; case 38: { i++; @@ -660,7 +642,7 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) params[i - 4], params[i - 3]); break; } - runes_display_set_fg_color_rgb( + runes_screen_set_fg_color_rgb( t, params[i - 2], params[i - 1], params[i]); break; case 5: @@ -672,7 +654,7 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) params[i - 2], params[i - 1]); break; } - runes_display_set_fg_color(t, params[i]); + runes_screen_set_fg_color(t, params[i]); break; default: i++; @@ -684,11 +666,11 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) break; } case 39: - runes_display_reset_fg_color(t); + runes_screen_reset_fg_color(t); break; case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: - runes_display_set_bg_color(t, params[i] - 40); + runes_screen_set_bg_color(t, params[i] - 40); break; case 48: { i++; @@ -709,7 +691,7 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) params[i - 4], params[i - 3]); break; } - runes_display_set_bg_color_rgb( + runes_screen_set_bg_color_rgb( t, params[i - 2], params[i - 1], params[i]); break; case 5: @@ -721,7 +703,7 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) params[i - 2], params[i - 1]); break; } - runes_display_set_bg_color(t, params[i]); + runes_screen_set_bg_color(t, params[i]); break; default: i++; @@ -733,15 +715,15 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) break; } case 49: - runes_display_reset_bg_color(t); + runes_screen_reset_bg_color(t); break; case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 97: - runes_display_set_fg_color(t, params[i] - 82); + runes_screen_set_fg_color(t, params[i] - 82); break; case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: - runes_display_set_bg_color(t, params[i] - 92); + runes_screen_set_bg_color(t, params[i] - 92); break; default: fprintf(stderr, "unknown SGR parameter: %d\n", params[i]); @@ -752,12 +734,13 @@ static void runes_parser_handle_sgr(RunesTerm *t, char *buf, size_t len) static void runes_parser_handle_csr(RunesTerm *t, char *buf, size_t len) { - int params[RUNES_PARSER_CSI_MAX_PARAMS] = { 1, t->rows, 1, t->cols }; + int params[RUNES_PARSER_CSI_MAX_PARAMS] = { + 1, t->scr.max.row, 1, t->scr.max.col }; int nparams; runes_parser_extract_csi_params(buf + 2, len - 3, params, &nparams); - runes_display_set_scroll_region( + runes_screen_set_scroll_region( t, params[0] - 1, params[1] - 1, params[2] - 1, params[3] - 1); } @@ -769,7 +752,7 @@ static void runes_parser_handle_decsed(RunesTerm *t, char *buf, size_t len) switch (params[0]) { case 0: /* XXX not quite correct */ - runes_display_clear_screen_forward(t); + runes_screen_clear_screen_forward(t); break; case 1: /* XXX */ @@ -777,7 +760,7 @@ static void runes_parser_handle_decsed(RunesTerm *t, char *buf, size_t len) break; case 2: /* XXX not quite correct */ - runes_display_clear_screen(t); + runes_screen_clear_screen(t); break; default: fprintf(stderr, "unknown DECSED parameter %d\n", params[0]); @@ -793,7 +776,7 @@ static void runes_parser_handle_decsel(RunesTerm *t, char *buf, size_t len) switch (params[0]) { case 0: /* XXX not quite correct */ - runes_display_kill_line_forward(t); + runes_screen_kill_line_forward(t); break; case 1: /* XXX */ @@ -811,28 +794,28 @@ static void runes_parser_handle_decsel(RunesTerm *t, char *buf, size_t len) static void runes_parser_handle_osc0(RunesTerm *t, char *buf, size_t len) { - runes_window_backend_set_icon_name(t, buf + 4, len - 5); - runes_window_backend_set_window_title(t, buf + 4, len - 5); + runes_screen_set_icon_name(t, buf + 4, len - 5); + runes_screen_set_window_title(t, buf + 4, len - 5); } static void runes_parser_handle_osc1(RunesTerm *t, char *buf, size_t len) { - runes_window_backend_set_icon_name(t, buf + 4, len - 5); + runes_screen_set_icon_name(t, buf + 4, len - 5); } static void runes_parser_handle_osc2(RunesTerm *t, char *buf, size_t len) { - runes_window_backend_set_window_title(t, buf + 4, len - 5); + runes_screen_set_window_title(t, buf + 4, len - 5); } static void runes_parser_handle_ascii(RunesTerm *t, char *text, size_t len) { - runes_display_show_string_ascii(t, text, len); + runes_screen_show_string_ascii(t, text, len); } static void runes_parser_handle_text(RunesTerm *t, char *text, size_t len) { - runes_display_show_string_utf8(t, text, len); + runes_screen_show_string_utf8(t, text, len); } /* XXX these are copied from the generated file so that I can add the UNUSED diff --git a/src/pty-unix.c b/src/pty-unix.c index 0a4dc8b..c969394 100644 --- a/src/pty-unix.c +++ b/src/pty-unix.c @@ -99,8 +99,8 @@ void runes_pty_backend_set_window_size(RunesTerm *t) { struct winsize size; - size.ws_row = t->rows; - size.ws_col = t->cols; + size.ws_row = t->scr.max.row; + size.ws_col = t->scr.max.col; size.ws_xpixel = t->xpixel; size.ws_ypixel = t->ypixel; ioctl(t->pty.master, TIOCSWINSZ, &size); @@ -144,7 +144,7 @@ static void runes_pty_backend_got_data(uv_work_t *req, int status) UNUSED(status); if (t->readlen > 0) { - runes_parser_process_string( + runes_screen_process_string( t, t->readbuf, t->readlen + t->remaininglen); uv_queue_work( t->loop, req, runes_pty_backend_read, runes_pty_backend_got_data); diff --git a/src/runes.h b/src/runes.h index 8c2861b..d4e8d9f 100644 --- a/src/runes.h +++ b/src/runes.h @@ -10,11 +10,13 @@ struct runes_term; struct runes_window; struct runes_pty; +struct runes_screen; struct runes_loop_data; typedef struct runes_term RunesTerm; typedef struct runes_window RunesWindowBackend; typedef struct runes_pty RunesPtyBackend; +typedef struct runes_screen RunesScreen; typedef struct runes_loop_data RunesLoopData; struct runes_loop_data { @@ -25,9 +27,9 @@ struct runes_loop_data { #include "window-xlib.h" #include "pty-unix.h" +#include "screen.h" #include "term.h" #include "display.h" -#include "parser.h" #include "config.h" #define UNUSED(x) ((void)x) diff --git a/src/screen.c b/src/screen.c new file mode 100644 index 0000000..b8e903a --- /dev/null +++ b/src/screen.c @@ -0,0 +1,369 @@ +#include +#include + +#include "runes.h" +#include "parser.h" + +void runes_screen_init(RunesTerm *t) +{ + int i; + + t->scr.rows = calloc(t->scr.max.row, sizeof(struct runes_row)); + for (i = 0; i < t->scr.max.row; ++i) { + t->scr.rows[i].cells = calloc( + t->scr.max.col, sizeof(struct runes_cell)); + } +} + +void runes_screen_process_string(RunesTerm *t, char *buf, size_t len) +{ + YY_BUFFER_STATE state; + yyscan_t scanner; + int remaining; + + /* XXX this will break if buf ends with a partial escape sequence or utf8 + * character. we need to detect that and not consume the entire input in + * that case */ + runes_parser_yylex_init_extra(t, &scanner); + state = runes_parser_yy_scan_bytes(buf, len, scanner); + while ((remaining = runes_parser_yylex(scanner)) == -1); + t->remaininglen = remaining; + if (t->remaininglen) { + memmove(t->readbuf, &buf[len - t->remaininglen], t->remaininglen); + } + runes_parser_yy_delete_buffer(state, scanner); + runes_parser_yylex_destroy(scanner); + + runes_display_draw_screen(t); +} + +void runes_screen_audible_bell(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "audible_bell nyi\n"); +} + +void runes_screen_visual_bell(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "visual_bell nyi\n"); +} + +void runes_screen_show_string_ascii(RunesTerm *t, char *buf, size_t len) +{ + RunesScreen *scr = &t->scr; + size_t i; + + for (i = 0; i < len; ++i) { + struct runes_cell *cell = &scr->rows[scr->cur.row].cells[scr->cur.col]; + + cell->contents[0] = buf[i]; + cell->contents[1] = '\0'; + cell->len = 1; + + scr->cur.col++; + if (scr->cur.col >= scr->max.col) { + scr->cur.col = 0; + scr->cur.row++; + } + } +} + +void runes_screen_show_string_utf8(RunesTerm *t, char *buf, size_t len) +{ + UNUSED(t); + UNUSED(buf); + UNUSED(len); + fprintf(stderr, "show_string_utf8 nyi\n"); +} + +void runes_screen_move_to(RunesTerm *t, int row, int col) +{ + RunesScreen *scr = &t->scr; + + scr->cur.row = row; + scr->cur.col = col; +} + +void runes_screen_clear_screen(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "clear_screen nyi\n"); +} + +void runes_screen_clear_screen_forward(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "clear_screen_forward nyi\n"); +} + +void runes_screen_clear_screen_backward(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "clear_screen_backward nyi\n"); +} + +void runes_screen_kill_line(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "kill_line nyi\n"); +} + +void runes_screen_kill_line_forward(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "kill_line_forward nyi\n"); +} + +void runes_screen_kill_line_backward(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "kill_line_backward nyi\n"); +} + +void runes_screen_insert_characters(RunesTerm *t, int count) +{ + UNUSED(t); + UNUSED(count); + fprintf(stderr, "insert_characters nyi\n"); +} + +void runes_screen_insert_lines(RunesTerm *t, int count) +{ + UNUSED(t); + UNUSED(count); + fprintf(stderr, "insert_lines nyi\n"); +} + +void runes_screen_delete_characters(RunesTerm *t, int count) +{ + UNUSED(t); + UNUSED(count); + fprintf(stderr, "delete_characters nyi\n"); +} + +void runes_screen_delete_lines(RunesTerm *t, int count) +{ + UNUSED(t); + UNUSED(count); + fprintf(stderr, "delete_lines nyi\n"); +} + +void runes_screen_set_scroll_region( + RunesTerm *t, int top, int bottom, int left, int right) +{ + UNUSED(t); + UNUSED(top); + UNUSED(bottom); + UNUSED(left); + UNUSED(right); + fprintf(stderr, "set_scroll_region nyi\n"); +} + +void runes_screen_reset_text_attributes(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "reset_text_attributes nyi\n"); +} + +void runes_screen_set_fg_color(RunesTerm *t, int idx) +{ + UNUSED(t); + UNUSED(idx); + fprintf(stderr, "set_fg_color nyi\n"); +} + +void runes_screen_set_fg_color_rgb(RunesTerm *t, int r, int g, int b) +{ + UNUSED(t); + UNUSED(r); + UNUSED(g); + UNUSED(b); + fprintf(stderr, "set_fg_color_rgb nyi\n"); +} + +void runes_screen_reset_fg_color(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "reset_fg_color nyi\n"); +} + +void runes_screen_set_bg_color(RunesTerm *t, int idx) +{ + UNUSED(t); + UNUSED(idx); + fprintf(stderr, "set_bg_color nyi\n"); +} + +void runes_screen_set_bg_color_rgb(RunesTerm *t, int r, int g, int b) +{ + UNUSED(t); + UNUSED(r); + UNUSED(g); + UNUSED(b); + fprintf(stderr, "set_bg_color_rgb nyi\n"); +} + +void runes_screen_reset_bg_color(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "reset_bg_color nyi\n"); +} + +void runes_screen_set_bold(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "set_bold nyi\n"); +} + +void runes_screen_set_italic(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "set_italic nyi\n"); +} + +void runes_screen_set_underline(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "set_underline nyi\n"); +} + +void runes_screen_set_inverse(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "set_inverse nyi\n"); +} + +void runes_screen_reset_bold(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "reset_bold nyi\n"); +} + +void runes_screen_reset_italic(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "reset_italic nyi\n"); +} + +void runes_screen_reset_underline(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "reset_underline nyi\n"); +} + +void runes_screen_reset_inverse(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "reset_inverse nyi\n"); +} + +void runes_screen_use_alternate_buffer(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "use_alternate_buffer nyi\n"); +} + +void runes_screen_use_normal_buffer(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "use_normal_buffer nyi\n"); +} + +void runes_screen_save_cursor(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "save_cursor nyi\n"); +} + +void runes_screen_restore_cursor(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "restore_cursor nyi\n"); +} + +void runes_screen_show_cursor(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "show_cursor nyi\n"); +} + +void runes_screen_hide_cursor(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "hide_cursor nyi\n"); +} + +void runes_screen_set_application_keypad(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "set_application_keypad nyi\n"); +} + +void runes_screen_reset_application_keypad(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "reset_application_keypad nyi\n"); +} + +void runes_screen_set_application_cursor(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "set_application_cursor nyi\n"); +} + +void runes_screen_reset_application_cursor(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "reset_application_cursor nyi\n"); +} + +void runes_screen_set_mouse_reporting_press(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "set_mouse_reporting_press nyi\n"); +} + +void runes_screen_reset_mouse_reporting_press(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "reset_mouse_reporting_press nyi\n"); +} + +void runes_screen_set_mouse_reporting_press_release(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "set_mouse_reporting_press_release nyi\n"); +} + +void runes_screen_reset_mouse_reporting_press_release(RunesTerm *t) +{ + UNUSED(t); + fprintf(stderr, "reset_mouse_reporting_press_release nyi\n"); +} + +void runes_screen_set_window_title(RunesTerm *t, char *buf, size_t len) +{ + UNUSED(t); + UNUSED(buf); + UNUSED(len); + fprintf(stderr, "set_window_title nyi\n"); +} + +void runes_screen_set_icon_name(RunesTerm *t, char *buf, size_t len) +{ + UNUSED(t); + UNUSED(buf); + UNUSED(len); + fprintf(stderr, "set_icon_name nyi\n"); +} + +void runes_screen_cleanup(RunesTerm *t) +{ + int i; + + for (i = 0; i < t->scr.max.row; ++i) { + free(t->scr.rows[i].cells); + } + free(t->scr.rows); +} diff --git a/src/screen.h b/src/screen.h new file mode 100644 index 0000000..77f12f2 --- /dev/null +++ b/src/screen.h @@ -0,0 +1,128 @@ +#ifndef _RUNES_SCREEN_H +#define _RUNES_SCREEN_H + +enum RunesColorType { + RUNES_COLOR_DEFAULT, + RUNES_COLOR_IDX, + RUNES_COLOR_RGB +}; + +struct runes_loc { + int row; + int col; +}; + +struct runes_color { + union { + struct { + unsigned char r; + unsigned char g; + unsigned char b; + }; + unsigned char idx; + }; + unsigned char type; +}; + +struct runes_cell { + char contents[8]; + size_t len; + struct runes_color fgcolor; + struct runes_color bgcolor; + unsigned char bold: 1; + unsigned char italic: 1; + unsigned char underline: 1; + unsigned char inverse: 1; +}; + +struct runes_row { + struct runes_cell *cells; + unsigned char dirty: 1; +}; + +struct runes_screen { + struct runes_loc cur; + struct runes_loc max; + struct runes_loc saved; + + int scroll_top; + int scroll_bottom; + + char *title; + char *icon_name; + + struct runes_row *rows; + + struct runes_color fgcolor; + struct runes_color bgcolor; + + unsigned char bold: 1; + unsigned char italic: 1; + unsigned char underline: 1; + unsigned char inverse: 1; + + unsigned char hide_cursor: 1; + unsigned char application_keypad: 1; + unsigned char application_cursor: 1; + unsigned char mouse_reporting_press: 1; + unsigned char mouse_reporting_press_release: 1; + + unsigned char visual_bell: 1; + unsigned char audible_bell: 1; + unsigned char update_title: 1; + unsigned char update_icon_name: 1; +}; + +void runes_screen_init(RunesTerm *t); +void runes_screen_process_string(RunesTerm *t, char *buf, size_t len); +void runes_screen_audible_bell(RunesTerm *t); +void runes_screen_visual_bell(RunesTerm *t); +void runes_screen_show_string_ascii(RunesTerm *t, char *buf, size_t len); +void runes_screen_show_string_utf8(RunesTerm *t, char *buf, size_t len); +void runes_screen_move_to(RunesTerm *t, int row, int col); +void runes_screen_clear_screen(RunesTerm *t); +void runes_screen_clear_screen_forward(RunesTerm *t); +void runes_screen_clear_screen_backward(RunesTerm *t); +void runes_screen_kill_line(RunesTerm *t); +void runes_screen_kill_line_forward(RunesTerm *t); +void runes_screen_kill_line_backward(RunesTerm *t); +void runes_screen_insert_characters(RunesTerm *t, int count); +void runes_screen_insert_lines(RunesTerm *t, int count); +void runes_screen_delete_characters(RunesTerm *t, int count); +void runes_screen_delete_lines(RunesTerm *t, int count); +void runes_screen_set_scroll_region( + RunesTerm *t, int top, int bottom, int left, int right); +void runes_screen_reset_text_attributes(RunesTerm *t); +void runes_screen_set_fg_color(RunesTerm *t, int idx); +void runes_screen_set_fg_color_rgb(RunesTerm *t, int r, int g, int b); +void runes_screen_reset_fg_color(RunesTerm *t); +void runes_screen_set_bg_color(RunesTerm *t, int idx); +void runes_screen_set_bg_color_rgb(RunesTerm *t, int r, int g, int b); +void runes_screen_reset_bg_color(RunesTerm *t); +void runes_screen_set_bold(RunesTerm *t); +void runes_screen_set_italic(RunesTerm *t); +void runes_screen_set_underline(RunesTerm *t); +void runes_screen_set_inverse(RunesTerm *t); +void runes_screen_reset_bold(RunesTerm *t); +void runes_screen_reset_italic(RunesTerm *t); +void runes_screen_reset_underline(RunesTerm *t); +void runes_screen_reset_inverse(RunesTerm *t); +void runes_screen_use_alternate_buffer(RunesTerm *t); +void runes_screen_use_normal_buffer(RunesTerm *t); +void runes_screen_save_cursor(RunesTerm *t); +void runes_screen_restore_cursor(RunesTerm *t); +void runes_screen_show_cursor(RunesTerm *t); +void runes_screen_hide_cursor(RunesTerm *t); +void runes_screen_set_application_keypad(RunesTerm *t); +void runes_screen_reset_application_keypad(RunesTerm *t); +void runes_screen_set_application_cursor(RunesTerm *t); +void runes_screen_reset_application_cursor(RunesTerm *t); +void runes_screen_set_mouse_reporting_press(RunesTerm *t); +void runes_screen_reset_mouse_reporting_press(RunesTerm *t); +void runes_screen_set_mouse_reporting_press_release(RunesTerm *t); +void runes_screen_reset_mouse_reporting_press_release(RunesTerm *t); +void runes_screen_set_window_title(RunesTerm *t, char *buf, size_t len); +void runes_screen_set_icon_name(RunesTerm *t, char *buf, size_t len); +void runes_screen_destroy(RunesTerm *t); + +#endif diff --git a/src/term.c b/src/term.c index 34cb4c7..21f2d1d 100644 --- a/src/term.c +++ b/src/term.c @@ -9,6 +9,7 @@ void runes_term_init(RunesTerm *t, int argc, char *argv[]) runes_pty_backend_spawn_subprocess(t); runes_display_set_window_size(t); + runes_screen_init(t); t->loop = uv_default_loop(); runes_window_backend_start_loop(t); diff --git a/src/term.h b/src/term.h index 71e0bcc..6baf961 100644 --- a/src/term.h +++ b/src/term.h @@ -4,12 +4,26 @@ struct runes_term { RunesWindowBackend w; RunesPtyBackend pty; + RunesScreen scr; cairo_t *cr; cairo_t *backend_cr; - cairo_t *alternate_cr; uv_loop_t *loop; + PangoLayout *layout; + + char readbuf[RUNES_READ_BUFFER_LENGTH]; + int readlen; + int remaininglen; + + int xpixel; + int ypixel; + int fontx; + int fonty; + + char visual_bell_is_ringing; + char unfocused; + cairo_pattern_t *mousecursorcolor; cairo_pattern_t *cursorcolor; @@ -19,48 +33,16 @@ struct runes_term { cairo_pattern_t *fgcustom; cairo_pattern_t *bgcustom; - int fgcolor; - int bgcolor; - - int row; - int col; - int saved_row; - int saved_col; - int scroll_top; - int scroll_bottom; - - int rows; - int cols; - int xpixel; - int ypixel; - int fontx; - int fonty; int default_rows; int default_cols; char *cmd; - char *font_name; - PangoLayout *layout; - - char readbuf[RUNES_READ_BUFFER_LENGTH]; - int readlen; - int remaininglen; char bell_is_urgent; char bold_is_bright; char bold_is_bold; - char bold; - char inverse; - char hide_cursor; - char unfocused; char audible_bell; - char visual_bell_is_ringing; - - char application_keypad; - char application_cursor; - char mouse_reporting_press; - char mouse_reporting_press_release; }; void runes_term_init(RunesTerm *t, int argc, char *argv[]); diff --git a/src/window-xlib.c b/src/window-xlib.c index 5cd2b04..fcb13ef 100644 --- a/src/window-xlib.c +++ b/src/window-xlib.c @@ -498,21 +498,22 @@ static void runes_window_backend_audible_bell(RunesTerm *t) static void runes_window_backend_draw_cursor(RunesTerm *t) { - if (!t->hide_cursor) { + if (!t->scr.hide_cursor) { cairo_save(t->backend_cr); cairo_set_source(t->backend_cr, t->cursorcolor); if (t->unfocused) { cairo_set_line_width(t->backend_cr, 1); cairo_rectangle( t->backend_cr, - t->col * t->fontx + 0.5, t->row * t->fonty + 0.5, + t->scr.cur.col * t->fontx + 0.5, + t->scr.cur.row * t->fonty + 0.5, t->fontx, t->fonty); cairo_stroke(t->backend_cr); } else { cairo_rectangle( t->backend_cr, - t->col * t->fontx, t->row * t->fonty, + t->scr.cur.col * t->fontx, t->scr.cur.row * t->fonty, t->fontx, t->fonty); cairo_fill(t->backend_cr); } @@ -620,8 +621,8 @@ static struct function_key *runes_window_backend_find_key_sequence( { struct function_key *key; - if (t->application_keypad) { - if (t->application_cursor) { + if (t->scr.application_keypad) { + if (t->scr.application_cursor) { key = &application_cursor_keys[0]; while (key->sym != XK_VoidSymbol) { if (key->sym == sym) { @@ -658,7 +659,7 @@ static void runes_window_backend_handle_button_event( } } - if (t->mouse_reporting_press_release) { + if (t->scr.mouse_reporting_press_release) { char response[7]; char status = 0; @@ -706,7 +707,7 @@ static void runes_window_backend_handle_button_event( ' ' + (e->y / t->fonty + 1)); runes_pty_backend_write(t, response, 6); } - else if (t->mouse_reporting_press && e->type == ButtonPress) { + else if (t->scr.mouse_reporting_press && e->type == ButtonPress) { char response[7]; sprintf( @@ -762,10 +763,10 @@ static void runes_window_backend_handle_focus_event( { runes_window_backend_clear_urgent(t); if (e->type == FocusIn) { - runes_display_focus_in(t); + t->unfocused = 0; } else { - runes_display_focus_out(t); + t->unfocused = 1; } runes_window_backend_flush(t); } -- cgit v1.2.3-54-g00ecf