Use new text renderer
This fixes the console and terminal layer to use the new text renderer instead of the old one. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
b074966af1
commit
5517fa16bd
@ -118,8 +118,9 @@ libkmscon_core_la_SOURCES = \
|
||||
src/pty.c src/pty.h \
|
||||
src/gl.h \
|
||||
src/gl_math.c \
|
||||
src/font_pango.c \
|
||||
src/text.h \
|
||||
src/text.c \
|
||||
src/text_bblit.c \
|
||||
src/text_font.c \
|
||||
src/text_font_8x16.c \
|
||||
src/text_font_pango.c
|
||||
|
@ -76,7 +76,7 @@ PKG_CHECK_MODULES([GLES2], [glesv2],
|
||||
PKG_CHECK_MODULES([XKBCOMMON], [xkbcommon],
|
||||
[have_xkbcommon=yes], [have_xkbcommon=no])
|
||||
|
||||
PKG_CHECK_MODULES([PANGO], [pango pangocairo cairo],
|
||||
PKG_CHECK_MODULES([PANGO], [pango pangoft2],
|
||||
[have_pango=yes], [have_pango=no])
|
||||
|
||||
PKG_CHECK_MODULES([FREETYPE2], [freetype2],
|
||||
|
@ -37,8 +37,8 @@
|
||||
#include <string.h>
|
||||
#include "console.h"
|
||||
#include "font.h"
|
||||
#include "gl.h"
|
||||
#include "log.h"
|
||||
#include "text.h"
|
||||
#include "unicode.h"
|
||||
|
||||
#define LOG_SUBSYSTEM "console"
|
||||
@ -729,17 +729,16 @@ void kmscon_console_reset_all_tabstops(struct kmscon_console *con)
|
||||
con->tab_ruler[i] = false;
|
||||
}
|
||||
|
||||
void kmscon_console_draw(struct kmscon_console *con, struct font_screen *fscr)
|
||||
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;
|
||||
float m[16];
|
||||
bool cursor_done = false, draw_bg;
|
||||
struct font_char_attr attr;
|
||||
bool cursor_done = false;
|
||||
|
||||
if (!con || !fscr)
|
||||
if (!con || !txt)
|
||||
return;
|
||||
|
||||
cur_x = con->cursor_x;
|
||||
@ -749,7 +748,7 @@ void kmscon_console_draw(struct kmscon_console *con, struct font_screen *fscr)
|
||||
if (con->cursor_y >= con->size_y)
|
||||
cur_y = con->size_y - 1;
|
||||
|
||||
font_screen_draw_start(fscr);
|
||||
kmscon_text_prepare(txt);
|
||||
|
||||
iter = con->sb_pos;
|
||||
k = 0;
|
||||
@ -780,22 +779,7 @@ void kmscon_console_draw(struct kmscon_console *con, struct font_screen *fscr)
|
||||
if (con->flags & KMSCON_CONSOLE_INVERSE)
|
||||
attr.inverse = !attr.inverse;
|
||||
|
||||
/* draw bg only if it differs from real bg */
|
||||
if (attr.inverse &&
|
||||
attr.fr == con->bg_r &&
|
||||
attr.fg == con->bg_g &&
|
||||
attr.fb == con->bg_b)
|
||||
draw_bg = false;
|
||||
else if (!attr.inverse &&
|
||||
attr.br == con->bg_r &&
|
||||
attr.bg == con->bg_g &&
|
||||
attr.bb == con->bg_b)
|
||||
draw_bg = false;
|
||||
else
|
||||
draw_bg = true;
|
||||
|
||||
font_screen_draw_char(fscr, cell->ch, &attr,
|
||||
j, i, 1, 1, draw_bg);
|
||||
kmscon_text_draw(txt, cell->ch, j, i, &attr);
|
||||
}
|
||||
|
||||
if (k == cur_y + 1 && !cursor_done) {
|
||||
@ -803,14 +787,12 @@ void kmscon_console_draw(struct kmscon_console *con, struct font_screen *fscr)
|
||||
if (!(con->flags & KMSCON_CONSOLE_HIDE_CURSOR)) {
|
||||
if (!(con->flags & KMSCON_CONSOLE_INVERSE))
|
||||
attr.inverse = !attr.inverse;
|
||||
font_screen_draw_char(fscr, 0, &attr,
|
||||
cur_x, i, 1, 1, true);
|
||||
kmscon_text_draw(txt, 0, cur_x, i, &attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gl_m4_identity(m);
|
||||
font_screen_draw_perform(fscr, m);
|
||||
kmscon_text_render(txt);
|
||||
}
|
||||
|
||||
void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch,
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include "font.h"
|
||||
#include "gl.h"
|
||||
#include "text.h"
|
||||
#include "unicode.h"
|
||||
|
||||
struct kmscon_console;
|
||||
@ -78,7 +78,7 @@ void kmscon_console_set_tabstop(struct kmscon_console *con);
|
||||
void kmscon_console_reset_tabstop(struct kmscon_console *con);
|
||||
void kmscon_console_reset_all_tabstops(struct kmscon_console *con);
|
||||
|
||||
void kmscon_console_draw(struct kmscon_console *con, struct font_screen *fscr);
|
||||
void kmscon_console_draw(struct kmscon_console *con, struct kmscon_text *txt);
|
||||
|
||||
void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch,
|
||||
const struct font_char_attr *attr);
|
||||
|
14
src/main.c
14
src/main.c
@ -33,6 +33,7 @@
|
||||
#include "eloop.h"
|
||||
#include "log.h"
|
||||
#include "static_misc.h"
|
||||
#include "text.h"
|
||||
#include "ui.h"
|
||||
#include "uterm.h"
|
||||
#include "vt.h"
|
||||
@ -333,10 +334,14 @@ int main(int argc, char **argv)
|
||||
if (ret)
|
||||
goto err_out;
|
||||
|
||||
kmscon_font_8x16_load();
|
||||
kmscon_font_pango_load();
|
||||
kmscon_text_bblit_load();
|
||||
|
||||
memset(&app, 0, sizeof(app));
|
||||
ret = setup_app(&app);
|
||||
if (ret)
|
||||
goto err_out;
|
||||
goto err_unload;
|
||||
|
||||
if (conf_global.switchvt) {
|
||||
/* TODO: implement automatic VT switching */
|
||||
@ -361,11 +366,18 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
destroy_app(&app);
|
||||
kmscon_text_bblit_unload();
|
||||
kmscon_font_pango_unload();
|
||||
kmscon_font_8x16_unload();
|
||||
conf_free();
|
||||
log_info("exiting");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
err_unload:
|
||||
kmscon_text_bblit_unload();
|
||||
kmscon_font_pango_unload();
|
||||
kmscon_font_8x16_unload();
|
||||
err_out:
|
||||
conf_free();
|
||||
log_err("cannot initialize kmscon, errno %d: %s", ret, strerror(-ret));
|
||||
|
159
src/terminal.c
159
src/terminal.c
@ -39,7 +39,9 @@
|
||||
#include "gl.h"
|
||||
#include "log.h"
|
||||
#include "pty.h"
|
||||
#include "static_misc.h"
|
||||
#include "terminal.h"
|
||||
#include "text.h"
|
||||
#include "unicode.h"
|
||||
#include "uterm.h"
|
||||
#include "vte.h"
|
||||
@ -47,12 +49,11 @@
|
||||
#define LOG_SUBSYSTEM "terminal"
|
||||
|
||||
struct screen {
|
||||
struct screen *next;
|
||||
struct screen *prev;
|
||||
struct kmscon_dlist list;
|
||||
struct uterm_display *disp;
|
||||
struct uterm_screen *screen;
|
||||
struct font_buffer *buf;
|
||||
struct font_screen *fscr;
|
||||
struct kmscon_font *font;
|
||||
struct kmscon_text *txt;
|
||||
};
|
||||
|
||||
struct kmscon_terminal {
|
||||
@ -63,9 +64,9 @@ struct kmscon_terminal {
|
||||
struct gl_shader *shader;
|
||||
bool opened;
|
||||
|
||||
struct screen *screens;
|
||||
unsigned int max_width;
|
||||
unsigned int max_height;
|
||||
struct kmscon_dlist screens;
|
||||
unsigned int min_cols;
|
||||
unsigned int min_rows;
|
||||
|
||||
bool redraw;
|
||||
struct kmscon_console *console;
|
||||
@ -79,18 +80,19 @@ struct kmscon_terminal {
|
||||
static void draw_all(struct ev_eloop *eloop, void *unused, void *data)
|
||||
{
|
||||
struct kmscon_terminal *term = data;
|
||||
struct screen *iter;
|
||||
struct uterm_screen *screen;
|
||||
int ret;
|
||||
unsigned int cflags;
|
||||
struct kmscon_dlist *iter;
|
||||
struct screen *ent;
|
||||
|
||||
ev_eloop_unregister_idle_cb(term->eloop, draw_all, term);
|
||||
term->redraw = false;
|
||||
cflags = kmscon_console_get_flags(term->console);
|
||||
|
||||
iter = term->screens;
|
||||
for (; iter; iter = iter->next) {
|
||||
screen = iter->screen;
|
||||
kmscon_dlist_for_each(iter, &term->screens) {
|
||||
ent = kmscon_dlist_entry(iter, struct screen, list);
|
||||
screen = ent->screen;
|
||||
|
||||
ret = uterm_screen_use(screen);
|
||||
if (!ret) {
|
||||
@ -101,7 +103,7 @@ static void draw_all(struct ev_eloop *eloop, void *unused, void *data)
|
||||
gl_clear_color(0.0, 0.0, 0.0, 1.0);
|
||||
gl_clear();
|
||||
}
|
||||
kmscon_console_draw(term->console, iter->fscr);
|
||||
kmscon_console_draw(term->console, ent->txt);
|
||||
uterm_screen_swap(screen);
|
||||
}
|
||||
}
|
||||
@ -120,15 +122,53 @@ static void schedule_redraw(struct kmscon_terminal *term)
|
||||
term->redraw = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resize terminal
|
||||
* We support multiple monitors per terminal. As some software-rendering
|
||||
* backends to not support scaling, we always use the smalles cols/rows that are
|
||||
* provided so wider displays will have black margins.
|
||||
* This can be extended to support scaling but that would mean we need to check
|
||||
* whether the text-renderer backend supports that, first (TODO).
|
||||
*
|
||||
* If @force is true, then the console/pty are notified even though the size did
|
||||
* not changed. If @notify is false, then console/pty are not notified even
|
||||
* though the size might have changed. force = true and notify = false doesn't
|
||||
* make any sense, though.
|
||||
*/
|
||||
static void terminal_resize(struct kmscon_terminal *term,
|
||||
unsigned int cols, unsigned int rows,
|
||||
bool force, bool notify)
|
||||
{
|
||||
bool resize = false;
|
||||
|
||||
if (!term->min_cols || (cols > 0 && cols < term->min_cols)) {
|
||||
term->min_cols = cols;
|
||||
resize = true;
|
||||
}
|
||||
if (!term->min_rows || (rows > 0 && rows < term->min_rows)) {
|
||||
term->min_rows = rows;
|
||||
resize = true;
|
||||
}
|
||||
|
||||
if (!notify || (!resize && !force))
|
||||
return;
|
||||
|
||||
/* shrinking always succeeds */
|
||||
kmscon_console_resize(term->console, term->min_cols, term->min_rows);
|
||||
kmscon_pty_resize(term->pty, term->min_cols, term->min_rows);
|
||||
}
|
||||
|
||||
static int add_display(struct kmscon_terminal *term, struct uterm_display *disp)
|
||||
{
|
||||
struct kmscon_dlist *iter;
|
||||
struct screen *scr;
|
||||
int ret;
|
||||
unsigned int width, height;
|
||||
struct screen *iter;
|
||||
unsigned int cols, rows;
|
||||
const struct kmscon_font_attr attr = { "", 0, 20, false, false, 0, 0 };
|
||||
|
||||
for (iter = term->screens; iter; iter = iter->next) {
|
||||
if (iter->disp == disp)
|
||||
kmscon_dlist_for_each(iter, &term->screens) {
|
||||
scr = kmscon_dlist_entry(iter, struct screen, list);
|
||||
if (scr->disp == disp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -146,34 +186,35 @@ static int add_display(struct kmscon_terminal *term, struct uterm_display *disp)
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
width = uterm_screen_width(scr->screen);
|
||||
height = uterm_screen_height(scr->screen);
|
||||
|
||||
ret = font_buffer_new(&scr->buf, width, height);
|
||||
ret = kmscon_font_find(&scr->font, &attr, NULL);
|
||||
if (ret) {
|
||||
log_error("cannot create buffer for display %p", scr->disp);
|
||||
log_error("cannot create font");
|
||||
goto err_screen;
|
||||
}
|
||||
|
||||
ret = font_screen_new_fixed(&scr->fscr, scr->buf, FONT_ATTR(NULL, 12, 0),
|
||||
80, 24, scr->screen, term->shader);
|
||||
ret = kmscon_text_new(&scr->txt, NULL);
|
||||
if (ret) {
|
||||
log_error("cannot create font for display %p", scr->disp);
|
||||
goto err_buf;
|
||||
log_error("cannot create text-renderer");
|
||||
goto err_font;
|
||||
}
|
||||
|
||||
scr->next = term->screens;
|
||||
if (scr->next)
|
||||
scr->next->prev = scr;
|
||||
term->screens = scr;
|
||||
kmscon_text_set_bgcolor(scr->txt, 0, 0, 0);
|
||||
kmscon_text_set_font(scr->txt, scr->font);
|
||||
kmscon_text_set_screen(scr->txt, scr->screen);
|
||||
|
||||
cols = kmscon_text_get_cols(scr->txt);
|
||||
rows = kmscon_text_get_rows(scr->txt);
|
||||
terminal_resize(term, cols, rows, false, true);
|
||||
|
||||
kmscon_dlist_link(&term->screens, &scr->list);
|
||||
|
||||
log_debug("added display %p to terminal %p", disp, term);
|
||||
schedule_redraw(term);
|
||||
uterm_display_ref(scr->disp);
|
||||
return 0;
|
||||
|
||||
err_buf:
|
||||
font_buffer_free(scr->buf);
|
||||
err_font:
|
||||
kmscon_font_unref(scr->font);
|
||||
err_screen:
|
||||
uterm_screen_unref(scr->screen);
|
||||
err_free:
|
||||
@ -181,49 +222,68 @@ err_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void free_screen(struct screen *scr)
|
||||
static void free_screen(struct kmscon_terminal *term, struct screen *scr,
|
||||
bool update)
|
||||
{
|
||||
struct kmscon_dlist *iter;
|
||||
struct screen *ent;
|
||||
|
||||
log_debug("destroying terminal screen %p", scr);
|
||||
font_screen_free(scr->fscr);
|
||||
font_buffer_free(scr->buf);
|
||||
kmscon_dlist_unlink(&scr->list);
|
||||
kmscon_text_unref(scr->txt);
|
||||
kmscon_font_unref(scr->font);
|
||||
uterm_screen_unref(scr->screen);
|
||||
uterm_display_unref(scr->disp);
|
||||
free(scr);
|
||||
|
||||
if (!update)
|
||||
return;
|
||||
|
||||
term->min_cols = 0;
|
||||
term->min_rows = 0;
|
||||
kmscon_dlist_for_each(iter, &term->screens) {
|
||||
ent = kmscon_dlist_entry(iter, struct screen, list);
|
||||
terminal_resize(term,
|
||||
kmscon_text_get_cols(ent->txt),
|
||||
kmscon_text_get_rows(ent->txt),
|
||||
false, false);
|
||||
}
|
||||
|
||||
terminal_resize(term, 0, 0, true, true);
|
||||
}
|
||||
|
||||
static void rm_display(struct kmscon_terminal *term, struct uterm_display *disp)
|
||||
{
|
||||
struct kmscon_dlist *iter;
|
||||
struct screen *scr;
|
||||
|
||||
for (scr = term->screens; scr; scr = scr->next) {
|
||||
if (scr->disp == disp) {
|
||||
if (scr->prev)
|
||||
scr->prev->next = scr->next;
|
||||
if (scr->next)
|
||||
scr->next->prev = scr->prev;
|
||||
if (term->screens == scr)
|
||||
term->screens = scr->next;
|
||||
kmscon_dlist_for_each(iter, &term->screens) {
|
||||
scr = kmscon_dlist_entry(iter, struct screen, list);
|
||||
if (scr->disp == disp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!scr)
|
||||
if (iter == &term->screens)
|
||||
return;
|
||||
|
||||
log_debug("removed display %p from terminal %p", disp, term);
|
||||
free_screen(scr);
|
||||
if (!term->screens && term->cb)
|
||||
free_screen(term, scr, true);
|
||||
if (kmscon_dlist_empty(&term->screens) && term->cb)
|
||||
term->cb(term, KMSCON_TERMINAL_NO_DISPLAY, term->data);
|
||||
}
|
||||
|
||||
static void rm_all_screens(struct kmscon_terminal *term)
|
||||
{
|
||||
struct kmscon_dlist *iter;
|
||||
struct screen *scr;
|
||||
|
||||
while ((scr = term->screens)) {
|
||||
term->screens = scr->next;
|
||||
free_screen(scr);
|
||||
while ((iter = term->screens.next) != &term->screens) {
|
||||
scr = kmscon_dlist_entry(iter, struct screen, list);
|
||||
free_screen(term, scr, false);
|
||||
}
|
||||
|
||||
term->min_cols = 0;
|
||||
term->min_rows = 0;
|
||||
}
|
||||
|
||||
static void pty_input(struct kmscon_pty *pty, const char *u8, size_t len,
|
||||
@ -280,6 +340,7 @@ int kmscon_terminal_new(struct kmscon_terminal **out,
|
||||
term->eloop = loop;
|
||||
term->video = video;
|
||||
term->input = input;
|
||||
kmscon_dlist_init(&term->screens);
|
||||
|
||||
ret = kmscon_console_new(&term->console);
|
||||
if (ret)
|
||||
|
Loading…
x
Reference in New Issue
Block a user