ui/console: dispatch get_label() through QOM virtual method
Replace the type-checking chain in qemu_console_get_label() (using QEMU_IS_GRAPHIC_CONSOLE/QEMU_IS_TEXT_CONSOLE) with a QemuConsoleClass virtual method, allowing each console subclass to provide its own get_label implementation. Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Marc-André Lureau committed
Feb 20, 2026 at 11:50 UTC
6640883afc39cdcd7f4463c7b50abde030400ffe
5 files changed
+65
-57
include/ui/console.h
+2
@@ -129,6 +129,8 @@ void console_handle_touch_event(QemuConsole *con,
129
130
struct QemuConsoleClass {
131
ObjectClass parent_class;
132
+
133
+ char * (*get_label)(const QemuConsole *con);
134
};
135
136
typedef struct ScanoutTexture {
ui/console-priv.h
-1
@@ -36,7 +36,6 @@ struct QemuConsole {
36
};
37
38
void qemu_text_console_update_size(QemuTextConsole *c);
39
-const char * qemu_text_console_get_label(QemuTextConsole *c);
39
void qemu_text_console_update_cursor(void);
40
void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym);
41
ui/console-vc-stubs.c
-6
@@ -14,12 +14,6 @@ void qemu_text_console_update_size(QemuTextConsole *c)
14
{
15
}
16
17
-const char *
18
-qemu_text_console_get_label(QemuTextConsole *c)
19
-{
20
- return NULL;
21
-}
22
-
17
void qemu_text_console_update_cursor(void)
18
{
19
}
ui/console-vc.c
+9
-3
@@ -122,10 +122,12 @@ static const pixman_color_t color_table_rgb[2][8] = {
122
static bool cursor_visible_phase;
123
static QEMUTimer *cursor_timer;
124
125
-const char *
126
-qemu_text_console_get_label(QemuTextConsole *c)
125
+static char *
126
+qemu_text_console_get_label(const QemuConsole *c)
127
{
128
- return c->chr ? c->chr->label : NULL;
128
+ QemuTextConsole *tc = QEMU_TEXT_CONSOLE(c);
129
+
130
+ return tc->chr ? g_strdup(tc->chr->label) : NULL;
131
}
132
133
static void qemu_console_fill_rect(QemuConsole *con, int posx, int posy,
@@ -1053,9 +1055,13 @@ qemu_text_console_finalize(Object *obj)
1055
static void
1056
qemu_text_console_class_init(ObjectClass *oc, const void *data)
1057
{
1058
+ QemuConsoleClass *cc = QEMU_CONSOLE_CLASS(oc);
1059
+
1060
if (!cursor_timer) {
1061
cursor_timer = timer_new_ms(QEMU_CLOCK_REALTIME, cursor_timer_cb, NULL);
1062
}
1063
+
1064
+ cc->get_label = qemu_text_console_get_label;
1065
}
1066
1067
static const GraphicHwOps text_console_ops = {
ui/console.c
+54
-47
@@ -436,9 +436,58 @@ qemu_graphic_console_prop_get_head(Object *obj, Visitor *v, const char *name,
436
visit_type_uint32(v, name, &c->head, errp);
437
}
438
439
+static bool
440
+qemu_graphic_console_is_multihead(QemuGraphicConsole *c)
441
+{
442
+ QemuConsole *con;
443
+
444
+ QTAILQ_FOREACH(con, &consoles, next) {
445
+ QemuGraphicConsole *candidate;
446
+
447
+ if (!QEMU_IS_GRAPHIC_CONSOLE(con)) {
448
+ continue;
449
+ }
450
+
451
+ candidate = QEMU_GRAPHIC_CONSOLE(con);
452
+ if (candidate->device != c->device) {
453
+ continue;
454
+ }
455
+
456
+ if (candidate->head != c->head) {
457
+ return true;
458
+ }
459
+ }
460
+ return false;
461
+}
462
+
463
+static char *
464
+qemu_graphic_console_get_label(const QemuConsole *con)
465
+{
466
+ QemuGraphicConsole *c = QEMU_GRAPHIC_CONSOLE(con);
467
+
468
+ if (c->device) {
469
+ DeviceState *dev;
470
+ bool multihead;
471
+
472
+ dev = DEVICE(c->device);
473
+ multihead = qemu_graphic_console_is_multihead(c);
474
+ if (multihead) {
475
+ return g_strdup_printf("%s.%d", dev->id ?
476
+ dev->id :
477
+ object_get_typename(c->device),
478
+ c->head);
479
+ } else {
480
+ return g_strdup(dev->id ? : object_get_typename(c->device));
481
+ }
482
+ }
483
+ return g_strdup("VGA");
484
+}
485
+
486
static void
487
qemu_graphic_console_class_init(ObjectClass *oc, const void *data)
488
{
489
+ QemuConsoleClass *cc = QEMU_CONSOLE_CLASS(oc);
490
+
491
object_class_property_add_link(oc, "device", TYPE_DEVICE,
492
offsetof(QemuGraphicConsole, device),
493
object_property_allow_set_link,
@@ -446,6 +495,8 @@ qemu_graphic_console_class_init(ObjectClass *oc, const void *data)
495
object_class_property_add(oc, "head", "uint32",
496
qemu_graphic_console_prop_get_head,
497
NULL, NULL, NULL);
498
+
499
+ cc->get_label = qemu_graphic_console_get_label;
500
}
501
502
static void
@@ -1347,56 +1398,12 @@ bool qemu_console_is_gl_blocked(QemuConsole *con)
1398
return con->gl_block;
1399
}
1400
1350
-static bool qemu_graphic_console_is_multihead(QemuGraphicConsole *c)
1351
-{
1352
- QemuConsole *con;
1353
-
1354
- QTAILQ_FOREACH(con, &consoles, next) {
1355
- QemuGraphicConsole *candidate;
1356
-
1357
- if (!QEMU_IS_GRAPHIC_CONSOLE(con)) {
1358
- continue;
1359
- }
1360
-
1361
- candidate = QEMU_GRAPHIC_CONSOLE(con);
1362
- if (candidate->device != c->device) {
1363
- continue;
1364
- }
1365
-
1366
- if (candidate->head != c->head) {
1367
- return true;
1368
- }
1369
- }
1370
- return false;
1371
-}
1372
-
1401
char *qemu_console_get_label(QemuConsole *con)
1402
{
1375
- if (QEMU_IS_GRAPHIC_CONSOLE(con)) {
1376
- QemuGraphicConsole *c = QEMU_GRAPHIC_CONSOLE(con);
1377
- if (c->device) {
1378
- DeviceState *dev;
1379
- bool multihead;
1380
-
1381
- dev = DEVICE(c->device);
1382
- multihead = qemu_graphic_console_is_multihead(c);
1383
- if (multihead) {
1384
- return g_strdup_printf("%s.%d", dev->id ?
1385
- dev->id :
1386
- object_get_typename(c->device),
1387
- c->head);
1388
- } else {
1389
- return g_strdup(dev->id ? : object_get_typename(c->device));
1390
- }
1391
- }
1392
- return g_strdup("VGA");
1393
- } else if (QEMU_IS_TEXT_CONSOLE(con)) {
1394
- const char *label = qemu_text_console_get_label(QEMU_TEXT_CONSOLE(con));
1395
- if (label) {
1396
- return g_strdup(label);
1397
- }
1403
+ char *label = QEMU_CONSOLE_GET_CLASS(con)->get_label(con);
1404
+ if (label) {
1405
+ return label;
1406
}
1399
-
1407
return g_strdup_printf("vc%d", con->index);
1408
}
1409