From fd8ecb6d0f9af3245e8b1a662987b8cf4e89dec9 Mon Sep 17 00:00:00 2001 From: Albert Cervin Date: Mon, 9 Jan 2023 23:50:48 +0100 Subject: More stuff Render things and line numbers. --- src/display.c | 142 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 52 deletions(-) (limited to 'src/display.c') diff --git a/src/display.c b/src/display.c index 94b1c36..146d31e 100644 --- a/src/display.c +++ b/src/display.c @@ -5,21 +5,48 @@ #include #include +#include #include #include #define ESC 0x1b -struct display display_create() { +struct render_command { + uint32_t col; + uint32_t row; + + uint8_t *data; + uint32_t len; + + uint8_t *fmt; + uint32_t fmt_len; +}; + +struct command_list { + struct render_command *cmds; + uint64_t ncmds; + uint64_t capacity; + + uint32_t xoffset; + uint32_t yoffset; + + uint8_t format[64]; + uint32_t format_len; + alloc_fn allocator; + + char name[16]; +}; + +struct winsize getsize() { struct winsize ws; - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) { - // TODO: if it fails to fetch, do something? - return (struct display){ - .height = 0, - .width = 0, - }; - } + ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws); + return ws; +} + +struct display display_create() { + + struct winsize ws = getsize(); // save old settings struct termios orig_term; @@ -28,9 +55,6 @@ struct display display_create() { // set terminal to raw mode struct termios term; cfmakeraw(&term); - // TODO: move to kbd? - term.c_cc[VMIN] = 0; - term.c_cc[VTIME] = 0; tcsetattr(0, TCSADRAIN, &term); @@ -42,6 +66,12 @@ struct display display_create() { }; } +void display_resize(struct display *display) { + struct winsize sz = getsize(); + display->width = sz.ws_col; + display->height = sz.ws_row; +} + void display_destroy(struct display *display) { // reset old terminal mode tcsetattr(0, TCSADRAIN, &display->orig_term); @@ -73,6 +103,19 @@ void put_ansiparm(int n) { putbyte((n % 10) + '0'); } +void put_format(uint8_t *bytes, uint32_t nbytes) { + putbyte(ESC); + putbyte('['); + putbyte('0'); + + if (nbytes > 0) { + putbyte(';'); + putbytes(bytes, nbytes); + } + + putbyte('m'); +} + void display_move_cursor(struct display *display, uint32_t row, uint32_t col) { putbyte(ESC); putbyte('['); @@ -94,7 +137,8 @@ void delete_to_eol() { } struct command_list *command_list_create(uint32_t capacity, alloc_fn allocator, - uint32_t xoffset, uint32_t yoffset) { + uint32_t xoffset, uint32_t yoffset, + const char *name) { struct command_list *command_list = allocator(sizeof(struct command_list)); command_list->capacity = capacity; @@ -102,8 +146,10 @@ struct command_list *command_list_create(uint32_t capacity, alloc_fn allocator, command_list->xoffset = xoffset; command_list->yoffset = yoffset; command_list->format_len = 0; + strncpy(command_list->name, name, 15); command_list->cmds = allocator(sizeof(struct render_command) * capacity); + command_list->allocator = allocator; return command_list; } @@ -111,78 +157,71 @@ struct command_list *command_list_create(uint32_t capacity, alloc_fn allocator, void push_format(struct command_list *list, const char *fmt, ...) { va_list args; va_start(args, fmt); - if (list->format_len == 0) { - list->format[0] = ESC; - list->format[1] = '['; - - list->format_len = 2; - } - if (list->format_len > 2) { + if (list->format_len > 0) { list->format[list->format_len] = ';'; ++list->format_len; } - uint32_t format_space_left = sizeof(list->format) - 1 - list->format_len; + uint32_t format_space_left = sizeof(list->format) - list->format_len; list->format_len += vsnprintf((char *)(list->format + list->format_len), format_space_left, fmt, args); va_end(args); } -void flush_format(struct command_list *list, uint32_t col, uint32_t row) { - list->format[list->format_len] = 'm'; - ++list->format_len; - - struct render_command *cmd = &list->cmds[list->ncmds]; - cmd->data = list->format; - cmd->col = col + list->xoffset; - cmd->row = row + list->yoffset; - cmd->len = list->format_len; - - list->format_len = 0; - - ++list->ncmds; +void set_cmd_format(struct command_list *list, struct render_command *cmd) { + if (list->format_len > 0) { + cmd->fmt = list->allocator(list->format_len); + memcpy(cmd->fmt, list->format, list->format_len); + cmd->fmt_len = list->format_len; + } else { + cmd->fmt = NULL; + cmd->fmt_len = 0; + } } +void reset_format(struct command_list *list) { list->format_len = 0; } + void command_list_draw_text(struct command_list *list, uint32_t col, uint32_t row, uint8_t *data, uint32_t len) { - uint32_t needed_capacity = list->ncmds + 1; - if (list->format_len > 0) { - ++needed_capacity; - } - - if (needed_capacity > list->capacity) { + if (list->ncmds == list->capacity) { // TODO: better return; } - if (list->format_len > 0) { - flush_format(list, col, row); - } - struct render_command *cmd = &list->cmds[list->ncmds]; cmd->data = data; cmd->col = col + list->xoffset; cmd->row = row + list->yoffset; cmd->len = len; + set_cmd_format(list, cmd); + ++list->ncmds; } +void command_list_draw_text_copy(struct command_list *list, uint32_t col, + uint32_t row, uint8_t *data, uint32_t len) { + uint8_t *bytes = (uint8_t *)list->allocator(len); + memcpy(bytes, data, len); + + command_list_draw_text(list, col, row, bytes, len); +} + void command_list_set_index_color_fg(struct command_list *list, uint8_t color_idx) { if (color_idx < 8) { push_format(list, "%d", 30 + color_idx); } else if (color_idx < 16) { - push_format(list, "%d", 90 + color_idx); + push_format(list, "%d", 90 + color_idx - 8); } else { - push_format(list, "30;5;%d", color_idx); + push_format(list, "38;5;%d", color_idx); } } void command_list_set_color_fg(struct command_list *list, uint8_t red, uint8_t green, uint8_t blue) { - push_format(list, "30;2;%d;%d;%d", red, green, blue); + push_format(list, "38;2;%d;%d;%d", red, green, blue); } void command_list_set_index_color_bg(struct command_list *list, @@ -190,20 +229,18 @@ void command_list_set_index_color_bg(struct command_list *list, if (color_idx < 8) { push_format(list, "%d", 40 + color_idx); } else if (color_idx < 16) { - push_format(list, "%d", 100 + color_idx); + push_format(list, "%d", 100 + color_idx - 8); } else { - push_format(list, "40;5;%d", color_idx); + push_format(list, "48;5;%d", color_idx); } } void command_list_set_color_bg(struct command_list *list, uint8_t red, uint8_t green, uint8_t blue) { - push_format(list, "40;2;%d;%d;%d", red, green, blue); + push_format(list, "48;2;%d;%d;%d", red, green, blue); } -void command_list_reset_color(struct command_list *list) { - push_format(list, "0"); -} +void command_list_reset_color(struct command_list *list) { reset_format(list); } void display_render(struct display *display, struct command_list *command_list) { @@ -213,6 +250,7 @@ void display_render(struct display *display, for (uint64_t cmdi = 0; cmdi < cl->ncmds; ++cmdi) { struct render_command *cmd = &cl->cmds[cmdi]; display_move_cursor(display, cmd->row, cmd->col); + put_format(cmd->fmt, cmd->fmt_len); putbytes(cmd->data, cmd->len); delete_to_eol(); } -- cgit v1.2.3