summaryrefslogtreecommitdiff
path: root/src/display.c
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2023-01-09 23:50:48 +0100
committerAlbert Cervin <albert@acervin.com>2023-01-09 23:50:48 +0100
commitfd8ecb6d0f9af3245e8b1a662987b8cf4e89dec9 (patch)
tree4d7236e75292153b917671251767218b979bdeb2 /src/display.c
parent690786504fce73edea78c7ec13b34771771e4caf (diff)
downloaddged-fd8ecb6d0f9af3245e8b1a662987b8cf4e89dec9.tar.gz
dged-fd8ecb6d0f9af3245e8b1a662987b8cf4e89dec9.tar.xz
dged-fd8ecb6d0f9af3245e8b1a662987b8cf4e89dec9.zip
More stuff
Render things and line numbers.
Diffstat (limited to 'src/display.c')
-rw-r--r--src/display.c142
1 files changed, 90 insertions, 52 deletions
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 <stdarg.h>
#include <stdio.h>
+#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#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();
}