mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-10-28 14:04:39 +08:00
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:
1 parent
90cfbb4a89
commit
378eb3d0db
2 files changed
+161
No files matched your search
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
Reference in new issue
Block a user