Commit 3faf2b0ae1 for qemu.org
commit 3faf2b0ae1affe926ea818a3f354753874f3d1bf
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
Date: Thu Feb 19 12:39:04 2026 +0100
ui/console-vc: decouple VT100 display updates via function pointer
Replace direct dpy_gfx_update() calls from the VT100 emulation code
with an indirect call through a new image_update function pointer in
QemuVT100. This decouples the VT100 terminal emulation from the
QEMU display layer, allowing different backends to provide their own
image update implementation.
The QemuVT100 typedef is changed to a forward-declared struct so the
function pointer signature can reference QemuVT100 itself.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
diff --git a/ui/console-vc.c b/ui/console-vc.c
index fb1c8866a0..bc8462f979 100644
--- a/ui/console-vc.c
+++ b/ui/console-vc.c
@@ -47,8 +47,11 @@ enum TTYState {
TTY_STATE_OSC,
};
-typedef struct QemuVT100 {
+typedef struct QemuVT100 QemuVT100;
+
+struct QemuVT100 {
pixman_image_t *image;
+ void (*image_update)(QemuVT100 *vt, int x, int y, int width, int height);
int width;
int height;
@@ -65,7 +68,7 @@ typedef struct QemuVT100 {
int update_y0;
int update_x1;
int update_y1;
-} QemuVT100;
+};
typedef struct QemuTextConsole {
QemuConsole parent;
@@ -221,6 +224,11 @@ static void vt100_show_cursor(QemuVT100 *vt, int show)
}
}
+static void vt100_image_update(QemuVT100 *vt, int x, int y, int width, int height)
+{
+ vt->image_update(vt, x, y, width, height);
+}
+
static void console_refresh(QemuTextConsole *s)
{
QemuVT100 *vt = &s->vt;
@@ -250,7 +258,7 @@ static void console_refresh(QemuTextConsole *s)
}
}
vt100_show_cursor(&s->vt, 1);
- dpy_gfx_update(QEMU_CONSOLE(s), 0, 0, w, h);
+ vt100_image_update(&s->vt, 0, 0, w, h);
}
static void console_scroll(QemuTextConsole *s, int ydelta)
@@ -1028,9 +1036,9 @@ static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len)
}
vt100_show_cursor(vt, 1);
if (vt->update_x0 < vt->update_x1) {
- dpy_gfx_update(QEMU_CONSOLE(s), vt->update_x0, vt->update_y0,
- vt->update_x1 - vt->update_x0,
- vt->update_y1 - vt->update_y0);
+ vt100_image_update(vt, vt->update_x0, vt->update_y0,
+ vt->update_x1 - vt->update_x0,
+ vt->update_y1 - vt->update_y0);
}
return len;
}
@@ -1128,6 +1136,13 @@ void qemu_text_console_update_size(QemuTextConsole *c)
dpy_text_resize(QEMU_CONSOLE(c), c->vt.width, c->vt.height);
}
+static void text_console_image_update(QemuVT100 *vt, int x, int y, int width, int height)
+{
+ QemuTextConsole *console = container_of(vt, QemuTextConsole, vt);
+
+ dpy_gfx_update(QEMU_CONSOLE(console), x, y, width, height);
+}
+
static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
{
ChardevVC *vc = backend->u.vc.data;
@@ -1158,6 +1173,7 @@ static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
}
dpy_gfx_replace_surface(QEMU_CONSOLE(s), qemu_create_displaysurface(width, height));
+ s->vt.image_update = text_console_image_update;
s->chr = chr;
drv->console = s;