Fast and reasonably complete (framebuffer) terminal emulator (Zig fork)

Misc improvements

mintsuki 9225cfb1 54238d9e

Changed files
+105 -8
backends
+6 -5
backends/framebuffer.c
···
static void fbterm_raw_putchar(struct term_context *_ctx, uint8_t c) {
struct fbterm_context *ctx = (void *)_ctx;
-
struct fbterm_char ch;
-
ch.c = c;
-
ch.fg = ctx->text_fg;
-
ch.bg = ctx->text_bg;
-
push_to_queue(_ctx, &ch, ctx->cursor_x++, ctx->cursor_y);
if (ctx->cursor_x == _ctx->cols && (ctx->cursor_y < _ctx->scroll_bottom_margin - 1 || _ctx->scroll_enabled)) {
ctx->cursor_x = 0;
ctx->cursor_y++;
···
ctx->cursor_y--;
fbterm_scroll(_ctx);
}
+
+
struct fbterm_char ch;
+
ch.c = c;
+
ch.fg = ctx->text_fg;
+
ch.bg = ctx->text_bg;
+
push_to_queue(_ctx, &ch, ctx->cursor_x++, ctx->cursor_y);
}
static void fbterm_full_refresh(struct term_context *_ctx) {
+93 -3
term.c
···
ctx->control_sequence = false;
ctx->csi = false;
ctx->escape = false;
+
ctx->osc = false;
+
ctx->osc_escape = false;
ctx->rrr = false;
ctx->discard_next = false;
ctx->bold = false;
+
ctx->bg_bold = false;
ctx->reverse_video = false;
ctx->dec_private = false;
ctx->insert_mode = false;
···
ctx->saved_cursor_x = 0;
ctx->saved_cursor_y = 0;
ctx->current_primary = (size_t)-1;
+
ctx->current_bg = (size_t)-1;
ctx->scroll_top_margin = 0;
ctx->scroll_bottom_margin = ctx->rows;
}
···
ctx->swap_palette(ctx);
}
ctx->bold = false;
+
ctx->bg_bold = false;
ctx->current_primary = (size_t)-1;
+
ctx->current_bg = (size_t)-1;
ctx->set_text_bg_default(ctx);
ctx->set_text_fg_default(ctx);
continue;
···
continue;
}
+
else if (ctx->esc_values[i] == 5) {
+
ctx->bg_bold = true;
+
if (ctx->current_bg != (size_t)-1) {
+
if (!ctx->reverse_video) {
+
ctx->set_text_bg_bright(ctx, ctx->current_bg);
+
} else {
+
ctx->set_text_fg_bright(ctx, ctx->current_bg);
+
}
+
}
+
continue;
+
}
+
else if (ctx->esc_values[i] == 22) {
ctx->bold = false;
if (ctx->current_primary != (size_t)-1) {
···
continue;
}
+
else if (ctx->esc_values[i] == 25) {
+
ctx->bg_bold = false;
+
if (ctx->current_bg != (size_t)-1) {
+
if (!ctx->reverse_video) {
+
ctx->set_text_bg(ctx, ctx->current_bg);
+
} else {
+
ctx->set_text_fg(ctx, ctx->current_bg);
+
}
+
}
+
continue;
+
}
+
else if (ctx->esc_values[i] >= 30 && ctx->esc_values[i] <= 37) {
offset = 30;
ctx->current_primary = ctx->esc_values[i] - offset;
···
}
set_fg:
-
if (ctx->bold && !ctx->reverse_video) {
+
if ((ctx->bold && !ctx->reverse_video)
+
|| (ctx->bg_bold && ctx->reverse_video)) {
ctx->set_text_fg_bright(ctx, ctx->esc_values[i] - offset);
} else {
ctx->set_text_fg(ctx, ctx->esc_values[i] - offset);
···
else if (ctx->esc_values[i] >= 40 && ctx->esc_values[i] <= 47) {
offset = 40;
+
ctx->current_bg = ctx->esc_values[i] - offset;
+
if (ctx->reverse_video) {
goto set_fg;
}
set_bg:
-
if (ctx->bold && ctx->reverse_video) {
+
if ((ctx->bold && ctx->reverse_video)
+
|| (ctx->bg_bold && !ctx->reverse_video)) {
ctx->set_text_bg_bright(ctx, ctx->esc_values[i] - offset);
} else {
ctx->set_text_bg(ctx, ctx->esc_values[i] - offset);
···
else if (ctx->esc_values[i] >= 100 && ctx->esc_values[i] <= 107) {
offset = 100;
+
ctx->current_bg = ctx->esc_values[i] - offset;
+
if (ctx->reverse_video) {
goto set_fg_bright;
}
···
}
else if (ctx->esc_values[i] == 49) {
+
ctx->current_bg = (size_t)-1;
+
if (ctx->reverse_video) {
ctx->swap_palette(ctx);
}
···
}
}
+
static void osc_parse(struct term_context *ctx, uint8_t c) {
+
if (ctx->osc_escape && c == '\\') {
+
goto cleanup;
+
}
+
+
ctx->osc_escape = false;
+
+
switch (c) {
+
case 0x1b:
+
ctx->osc_escape = true;
+
break;
+
case '\a':
+
goto cleanup;
+
}
+
+
return;
+
+
cleanup:
+
ctx->osc_escape = false;
+
ctx->osc = false;
+
ctx->escape = false;
+
}
+
static void control_sequence_parse(struct term_context *ctx, uint8_t c) {
if (ctx->escape_offset == 2) {
switch (c) {
···
ctx->esc_values[0] = ctx->rows - 1;
ctx->set_cursor_pos(ctx, ctx->esc_values[1], ctx->esc_values[0]);
break;
+
case 'M':
+
for (size_t i = 0; i < ctx->esc_values[0]; i++) {
+
ctx->scroll(ctx);
+
}
+
break;
+
case 'L': {
+
size_t old_scroll_top_margin = ctx->scroll_top_margin;
+
ctx->scroll_top_margin = y + 1;
+
for (size_t i = 0; i < ctx->esc_values[0]; i++) {
+
ctx->revscroll(ctx);
+
}
+
ctx->scroll_top_margin = old_scroll_top_margin;
+
break;
+
}
case 'n':
switch (ctx->esc_values[0]) {
case 5:
···
case 0: {
size_t rows_remaining = ctx->rows - (y + 1);
size_t cols_diff = ctx->cols - (x + 1);
-
size_t to_clear = rows_remaining * ctx->cols + cols_diff;
+
size_t to_clear = rows_remaining * ctx->cols + cols_diff + 1;
for (size_t i = 0; i < to_clear; i++) {
ctx->raw_putchar(ctx, ' ');
}
···
static void restore_state(struct term_context *ctx) {
ctx->bold = ctx->saved_state_bold;
+
ctx->bg_bold = ctx->saved_state_bg_bold;
ctx->reverse_video = ctx->saved_state_reverse_video;
ctx->current_charset = ctx->saved_state_current_charset;
ctx->current_primary = ctx->saved_state_current_primary;
+
ctx->current_bg = ctx->saved_state_current_bg;
ctx->restore_state(ctx);
}
···
ctx->save_state(ctx);
ctx->saved_state_bold = ctx->bold;
+
ctx->saved_state_bg_bold = ctx->bg_bold;
ctx->saved_state_reverse_video = ctx->reverse_video;
ctx->saved_state_current_charset = ctx->current_charset;
ctx->saved_state_current_primary = ctx->current_primary;
+
ctx->saved_state_current_bg = ctx->current_bg;
}
static void escape_parse(struct term_context *ctx, uint8_t c) {
ctx->escape_offset++;
+
+
if (ctx->osc == true) {
+
osc_parse(ctx, c);
+
return;
+
}
if (ctx->control_sequence == true) {
control_sequence_parse(ctx, c);
···
ctx->get_cursor_pos(ctx, &x, &y);
switch (c) {
+
case ']':
+
ctx->osc_escape = false;
+
ctx->osc = true;
+
return;
case '[':
is_csi:
for (size_t i = 0; i < TERM_MAX_ESC_VALUES; i++)
···
ctx->escape = false;
ctx->csi = false;
ctx->control_sequence = false;
+
ctx->osc = false;
+
ctx->osc_escape = false;
ctx->g_select = 0;
return;
}
+6
term.h
···
bool control_sequence;
bool csi;
bool escape;
+
bool osc;
+
bool osc_escape;
bool rrr;
bool discard_next;
bool bold;
+
bool bg_bold;
bool reverse_video;
bool dec_private;
bool insert_mode;
···
size_t saved_cursor_x;
size_t saved_cursor_y;
size_t current_primary;
+
size_t current_bg;
size_t scroll_top_margin;
size_t scroll_bottom_margin;
uint32_t esc_values[TERM_MAX_ESC_VALUES];
bool saved_state_bold;
+
bool saved_state_bg_bold;
bool saved_state_reverse_video;
size_t saved_state_current_charset;
size_t saved_state_current_primary;
+
size_t saved_state_current_bg;
/* to be set by backend */