summaryrefslogtreecommitdiff
path: root/src/dged/display.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dged/display.c')
-rw-r--r--src/dged/display.c65
1 files changed, 61 insertions, 4 deletions
diff --git a/src/dged/display.c b/src/dged/display.c
index 332f3bc..ae5369b 100644
--- a/src/dged/display.c
+++ b/src/dged/display.c
@@ -23,6 +23,7 @@ struct display {
struct termios orig_term;
uint32_t width;
uint32_t height;
+ bool render_in_progress;
};
enum render_cmd_type {
@@ -32,6 +33,7 @@ enum render_cmd_type {
RenderCommand_ClearFormat = 3,
RenderCommand_SetShowWhitespace = 4,
RenderCommand_DrawList = 5,
+ RenderCommand_ClearLine = 6,
};
struct render_command {
@@ -42,6 +44,7 @@ struct render_command {
struct repeat_cmd *repeat;
struct show_ws_cmd *show_ws;
struct draw_list_cmd *draw_list;
+ struct clear_line_cmd *clear_line;
} data;
};
@@ -73,6 +76,11 @@ struct draw_list_cmd {
struct command_list *list;
};
+struct clear_line_cmd {
+ uint32_t col;
+ uint32_t row;
+};
+
struct command_list {
struct render_command *cmds;
uint64_t ncmds;
@@ -147,6 +155,7 @@ struct display *display_create(void) {
d->term = term;
d->height = ws.ws_row;
d->width = ws.ws_col;
+ d->render_in_progress = false;
return d;
}
@@ -241,6 +250,15 @@ void display_clear(struct display *display) {
putc('J', stdout);
}
+static void display_clear_line(struct display *display, uint32_t row,
+ uint32_t col) {
+ display_move_cursor(display, row, col);
+ putc(ESC, stdout);
+ putc('[', stdout);
+ putc('0', stdout);
+ putc('K', stdout);
+}
+
struct command_list *command_list_create(uint32_t initial_capacity,
void *(*allocator)(size_t),
uint32_t xoffset, uint32_t yoffset,
@@ -262,6 +280,8 @@ struct command_list *command_list_create(uint32_t initial_capacity,
return command_list;
}
+bool command_list_empty(struct command_list *list) { return list->ncmds == 0; }
+
struct render_command *add_command(struct command_list *list,
enum render_cmd_type tp) {
struct command_list *l = list;
@@ -299,6 +319,9 @@ struct render_command *add_command(struct command_list *list,
case RenderCommand_DrawList:
cmd->data.draw_list = l->allocator(sizeof(struct draw_list_cmd));
break;
+ case RenderCommand_ClearLine:
+ cmd->data.clear_line = l->allocator(sizeof(struct clear_line_cmd));
+ break;
default:
assert(false);
}
@@ -334,6 +357,14 @@ void command_list_draw_repeated(struct command_list *list, uint32_t col,
cmd->nrepeat = nrepeat;
}
+void command_list_clear_line(struct command_list *list, uint32_t col,
+ uint32_t row) {
+ struct clear_line_cmd *cmd =
+ add_command(list, RenderCommand_ClearLine)->data.clear_line;
+ cmd->col = col;
+ cmd->row = row;
+}
+
void command_list_draw_command_list(struct command_list *list,
struct command_list *to_draw) {
struct draw_list_cmd *cmd =
@@ -420,7 +451,6 @@ void display_render(struct display *display,
bool show_whitespace_state = false;
while (cl != NULL) {
-
for (uint64_t cmdi = 0; cmdi < cl->ncmds; ++cmdi) {
struct render_command *cmd = &cl->cmds[cmdi];
switch (cmd->type) {
@@ -467,6 +497,13 @@ void display_render(struct display *display,
fmt_stack_len = 3;
break;
+ case RenderCommand_ClearLine: {
+ apply_fmt(fmt_stack, fmt_stack_len);
+ struct clear_line_cmd *clear_cmd = cmd->data.clear_line;
+ display_clear_line(display, cl->yoffset + clear_cmd->row,
+ cl->xoffset + clear_cmd->col);
+ } break;
+
case RenderCommand_SetShowWhitespace:
show_whitespace_state = cmd->data.show_ws->show;
break;
@@ -500,13 +537,33 @@ void show_cursor(void) {
putc('h', stdout);
}
+static void begin_update(void) {
+ putc(ESC, stdout);
+ putc('[', stdout);
+ putc('?', stdout);
+ put_ansiparm(2026);
+ putc('h', stdout);
+}
+
+static void end_update(void) {
+ putc(ESC, stdout);
+ putc('[', stdout);
+ putc('?', stdout);
+ put_ansiparm(2026);
+ putc('l', stdout);
+}
+
void display_begin_render(struct display *display) {
- (void)display;
+ assert(!display->render_in_progress);
+
+ display->render_in_progress = true;
+ begin_update();
hide_cursor();
+ fflush(stdout);
}
void display_end_render(struct display *display) {
- (void)display;
-
show_cursor();
+ end_update();
fflush(stdout);
+ display->render_in_progress = false;
}