diff --git a/src/console.c b/src/console.c index 2f19b01..882ae5d 100644 --- a/src/console.c +++ b/src/console.c @@ -39,7 +39,6 @@ #include "log.h" #include "main.h" #include "static_misc.h" -#include "text.h" #include "unicode.h" #define LOG_SUBSYSTEM "console" @@ -792,113 +791,6 @@ void kmscon_console_reset_all_tabstops(struct kmscon_console *con) con->tab_ruler[i] = false; } -void kmscon_console_draw(struct kmscon_console *con, struct kmscon_text *txt) -{ - unsigned int cur_x, cur_y; - unsigned int i, j, k; - struct line *iter, *line = NULL; - struct cell *cell; - struct kmscon_console_attr attr; - bool cursor_done = false; - int ret, warned = 0; - uint64_t time_prep = 0, time_draw = 0, time_rend = 0; - - if (!con || !txt) - return; - - cur_x = con->cursor_x; - if (con->cursor_x >= con->size_x) - cur_x = con->size_x - 1; - cur_y = con->cursor_y; - if (con->cursor_y >= con->size_y) - cur_y = con->size_y - 1; - - /* render preparation */ - - if (kmscon_conf.render_timing) - kmscon_timer_reset(con->timer); - - ret = kmscon_text_prepare(txt); - if (ret) { - log_warning("cannot prepare text-renderer for rendering"); - return; - } - - if (kmscon_conf.render_timing) - time_prep = kmscon_timer_elapsed(con->timer); - - /* push each character into rendering pipeline */ - - if (kmscon_conf.render_timing) - kmscon_timer_reset(con->timer); - - iter = con->sb_pos; - k = 0; - for (i = 0; i < con->size_y; ++i) { - if (iter) { - line = iter; - iter = iter->next; - } else { - line = con->lines[k]; - k++; - } - - for (j = 0; j < con->size_x; ++j) { - cell = &line->cells[j]; - memcpy(&attr, &cell->attr, sizeof(attr)); - - if (k == cur_y + 1 && - j == cur_x) { - cursor_done = true; - if (!(con->flags & KMSCON_CONSOLE_HIDE_CURSOR)) - attr.inverse = !attr.inverse; - } - - /* TODO: do some more sophisticated inverse here. When - * INVERSE mode is set, we should instead just select - * inverse colors instead of switching background and - * foreground */ - if (con->flags & KMSCON_CONSOLE_INVERSE) - attr.inverse = !attr.inverse; - - ret = kmscon_text_draw(txt, cell->ch, j, i, &attr); - if (ret && warned++ < 3) { - log_debug("cannot draw glyph at %ux%u via text-renderer", - j, i); - if (warned == 3) - log_debug("suppressing further warnings during this rendering"); - } - } - - if (k == cur_y + 1 && !cursor_done) { - cursor_done = true; - if (!(con->flags & KMSCON_CONSOLE_HIDE_CURSOR)) { - if (!(con->flags & KMSCON_CONSOLE_INVERSE)) - attr.inverse = !attr.inverse; - kmscon_text_draw(txt, 0, cur_x, i, &attr); - } - } - } - - if (kmscon_conf.render_timing) - time_draw = kmscon_timer_elapsed(con->timer); - - /* perform final rendering steps */ - - if (kmscon_conf.render_timing) - kmscon_timer_reset(con->timer); - - ret = kmscon_text_render(txt); - if (ret) - log_warning("cannot render via text-renderer"); - - if (kmscon_conf.render_timing) { - time_rend = kmscon_timer_elapsed(con->timer); - log_debug("timing: prepare: %llu draw: %llu render: %llu", - time_prep, time_draw, time_rend); - } -} - void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch, const struct kmscon_console_attr *attr) { @@ -1348,3 +1240,123 @@ void kmscon_console_erase_screen(struct kmscon_console *con, bool protect) console_erase_region(con, 0, 0, con->size_x - 1, con->size_y - 1, protect); } + +void kmscon_console_draw(struct kmscon_console *con, + kmscon_console_prepare_cb prepare_cb, + kmscon_console_draw_cb draw_cb, + kmscon_console_render_cb render_cb, + void *data) +{ + unsigned int cur_x, cur_y; + unsigned int i, j, k; + struct line *iter, *line = NULL; + struct cell *cell; + struct kmscon_console_attr attr; + bool cursor_done = false; + int ret, warned = 0; + uint64_t time_prep = 0, time_draw = 0, time_rend = 0; + + if (!con || !draw_cb) + return; + + cur_x = con->cursor_x; + if (con->cursor_x >= con->size_x) + cur_x = con->size_x - 1; + cur_y = con->cursor_y; + if (con->cursor_y >= con->size_y) + cur_y = con->size_y - 1; + + /* render preparation */ + + if (prepare_cb) { + if (kmscon_conf.render_timing) + kmscon_timer_reset(con->timer); + + ret = prepare_cb(con, data); + if (ret) { + log_warning("cannot prepare text-renderer for rendering"); + return; + } + + if (kmscon_conf.render_timing) + time_prep = kmscon_timer_elapsed(con->timer); + } else { + time_prep = 0; + } + + /* push each character into rendering pipeline */ + + if (kmscon_conf.render_timing) + kmscon_timer_reset(con->timer); + + iter = con->sb_pos; + k = 0; + for (i = 0; i < con->size_y; ++i) { + if (iter) { + line = iter; + iter = iter->next; + } else { + line = con->lines[k]; + k++; + } + + for (j = 0; j < con->size_x; ++j) { + cell = &line->cells[j]; + memcpy(&attr, &cell->attr, sizeof(attr)); + + if (k == cur_y + 1 && + j == cur_x) { + cursor_done = true; + if (!(con->flags & KMSCON_CONSOLE_HIDE_CURSOR)) + attr.inverse = !attr.inverse; + } + + /* TODO: do some more sophisticated inverse here. When + * INVERSE mode is set, we should instead just select + * inverse colors instead of switching background and + * foreground */ + if (con->flags & KMSCON_CONSOLE_INVERSE) + attr.inverse = !attr.inverse; + + ret = draw_cb(con, cell->ch, j, i, &attr, data); + if (ret && warned++ < 3) { + log_debug("cannot draw glyph at %ux%u via text-renderer", + j, i); + if (warned == 3) + log_debug("suppressing further warnings during this rendering"); + } + } + + if (k == cur_y + 1 && !cursor_done) { + cursor_done = true; + if (!(con->flags & KMSCON_CONSOLE_HIDE_CURSOR)) { + if (!(con->flags & KMSCON_CONSOLE_INVERSE)) + attr.inverse = !attr.inverse; + draw_cb(con, 0, cur_x, i, &attr, data); + } + } + } + + if (kmscon_conf.render_timing) + time_draw = kmscon_timer_elapsed(con->timer); + + /* perform final rendering steps */ + + if (render_cb) { + if (kmscon_conf.render_timing) + kmscon_timer_reset(con->timer); + + ret = render_cb(con, data); + if (ret) + log_warning("cannot render via text-renderer"); + + if (kmscon_conf.render_timing) + time_rend = kmscon_timer_elapsed(con->timer); + } else { + time_rend = 0; + } + + if (kmscon_conf.render_timing) + log_debug("timing: prepare: %llu draw: %llu render: %llu", + time_prep, time_draw, time_rend); +} diff --git a/src/console.h b/src/console.h index ebf7e4e..7e94dcd 100644 --- a/src/console.h +++ b/src/console.h @@ -35,8 +35,8 @@ #define KMSCON_CONSOLE_H #include +#include #include -#include "text.h" #include "unicode.h" struct kmscon_console; @@ -63,6 +63,17 @@ struct kmscon_console_attr { unsigned int protect : 1; /* cannot be erased */ }; +typedef int (*kmscon_console_prepare_cb) (struct kmscon_console *con, + void *data); +typedef int (*kmscon_console_draw_cb) (struct kmscon_console *con, + kmscon_symbol_t ch, + unsigned int posx, + unsigned int posy, + const struct kmscon_console_attr *attr, + void *data); +typedef int (*kmscon_console_render_cb) (struct kmscon_console *con, + void *data); + int kmscon_console_new(struct kmscon_console **out); void kmscon_console_ref(struct kmscon_console *con); void kmscon_console_unref(struct kmscon_console *con); @@ -131,6 +142,10 @@ void kmscon_console_erase_cursor_to_screen(struct kmscon_console *con, bool protect); void kmscon_console_erase_screen(struct kmscon_console *con, bool protect); -void kmscon_console_draw(struct kmscon_console *con, struct kmscon_text *txt); +void kmscon_console_draw(struct kmscon_console *con, + kmscon_console_prepare_cb prepare_cb, + kmscon_console_draw_cb draw_cb, + kmscon_console_render_cb render_cb, + void *data); #endif /* KMSCON_CONSOLE_H */ diff --git a/src/terminal.c b/src/terminal.c index 57952a9..898817b 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -91,7 +91,11 @@ static void redraw(struct kmscon_terminal *term) ent = kmscon_dlist_entry(iter, struct screen, list); screen = ent->screen; - kmscon_console_draw(term->console, ent->txt); + kmscon_console_draw(term->console, + kmscon_text_prepare_cb, + kmscon_text_draw_cb, + kmscon_text_render_cb, + ent->txt); uterm_screen_swap(screen); } } diff --git a/src/text.c b/src/text.c index 88aa547..aa80301 100644 --- a/src/text.c +++ b/src/text.c @@ -497,3 +497,20 @@ void kmscon_text_abort(struct kmscon_text *txt) txt->ops->abort(txt); txt->rendering = false; } + +int kmscon_text_prepare_cb(struct kmscon_console *con, void *data) +{ + return kmscon_text_prepare(data); +} + +int kmscon_text_draw_cb(struct kmscon_console *con, kmscon_symbol_t ch, + unsigned int posx, unsigned int posy, + const struct kmscon_console_attr *attr, void *data) +{ + return kmscon_text_draw(data, ch, posx, posy, attr); +} + +int kmscon_text_render_cb(struct kmscon_console *con, void *data) +{ + return kmscon_text_render(data); +} diff --git a/src/text.h b/src/text.h index 0a51f2b..3f5ee99 100644 --- a/src/text.h +++ b/src/text.h @@ -163,6 +163,12 @@ int kmscon_text_draw(struct kmscon_text *txt, kmscon_symbol_t ch, int kmscon_text_render(struct kmscon_text *txt); void kmscon_text_abort(struct kmscon_text *txt); +int kmscon_text_prepare_cb(struct kmscon_console *con, void *data); +int kmscon_text_draw_cb(struct kmscon_console *con, kmscon_symbol_t ch, + unsigned int posx, unsigned int posy, + const struct kmscon_console_attr *attr, void *data); +int kmscon_text_render_cb(struct kmscon_console *con, void *data); + /* modularized backends */ #ifdef KMSCON_HAVE_UNIFONT diff --git a/src/vte.h b/src/vte.h index 8f3c87d..8d4ba0a 100644 --- a/src/vte.h +++ b/src/vte.h @@ -36,6 +36,7 @@ #include #include "console.h" #include "unicode.h" +#include "uterm.h" /* available character sets */