diff options
Diffstat (limited to 'src/sysbin/terminal/main.c')
-rw-r--r-- | src/sysbin/terminal/main.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/src/sysbin/terminal/main.c b/src/sysbin/terminal/main.c index 77bf141..604228a 100644 --- a/src/sysbin/terminal/main.c +++ b/src/sysbin/terminal/main.c @@ -39,6 +39,7 @@ typedef struct { fb_t *fb; uint32_t sv_features, cl_features; + fb_region_t damage; font_t *font; int cw, ch; // size of a character @@ -56,6 +57,7 @@ typedef struct { int csrl, csrc; bool csr_visible; + gip_handler_t *handler; mainloop_fd_t app; char rd_c_buf; char wr_c_buf; @@ -72,6 +74,8 @@ void gip_async_initiate(gip_handler_t *s, gip_msg_header *p, void* msgdata, void void term_on_rd_c(mainloop_fd_t *fd); void term_app_on_error(mainloop_fd_t *fd); +void idle_cb(void* data); + gip_handler_callbacks_t term_gip_cb = { .reset = 0, @@ -106,8 +110,11 @@ int main(int argc, char **argv) { term.cw = g_text_width(term.font, "#", 8); term.ch = g_text_height(term.font, "#", 8); + term.damage.x = term.damage.y = term.damage.h = term.damage.w = -1; + gip_handler_t *h = new_gip_handler(&term_gip_cb, &term); ASSERT(h != 0); + term.handler = h; h->mainloop_item.fd = STD_FD_GIP; mainloop_add_fd(&h->mainloop_item); @@ -121,6 +128,8 @@ int main(int argc, char **argv) { gip_msg_header reset_msg = { .code = GIPC_RESET, .arg = 0 }; gip_cmd(h, &reset_msg, 0, gip_async_initiate, 0); + mainloop_when_idle(idle_cb, &term); + mainloop_run(); return 0; @@ -128,6 +137,24 @@ int main(int argc, char **argv) { // Terminal features +void term_damage_at(term_t *t, int x, int y, int w, int h) { + if (t->damage.x == -1) { + t->damage.x = x; + t->damage.y = y; + t->damage.w = w; + t->damage.h = h; + } else { + int px1 = t->damage.x + t->damage.w; + int py1 = t->damage.y + t->damage.h; + int nx1 = (px1 > x+w ? px1 : x+w); + int ny1 = (py1 > y+h ? py1 : y+h); + t->damage.x = (t->damage.x < x ? t->damage.x : x); + t->damage.y = (t->damage.y < y ? t->damage.y : y); + t->damage.w = nx1 - t->damage.x; + t->damage.h = ny1 - t->damage.y; + } +} + void term_draw_c(term_t *t, int l, int c) { color_t bg = t->bg; if (l == t->csrl && c == t->csrc) bg = t->csr_bg; @@ -139,6 +166,7 @@ void term_draw_c(term_t *t, int l, int c) { if (t->fb) { g_fillrect(t->fb, c * t->cw, l * t->ch, t->cw, t->ch, bg); g_write(t->fb, c * t->cw, l * t->ch, ss, t->font, 16, t->fg); + term_damage_at(t, c * t->cw, l * t->ch, t->cw, t->ch); } } @@ -162,8 +190,10 @@ void term_clear_screen(term_t *t) { for (int i = 0; i < t->w * t->h; i++) t->scr_chars[i] = ' '; - if (t->fb) + if (t->fb) { g_fillrect(t->fb, 0, 0, t->mode.width, t->mode.height, t->bg); + term_damage_at(t, 0, 0, t->mode.width, t->mode.height); + } term_move_cursor(t, 0, 0); } @@ -179,6 +209,7 @@ void term_scroll1(term_t *t) { if (t->fb) { g_scroll_up(t->fb, t->ch); g_fillrect(t->fb, 0, t->ch * (t->h - 1), t->cw * t->w, t->ch, t->bg); + term_damage_at(t, 0, 0, t->mode.width, t->mode.height); } } @@ -386,6 +417,17 @@ void term_on_rd_c(mainloop_fd_t *fd) { term_putc(t, t->rd_c_buf); } +void idle_cb(void* data) { + term_t *t = (term_t*)data; + + // we are done processing events ; flush damaged region + if (t->damage.x != -1) { + gip_msg_header damage_msg = { .code = GIPN_BUFFER_DAMAGE, .arg = 0 }; + gip_cmd(t->handler, &damage_msg, &t->damage, 0, 0); + t->damage.x = t->damage.y = t->damage.w = t->damage.h = -1; + } +} + void term_app_on_error(mainloop_fd_t *fd) { // TODO } |