aboutsummaryrefslogtreecommitdiff
path: root/src/sysbin/terminal/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sysbin/terminal/main.c')
-rw-r--r--src/sysbin/terminal/main.c44
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
}