aboutsummaryrefslogtreecommitdiffstats
path: root/fbcon.c
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2019-02-28 12:36:45 +0100
committerGerd Hoffmann <kraxel@redhat.com>2019-02-28 12:36:45 +0100
commit853c1b3a67a6b9c7bd6a67c67b5ce6f43f9fe90d (patch)
tree53ee96da1ecd41ba75601721a6165aec40c135e5 /fbcon.c
parent6d62ddcf9d95c5ddcbe1da14630cc69b44076f3c (diff)
downloadfbida-853c1b3a67a6b9c7bd6a67c67b5ce6f43f9fe90d.tar.gz
fbcon: switch to libtsm
Diffstat (limited to 'fbcon.c')
-rw-r--r--fbcon.c244
1 files changed, 145 insertions, 99 deletions
diff --git a/fbcon.c b/fbcon.c
index b5fd57c..9ec115c 100644
--- a/fbcon.c
+++ b/fbcon.c
@@ -26,12 +26,12 @@
#include <libudev.h>
#include <libinput.h>
#include <xkbcommon/xkbcommon.h>
+#include <libtsm.h>
#include "fbtools.h"
#include "drmtools.h"
#include "vt.h"
#include "kbd.h"
-#include "tmt.h"
/* ---------------------------------------------------------------------- */
@@ -40,14 +40,15 @@ static char *font_name = "monospace";
static int font_size = 16;
static gfxstate *gfx;
-static cairo_surface_t *surface1;
-static cairo_surface_t *surface2;
-static cairo_t *context1;
-static cairo_t *context2;
-cairo_font_extents_t extents;
-
-static TMT *vt;
-static int clear, dirty, pty;
+static cairo_font_extents_t extents;
+static struct cairo_state {
+ cairo_surface_t *surface;
+ cairo_t *context;
+ tsm_age_t age;
+ int clear;
+} state1, state2;
+
+static int dirty, pty;
static struct udev *udev;
static struct libinput *kbd;
@@ -62,6 +63,9 @@ static struct xkb_rule_names layout = {
.options = NULL,
};
+static struct tsm_screen *vts;
+static struct tsm_vte *vte;
+
int debug = 0;
/* ---------------------------------------------------------------------- */
@@ -118,7 +122,8 @@ static void console_switch_resume(void)
{
gfx->restore_display();
libinput_resume(kbd);
- clear++;
+ state1.clear++;
+ state2.clear++;
dirty++;
}
@@ -182,12 +187,7 @@ static void xkb_configure(void)
/* ---------------------------------------------------------------------- */
-struct color {
- float r;
- float g;
- float b;
-};
-
+#if 0
static struct color tmt_colors_normal[] = {
[ TMT_COLOR_BLACK ] = { .r = 0.0, .g = 0.0, .b = 0.0 },
[ TMT_COLOR_RED ] = { .r = 0.7, .g = 0.0, .b = 0.0 },
@@ -230,80 +230,123 @@ struct color *tmt_background(struct TMTATTRS *a)
bg = TMT_COLOR_BLACK;
return tmt_colors_normal + bg;
}
+#endif
/* ---------------------------------------------------------------------- */
-static void render(void)
+struct color {
+ float r;
+ float g;
+ float b;
+};
+
+static const struct color black = { 0, 0, 0 };
+static const struct color white = { 1, 1, 1 };
+
+void tsm_log_cb(void *data, const char *file, int line,
+ const char *func, const char *subs, unsigned int sev,
+ const char *format, va_list args)
{
- static bool second;
- const TMTSCREEN *s = tmt_screen(vt);
- const TMTPOINT *cursor = tmt_cursor(vt);
- cairo_t *context;
- int line, col, tx, ty;
- wchar_t ws[2];
- char utf8[10];
+ if (sev == 7 /* debug */ && !debug)
+ return;
- if (surface2)
- second = !second;
- context = second ? context2 : context1;
+ fprintf(stderr, "<%d> ", sev);
+ if (file)
+ fprintf(stderr, "[%s:%d] ", file, line);
+ vfprintf(stderr, format, args);
+ fprintf(stderr, "\n");
+}
- tx = (gfx->hdisplay - (extents.max_x_advance * s->ncol)) / 2;
- ty = (gfx->vdisplay - (extents.height * s->nline)) / 2;
+void tsm_write_cb(struct tsm_vte *vte, const char *u8, size_t len, void *data)
+{
+}
- if (clear) {
- cairo_set_source_rgb(context, 0, 0, 0);
- cairo_paint(context);
+int tsm_draw_cb(struct tsm_screen *con, uint32_t id,
+ const uint32_t *ch, size_t len,
+ unsigned int width, unsigned int posx, unsigned int posy,
+ const struct tsm_screen_attr *attr,
+ tsm_age_t age, void *data)
+{
+ struct cairo_state *s = data;
+ struct color bg = {
+ .r = attr->br / 255.0,
+ .g = attr->bg / 255.0,
+ .b = attr->bb / 255.0,
+ };
+ struct color fg = {
+ .r = attr->fr / 255.0,
+ .g = attr->fg / 255.0,
+ .b = attr->fb / 255.0,
+ };
+ int sw = tsm_screen_get_width(con) * extents.max_x_advance;
+ int sh = tsm_screen_get_height(con) * extents.height;
+ int tx = (gfx->hdisplay - sw) / 2;
+ int ty = (gfx->vdisplay - sh) / 2;
+ wchar_t ws[8];
+ char utf8[32];
+ int i;
+
+ if (posx == tsm_screen_get_cursor_x(con) &&
+ posy == tsm_screen_get_cursor_y(con) &&
+ !(tsm_screen_get_flags(con) & TSM_SCREEN_HIDE_CURSOR)) {
+ bg = white;
+ fg = black;
}
- for (line = 0; line < s->nline; line++) {
- for (col = 0; col < s->ncol; col++) {
- TMTCHAR *c = &s->lines[line]->chars[col];
- struct color *bg = tmt_background(&c->a);
- struct color *fg = tmt_foreground(&c->a);
+ /* background */
+ cairo_rectangle(s->context,
+ tx + posx * extents.max_x_advance,
+ ty + posy * extents.height,
+ extents.max_x_advance * width,
+ extents.height);
+ cairo_set_source_rgb(s->context, bg.r, bg.g, bg.b);
+ cairo_fill(s->context);
+
+ /* char */
+ cairo_move_to(s->context,
+ tx + posx * extents.max_x_advance,
+ ty + posy * extents.height + extents.ascent);
+ cairo_set_source_rgb(s->context, fg.r, fg.g, fg.b);
+ for (i = 0; i < len && i < ARRAY_SIZE(ws)-1; i++)
+ ws[i] = ch[i];
+ ws[i] = 0;
+ wcstombs(utf8, ws, sizeof(utf8));
+ cairo_show_text(s->context, utf8);
- if (cursor->r == line && cursor->c == col) {
- bg = tmt_colors_normal + TMT_COLOR_WHITE;
- fg = tmt_colors_normal + TMT_COLOR_BLACK;
- }
+ return 0;
+}
- /* background */
- cairo_rectangle(context,
- tx + col * extents.max_x_advance,
- ty + line * extents.height,
- extents.max_x_advance,
- extents.height);
- cairo_set_source_rgb(context, bg->r, bg->g, bg->b);
- cairo_fill(context);
-
- /* char */
- cairo_move_to(context,
- tx + col * extents.max_x_advance,
- ty + line * extents.height + extents.ascent);
- cairo_set_source_rgb(context, fg->r, fg->g, fg->b);
- ws[0] = c->c;
- ws[1] = 0;
- wcstombs(utf8, ws, sizeof(utf8));
- cairo_show_text(context, utf8);
- }
+static void cairo_render(void)
+{
+ static bool second;
+ struct cairo_state *s;
+
+ if (state2.surface)
+ second = !second;
+ s = second ? &state2 : &state1;
+
+ if (s->clear) {
+ s->clear = 0;
+ cairo_set_source_rgb(s->context, 0, 0, 0);
+ cairo_paint(s->context);
+ s->age = 0;
}
- cairo_show_page(context);
+ s->age = tsm_screen_draw(vts, tsm_draw_cb, s);
+ cairo_show_page(s->context);
if (gfx->flush_display)
gfx->flush_display(second);
}
-static void tmt_callback(tmt_msg_t m, TMT *vt, const void *a, void *p)
+static void cairo_state_init(struct cairo_state *s,
+ const char *font_name, int font_size)
{
- switch (m) {
- case TMT_MSG_UPDATE:
- dirty++;
- break;
- case TMT_MSG_ANSWER:
- write(pty, a, strlen(a));
- default:
- break;
- }
+ s->context = cairo_create(s->surface);
+ cairo_select_font_face(s->context, font_name,
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size(s->context, font_size);
}
static void child_exec_shell(struct winsize *win)
@@ -335,7 +378,7 @@ static void child_exec_shell(struct winsize *win)
/* prepare environment, run shell */
snprintf(lines, sizeof(lines), "%d", win->ws_row);
snprintf(columns, sizeof(columns), "%d", win->ws_col);
- setenv("TERM", "ansi", true);
+ setenv("TERM", "xterm-256color", true);
setenv("LINES", lines, true);
setenv("COLUMNS", columns, true);
@@ -402,28 +445,20 @@ int main(int argc, char *argv[])
}
/* init cairo */
- surface1 = cairo_image_surface_create_for_data(gfx->mem,
- gfx->fmt->cairo,
- gfx->hdisplay,
- gfx->vdisplay,
- gfx->stride);
- context1 = cairo_create(surface1);
- cairo_select_font_face(context1, font_name,
- CAIRO_FONT_SLANT_NORMAL,
- CAIRO_FONT_WEIGHT_NORMAL);
- cairo_set_font_size(context1, font_size);
- cairo_font_extents(context1, &extents);
+ state1.surface = cairo_image_surface_create_for_data(gfx->mem,
+ gfx->fmt->cairo,
+ gfx->hdisplay,
+ gfx->vdisplay,
+ gfx->stride);
+ cairo_state_init(&state1, font_name, font_size);
+ cairo_font_extents(state1.context, &extents);
if (gfx->mem2) {
- surface2 = cairo_image_surface_create_for_data(gfx->mem2,
- gfx->fmt->cairo,
- gfx->hdisplay,
- gfx->vdisplay,
- gfx->stride);
- context2 = cairo_create(surface2);
- cairo_select_font_face(context2, font_name,
- CAIRO_FONT_SLANT_NORMAL,
- CAIRO_FONT_WEIGHT_NORMAL);
- cairo_set_font_size(context2, font_size);
+ state2.surface = cairo_image_surface_create_for_data(gfx->mem2,
+ gfx->fmt->cairo,
+ gfx->hdisplay,
+ gfx->vdisplay,
+ gfx->stride);
+ cairo_state_init(&state2, font_name, font_size);
}
/* init libinput */
@@ -450,7 +485,12 @@ int main(int argc, char *argv[])
win.ws_row = gfx->vdisplay / extents.height;
win.ws_xpixel = extents.max_x_advance;
win.ws_ypixel = extents.height;
- vt = tmt_open(win.ws_row, win.ws_col, tmt_callback, NULL, NULL);
+
+ tsm_screen_new(&vts, tsm_log_cb, NULL);
+ tsm_screen_resize(vts, win.ws_col, win.ws_row);
+ tsm_vte_new(&vte, vts, tsm_write_cb, NULL, tsm_log_cb, NULL);
+
+ /* run shell */
child = forkpty(&pty, NULL, NULL, &win);
if (0 == child) {
child_exec_shell(&win);
@@ -460,14 +500,17 @@ int main(int argc, char *argv[])
}
/* parent */
- clear++;
+ state1.clear++;
+ state2.clear++;
dirty++;
for (;;) {
fd_set set;
int rc, max;
- if (dirty)
- render();
+ if (dirty) {
+ cairo_render();
+ dirty = 0;
+ }
max = 0;
FD_ZERO(&set);
@@ -489,8 +532,10 @@ int main(int argc, char *argv[])
break; /* read error */
if (rc == 0)
break; /* no data -> EOF */
- if (rc > 0)
- tmt_write(vt, buf, rc);
+ if (rc > 0) {
+ tsm_vte_input(vte, buf, rc);
+ dirty++;
+ }
}
if (FD_ISSET(input, &set)) {
@@ -520,6 +565,7 @@ int main(int argc, char *argv[])
if (rc > 0)
write(pty, buf, rc);
}
+ dirty++;
}
break;
default: