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

Rebrand to Flanterm

mintsuki 87bfe509 30cd1dfc

Changed files
+299 -299
backends
LICENSE.md LICENSE
+109 -109
backends/framebuffer.c backends/fb.c
···
#include <stdint.h>
#include <stddef.h>
-
#include "../term.h"
-
#include "framebuffer.h"
+
#include "../flanterm.h"
+
#include "fb.h"
void *memset(void *, int, size_t);
void *memcpy(void *, const void *, size_t);
···
0x00, 0x00, 0x00, 0x00
};
-
static void fbterm_save_state(struct term_context *_ctx) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_save_state(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->saved_state_text_fg = ctx->text_fg;
ctx->saved_state_text_bg = ctx->text_bg;
ctx->saved_state_cursor_x = ctx->cursor_x;
ctx->saved_state_cursor_y = ctx->cursor_y;
}
-
static void fbterm_restore_state(struct term_context *_ctx) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_restore_state(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_fg = ctx->saved_state_text_fg;
ctx->text_bg = ctx->saved_state_text_bg;
ctx->cursor_x = ctx->saved_state_cursor_x;
ctx->cursor_y = ctx->saved_state_cursor_y;
}
-
static void fbterm_swap_palette(struct term_context *_ctx) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_swap_palette(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
uint32_t tmp = ctx->text_bg;
ctx->text_bg = ctx->text_fg;
ctx->text_fg = tmp;
}
-
static void plot_char(struct term_context *_ctx, struct fbterm_char *c, size_t x, size_t y) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void plot_char(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
if (x >= _ctx->cols || y >= _ctx->rows) {
return;
···
}
}
-
static void plot_char_fast(struct term_context *_ctx, struct fbterm_char *old, struct fbterm_char *c, size_t x, size_t y) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void plot_char_fast(struct flanterm_context *_ctx, struct flanterm_fb_char *old, struct flanterm_fb_char *c, size_t x, size_t y) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
if (x >= _ctx->cols || y >= _ctx->rows) {
return;
···
}
}
-
static inline bool compare_char(struct fbterm_char *a, struct fbterm_char *b) {
+
static inline bool compare_char(struct flanterm_fb_char *a, struct flanterm_fb_char *b) {
return !(a->c != b->c || a->bg != b->bg || a->fg != b->fg);
}
-
static void push_to_queue(struct term_context *_ctx, struct fbterm_char *c, size_t x, size_t y) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void push_to_queue(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
if (x >= _ctx->cols || y >= _ctx->rows) {
return;
···
size_t i = y * _ctx->cols + x;
-
struct fbterm_queue_item *q = ctx->map[i];
+
struct flanterm_fb_queue_item *q = ctx->map[i];
if (q == NULL) {
if (compare_char(&ctx->grid[i], c)) {
···
q->c = *c;
}
-
static void fbterm_revscroll(struct term_context *_ctx) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_revscroll(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
for (size_t i = (_ctx->scroll_bottom_margin - 1) * _ctx->cols - 1;
i >= _ctx->scroll_top_margin * _ctx->cols; i--) {
if (i == (size_t)-1) {
break;
}
-
struct fbterm_char *c;
-
struct fbterm_queue_item *q = ctx->map[i];
+
struct flanterm_fb_char *c;
+
struct flanterm_fb_queue_item *q = ctx->map[i];
if (q != NULL) {
c = &q->c;
} else {
···
}
// Clear the first line of the screen.
-
struct fbterm_char empty;
+
struct flanterm_fb_char empty;
empty.c = ' ';
empty.fg = ctx->text_fg;
empty.bg = ctx->text_bg;
···
}
}
-
static void fbterm_scroll(struct term_context *_ctx) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_scroll(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
for (size_t i = (_ctx->scroll_top_margin + 1) * _ctx->cols;
i < _ctx->scroll_bottom_margin * _ctx->cols; i++) {
-
struct fbterm_char *c;
-
struct fbterm_queue_item *q = ctx->map[i];
+
struct flanterm_fb_char *c;
+
struct flanterm_fb_queue_item *q = ctx->map[i];
if (q != NULL) {
c = &q->c;
} else {
···
}
// Clear the last line of the screen.
-
struct fbterm_char empty;
+
struct flanterm_fb_char empty;
empty.c = ' ';
empty.fg = ctx->text_fg;
empty.bg = ctx->text_bg;
···
}
}
-
static void fbterm_clear(struct term_context *_ctx, bool move) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_clear(struct flanterm_context *_ctx, bool move) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
-
struct fbterm_char empty;
+
struct flanterm_fb_char empty;
empty.c = ' ';
empty.fg = ctx->text_fg;
empty.bg = ctx->text_bg;
···
}
}
-
static void fbterm_set_cursor_pos(struct term_context *_ctx, size_t x, size_t y) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_set_cursor_pos(struct flanterm_context *_ctx, size_t x, size_t y) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
if (x >= _ctx->cols) {
if ((int)x < 0) {
···
ctx->cursor_y = y;
}
-
static void fbterm_get_cursor_pos(struct term_context *_ctx, size_t *x, size_t *y) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_get_cursor_pos(struct flanterm_context *_ctx, size_t *x, size_t *y) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
*x = ctx->cursor_x >= _ctx->cols ? _ctx->cols - 1 : ctx->cursor_x;
*y = ctx->cursor_y >= _ctx->rows ? _ctx->rows - 1 : ctx->cursor_y;
}
-
static void fbterm_move_character(struct term_context *_ctx, size_t new_x, size_t new_y, size_t old_x, size_t old_y) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_move_character(struct flanterm_context *_ctx, size_t new_x, size_t new_y, size_t old_x, size_t old_y) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
if (old_x >= _ctx->cols || old_y >= _ctx->rows
|| new_x >= _ctx->cols || new_y >= _ctx->rows) {
···
size_t i = old_x + old_y * _ctx->cols;
-
struct fbterm_char *c;
-
struct fbterm_queue_item *q = ctx->map[i];
+
struct flanterm_fb_char *c;
+
struct flanterm_fb_queue_item *q = ctx->map[i];
if (q != NULL) {
c = &q->c;
} else {
···
push_to_queue(_ctx, c, new_x, new_y);
}
-
static void fbterm_set_text_fg(struct term_context *_ctx, size_t fg) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_set_text_fg(struct flanterm_context *_ctx, size_t fg) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_fg = ctx->ansi_colours[fg];
}
-
static void fbterm_set_text_bg(struct term_context *_ctx, size_t bg) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_set_text_bg(struct flanterm_context *_ctx, size_t bg) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_bg = ctx->ansi_colours[bg];
}
-
static void fbterm_set_text_fg_bright(struct term_context *_ctx, size_t fg) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_set_text_fg_bright(struct flanterm_context *_ctx, size_t fg) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_fg = ctx->ansi_bright_colours[fg];
}
-
static void fbterm_set_text_bg_bright(struct term_context *_ctx, size_t bg) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_set_text_bg_bright(struct flanterm_context *_ctx, size_t bg) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_bg = ctx->ansi_bright_colours[bg];
}
-
static void fbterm_set_text_fg_rgb(struct term_context *_ctx, uint32_t fg) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_set_text_fg_rgb(struct flanterm_context *_ctx, uint32_t fg) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_fg = fg;
}
-
static void fbterm_set_text_bg_rgb(struct term_context *_ctx, uint32_t bg) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_set_text_bg_rgb(struct flanterm_context *_ctx, uint32_t bg) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_bg = bg;
}
-
static void fbterm_set_text_fg_default(struct term_context *_ctx) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_set_text_fg_default(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_fg = ctx->default_fg;
}
-
static void fbterm_set_text_bg_default(struct term_context *_ctx) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_set_text_bg_default(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_bg = 0xffffffff;
}
-
static void fbterm_set_text_fg_default_bright(struct term_context *_ctx) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_set_text_fg_default_bright(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_fg = ctx->default_fg_bright;
}
-
static void fbterm_set_text_bg_default_bright(struct term_context *_ctx) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_set_text_bg_default_bright(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_bg = ctx->default_bg_bright;
}
-
static void draw_cursor(struct term_context *_ctx) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void draw_cursor(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
if (ctx->cursor_x >= _ctx->cols || ctx->cursor_y >= _ctx->rows) {
return;
···
size_t i = ctx->cursor_x + ctx->cursor_y * _ctx->cols;
-
struct fbterm_char c;
-
struct fbterm_queue_item *q = ctx->map[i];
+
struct flanterm_fb_char c;
+
struct flanterm_fb_queue_item *q = ctx->map[i];
if (q != NULL) {
c = q->c;
} else {
···
}
}
-
static void fbterm_double_buffer_flush(struct term_context *_ctx) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_double_buffer_flush(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
if (_ctx->cursor_enabled) {
draw_cursor(_ctx);
}
for (size_t i = 0; i < ctx->queue_i; i++) {
-
struct fbterm_queue_item *q = &ctx->queue[i];
+
struct flanterm_fb_queue_item *q = &ctx->queue[i];
size_t offset = q->y * _ctx->cols + q->x;
if (ctx->map[offset] == NULL) {
continue;
}
-
struct fbterm_char *old = &ctx->grid[offset];
+
struct flanterm_fb_char *old = &ctx->grid[offset];
if (q->c.bg == old->bg && q->c.fg == old->fg) {
plot_char_fast(_ctx, old, &q->c, q->x, q->y);
} else {
···
ctx->queue_i = 0;
}
-
static void fbterm_raw_putchar(struct term_context *_ctx, uint8_t c) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_raw_putchar(struct flanterm_context *_ctx, uint8_t c) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
if (ctx->cursor_x >= _ctx->cols && (ctx->cursor_y < _ctx->scroll_bottom_margin - 1 || _ctx->scroll_enabled)) {
ctx->cursor_x = 0;
ctx->cursor_y++;
if (ctx->cursor_y == _ctx->scroll_bottom_margin) {
ctx->cursor_y--;
-
fbterm_scroll(_ctx);
+
flanterm_fb_scroll(_ctx);
}
if (ctx->cursor_y >= _ctx->cols) {
ctx->cursor_y = _ctx->cols - 1;
}
}
-
struct fbterm_char ch;
+
struct flanterm_fb_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) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_full_refresh(struct flanterm_context *_ctx) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
for (size_t y = 0; y < ctx->height; y++) {
for (size_t x = 0; x < ctx->width; x++) {
···
}
}
-
static void fbterm_deinit(struct term_context *_ctx, void (*_free)(void *, size_t)) {
-
struct fbterm_context *ctx = (void *)_ctx;
+
static void flanterm_fb_deinit(struct flanterm_context *_ctx, void (*_free)(void *, size_t)) {
+
struct flanterm_fb_context *ctx = (void *)_ctx;
_free(ctx->font_bits, ctx->font_bits_size);
_free(ctx->font_bool, ctx->font_bool_size);
···
_free(ctx->queue, ctx->queue_size);
_free(ctx->map, ctx->map_size);
_free(ctx->canvas, ctx->canvas_size);
-
_free(ctx, sizeof(struct fbterm_context));
+
_free(ctx, sizeof(struct flanterm_fb_context));
}
-
struct term_context *fbterm_init(
+
struct flanterm_context *flanterm_fb_init(
void *(*_malloc)(size_t),
uint32_t *framebuffer, size_t width, size_t height, size_t pitch,
uint32_t *canvas,
···
size_t font_scale_x, size_t font_scale_y,
size_t margin
) {
-
struct fbterm_context *ctx = _malloc(sizeof(struct fbterm_context));
+
struct flanterm_fb_context *ctx = _malloc(sizeof(struct flanterm_fb_context));
-
struct term_context *_ctx = (void *)ctx;
+
struct flanterm_context *_ctx = (void *)ctx;
-
memset(ctx, 0, sizeof(struct fbterm_context));
+
memset(ctx, 0, sizeof(struct flanterm_fb_context));
if (ansi_colours != NULL) {
memcpy(ctx->ansi_colours, ansi_colours, sizeof(ctx->ansi_colours));
···
ctx->height = height;
ctx->pitch = pitch;
-
#define FONT_BYTES ((font_width * font_height * FBTERM_FONT_GLYPHS) / 8)
+
#define FONT_BYTES ((font_width * font_height * FLANTERM_FB_FONT_GLYPHS) / 8)
if (font != NULL) {
ctx->font_width = font_width;
···
ctx->font_width += font_spacing;
-
ctx->font_bool_size = FBTERM_FONT_GLYPHS * font_height * ctx->font_width * sizeof(bool);
+
ctx->font_bool_size = FLANTERM_FB_FONT_GLYPHS * font_height * ctx->font_width * sizeof(bool);
ctx->font_bool = _malloc(ctx->font_bool_size);
-
for (size_t i = 0; i < FBTERM_FONT_GLYPHS; i++) {
+
for (size_t i = 0; i < FLANTERM_FB_FONT_GLYPHS; i++) {
uint8_t *glyph = &ctx->font_bits[i * font_height];
for (size_t y = 0; y < font_height; y++) {
···
ctx->offset_x = margin + ((ctx->width - margin * 2) % ctx->glyph_width) / 2;
ctx->offset_y = margin + ((ctx->height - margin * 2) % ctx->glyph_height) / 2;
-
ctx->grid_size = _ctx->rows * _ctx->cols * sizeof(struct fbterm_char);
+
ctx->grid_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_char);
ctx->grid = _malloc(ctx->grid_size);
for (size_t i = 0; i < _ctx->rows * _ctx->cols; i++) {
ctx->grid[i].c = ' ';
···
ctx->grid[i].bg = ctx->text_bg;
}
-
ctx->queue_size = _ctx->rows * _ctx->cols * sizeof(struct fbterm_queue_item);
+
ctx->queue_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item);
ctx->queue = _malloc(ctx->queue_size);
ctx->queue_i = 0;
memset(ctx->queue, 0, ctx->queue_size);
-
ctx->map_size = _ctx->rows * _ctx->cols * sizeof(struct fbterm_queue_item *);
+
ctx->map_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item *);
ctx->map = _malloc(ctx->map_size);
memset(ctx->map, 0, ctx->map_size);
···
}
}
-
_ctx->raw_putchar = fbterm_raw_putchar;
-
_ctx->clear = fbterm_clear;
-
_ctx->set_cursor_pos = fbterm_set_cursor_pos;
-
_ctx->get_cursor_pos = fbterm_get_cursor_pos;
-
_ctx->set_text_fg = fbterm_set_text_fg;
-
_ctx->set_text_bg = fbterm_set_text_bg;
-
_ctx->set_text_fg_bright = fbterm_set_text_fg_bright;
-
_ctx->set_text_bg_bright = fbterm_set_text_bg_bright;
-
_ctx->set_text_fg_rgb = fbterm_set_text_fg_rgb;
-
_ctx->set_text_bg_rgb = fbterm_set_text_bg_rgb;
-
_ctx->set_text_fg_default = fbterm_set_text_fg_default;
-
_ctx->set_text_bg_default = fbterm_set_text_bg_default;
-
_ctx->set_text_fg_default_bright = fbterm_set_text_fg_default_bright;
-
_ctx->set_text_bg_default_bright = fbterm_set_text_bg_default_bright;
-
_ctx->move_character = fbterm_move_character;
-
_ctx->scroll = fbterm_scroll;
-
_ctx->revscroll = fbterm_revscroll;
-
_ctx->swap_palette = fbterm_swap_palette;
-
_ctx->save_state = fbterm_save_state;
-
_ctx->restore_state = fbterm_restore_state;
-
_ctx->double_buffer_flush = fbterm_double_buffer_flush;
-
_ctx->full_refresh = fbterm_full_refresh;
-
_ctx->deinit = fbterm_deinit;
+
_ctx->raw_putchar = flanterm_fb_raw_putchar;
+
_ctx->clear = flanterm_fb_clear;
+
_ctx->set_cursor_pos = flanterm_fb_set_cursor_pos;
+
_ctx->get_cursor_pos = flanterm_fb_get_cursor_pos;
+
_ctx->set_text_fg = flanterm_fb_set_text_fg;
+
_ctx->set_text_bg = flanterm_fb_set_text_bg;
+
_ctx->set_text_fg_bright = flanterm_fb_set_text_fg_bright;
+
_ctx->set_text_bg_bright = flanterm_fb_set_text_bg_bright;
+
_ctx->set_text_fg_rgb = flanterm_fb_set_text_fg_rgb;
+
_ctx->set_text_bg_rgb = flanterm_fb_set_text_bg_rgb;
+
_ctx->set_text_fg_default = flanterm_fb_set_text_fg_default;
+
_ctx->set_text_bg_default = flanterm_fb_set_text_bg_default;
+
_ctx->set_text_fg_default_bright = flanterm_fb_set_text_fg_default_bright;
+
_ctx->set_text_bg_default_bright = flanterm_fb_set_text_bg_default_bright;
+
_ctx->move_character = flanterm_fb_move_character;
+
_ctx->scroll = flanterm_fb_scroll;
+
_ctx->revscroll = flanterm_fb_revscroll;
+
_ctx->swap_palette = flanterm_fb_swap_palette;
+
_ctx->save_state = flanterm_fb_save_state;
+
_ctx->restore_state = flanterm_fb_restore_state;
+
_ctx->double_buffer_flush = flanterm_fb_double_buffer_flush;
+
_ctx->full_refresh = flanterm_fb_full_refresh;
+
_ctx->deinit = flanterm_fb_deinit;
-
term_context_reinit(_ctx);
-
fbterm_full_refresh(_ctx);
+
flanterm_context_reinit(_ctx);
+
flanterm_fb_full_refresh(_ctx);
return _ctx;
}
+13 -13
backends/framebuffer.h backends/fb.h
···
-
#ifndef _TERM_FRAMEBUFFER_H
-
#define _TERM_FRAMEBUFFER_H
+
#ifndef _FLANTERM_FR_H
+
#define _FLANTERM_FB_H 1
#ifdef __cplusplus
extern "C" {
···
#include <stddef.h>
#include <stdbool.h>
-
#include "../term.h"
+
#include "../flanterm.h"
-
#define FBTERM_FONT_GLYPHS 256
+
#define FLANTERM_FB_FONT_GLYPHS 256
-
struct fbterm_char {
+
struct flanterm_fb_char {
uint32_t c;
uint32_t fg;
uint32_t bg;
};
-
struct fbterm_queue_item {
+
struct flanterm_fb_queue_item {
size_t x, y;
-
struct fbterm_char c;
+
struct flanterm_fb_char c;
};
-
struct fbterm_context {
-
struct term_context term;
+
struct flanterm_fb_context {
+
struct flanterm_context term;
size_t font_width;
size_t font_height;
···
size_t queue_size;
size_t map_size;
-
struct fbterm_char *grid;
+
struct flanterm_fb_char *grid;
-
struct fbterm_queue_item *queue;
+
struct flanterm_fb_queue_item *queue;
size_t queue_i;
-
struct fbterm_queue_item **map;
+
struct flanterm_fb_queue_item **map;
uint32_t text_fg;
uint32_t text_bg;
···
size_t old_cursor_y;
};
-
struct term_context *fbterm_init(
+
struct flanterm_context *flanterm_fb_init(
void *(*_malloc)(size_t),
uint32_t *framebuffer, size_t width, size_t height, size_t pitch,
uint32_t *canvas,
+114
flanterm.h
···
+
#ifndef _FLANTERM_H
+
#define _FLANTERM_H 1
+
+
#ifdef __cplusplus
+
extern "C" {
+
#endif
+
+
#include <stddef.h>
+
#include <stdint.h>
+
#include <stdbool.h>
+
+
#define FLANTERM_MAX_ESC_VALUES 16
+
+
#define FLANTERM_CB_DEC 10
+
#define FLANTERM_CB_BELL 20
+
#define FLANTERM_CB_PRIVATE_ID 30
+
#define FLANTERM_CB_STATUS_REPORT 40
+
#define FLANTERM_CB_POS_REPORT 50
+
#define FLANTERM_CB_KBD_LEDS 60
+
#define FLANTERM_CB_MODE 70
+
#define FLANTERM_CB_LINUX 80
+
+
#define FLANTERM_OOB_OUTPUT_OCRNL (1 << 0)
+
#define FLANTERM_OOB_OUTPUT_OFDEL (1 << 1)
+
#define FLANTERM_OOB_OUTPUT_OFILL (1 << 2)
+
#define FLANTERM_OOB_OUTPUT_OLCUC (1 << 3)
+
#define FLANTERM_OOB_OUTPUT_ONLCR (1 << 4)
+
#define FLANTERM_OOB_OUTPUT_ONLRET (1 << 5)
+
#define FLANTERM_OOB_OUTPUT_ONOCR (1 << 6)
+
#define FLANTERM_OOB_OUTPUT_OPOST (1 << 7)
+
+
struct flanterm_context {
+
/* internal use */
+
+
size_t tab_size;
+
bool autoflush;
+
bool cursor_enabled;
+
bool scroll_enabled;
+
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;
+
uint64_t code_point;
+
size_t unicode_remaining;
+
uint8_t g_select;
+
uint8_t charsets[2];
+
size_t current_charset;
+
size_t escape_offset;
+
size_t esc_values_i;
+
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[FLANTERM_MAX_ESC_VALUES];
+
uint64_t oob_output;
+
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 */
+
+
size_t rows, cols;
+
bool in_bootloader;
+
+
void (*raw_putchar)(struct flanterm_context *, uint8_t c);
+
void (*clear)(struct flanterm_context *, bool move);
+
void (*set_cursor_pos)(struct flanterm_context *, size_t x, size_t y);
+
void (*get_cursor_pos)(struct flanterm_context *, size_t *x, size_t *y);
+
void (*set_text_fg)(struct flanterm_context *, size_t fg);
+
void (*set_text_bg)(struct flanterm_context *, size_t bg);
+
void (*set_text_fg_bright)(struct flanterm_context *, size_t fg);
+
void (*set_text_bg_bright)(struct flanterm_context *, size_t bg);
+
void (*set_text_fg_rgb)(struct flanterm_context *, uint32_t fg);
+
void (*set_text_bg_rgb)(struct flanterm_context *, uint32_t bg);
+
void (*set_text_fg_default)(struct flanterm_context *);
+
void (*set_text_bg_default)(struct flanterm_context *);
+
void (*set_text_fg_default_bright)(struct flanterm_context *);
+
void (*set_text_bg_default_bright)(struct flanterm_context *);
+
void (*move_character)(struct flanterm_context *, size_t new_x, size_t new_y, size_t old_x, size_t old_y);
+
void (*scroll)(struct flanterm_context *);
+
void (*revscroll)(struct flanterm_context *);
+
void (*swap_palette)(struct flanterm_context *);
+
void (*save_state)(struct flanterm_context *);
+
void (*restore_state)(struct flanterm_context *);
+
void (*double_buffer_flush)(struct flanterm_context *);
+
void (*full_refresh)(struct flanterm_context *);
+
void (*deinit)(struct flanterm_context *, void (*)(void *, size_t));
+
+
/* to be set by client */
+
+
void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t, uint64_t);
+
};
+
+
void flanterm_context_reinit(struct flanterm_context *ctx);
+
void flanterm_write(struct flanterm_context *ctx, const char *buf, size_t count);
+
+
#ifdef __cplusplus
+
}
+
#endif
+
+
#endif
+63 -63
term.c flanterm.c
···
#include <stddef.h>
#include <stdbool.h>
-
#include "term.h"
+
#include "flanterm.h"
static const uint32_t col256[] = {
0x000000, 0x00005f, 0x000087, 0x0000af, 0x0000d7, 0x0000ff, 0x005f00, 0x005f5f,
···
#define CHARSET_DEFAULT 0
#define CHARSET_DEC_SPECIAL 1
-
void term_context_reinit(struct term_context *ctx) {
+
void flanterm_context_reinit(struct flanterm_context *ctx) {
ctx->tab_size = 8;
ctx->autoflush = true;
ctx->cursor_enabled = true;
···
ctx->current_bg = (size_t)-1;
ctx->scroll_top_margin = 0;
ctx->scroll_bottom_margin = ctx->rows;
-
ctx->oob_output = TERM_OOB_OUTPUT_ONLCR;
+
ctx->oob_output = FLANTERM_OOB_OUTPUT_ONLCR;
}
-
static void term_putchar(struct term_context *ctx, uint8_t c);
+
static void flanterm_putchar(struct flanterm_context *ctx, uint8_t c);
-
void term_write(struct term_context *ctx, const char *buf, size_t count) {
+
void flanterm_write(struct flanterm_context *ctx, const char *buf, size_t count) {
for (size_t i = 0; i < count; i++) {
-
term_putchar(ctx, buf[i]);
+
flanterm_putchar(ctx, buf[i]);
}
if (ctx->autoflush) {
···
}
}
-
static void sgr(struct term_context *ctx) {
+
static void sgr(struct flanterm_context *ctx) {
size_t i = 0;
if (!ctx->esc_values_i)
···
out:;
}
-
static void dec_private_parse(struct term_context *ctx, uint8_t c) {
+
static void dec_private_parse(struct flanterm_context *ctx, uint8_t c) {
ctx->dec_private = false;
if (ctx->esc_values_i == 0) {
···
}
if (ctx->callback != NULL) {
-
ctx->callback(ctx, TERM_CB_DEC, ctx->esc_values_i, (uintptr_t)ctx->esc_values, c);
+
ctx->callback(ctx, FLANTERM_CB_DEC, ctx->esc_values_i, (uintptr_t)ctx->esc_values, c);
}
}
-
static void linux_private_parse(struct term_context *ctx) {
+
static void linux_private_parse(struct flanterm_context *ctx) {
if (ctx->esc_values_i == 0) {
return;
}
if (ctx->callback != NULL) {
-
ctx->callback(ctx, TERM_CB_LINUX, ctx->esc_values_i, (uintptr_t)ctx->esc_values, 0);
+
ctx->callback(ctx, FLANTERM_CB_LINUX, ctx->esc_values_i, (uintptr_t)ctx->esc_values, 0);
}
}
-
static void mode_toggle(struct term_context *ctx, uint8_t c) {
+
static void mode_toggle(struct flanterm_context *ctx, uint8_t c) {
if (ctx->esc_values_i == 0) {
return;
}
···
}
if (ctx->callback != NULL) {
-
ctx->callback(ctx, TERM_CB_MODE, ctx->esc_values_i, (uintptr_t)ctx->esc_values, c);
+
ctx->callback(ctx, FLANTERM_CB_MODE, ctx->esc_values_i, (uintptr_t)ctx->esc_values, c);
}
}
-
static void osc_parse(struct term_context *ctx, uint8_t c) {
+
static void osc_parse(struct flanterm_context *ctx, uint8_t c) {
if (ctx->osc_escape && c == '\\') {
goto cleanup;
}
···
ctx->escape = false;
}
-
static void control_sequence_parse(struct term_context *ctx, uint8_t c) {
+
static void control_sequence_parse(struct flanterm_context *ctx, uint8_t c) {
if (ctx->escape_offset == 2) {
switch (c) {
case '[':
···
}
if (c >= '0' && c <= '9') {
-
if (ctx->esc_values_i == TERM_MAX_ESC_VALUES) {
+
if (ctx->esc_values_i == FLANTERM_MAX_ESC_VALUES) {
return;
}
ctx->rrr = true;
···
if (c == ';')
return;
} else if (c == ';') {
-
if (ctx->esc_values_i == TERM_MAX_ESC_VALUES) {
+
if (ctx->esc_values_i == FLANTERM_MAX_ESC_VALUES) {
return;
}
ctx->esc_values[ctx->esc_values_i] = 0;
···
esc_default = 1; break;
}
-
for (size_t i = ctx->esc_values_i; i < TERM_MAX_ESC_VALUES; i++) {
+
for (size_t i = ctx->esc_values_i; i < FLANTERM_MAX_ESC_VALUES; i++) {
ctx->esc_values[i] = esc_default;
}
···
break;
case 'c':
if (ctx->callback != NULL) {
-
ctx->callback(ctx, TERM_CB_PRIVATE_ID, 0, 0, 0);
+
ctx->callback(ctx, FLANTERM_CB_PRIVATE_ID, 0, 0, 0);
}
break;
case 'd':
···
switch (ctx->esc_values[0]) {
case 5:
if (ctx->callback != NULL) {
-
ctx->callback(ctx, TERM_CB_STATUS_REPORT, 0, 0, 0);
+
ctx->callback(ctx, FLANTERM_CB_STATUS_REPORT, 0, 0, 0);
}
break;
case 6:
if (ctx->callback != NULL) {
-
ctx->callback(ctx, TERM_CB_POS_REPORT, x + 1, y + 1, 0);
+
ctx->callback(ctx, FLANTERM_CB_POS_REPORT, x + 1, y + 1, 0);
}
break;
}
break;
case 'q':
if (ctx->callback != NULL) {
-
ctx->callback(ctx, TERM_CB_KBD_LEDS, ctx->esc_values[0], 0, 0);
+
ctx->callback(ctx, FLANTERM_CB_KBD_LEDS, ctx->esc_values[0], 0, 0);
}
break;
case 'J':
···
ctx->escape = false;
}
-
static void restore_state(struct term_context *ctx) {
+
static void restore_state(struct flanterm_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->restore_state(ctx);
}
-
static void save_state(struct term_context *ctx) {
+
static void save_state(struct flanterm_context *ctx) {
ctx->save_state(ctx);
ctx->saved_state_bold = ctx->bold;
···
ctx->saved_state_current_bg = ctx->current_bg;
}
-
static void escape_parse(struct term_context *ctx, uint8_t c) {
+
static void escape_parse(struct flanterm_context *ctx, uint8_t c) {
ctx->escape_offset++;
if (ctx->osc == true) {
···
return;
case '[':
is_csi:
-
for (size_t i = 0; i < TERM_MAX_ESC_VALUES; i++)
+
for (size_t i = 0; i < FLANTERM_MAX_ESC_VALUES; i++)
ctx->esc_values[i] = 0;
ctx->esc_values_i = 0;
ctx->rrr = false;
···
restore_state(ctx);
break;
case 'c':
-
term_context_reinit(ctx);
+
flanterm_context_reinit(ctx);
ctx->clear(ctx, true);
break;
case 'D':
···
break;
case 'Z':
if (ctx->callback != NULL) {
-
ctx->callback(ctx, TERM_CB_PRIVATE_ID, 0, 0, 0);
+
ctx->callback(ctx, FLANTERM_CB_PRIVATE_ID, 0, 0, 0);
}
break;
case '(':
···
ctx->escape = false;
}
-
static bool dec_special_print(struct term_context *ctx, uint8_t c) {
-
#define TERM_DEC_SPCL_PRN(C) ctx->raw_putchar(ctx, (C)); return true;
+
static bool dec_special_print(struct flanterm_context *ctx, uint8_t c) {
+
#define FLANTERM_DEC_SPCL_PRN(C) ctx->raw_putchar(ctx, (C)); return true;
switch (c) {
-
case '`': TERM_DEC_SPCL_PRN(0x04)
-
case '0': TERM_DEC_SPCL_PRN(0xdb)
-
case '-': TERM_DEC_SPCL_PRN(0x18)
-
case ',': TERM_DEC_SPCL_PRN(0x1b)
-
case '.': TERM_DEC_SPCL_PRN(0x19)
-
case 'a': TERM_DEC_SPCL_PRN(0xb1)
-
case 'f': TERM_DEC_SPCL_PRN(0xf8)
-
case 'g': TERM_DEC_SPCL_PRN(0xf1)
-
case 'h': TERM_DEC_SPCL_PRN(0xb0)
-
case 'j': TERM_DEC_SPCL_PRN(0xd9)
-
case 'k': TERM_DEC_SPCL_PRN(0xbf)
-
case 'l': TERM_DEC_SPCL_PRN(0xda)
-
case 'm': TERM_DEC_SPCL_PRN(0xc0)
-
case 'n': TERM_DEC_SPCL_PRN(0xc5)
-
case 'q': TERM_DEC_SPCL_PRN(0xc4)
-
case 's': TERM_DEC_SPCL_PRN(0x5f)
-
case 't': TERM_DEC_SPCL_PRN(0xc3)
-
case 'u': TERM_DEC_SPCL_PRN(0xb4)
-
case 'v': TERM_DEC_SPCL_PRN(0xc1)
-
case 'w': TERM_DEC_SPCL_PRN(0xc2)
-
case 'x': TERM_DEC_SPCL_PRN(0xb3)
-
case 'y': TERM_DEC_SPCL_PRN(0xf3)
-
case 'z': TERM_DEC_SPCL_PRN(0xf2)
-
case '~': TERM_DEC_SPCL_PRN(0xfa)
-
case '_': TERM_DEC_SPCL_PRN(0xff)
-
case '+': TERM_DEC_SPCL_PRN(0x1a)
-
case '{': TERM_DEC_SPCL_PRN(0xe3)
-
case '}': TERM_DEC_SPCL_PRN(0x9c)
+
case '`': FLANTERM_DEC_SPCL_PRN(0x04)
+
case '0': FLANTERM_DEC_SPCL_PRN(0xdb)
+
case '-': FLANTERM_DEC_SPCL_PRN(0x18)
+
case ',': FLANTERM_DEC_SPCL_PRN(0x1b)
+
case '.': FLANTERM_DEC_SPCL_PRN(0x19)
+
case 'a': FLANTERM_DEC_SPCL_PRN(0xb1)
+
case 'f': FLANTERM_DEC_SPCL_PRN(0xf8)
+
case 'g': FLANTERM_DEC_SPCL_PRN(0xf1)
+
case 'h': FLANTERM_DEC_SPCL_PRN(0xb0)
+
case 'j': FLANTERM_DEC_SPCL_PRN(0xd9)
+
case 'k': FLANTERM_DEC_SPCL_PRN(0xbf)
+
case 'l': FLANTERM_DEC_SPCL_PRN(0xda)
+
case 'm': FLANTERM_DEC_SPCL_PRN(0xc0)
+
case 'n': FLANTERM_DEC_SPCL_PRN(0xc5)
+
case 'q': FLANTERM_DEC_SPCL_PRN(0xc4)
+
case 's': FLANTERM_DEC_SPCL_PRN(0x5f)
+
case 't': FLANTERM_DEC_SPCL_PRN(0xc3)
+
case 'u': FLANTERM_DEC_SPCL_PRN(0xb4)
+
case 'v': FLANTERM_DEC_SPCL_PRN(0xc1)
+
case 'w': FLANTERM_DEC_SPCL_PRN(0xc2)
+
case 'x': FLANTERM_DEC_SPCL_PRN(0xb3)
+
case 'y': FLANTERM_DEC_SPCL_PRN(0xf3)
+
case 'z': FLANTERM_DEC_SPCL_PRN(0xf2)
+
case '~': FLANTERM_DEC_SPCL_PRN(0xfa)
+
case '_': FLANTERM_DEC_SPCL_PRN(0xff)
+
case '+': FLANTERM_DEC_SPCL_PRN(0x1a)
+
case '{': FLANTERM_DEC_SPCL_PRN(0xe3)
+
case '}': FLANTERM_DEC_SPCL_PRN(0x9c)
}
-
#undef TERM_DEC_SPCL_PRN
+
#undef FLANTERM_DEC_SPCL_PRN
return false;
}
···
return -1;
-
static void term_putchar(struct term_context *ctx, uint8_t c) {
+
static void flanterm_putchar(struct flanterm_context *ctx, uint8_t c) {
if (ctx->discard_next || (ctx->in_bootloader == false && (c == 0x18 || c == 0x1a))) {
ctx->discard_next = false;
ctx->escape = false;
···
case '\n':
if (y == ctx->scroll_bottom_margin - 1) {
ctx->scroll(ctx);
-
ctx->set_cursor_pos(ctx, (ctx->oob_output & TERM_OOB_OUTPUT_ONLCR) ? 0 : x, y);
+
ctx->set_cursor_pos(ctx, (ctx->oob_output & FLANTERM_OOB_OUTPUT_ONLCR) ? 0 : x, y);
} else {
-
ctx->set_cursor_pos(ctx, (ctx->oob_output & TERM_OOB_OUTPUT_ONLCR) ? 0 : x, y + 1);
+
ctx->set_cursor_pos(ctx, (ctx->oob_output & FLANTERM_OOB_OUTPUT_ONLCR) ? 0 : x, y + 1);
return;
case '\b':
···
case '\a':
// The bell is handled by the kernel
if (ctx->callback != NULL) {
-
ctx->callback(ctx, TERM_CB_BELL, 0, 0, 0);
+
ctx->callback(ctx, FLANTERM_CB_BELL, 0, 0, 0);
return;
case 14:
-114
term.h
···
-
#ifndef _TERM_H
-
#define _TERM_H
-
-
#ifdef __cplusplus
-
extern "C" {
-
#endif
-
-
#include <stddef.h>
-
#include <stdint.h>
-
#include <stdbool.h>
-
-
#define TERM_MAX_ESC_VALUES 16
-
-
#define TERM_CB_DEC 10
-
#define TERM_CB_BELL 20
-
#define TERM_CB_PRIVATE_ID 30
-
#define TERM_CB_STATUS_REPORT 40
-
#define TERM_CB_POS_REPORT 50
-
#define TERM_CB_KBD_LEDS 60
-
#define TERM_CB_MODE 70
-
#define TERM_CB_LINUX 80
-
-
#define TERM_OOB_OUTPUT_OCRNL (1 << 0)
-
#define TERM_OOB_OUTPUT_OFDEL (1 << 1)
-
#define TERM_OOB_OUTPUT_OFILL (1 << 2)
-
#define TERM_OOB_OUTPUT_OLCUC (1 << 3)
-
#define TERM_OOB_OUTPUT_ONLCR (1 << 4)
-
#define TERM_OOB_OUTPUT_ONLRET (1 << 5)
-
#define TERM_OOB_OUTPUT_ONOCR (1 << 6)
-
#define TERM_OOB_OUTPUT_OPOST (1 << 7)
-
-
struct term_context {
-
/* internal use */
-
-
size_t tab_size;
-
bool autoflush;
-
bool cursor_enabled;
-
bool scroll_enabled;
-
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;
-
uint64_t code_point;
-
size_t unicode_remaining;
-
uint8_t g_select;
-
uint8_t charsets[2];
-
size_t current_charset;
-
size_t escape_offset;
-
size_t esc_values_i;
-
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];
-
uint64_t oob_output;
-
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 */
-
-
size_t rows, cols;
-
bool in_bootloader;
-
-
void (*raw_putchar)(struct term_context *, uint8_t c);
-
void (*clear)(struct term_context *, bool move);
-
void (*set_cursor_pos)(struct term_context *, size_t x, size_t y);
-
void (*get_cursor_pos)(struct term_context *, size_t *x, size_t *y);
-
void (*set_text_fg)(struct term_context *, size_t fg);
-
void (*set_text_bg)(struct term_context *, size_t bg);
-
void (*set_text_fg_bright)(struct term_context *, size_t fg);
-
void (*set_text_bg_bright)(struct term_context *, size_t bg);
-
void (*set_text_fg_rgb)(struct term_context *, uint32_t fg);
-
void (*set_text_bg_rgb)(struct term_context *, uint32_t bg);
-
void (*set_text_fg_default)(struct term_context *);
-
void (*set_text_bg_default)(struct term_context *);
-
void (*set_text_fg_default_bright)(struct term_context *);
-
void (*set_text_bg_default_bright)(struct term_context *);
-
void (*move_character)(struct term_context *, size_t new_x, size_t new_y, size_t old_x, size_t old_y);
-
void (*scroll)(struct term_context *);
-
void (*revscroll)(struct term_context *);
-
void (*swap_palette)(struct term_context *);
-
void (*save_state)(struct term_context *);
-
void (*restore_state)(struct term_context *);
-
void (*double_buffer_flush)(struct term_context *);
-
void (*full_refresh)(struct term_context *);
-
void (*deinit)(struct term_context *, void (*)(void *, size_t));
-
-
/* to be set by client */
-
-
void (*callback)(struct term_context *, uint64_t, uint64_t, uint64_t, uint64_t);
-
};
-
-
void term_context_reinit(struct term_context *ctx);
-
void term_write(struct term_context *ctx, const char *buf, size_t count);
-
-
#ifdef __cplusplus
-
}
-
#endif
-
-
#endif