From: Chengyang Zhu <[email protected]> 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: <[email protected]> Signed-off-by: Marc-André Lureau <[email protected]> Signed-off-by: Chengyang Zhu <[email protected]> --- ui/dbus-console.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++ ui/dbus-display1.xml | 55 ++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) diff --git a/ui/dbus-console.c b/ui/dbus-console.c index e1ac06814ba8..947c3b3a545e 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -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; } diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml index d96bae2ed642..a23ca0b8b125 100644 --- a/ui/dbus-display1.xml +++ b/ui/dbus-display1.xml @@ -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> -- 2.55.0.543.g5ebe2ebe4ea8
