console: make independent of text drawing layer

We finally want to get rid of any dependencies in the vte/console layer so
we can split it out into a separate library.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2012-09-08 14:09:09 +02:00
parent 4250cffd6c
commit 0d43751e88
6 changed files with 166 additions and 111 deletions

View File

@ -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);
}

View File

@ -35,8 +35,8 @@
#define KMSCON_CONSOLE_H
#include <inttypes.h>
#include <stdbool.h>
#include <stdlib.h>
#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 */

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -36,6 +36,7 @@
#include <stdlib.h>
#include "console.h"
#include "unicode.h"
#include "uterm.h"
/* available character sets */