From de9f844ce27ef8540bb9e8b4dd2c159b676d78a5 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Mon, 19 Jun 2023 11:53:37 +0200 Subject: ui/dbus: Expose a touch device interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So that clients making use of the DBus backend could send touch events through the new org.qemu.Display1.Touch interface Signed-off-by: Bilal Elmoussaoui Reviewed-by: Marc-André Lureau Message-Id: <20230619095337.9899-3-belmouss@redhat.com> --- ui/dbus-console.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'ui/dbus-console.c') diff --git a/ui/dbus-console.c b/ui/dbus-console.c index f77bc49d2e..bc97614fec 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -32,6 +32,8 @@ #include "dbus.h" +static struct touch_slot touch_slots[INPUT_EVENT_SLOTS_MAX]; + struct _DBusDisplayConsole { GDBusObjectSkeleton parent_instance; DisplayChangeListener dcl; @@ -44,6 +46,7 @@ struct _DBusDisplayConsole { QKbdState *kbd; QemuDBusDisplay1Mouse *iface_mouse; + QemuDBusDisplay1MultiTouch *iface_touch; gboolean last_set; guint last_x; guint last_y; @@ -345,6 +348,46 @@ dbus_mouse_rel_motion(DBusDisplayConsole *ddc, return DBUS_METHOD_INVOCATION_HANDLED; } +static gboolean +dbus_touch_send_event(DBusDisplayConsole *ddc, + GDBusMethodInvocation *invocation, + guint kind, uint64_t num_slot, + double x, double y) +{ + Error *error = NULL; + int width, height; + trace_dbus_touch_send_event(kind, num_slot, x, y); + + if (kind != INPUT_MULTI_TOUCH_TYPE_BEGIN && + kind != INPUT_MULTI_TOUCH_TYPE_UPDATE && + kind != INPUT_MULTI_TOUCH_TYPE_CANCEL && + kind != INPUT_MULTI_TOUCH_TYPE_END) + { + g_dbus_method_invocation_return_error( + invocation, DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + "Invalid touch event kind"); + return DBUS_METHOD_INVOCATION_HANDLED; + } + width = qemu_console_get_width(ddc->dcl.con, 0); + height = qemu_console_get_height(ddc->dcl.con, 0); + + console_handle_touch_event(ddc->dcl.con, touch_slots, + num_slot, width, height, + x, y, kind, &error); + if (error != NULL) { + g_dbus_method_invocation_return_error( + invocation, DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + error_get_pretty(error), NULL); + error_free(error); + } else { + qemu_dbus_display1_multi_touch_complete_send_event(ddc->iface_touch, + invocation); + } + return DBUS_METHOD_INVOCATION_HANDLED; +} + static gboolean dbus_mouse_set_pos(DBusDisplayConsole *ddc, GDBusMethodInvocation *invocation, @@ -440,7 +483,7 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con) g_autofree char *label = NULL; char device_addr[256] = ""; DBusDisplayConsole *ddc; - int idx; + int idx, i; assert(display); assert(con); @@ -495,6 +538,20 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con) g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(ddc), G_DBUS_INTERFACE_SKELETON(ddc->iface_mouse)); + ddc->iface_touch = qemu_dbus_display1_multi_touch_skeleton_new(); + g_object_connect(ddc->iface_touch, + "swapped-signal::handle-send-event", dbus_touch_send_event, ddc, + NULL); + qemu_dbus_display1_multi_touch_set_max_slots(ddc->iface_touch, + INPUT_EVENT_SLOTS_MAX); + g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(ddc), + G_DBUS_INTERFACE_SKELETON(ddc->iface_touch)); + + for (i = 0; i < INPUT_EVENT_SLOTS_MAX; i++) { + struct touch_slot *slot = &touch_slots[i]; + slot->tracking_id = -1; + } + register_displaychangelistener(&ddc->dcl); ddc->mouse_mode_notifier.notify = dbus_mouse_mode_change; qemu_add_mouse_mode_change_notifier(&ddc->mouse_mode_notifier); -- cgit 1.4.1 From 29c5c7e5f65977a77eddf6580fdc31ea4a263a6a Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Tue, 6 Jun 2023 15:56:40 +0400 Subject: ui/dbus: compile without gio/gunixfdlist.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit D-Bus on windows doesn't support fd-passing. Let's isolate the fdlist-related code as a first step, before adding Windows support, using another mechanism. Signed-off-by: Marc-André Lureau Message-Id: <20230606115658.677673-4-marcandre.lureau@redhat.com> --- audio/dbusaudio.c | 7 +++++++ ui/dbus-chardev.c | 6 ++++++ ui/dbus-console.c | 8 ++++++++ ui/dbus-listener.c | 2 ++ 4 files changed, 23 insertions(+) (limited to 'ui/dbus-console.c') diff --git a/audio/dbusaudio.c b/audio/dbusaudio.c index fece74f78c..de59467d9e 100644 --- a/audio/dbusaudio.c +++ b/audio/dbusaudio.c @@ -29,7 +29,10 @@ #include "qemu/timer.h" #include "qemu/dbus.h" +#ifdef G_OS_UNIX #include +#endif + #include "ui/dbus-display1.h" #define AUDIO_CAP "dbus" @@ -419,6 +422,7 @@ dbus_audio_fini(void *opaque) g_free(da); } +#ifdef G_OS_UNIX static void listener_out_vanished_cb(GDBusConnection *connection, gboolean remote_peer_vanished, @@ -591,6 +595,7 @@ dbus_audio_register_in_listener(AudioState *s, return dbus_audio_register_listener(s, invocation, fd_list, arg_listener, false); } +#endif static void dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server, bool p2p) @@ -605,12 +610,14 @@ dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server, bool p2p) da->audio = g_dbus_object_skeleton_new(DBUS_DISPLAY1_AUDIO_PATH); da->iface = qemu_dbus_display1_audio_skeleton_new(); +#ifdef G_OS_UNIX g_object_connect(da->iface, "swapped-signal::handle-register-in-listener", dbus_audio_register_in_listener, s, "swapped-signal::handle-register-out-listener", dbus_audio_register_out_listener, s, NULL); +#endif g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(da->audio), G_DBUS_INTERFACE_SKELETON(da->iface)); diff --git a/ui/dbus-chardev.c b/ui/dbus-chardev.c index 940ef937cd..7154d81a9a 100644 --- a/ui/dbus-chardev.c +++ b/ui/dbus-chardev.c @@ -27,7 +27,9 @@ #include "qemu/config-file.h" #include "qemu/option.h" +#ifdef G_OS_UNIX #include +#endif #include "dbus.h" @@ -108,6 +110,7 @@ dbus_chardev_init(DBusDisplay *dpy) dbus_display_chardev_foreach, dpy); } +#ifdef G_OS_UNIX static gboolean dbus_chr_register( DBusChardev *dc, @@ -145,6 +148,7 @@ dbus_chr_register( qemu_dbus_display1_chardev_complete_register(object, invocation, NULL); return DBUS_METHOD_INVOCATION_HANDLED; } +#endif static gboolean dbus_chr_send_break( @@ -175,8 +179,10 @@ dbus_chr_open(Chardev *chr, ChardevBackend *backend, dc->iface = qemu_dbus_display1_chardev_skeleton_new(); g_object_set(dc->iface, "name", backend->u.dbus.data->name, NULL); g_object_connect(dc->iface, +#ifdef G_OS_UNIX "swapped-signal::handle-register", dbus_chr_register, dc, +#endif "swapped-signal::handle-send-break", dbus_chr_send_break, dc, NULL); diff --git a/ui/dbus-console.c b/ui/dbus-console.c index bc97614fec..d5f6c93637 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -28,7 +28,9 @@ #include "ui/kbd-state.h" #include "trace.h" +#ifdef G_OS_UNIX #include +#endif #include "dbus.h" @@ -163,6 +165,7 @@ dbus_display_console_class_init(DBusDisplayConsoleClass *klass) gobject_class->dispose = dbus_display_console_dispose; } +#ifdef G_OS_UNIX static void listener_vanished_cb(DBusDisplayListener *listener) { @@ -174,6 +177,7 @@ listener_vanished_cb(DBusDisplayListener *listener) g_hash_table_remove(ddc->listeners, name); qkbd_state_lift_all_keys(ddc->kbd); } +#endif static gboolean dbus_console_set_ui_info(DBusDisplayConsole *ddc, @@ -207,6 +211,7 @@ dbus_console_set_ui_info(DBusDisplayConsole *ddc, return DBUS_METHOD_INVOCATION_HANDLED; } +#ifdef G_OS_UNIX static gboolean dbus_console_register_listener(DBusDisplayConsole *ddc, GDBusMethodInvocation *invocation, @@ -282,6 +287,7 @@ dbus_console_register_listener(DBusDisplayConsole *ddc, trace_dbus_registered_listener(sender); return DBUS_METHOD_INVOCATION_HANDLED; } +#endif static gboolean dbus_kbd_press(DBusDisplayConsole *ddc, @@ -510,8 +516,10 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con) "device-address", device_addr, NULL); g_object_connect(ddc->iface, +#ifdef G_OS_UNIX "swapped-signal::handle-register-listener", dbus_console_register_listener, ddc, +#endif "swapped-signal::handle-set-uiinfo", dbus_console_set_ui_info, ddc, NULL); diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 23034eebf9..41597a0078 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -25,7 +25,9 @@ #include "qemu/error-report.h" #include "sysemu/sysemu.h" #include "dbus.h" +#ifdef G_OS_UNIX #include +#endif #ifdef CONFIG_OPENGL #include "ui/shader.h" -- cgit 1.4.1 From 6cc5a6159a0067fefbe0b7912c187018aa4b460a Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Tue, 6 Jun 2023 15:56:42 +0400 Subject: ui/dbus: win32 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit D-Bus doesn't support fd-passing on Windows (AF_UNIX doesn't have SCM_RIGHTS yet, but there are other means to share objects. I have proposed various solutions upstream, but none seem fitting enough atm). To make the "-display dbus" work on Windows, implement an alternative D-Bus interface where all the 'h' (FDs) arguments are replaced with 'ay' (WSASocketW data), and sockets are passed to the other end via WSADuplicateSocket(). Signed-off-by: Marc-André Lureau Message-Id: <20230606115658.677673-6-marcandre.lureau@redhat.com> --- audio/dbusaudio.c | 44 ++++++++++++++++++++++++++++++++------- meson.build | 4 ++-- ui/dbus-chardev.c | 22 +++++++++++++++----- ui/dbus-console.c | 59 +++++++++++++++++++++++++++++++++++++++++++++------- ui/dbus-display1.xml | 28 +++++++++++++++++++++++++ ui/dbus.h | 6 ++++++ ui/meson.build | 9 +++++++- 7 files changed, 149 insertions(+), 23 deletions(-) (limited to 'ui/dbus-console.c') diff --git a/audio/dbusaudio.c b/audio/dbusaudio.c index de59467d9e..7a11fbfb42 100644 --- a/audio/dbusaudio.c +++ b/audio/dbusaudio.c @@ -33,6 +33,7 @@ #include #endif +#include "ui/dbus.h" #include "ui/dbus-display1.h" #define AUDIO_CAP "dbus" @@ -422,7 +423,6 @@ dbus_audio_fini(void *opaque) g_free(da); } -#ifdef G_OS_UNIX static void listener_out_vanished_cb(GDBusConnection *connection, gboolean remote_peer_vanished, @@ -448,7 +448,9 @@ listener_in_vanished_cb(GDBusConnection *connection, static gboolean dbus_audio_register_listener(AudioState *s, GDBusMethodInvocation *invocation, +#ifdef G_OS_UNIX GUnixFDList *fd_list, +#endif GVariant *arg_listener, bool out) { @@ -475,6 +477,11 @@ dbus_audio_register_listener(AudioState *s, return DBUS_METHOD_INVOCATION_HANDLED; } +#ifdef G_OS_WIN32 + if (!dbus_win32_import_socket(invocation, arg_listener, &fd)) { + return DBUS_METHOD_INVOCATION_HANDLED; + } +#else fd = g_unix_fd_list_get(fd_list, g_variant_get_handle(arg_listener), &err); if (err) { g_dbus_method_invocation_return_error(invocation, @@ -484,6 +491,7 @@ dbus_audio_register_listener(AudioState *s, err->message); return DBUS_METHOD_INVOCATION_HANDLED; } +#endif socket = g_socket_new_from_fd(fd, &err); if (err) { @@ -492,15 +500,28 @@ dbus_audio_register_listener(AudioState *s, DBUS_DISPLAY_ERROR_FAILED, "Couldn't make a socket: %s", err->message); +#ifdef G_OS_WIN32 + closesocket(fd); +#else + close(fd); +#endif return DBUS_METHOD_INVOCATION_HANDLED; } socket_conn = g_socket_connection_factory_create_connection(socket); if (out) { qemu_dbus_display1_audio_complete_register_out_listener( - da->iface, invocation, NULL); + da->iface, invocation +#ifdef G_OS_UNIX + , NULL +#endif + ); } else { qemu_dbus_display1_audio_complete_register_in_listener( - da->iface, invocation, NULL); + da->iface, invocation +#ifdef G_OS_UNIX + , NULL +#endif + ); } listener_conn = @@ -578,24 +599,33 @@ dbus_audio_register_listener(AudioState *s, static gboolean dbus_audio_register_out_listener(AudioState *s, GDBusMethodInvocation *invocation, +#ifdef G_OS_UNIX GUnixFDList *fd_list, +#endif GVariant *arg_listener) { return dbus_audio_register_listener(s, invocation, - fd_list, arg_listener, true); +#ifdef G_OS_UNIX + fd_list, +#endif + arg_listener, true); } static gboolean dbus_audio_register_in_listener(AudioState *s, GDBusMethodInvocation *invocation, +#ifdef G_OS_UNIX GUnixFDList *fd_list, +#endif GVariant *arg_listener) { return dbus_audio_register_listener(s, invocation, - fd_list, arg_listener, false); -} +#ifdef G_OS_UNIX + fd_list, #endif + arg_listener, false); +} static void dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server, bool p2p) @@ -610,14 +640,12 @@ dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server, bool p2p) da->audio = g_dbus_object_skeleton_new(DBUS_DISPLAY1_AUDIO_PATH); da->iface = qemu_dbus_display1_audio_skeleton_new(); -#ifdef G_OS_UNIX g_object_connect(da->iface, "swapped-signal::handle-register-in-listener", dbus_audio_register_in_listener, s, "swapped-signal::handle-register-out-listener", dbus_audio_register_out_listener, s, NULL); -#endif g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(da->audio), G_DBUS_INTERFACE_SKELETON(da->iface)); diff --git a/meson.build b/meson.build index b409788832..9a1ce43471 100644 --- a/meson.build +++ b/meson.build @@ -838,6 +838,8 @@ if gdbus_codegen.found() and get_option('cfi') gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity' endif +xml_pp = find_program('scripts/xml-preprocess.py') + lttng = not_found if 'ust' in get_option('trace_backends') lttng = dependency('lttng-ust', required: true, version: '>= 2.1', @@ -1985,8 +1987,6 @@ dbus_display = get_option('dbus_display') \ error_message: '-display dbus requires glib>=2.64') \ .require(gdbus_codegen.found(), error_message: gdbus_codegen_error.format('-display dbus')) \ - .require(targetos != 'windows', - error_message: '-display dbus is not available on Windows') \ .allowed() have_virtfs = get_option('virtfs') \ diff --git a/ui/dbus-chardev.c b/ui/dbus-chardev.c index 7154d81a9a..1d3a7122a1 100644 --- a/ui/dbus-chardev.c +++ b/ui/dbus-chardev.c @@ -110,18 +110,24 @@ dbus_chardev_init(DBusDisplay *dpy) dbus_display_chardev_foreach, dpy); } -#ifdef G_OS_UNIX static gboolean dbus_chr_register( DBusChardev *dc, GDBusMethodInvocation *invocation, +#ifdef G_OS_UNIX GUnixFDList *fd_list, +#endif GVariant *arg_stream, QemuDBusDisplay1Chardev *object) { g_autoptr(GError) err = NULL; int fd; +#ifdef G_OS_WIN32 + if (!dbus_win32_import_socket(invocation, arg_stream, &fd)) { + return DBUS_METHOD_INVOCATION_HANDLED; + } +#else fd = g_unix_fd_list_get(fd_list, g_variant_get_handle(arg_stream), &err); if (err) { g_dbus_method_invocation_return_error( @@ -131,13 +137,18 @@ dbus_chr_register( "Couldn't get peer FD: %s", err->message); return DBUS_METHOD_INVOCATION_HANDLED; } +#endif if (qemu_chr_add_client(CHARDEV(dc), fd) < 0) { g_dbus_method_invocation_return_error(invocation, DBUS_DISPLAY_ERROR, DBUS_DISPLAY_ERROR_FAILED, "Couldn't register FD!"); +#ifdef G_OS_WIN32 + closesocket(fd); +#else close(fd); +#endif return DBUS_METHOD_INVOCATION_HANDLED; } @@ -145,10 +156,13 @@ dbus_chr_register( "owner", g_dbus_method_invocation_get_sender(invocation), NULL); - qemu_dbus_display1_chardev_complete_register(object, invocation, NULL); + qemu_dbus_display1_chardev_complete_register(object, invocation +#ifndef G_OS_WIN32 + , NULL +#endif + ); return DBUS_METHOD_INVOCATION_HANDLED; } -#endif static gboolean dbus_chr_send_break( @@ -179,10 +193,8 @@ dbus_chr_open(Chardev *chr, ChardevBackend *backend, dc->iface = qemu_dbus_display1_chardev_skeleton_new(); g_object_set(dc->iface, "name", backend->u.dbus.data->name, NULL); g_object_connect(dc->iface, -#ifdef G_OS_UNIX "swapped-signal::handle-register", dbus_chr_register, dc, -#endif "swapped-signal::handle-send-break", dbus_chr_send_break, dc, NULL); diff --git a/ui/dbus-console.c b/ui/dbus-console.c index d5f6c93637..4a1c1fb55e 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -165,7 +165,6 @@ dbus_display_console_class_init(DBusDisplayConsoleClass *klass) gobject_class->dispose = dbus_display_console_dispose; } -#ifdef G_OS_UNIX static void listener_vanished_cb(DBusDisplayListener *listener) { @@ -177,7 +176,6 @@ listener_vanished_cb(DBusDisplayListener *listener) g_hash_table_remove(ddc->listeners, name); qkbd_state_lift_all_keys(ddc->kbd); } -#endif static gboolean dbus_console_set_ui_info(DBusDisplayConsole *ddc, @@ -211,11 +209,47 @@ dbus_console_set_ui_info(DBusDisplayConsole *ddc, return DBUS_METHOD_INVOCATION_HANDLED; } -#ifdef G_OS_UNIX +#ifdef G_OS_WIN32 +bool +dbus_win32_import_socket(GDBusMethodInvocation *invocation, + GVariant *arg_listener, int *socket) +{ + gsize n; + WSAPROTOCOL_INFOW *info = (void *)g_variant_get_fixed_array(arg_listener, &n, 1); + + if (!info || n != sizeof(*info)) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Failed to get socket infos"); + return false; + } + + *socket = WSASocketW(FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, + info, 0, 0); + if (*socket == INVALID_SOCKET) { + g_autofree gchar *emsg = g_win32_error_message(WSAGetLastError()); + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Couldn't create socket: %s", emsg); + return false; + } + + return true; +} +#endif + static gboolean dbus_console_register_listener(DBusDisplayConsole *ddc, GDBusMethodInvocation *invocation, +#ifdef G_OS_UNIX GUnixFDList *fd_list, +#endif GVariant *arg_listener) { const char *sender = g_dbus_method_invocation_get_sender(invocation); @@ -237,6 +271,11 @@ dbus_console_register_listener(DBusDisplayConsole *ddc, return DBUS_METHOD_INVOCATION_HANDLED; } +#ifdef G_OS_WIN32 + if (!dbus_win32_import_socket(invocation, arg_listener, &fd)) { + return DBUS_METHOD_INVOCATION_HANDLED; + } +#else fd = g_unix_fd_list_get(fd_list, g_variant_get_handle(arg_listener), &err); if (err) { g_dbus_method_invocation_return_error( @@ -246,6 +285,7 @@ dbus_console_register_listener(DBusDisplayConsole *ddc, "Couldn't get peer fd: %s", err->message); return DBUS_METHOD_INVOCATION_HANDLED; } +#endif socket = g_socket_new_from_fd(fd, &err); if (err) { @@ -254,13 +294,21 @@ dbus_console_register_listener(DBusDisplayConsole *ddc, DBUS_DISPLAY_ERROR, DBUS_DISPLAY_ERROR_FAILED, "Couldn't make a socket: %s", err->message); +#ifdef G_OS_WIN32 + closesocket(fd); +#else close(fd); +#endif return DBUS_METHOD_INVOCATION_HANDLED; } socket_conn = g_socket_connection_factory_create_connection(socket); qemu_dbus_display1_console_complete_register_listener( - ddc->iface, invocation, NULL); + ddc->iface, invocation +#ifdef G_OS_UNIX + , NULL +#endif + ); listener_conn = g_dbus_connection_new_sync( G_IO_STREAM(socket_conn), @@ -287,7 +335,6 @@ dbus_console_register_listener(DBusDisplayConsole *ddc, trace_dbus_registered_listener(sender); return DBUS_METHOD_INVOCATION_HANDLED; } -#endif static gboolean dbus_kbd_press(DBusDisplayConsole *ddc, @@ -516,10 +563,8 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con) "device-address", device_addr, NULL); g_object_connect(ddc->iface, -#ifdef G_OS_UNIX "swapped-signal::handle-register-listener", dbus_console_register_listener, ddc, -#endif "swapped-signal::handle-set-uiinfo", dbus_console_set_ui_info, ddc, NULL); diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml index cc0c9b68bf..cd596f774e 100644 --- a/ui/dbus-display1.xml +++ b/ui/dbus-display1.xml @@ -57,7 +57,13 @@ :dbus:iface:`org.qemu.Display1.Listener` interface. --> + + + + + + + + + + + + + + + + + + + @@ -760,7 +782,13 @@ The current handler, if any, will be replaced. --> + + + + + + + + + + + + @@ -171,7 +200,8 @@ + + + + + + + + -- cgit 1.4.1 From bf41ab61908b340e5745c334586349bc8a3a0349 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Tue, 6 Jun 2023 15:56:56 +0400 Subject: ui: add optional d3d texture pointer to scanout texture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following patch will get the underlying D3D11 Texture2D from the virgl renderer scanout. Pass it along to the texture scanout callbacks as a priliminary step, to simplify review. Signed-off-by: Marc-André Lureau Message-Id: <20230606115658.677673-20-marcandre.lureau@redhat.com> --- hw/display/virtio-gpu-virgl.c | 4 +++- include/ui/console.h | 7 +++++-- include/ui/gtk.h | 6 ++++-- include/ui/sdl2.h | 3 ++- ui/console.c | 11 +++++++---- ui/dbus-console.c | 3 ++- ui/dbus-listener.c | 5 +++-- ui/egl-headless.c | 5 +++-- ui/gtk-egl.c | 5 +++-- ui/gtk-gl-area.c | 5 +++-- ui/sdl2-gl.c | 3 ++- ui/spice-display.c | 3 ++- 12 files changed, 39 insertions(+), 21 deletions(-) (limited to 'ui/dbus-console.c') diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c index 9831c482e5..8fa9809371 100644 --- a/hw/display/virtio-gpu-virgl.c +++ b/hw/display/virtio-gpu-virgl.c @@ -154,6 +154,7 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g, { struct virtio_gpu_set_scanout ss; struct virgl_renderer_resource_info info; + void *d3d_tex2d = NULL; int ret; VIRTIO_GPU_FILL_CMD(ss); @@ -186,7 +187,8 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g, g->parent_obj.scanout[ss.scanout_id].con, info.tex_id, info.flags & VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP, info.width, info.height, - ss.r.x, ss.r.y, ss.r.width, ss.r.height); + ss.r.x, ss.r.y, ss.r.width, ss.r.height, + d3d_tex2d); } else { dpy_gfx_replace_surface( g->parent_obj.scanout[ss.scanout_id].con, NULL); diff --git a/include/ui/console.h b/include/ui/console.h index 2ab0c7112a..f27b2aad4f 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -132,6 +132,7 @@ typedef struct ScanoutTexture { uint32_t y; uint32_t width; uint32_t height; + void *d3d_tex2d; } ScanoutTexture; typedef struct DisplaySurface { @@ -270,7 +271,8 @@ typedef struct DisplayChangeListenerOps { uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t w, uint32_t h); + uint32_t w, uint32_t h, + void *d3d_tex2d); /* optional (default to true if has dpy_gl_scanout_dmabuf) */ bool (*dpy_has_dmabuf)(DisplayChangeListener *dcl); /* optional */ @@ -378,7 +380,8 @@ void dpy_gl_scanout_disable(QemuConsole *con); void dpy_gl_scanout_texture(QemuConsole *con, uint32_t backing_id, bool backing_y_0_top, uint32_t backing_width, uint32_t backing_height, - uint32_t x, uint32_t y, uint32_t w, uint32_t h); + uint32_t x, uint32_t y, uint32_t w, uint32_t h, + void *d3d_tex2d); void dpy_gl_scanout_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf); void dpy_gl_cursor_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf, diff --git a/include/ui/gtk.h b/include/ui/gtk.h index ae0f53740d..aa3d637029 100644 --- a/include/ui/gtk.h +++ b/include/ui/gtk.h @@ -175,7 +175,8 @@ void gd_egl_scanout_texture(DisplayChangeListener *dcl, uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t w, uint32_t h); + uint32_t w, uint32_t h, + void *d3d_tex2d); void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl, QemuDmaBuf *dmabuf); void gd_egl_cursor_dmabuf(DisplayChangeListener *dcl, @@ -211,7 +212,8 @@ void gd_gl_area_scanout_texture(DisplayChangeListener *dcl, uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t w, uint32_t h); + uint32_t w, uint32_t h, + void *d3d_tex2d); void gd_gl_area_scanout_disable(DisplayChangeListener *dcl); void gd_gl_area_scanout_flush(DisplayChangeListener *dcl, uint32_t x, uint32_t y, uint32_t w, uint32_t h); diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index 8fb7e08262..e3acc7c82a 100644 --- a/include/ui/sdl2.h +++ b/include/ui/sdl2.h @@ -90,7 +90,8 @@ void sdl2_gl_scanout_texture(DisplayChangeListener *dcl, uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t w, uint32_t h); + uint32_t w, uint32_t h, + void *d3d_tex2d); void sdl2_gl_scanout_flush(DisplayChangeListener *dcl, uint32_t x, uint32_t y, uint32_t w, uint32_t h); diff --git a/ui/console.c b/ui/console.c index 4957110723..c1544e0fb8 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1223,7 +1223,8 @@ static void displaychangelistener_display_console(DisplayChangeListener *dcl, con->scanout.texture.x, con->scanout.texture.y, con->scanout.texture.width, - con->scanout.texture.height); + con->scanout.texture.height, + con->scanout.texture.d3d_tex2d); } } @@ -2115,7 +2116,8 @@ void dpy_gl_scanout_texture(QemuConsole *con, uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t width, uint32_t height) + uint32_t width, uint32_t height, + void *d3d_tex2d) { DisplayState *s = con->ds; DisplayChangeListener *dcl; @@ -2123,7 +2125,7 @@ void dpy_gl_scanout_texture(QemuConsole *con, con->scanout.kind = SCANOUT_TEXTURE; con->scanout.texture = (ScanoutTexture) { backing_id, backing_y_0_top, backing_width, backing_height, - x, y, width, height + x, y, width, height, d3d_tex2d, }; QLIST_FOREACH(dcl, &s->listeners, next) { if (con != (dcl->con ? dcl->con : active_console)) { @@ -2133,7 +2135,8 @@ void dpy_gl_scanout_texture(QemuConsole *con, dcl->ops->dpy_gl_scanout_texture(dcl, backing_id, backing_y_0_top, backing_width, backing_height, - x, y, width, height); + x, y, width, height, + d3d_tex2d); } } } diff --git a/ui/dbus-console.c b/ui/dbus-console.c index aaa9d3b0b3..e19774f985 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -98,7 +98,8 @@ dbus_gl_scanout_texture(DisplayChangeListener *dcl, uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t w, uint32_t h) + uint32_t w, uint32_t h, + void *d3d_tex2d) { DBusDisplayConsole *ddc = container_of(dcl, DBusDisplayConsole, dcl); diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 8605dffd8a..80c0fca9df 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -212,7 +212,8 @@ static void dbus_scanout_texture(DisplayChangeListener *dcl, uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t w, uint32_t h) + uint32_t w, uint32_t h, + void *d3d_tex2d) { trace_dbus_scanout_texture(tex_id, backing_y_0_top, backing_width, backing_height, x, y, w, h); @@ -434,7 +435,7 @@ static void dbus_gl_gfx_switch(DisplayChangeListener *dcl, /* TODO: lazy send dmabuf (there are unnecessary sent otherwise) */ dbus_scanout_texture(&ddl->dcl, ddl->ds->texture, false, - width, height, 0, 0, width, height); + width, height, 0, 0, width, height, NULL); } } #endif diff --git a/ui/egl-headless.c b/ui/egl-headless.c index e4177206f2..d5637dadb2 100644 --- a/ui/egl-headless.c +++ b/ui/egl-headless.c @@ -61,7 +61,8 @@ static void egl_scanout_texture(DisplayChangeListener *dcl, uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t w, uint32_t h) + uint32_t w, uint32_t h, + void *d3d_tex2d) { egl_dpy *edpy = container_of(dcl, egl_dpy, dcl); @@ -91,7 +92,7 @@ static void egl_scanout_dmabuf(DisplayChangeListener *dcl, egl_scanout_texture(dcl, dmabuf->texture, false, dmabuf->width, dmabuf->height, - 0, 0, dmabuf->width, dmabuf->height); + 0, 0, dmabuf->width, dmabuf->height, NULL); } static void egl_cursor_dmabuf(DisplayChangeListener *dcl, diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c index 64dc0eeec8..d59b8cd7d7 100644 --- a/ui/gtk-egl.c +++ b/ui/gtk-egl.c @@ -224,7 +224,8 @@ void gd_egl_scanout_texture(DisplayChangeListener *dcl, uint32_t backing_id, bool backing_y_0_top, uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t w, uint32_t h) + uint32_t w, uint32_t h, + void *d3d_tex2d) { VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); @@ -259,7 +260,7 @@ void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl, gd_egl_scanout_texture(dcl, dmabuf->texture, dmabuf->y0_top, dmabuf->width, dmabuf->height, dmabuf->x, dmabuf->y, dmabuf->scanout_width, - dmabuf->scanout_height); + dmabuf->scanout_height, NULL); if (dmabuf->allow_fences) { vc->gfx.guest_fb.dmabuf = dmabuf; diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c index 1605818bd1..7367dfd793 100644 --- a/ui/gtk-gl-area.c +++ b/ui/gtk-gl-area.c @@ -244,7 +244,8 @@ void gd_gl_area_scanout_texture(DisplayChangeListener *dcl, uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t w, uint32_t h) + uint32_t w, uint32_t h, + void *d3d_tex2d) { VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); @@ -300,7 +301,7 @@ void gd_gl_area_scanout_dmabuf(DisplayChangeListener *dcl, gd_gl_area_scanout_texture(dcl, dmabuf->texture, dmabuf->y0_top, dmabuf->width, dmabuf->height, dmabuf->x, dmabuf->y, dmabuf->scanout_width, - dmabuf->scanout_height); + dmabuf->scanout_height, NULL); if (dmabuf->allow_fences) { vc->gfx.guest_fb.dmabuf = dmabuf; diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c index bbfa70eac3..28d796607c 100644 --- a/ui/sdl2-gl.c +++ b/ui/sdl2-gl.c @@ -205,7 +205,8 @@ void sdl2_gl_scanout_texture(DisplayChangeListener *dcl, uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t w, uint32_t h) + uint32_t w, uint32_t h, + void *d3d_tex2d) { struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); diff --git a/ui/spice-display.c b/ui/spice-display.c index 5bee19a7f9..3f3f8013d8 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -935,7 +935,8 @@ static void qemu_spice_gl_scanout_texture(DisplayChangeListener *dcl, uint32_t backing_width, uint32_t backing_height, uint32_t x, uint32_t y, - uint32_t w, uint32_t h) + uint32_t w, uint32_t h, + void *d3d_tex2d) { SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl); EGLint stride = 0, fourcc = 0; -- cgit 1.4.1