ui/dbus: add org.qemu.Display1.UIInfo interface

Currently, the SetUIInfo method cannot set a refresh rate.
Simply adding a refresh_rate argument would break the method signature.

This patch adds the UIInfo interface containing
  * property `Supported` indicating whether console UI info is supported.
  * the method `Apply` taking a dictionary as input.
  * the method `Get` returning the current UI info as a dictionary.

Message-ID: <20260830054641.45437-2-colazcyg@gmail.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Chengyang Zhu <colazcyg@gmail.com>
This commit is contained in:
Chengyang Zhu authored and Marc-André Lureau committed 2026-09-13 14:41:11 +04:00
1 parent 90cfbb4a89
commit 378eb3d0db
2 files changed
+161

No files matched your search

+106
View File
@@ -55,6 +55,8 @@ struct _DBusDisplayConsole {
guint last_x;
guint last_y;
Notifier mouse_mode_notifier;
QemuDBusDisplay1UIInfo *iface_ui_info;
};
G_DEFINE_TYPE(DBusDisplayConsole,
@@ -155,6 +157,7 @@ dbus_display_console_dispose(GObject *object)
qemu_input_led_notifier_remove(&ddc->led_notifier);
qemu_console_unregister_listener(&ddc->dcl);
qemu_remove_mouse_mode_change_notifier(&ddc->mouse_mode_notifier);
g_clear_object(&ddc->iface_ui_info);
g_clear_object(&ddc->iface_touch);
g_clear_object(&ddc->iface_mouse);
g_clear_object(&ddc->iface_kbd);
@@ -528,6 +531,98 @@ dbus_mouse_mode_change(Notifier *notify, void *data)
dbus_mouse_update_is_absolute(ddc);
}
static gboolean
dbus_ui_info_get(DBusDisplayConsole *ddc,
GDBusMethodInvocation *invocation)
{
QemuUIInfo ui_info;
GVariantDict dict;
if (!qemu_console_ui_info_supported(ddc->dcl.con)) {
g_dbus_method_invocation_return_error(invocation,
DBUS_DISPLAY_ERROR,
DBUS_DISPLAY_ERROR_UNSUPPORTED,
"UIInfo is not supported");
return DBUS_METHOD_INVOCATION_HANDLED;
}
ui_info = *qemu_console_get_ui_info(ddc->dcl.con);
g_variant_dict_init(&dict, NULL);
g_variant_dict_insert(&dict, "width_mm", "q", ui_info.width_mm);
g_variant_dict_insert(&dict, "height_mm", "q", ui_info.height_mm);
g_variant_dict_insert(&dict, "xoff", "i", ui_info.xoff);
g_variant_dict_insert(&dict, "yoff", "i", ui_info.yoff);
g_variant_dict_insert(&dict, "width", "u", ui_info.width);
g_variant_dict_insert(&dict, "height", "u", ui_info.height);
g_variant_dict_insert(&dict, "refresh_rate", "u", ui_info.refresh_rate);
qemu_dbus_display1_uiinfo_complete_get(ddc->iface_ui_info, invocation,
g_variant_dict_end(&dict));
return DBUS_METHOD_INVOCATION_HANDLED;
}
static bool
dbus_ui_info_apply_lookup(GDBusMethodInvocation *invocation,
GVariantDict *dict,
const gchar *key,
const gchar *fmt_str,
void *res)
{
if (g_variant_dict_contains(dict, key) &&
!g_variant_dict_lookup(dict, key, fmt_str, res)) {
g_dbus_method_invocation_return_error(invocation,
DBUS_DISPLAY_ERROR,
DBUS_DISPLAY_ERROR_INVALID,
"%s must have D-Bus signature %s",
key, fmt_str);
return false;
}
return true;
}
static gboolean
dbus_ui_info_apply(DBusDisplayConsole *ddc,
GDBusMethodInvocation *invocation,
GVariant *arg_ui_info)
{
QemuUIInfo ui_info;
g_auto(GVariantDict) dict = G_VARIANT_DICT_INIT(arg_ui_info);
if (!qemu_console_ui_info_supported(ddc->dcl.con)) {
g_dbus_method_invocation_return_error(invocation,
DBUS_DISPLAY_ERROR,
DBUS_DISPLAY_ERROR_UNSUPPORTED,
"UIInfo is not supported");
return DBUS_METHOD_INVOCATION_HANDLED;
}
ui_info = *qemu_console_get_ui_info(ddc->dcl.con);
if (!dbus_ui_info_apply_lookup(invocation, &dict, "width_mm", "q",
&ui_info.width_mm) ||
!dbus_ui_info_apply_lookup(invocation, &dict, "height_mm", "q",
&ui_info.height_mm) ||
!dbus_ui_info_apply_lookup(invocation, &dict, "xoff", "i",
&ui_info.xoff) ||
!dbus_ui_info_apply_lookup(invocation, &dict, "yoff", "i",
&ui_info.yoff) ||
!dbus_ui_info_apply_lookup(invocation, &dict, "width", "u",
&ui_info.width) ||
!dbus_ui_info_apply_lookup(invocation, &dict, "height", "u",
&ui_info.height) ||
!dbus_ui_info_apply_lookup(invocation, &dict, "refresh_rate", "u",
&ui_info.refresh_rate)) {
return DBUS_METHOD_INVOCATION_HANDLED;
}
qemu_console_set_ui_info(ddc->dcl.con, &ui_info, false);
qemu_dbus_display1_uiinfo_complete_apply(ddc->iface_ui_info, invocation);
return DBUS_METHOD_INVOCATION_HANDLED;
}
int dbus_display_console_get_index(DBusDisplayConsole *ddc)
{
return qemu_console_get_index(ddc->dcl.con);
@@ -550,6 +645,7 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con)
"org.qemu.Display1.Keyboard",
"org.qemu.Display1.Mouse",
"org.qemu.Display1.MultiTouch",
"org.qemu.Display1.UIInfo",
NULL
};
@@ -626,5 +722,15 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con)
qemu_add_mouse_mode_change_notifier(&ddc->mouse_mode_notifier);
dbus_mouse_update_is_absolute(ddc);
ddc->iface_ui_info = qemu_dbus_display1_uiinfo_skeleton_new();
qemu_dbus_display1_uiinfo_set_supported(ddc->iface_ui_info,
qemu_console_ui_info_supported(ddc->dcl.con));
g_object_connect(ddc->iface_ui_info,
"swapped-signal::handle-get", dbus_ui_info_get, ddc,
"swapped-signal::handle-apply", dbus_ui_info_apply, ddc,
NULL);
g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(ddc),
G_DBUS_INTERFACE_SKELETON(ddc->iface_ui_info));
return ddc;
}
+55
View File
@@ -90,6 +90,10 @@
@height: console height, in pixels.
Modify the dimensions and display settings.
.. seealso::
:dbus:iface:`org.qemu.Display1.UIInfo` which supports a superset of these properties.
-->
<method name="SetUIInfo">
<arg name="width_mm" type="q" direction="in"/>
@@ -1159,4 +1163,55 @@
-->
<property name="Encoding" type="s" access="read"/>
</interface>
<!--
org.qemu.Display1.UIInfo:
This interface is implemented on
``/org/qemu/Display1/Console_$id`` (see
:dbus:iface:`~org.qemu.Display1.Console`).
-->
<interface name="org.qemu.Display1.UIInfo">
<!--
Supported:
Whether console UI info is supported.
-->
<property name="Supported" type="b" access="read"/>
<!--
Get:
@ui_info: a dictionary of UI info properties.
Return the currently requested properties for the console.
The list of returned properties may vary and be extended in the future.
- ``width_mm`` (q): the physical display width in millimeters.
- ``height_mm`` (q): the physical display height in millimeters.
- ``xoff`` (i): the horizontal offset in pixels.
- ``yoff`` (i): the vertical offset in pixels.
- ``width`` (u): the console width in pixels.
- ``height`` (u): the console height in pixels.
- ``refresh_rate`` (u): the display refresh rate in millihertz.
-->
<method name="Get">
<arg name="ui_info" type="a{sv}" direction="out"/>
</method>
<!--
Apply:
@ui_info: a dictionary of new UI info properties.
Apply the properties to the console display.
The dictionary schema of ``Apply`` is a subset of that of ``Get``.
The properties will be merged with existing values.
Extra keys will be ignored.
The invocation will fail if any key has the wrong type,
leaving the UI info unchanged.
-->
<method name="Apply">
<arg name="ui_info" type="a{sv}" direction="in"/>
</method>
</interface>
</node>