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>
This commit is contained in:
Marc-André Lureau
2026-02-20 11:50:50 +01:00
parent 8502b70f6e
commit 6640883afc
5 changed files with 65 additions and 57 deletions

View File

@@ -129,6 +129,8 @@ void console_handle_touch_event(QemuConsole *con,
struct QemuConsoleClass {
ObjectClass parent_class;
char * (*get_label)(const QemuConsole *con);
};
typedef struct ScanoutTexture {

View File

@@ -36,7 +36,6 @@ struct QemuConsole {
};
void qemu_text_console_update_size(QemuTextConsole *c);
const char * qemu_text_console_get_label(QemuTextConsole *c);
void qemu_text_console_update_cursor(void);
void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym);

View File

@@ -14,12 +14,6 @@ void qemu_text_console_update_size(QemuTextConsole *c)
{
}
const char *
qemu_text_console_get_label(QemuTextConsole *c)
{
return NULL;
}
void qemu_text_console_update_cursor(void)
{
}

View File

@@ -122,10 +122,12 @@ static const pixman_color_t color_table_rgb[2][8] = {
static bool cursor_visible_phase;
static QEMUTimer *cursor_timer;
const char *
qemu_text_console_get_label(QemuTextConsole *c)
static char *
qemu_text_console_get_label(const QemuConsole *c)
{
return c->chr ? c->chr->label : NULL;
QemuTextConsole *tc = QEMU_TEXT_CONSOLE(c);
return tc->chr ? g_strdup(tc->chr->label) : NULL;
}
static void qemu_console_fill_rect(QemuConsole *con, int posx, int posy,
@@ -1053,9 +1055,13 @@ qemu_text_console_finalize(Object *obj)
static void
qemu_text_console_class_init(ObjectClass *oc, const void *data)
{
QemuConsoleClass *cc = QEMU_CONSOLE_CLASS(oc);
if (!cursor_timer) {
cursor_timer = timer_new_ms(QEMU_CLOCK_REALTIME, cursor_timer_cb, NULL);
}
cc->get_label = qemu_text_console_get_label;
}
static const GraphicHwOps text_console_ops = {

View File

@@ -436,9 +436,58 @@ qemu_graphic_console_prop_get_head(Object *obj, Visitor *v, const char *name,
visit_type_uint32(v, name, &c->head, errp);
}
static bool
qemu_graphic_console_is_multihead(QemuGraphicConsole *c)
{
QemuConsole *con;
QTAILQ_FOREACH(con, &consoles, next) {
QemuGraphicConsole *candidate;
if (!QEMU_IS_GRAPHIC_CONSOLE(con)) {
continue;
}
candidate = QEMU_GRAPHIC_CONSOLE(con);
if (candidate->device != c->device) {
continue;
}
if (candidate->head != c->head) {
return true;
}
}
return false;
}
static char *
qemu_graphic_console_get_label(const QemuConsole *con)
{
QemuGraphicConsole *c = QEMU_GRAPHIC_CONSOLE(con);
if (c->device) {
DeviceState *dev;
bool multihead;
dev = DEVICE(c->device);
multihead = qemu_graphic_console_is_multihead(c);
if (multihead) {
return g_strdup_printf("%s.%d", dev->id ?
dev->id :
object_get_typename(c->device),
c->head);
} else {
return g_strdup(dev->id ? : object_get_typename(c->device));
}
}
return g_strdup("VGA");
}
static void
qemu_graphic_console_class_init(ObjectClass *oc, const void *data)
{
QemuConsoleClass *cc = QEMU_CONSOLE_CLASS(oc);
object_class_property_add_link(oc, "device", TYPE_DEVICE,
offsetof(QemuGraphicConsole, device),
object_property_allow_set_link,
@@ -446,6 +495,8 @@ qemu_graphic_console_class_init(ObjectClass *oc, const void *data)
object_class_property_add(oc, "head", "uint32",
qemu_graphic_console_prop_get_head,
NULL, NULL, NULL);
cc->get_label = qemu_graphic_console_get_label;
}
static void
@@ -1347,56 +1398,12 @@ bool qemu_console_is_gl_blocked(QemuConsole *con)
return con->gl_block;
}
static bool qemu_graphic_console_is_multihead(QemuGraphicConsole *c)
{
QemuConsole *con;
QTAILQ_FOREACH(con, &consoles, next) {
QemuGraphicConsole *candidate;
if (!QEMU_IS_GRAPHIC_CONSOLE(con)) {
continue;
}
candidate = QEMU_GRAPHIC_CONSOLE(con);
if (candidate->device != c->device) {
continue;
}
if (candidate->head != c->head) {
return true;
}
}
return false;
}
char *qemu_console_get_label(QemuConsole *con)
{
if (QEMU_IS_GRAPHIC_CONSOLE(con)) {
QemuGraphicConsole *c = QEMU_GRAPHIC_CONSOLE(con);
if (c->device) {
DeviceState *dev;
bool multihead;
dev = DEVICE(c->device);
multihead = qemu_graphic_console_is_multihead(c);
if (multihead) {
return g_strdup_printf("%s.%d", dev->id ?
dev->id :
object_get_typename(c->device),
c->head);
} else {
return g_strdup(dev->id ? : object_get_typename(c->device));
}
}
return g_strdup("VGA");
} else if (QEMU_IS_TEXT_CONSOLE(con)) {
const char *label = qemu_text_console_get_label(QEMU_TEXT_CONSOLE(con));
if (label) {
return g_strdup(label);
}
char *label = QEMU_CONSOLE_GET_CLASS(con)->get_label(con);
if (label) {
return label;
}
return g_strdup_printf("vc%d", con->index);
}