From ed03ea51488d7d8dc9da33c0f2c09f9456954518 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Fri, 10 Feb 2023 16:14:51 -0800 Subject: [PATCH] lib: move PaintableListener into MksPaintable The goal here is to keep the MksPaintableListener inside of MksPaintable so that we don't have to create API between the two. Additionally, the MksPaintable can own it's own G-DBus connection as we don't want to share them for updates with anything else (as they can have large data chunks coming across). --- lib/libmks.h | 1 - lib/meson.build | 4 +- lib/mks-init.c | 4 +- lib/mks-paintable-listener-private.h | 35 -- lib/mks-paintable-listener.c | 150 --------- lib/mks-paintable-private.h | 13 +- lib/mks-paintable.c | 472 +++++++++++++++++---------- lib/mks-paintable.h | 45 --- lib/mks-screen.c | 115 +------ 9 files changed, 322 insertions(+), 517 deletions(-) delete mode 100644 lib/mks-paintable-listener-private.h delete mode 100644 lib/mks-paintable-listener.c delete mode 100644 lib/mks-paintable.h diff --git a/lib/libmks.h b/lib/libmks.h index b8c38fe..d2d5af1 100644 --- a/lib/libmks.h +++ b/lib/libmks.h @@ -30,7 +30,6 @@ G_BEGIN_DECLS # include "mks-init.h" # include "mks-keyboard.h" # include "mks-mouse.h" -# include "mks-paintable.h" # include "mks-screen.h" # include "mks-screen-attributes.h" # include "mks-session.h" diff --git a/lib/meson.build b/lib/meson.build index c3fc1a5..6bbbdc7 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -15,7 +15,6 @@ libmks_headers = [ 'mks-init.h', 'mks-keyboard.h', 'mks-mouse.h', - 'mks-paintable.h', 'mks-screen.h', 'mks-screen-attributes.h', 'mks-session.h', @@ -24,7 +23,6 @@ libmks_headers = [ libmks_private_sources = [ 'mks-framebuffer.c', - 'mks-paintable-listener.c', 'mks-read-only-list-model.c', gnome.gdbus_codegen('mks-qemu', @@ -104,4 +102,4 @@ libmks_gir = gnome.generate_gir(libmks, identifier_prefix: 'Mks', includes: ['Gio-2.0', 'Gtk-4.0'], install: true, -) \ No newline at end of file +) diff --git a/lib/mks-init.c b/lib/mks-init.c index ba6dc3b..b7951d6 100644 --- a/lib/mks-init.c +++ b/lib/mks-init.c @@ -26,7 +26,7 @@ #include "mks-init.h" #include "mks-keyboard.h" #include "mks-mouse.h" -#include "mks-paintable.h" +#include "mks-paintable-private.h" #include "mks-qemu.h" #include "mks-read-only-list-model-private.h" #include "mks-screen.h" @@ -50,12 +50,12 @@ mks_init_gtypes (void) /* Internal types not exposed in public API */ g_type_ensure (MKS_TYPE_READ_ONLY_LIST_MODEL); + g_type_ensure (MKS_TYPE_PAINTABLE); /* GTypes that are part of our public API */ g_type_ensure (MKS_TYPE_DEVICE); g_type_ensure (MKS_TYPE_KEYBOARD); g_type_ensure (MKS_TYPE_MOUSE); - g_type_ensure (MKS_TYPE_PAINTABLE); g_type_ensure (MKS_TYPE_SCREEN); g_type_ensure (MKS_TYPE_SCREEN_ATTRIBUTES); g_type_ensure (MKS_TYPE_SESSION); diff --git a/lib/mks-paintable-listener-private.h b/lib/mks-paintable-listener-private.h deleted file mode 100644 index 072f1f6..0000000 --- a/lib/mks-paintable-listener-private.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * mks-paintable-listener-private.h - * - * Copyright 2023 Christian Hergert - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#pragma once - -#include "mks-qemu.h" - -G_BEGIN_DECLS - -#define MKS_TYPE_PAINTABLE_LISTENER (mks_paintable_listener_get_type()) -#define MKS_PAINTABLE_LISTENER_OBJECT_PATH "/org/qemu/Display1/Listener" - -G_DECLARE_FINAL_TYPE (MksPaintableListener, mks_paintable_listener, MKS, PAINTABLE_LISTENER, MksQemuListenerSkeleton) - -MksPaintableListener *mks_paintable_listener_new (void); - -G_END_DECLS diff --git a/lib/mks-paintable-listener.c b/lib/mks-paintable-listener.c deleted file mode 100644 index dc72106..0000000 --- a/lib/mks-paintable-listener.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * mks-paintable-listener.c - * - * Copyright 2023 Christian Hergert - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#include "config.h" - -#include "mks-paintable-listener-private.h" - -struct _MksPaintableListener -{ - MksQemuListenerSkeleton parent_instance; -}; - -static gboolean -mks_paintable_listener_update_dmabuf (MksQemuListener *listener, - GDBusMethodInvocation *invocation, - int x, - int y, - int width, - int height) -{ - return FALSE; -} - -static gboolean -mks_paintable_listener_scanout_dmabuf (MksQemuListener *listener, - GDBusMethodInvocation *invocation, - GUnixFDList *unix_fd_list, - GVariant *dmabuf, - guint width, - guint height, - guint stride, - guint fourcc, - guint64 modifier, - gboolean y0_top) -{ - return FALSE; -} - -static gboolean -mks_paintable_listener_update (MksQemuListener *listener, - GDBusMethodInvocation *invocation, - int x, - int y, - int width, - int height, - guint stride, - guint pixman_format, - GVariant *bytes) -{ - return TRUE; -} - -static gboolean -mks_paintable_listener_scanout (MksQemuListener *listener, - GDBusMethodInvocation *invocation, - guint width, - guint height, - guint stride, - guint pixman_format, - GVariant *bytes) -{ - return TRUE; -} - -static gboolean -mks_paintable_listener_cursor_define (MksQemuListener *listener, - GDBusMethodInvocation *invocation, - int width, - int height, - int hot_x, - int hot_y, - GVariant *bytes) -{ - return FALSE; -} - -static gboolean -mks_paintable_listener_mouse_set (MksQemuListener *listener, - GDBusMethodInvocation *invocation, - int x, - int y, - int on) -{ - return FALSE; -} - -static gboolean -mks_paintable_listener_disable (MksQemuListener *listener, - GDBusMethodInvocation *invocation) -{ - return TRUE; -} - -static void -listener_iface_init (MksQemuListenerIface *iface) -{ - iface->handle_update = mks_paintable_listener_update; - iface->handle_scanout = mks_paintable_listener_scanout; - iface->handle_update_dmabuf = mks_paintable_listener_update_dmabuf; - iface->handle_scanout_dmabuf = mks_paintable_listener_scanout_dmabuf; - iface->handle_cursor_define = mks_paintable_listener_cursor_define; - iface->handle_mouse_set = mks_paintable_listener_mouse_set; - iface->handle_disable = mks_paintable_listener_disable; -} - -G_DEFINE_FINAL_TYPE_WITH_CODE (MksPaintableListener, mks_paintable_listener, MKS_QEMU_TYPE_LISTENER_SKELETON, - G_IMPLEMENT_INTERFACE (MKS_QEMU_TYPE_LISTENER, listener_iface_init)) - -MksPaintableListener * -mks_paintable_listener_new (void) -{ - return g_object_new (MKS_TYPE_PAINTABLE_LISTENER, NULL); -} - -static void -mks_paintable_listener_finalize (GObject *object) -{ - G_OBJECT_CLASS (mks_paintable_listener_parent_class)->finalize (object); -} - -static void -mks_paintable_listener_class_init (MksPaintableListenerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = mks_paintable_listener_finalize; -} - -static void -mks_paintable_listener_init (MksPaintableListener *self) -{ -} diff --git a/lib/mks-paintable-private.h b/lib/mks-paintable-private.h index bf3aae2..a86fe16 100644 --- a/lib/mks-paintable-private.h +++ b/lib/mks-paintable-private.h @@ -21,13 +21,16 @@ #pragma once -#include "mks-paintable.h" -#include "mks-paintable-listener-private.h" +#include G_BEGIN_DECLS -GdkPaintable *_mks_paintable_new (GDBusConnection *connection, - MksScreen *screen, - MksPaintableListener *listener); +#define MKS_TYPE_PAINTABLE (mks_paintable_get_type()) + +G_DECLARE_FINAL_TYPE (MksPaintable, mks_paintable, MKS, PAINTABLE, GObject) + +GdkPaintable *_mks_paintable_new (GCancellable *cancellable, + int *peer_fd, + GError **error); G_END_DECLS diff --git a/lib/mks-paintable.c b/lib/mks-paintable.c index f8ea875..fbdb67b 100644 --- a/lib/mks-paintable.c +++ b/lib/mks-paintable.c @@ -21,185 +21,46 @@ #include "config.h" +#include +#include + +#include + #include "mks-paintable-private.h" -#include "mks-screen.h" +#include "mks-qemu.h" struct _MksPaintable { - GObject parent_instance; - MksScreen *screen; + GObject parent_instance; + + guint width; + guint height; + + MksQemuListener *listener; + GDBusConnection *connection; }; -static void paintable_iface_init (GdkPaintableInterface *iface); - -G_DEFINE_FINAL_TYPE_WITH_CODE (MksPaintable, mks_paintable, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, paintable_iface_init)) - -enum { - PROP_0, - PROP_SCREEN, - N_PROPS -}; - -static GParamSpec *properties [N_PROPS]; - -GdkPaintable * -mks_paintable_new (MksScreen *screen) -{ - g_return_val_if_fail (MKS_IS_SCREEN (screen), NULL); - - return g_object_new (MKS_TYPE_PAINTABLE, - "screen", screen, - NULL); -} - -static void -mks_paintable_set_screen (MksPaintable *self, - MksScreen *screen) -{ - g_assert (MKS_IS_PAINTABLE (self)); - g_assert (MKS_IS_SCREEN (screen)); - - if (g_set_object (&self->screen, screen)) - { - g_signal_connect_object (self->screen, - "notify::width", - G_CALLBACK (gdk_paintable_invalidate_size), - self, - G_CONNECT_SWAPPED); - g_signal_connect_object (self->screen, - "notify::height", - G_CALLBACK (gdk_paintable_invalidate_size), - self, - G_CONNECT_SWAPPED); - } -} - -static void -mks_paintable_dispose (GObject *object) -{ - MksPaintable *self = (MksPaintable *)object; - - g_clear_object (&self->screen); - - G_OBJECT_CLASS (mks_paintable_parent_class)->dispose (object); -} - -static void -mks_paintable_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - MksPaintable *self = MKS_PAINTABLE (object); - - switch (prop_id) - { - case PROP_SCREEN: - g_value_set_object (value, mks_paintable_get_screen (self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -mks_paintable_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - MksPaintable *self = MKS_PAINTABLE (object); - - switch (prop_id) - { - case PROP_SCREEN: - mks_paintable_set_screen (self, g_value_get_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -mks_paintable_class_init (MksPaintableClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = mks_paintable_dispose; - object_class->get_property = mks_paintable_get_property; - object_class->set_property = mks_paintable_set_property; - - properties [PROP_SCREEN] = - g_param_spec_object ("screen", NULL, NULL, - MKS_TYPE_SCREEN, - (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_properties (object_class, N_PROPS, properties); -} - -static void -mks_paintable_init (MksPaintable *self) -{ -} - -/** - * mks_paintable_get_screen: - * @self: a #MksPaintable - * - * Gets the #MksScreen displayed in the paintable. - * - * Returns: (nullable) (transfer none): a #MksScreen or %NULL - */ -MksScreen * -mks_paintable_get_screen (MksPaintable *self) -{ - g_return_val_if_fail (MKS_IS_PAINTABLE (self), NULL); - - return self->screen; -} - static int mks_paintable_get_intrinsic_height (GdkPaintable *paintable) { - MksPaintable *self = MKS_PAINTABLE (paintable); - - return self->screen ? mks_screen_get_height (self->screen) : 0; + return MKS_PAINTABLE (paintable)->height; } static int mks_paintable_get_intrinsic_width (GdkPaintable *paintable) { - MksPaintable *self = MKS_PAINTABLE (paintable); - - return self->screen ? mks_screen_get_width (self->screen) : 0; + return MKS_PAINTABLE (paintable)->width; } static double mks_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable) { MksPaintable *self = MKS_PAINTABLE (paintable); - double width; - double height; - if (self->screen == NULL) + if (self->width == 0 || self->height == 0) return 1.; - width = mks_screen_get_width (self->screen); - height = mks_screen_get_height (self->screen); - - if (width == 0 || height == 0) - return 1; - - return width / height; -} - -static GdkPaintableFlags -mks_paintable_get_flags (GdkPaintable *paintable) -{ - return 0; + return (double)self->width / (double)self->height; } static void @@ -208,11 +69,6 @@ mks_paintable_snapshot (GdkPaintable *paintable, double width, double height) { - MksPaintable *self = (MksPaintable *)paintable; - - g_assert (MKS_IS_PAINTABLE (self)); - g_assert (GDK_IS_SNAPSHOT (snapshot)); - } static void @@ -220,21 +76,295 @@ paintable_iface_init (GdkPaintableInterface *iface) { iface->get_intrinsic_height = mks_paintable_get_intrinsic_height; iface->get_intrinsic_width = mks_paintable_get_intrinsic_width; - iface->get_flags = mks_paintable_get_flags; iface->get_intrinsic_aspect_ratio = mks_paintable_get_intrinsic_aspect_ratio; iface->snapshot = mks_paintable_snapshot; } -GdkPaintable * -_mks_paintable_new (GDBusConnection *connection, - MksScreen *screen, - MksPaintableListener *listener) +G_DEFINE_FINAL_TYPE_WITH_CODE (MksPaintable, mks_paintable, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, paintable_iface_init)) + +static void +mks_paintable_dispose (GObject *object) { - g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); - g_return_val_if_fail (MKS_IS_SCREEN (screen), NULL); - g_return_val_if_fail (MKS_IS_PAINTABLE_LISTENER (listener), NULL); + MksPaintable *self = (MksPaintable *)object; - /* TODO: */ + g_clear_object (&self->connection); + g_clear_object (&self->listener); - return mks_paintable_new (screen); + G_OBJECT_CLASS (mks_paintable_parent_class)->dispose (object); +} + +static void +mks_paintable_class_init (MksPaintableClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = mks_paintable_dispose; +} + +static void +mks_paintable_init (MksPaintable *self) +{ +} + +static gboolean +mks_paintable_listener_update_dmabuf (MksPaintable *self, + GDBusMethodInvocation *invocation, + int x, + int y, + int width, + int height, + MksQemuListener *listener) +{ + g_assert (MKS_IS_PAINTABLE (self)); + g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_assert (MKS_QEMU_IS_LISTENER (listener)); + + return FALSE; +} + +static gboolean +mks_paintable_listener_scanout_dmabuf (MksPaintable *self, + GDBusMethodInvocation *invocation, + GUnixFDList *unix_fd_list, + GVariant *dmabuf, + guint width, + guint height, + guint stride, + guint fourcc, + guint64 modifier, + gboolean y0_top, + MksQemuListener *listener) +{ + gboolean size_changed; + + g_assert (MKS_IS_PAINTABLE (self)); + g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_assert (MKS_QEMU_IS_LISTENER (listener)); + + size_changed = width != self->width || height != self->height; + + if (size_changed) + gdk_paintable_invalidate_size (GDK_PAINTABLE (self)); + else + gdk_paintable_invalidate_contents (GDK_PAINTABLE (self)); + + return FALSE; +} + +static gboolean +mks_paintable_listener_update (MksPaintable *self, + GDBusMethodInvocation *invocation, + int x, + int y, + int width, + int height, + guint stride, + guint pixman_format, + GVariant *bytes, + MksQemuListener *listener) +{ + g_assert (MKS_IS_PAINTABLE (self)); + g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_assert (MKS_QEMU_IS_LISTENER (listener)); + + return FALSE; +} + +static gboolean +mks_paintable_listener_scanout (MksPaintable *self, + GDBusMethodInvocation *invocation, + guint width, + guint height, + guint stride, + guint pixman_format, + GVariant *bytes, + MksQemuListener *listener) +{ + gboolean size_changed; + + g_assert (MKS_IS_PAINTABLE (self)); + g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_assert (MKS_QEMU_IS_LISTENER (listener)); + + size_changed = width != self->width || height != self->height; + + if (size_changed) + gdk_paintable_invalidate_size (GDK_PAINTABLE (self)); + else + gdk_paintable_invalidate_contents (GDK_PAINTABLE (self)); + + return FALSE; +} + +static gboolean +mks_paintable_listener_cursor_define (MksPaintable *self, + GDBusMethodInvocation *invocation, + int width, + int height, + int hot_x, + int hot_y, + GVariant *bytes, + MksQemuListener *listener) +{ + g_assert (MKS_IS_PAINTABLE (self)); + g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_assert (MKS_QEMU_IS_LISTENER (listener)); + + return FALSE; +} + +static gboolean +mks_paintable_listener_mouse_set (MksPaintable *self, + GDBusMethodInvocation *invocation, + int x, + int y, + int on, + MksQemuListener *listener) +{ + g_assert (MKS_IS_PAINTABLE (self)); + g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_assert (MKS_QEMU_IS_LISTENER (listener)); + + return FALSE; +} + +static gboolean +mks_paintable_listener_disable (MksPaintable *self, + GDBusMethodInvocation *invocation, + MksQemuListener *listener) +{ + g_assert (MKS_IS_PAINTABLE (self)); + g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_assert (MKS_QEMU_IS_LISTENER (listener)); + + return FALSE; +} + +static gboolean +create_socketpair (int *us, + int *them, + GError **error) +{ + int fds[2]; + int rv; + + rv = socketpair (AF_UNIX, SOCK_NONBLOCK|SOCK_CLOEXEC, SOCK_STREAM, fds); + + if (rv != 0) + { + int errsv = errno; + g_set_error_literal (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + g_strerror (errsv)); + return FALSE; + } + + *us = fds[0]; + *them = fds[1]; + + return TRUE; +} + +GdkPaintable * +_mks_paintable_new (GCancellable *cancellable, + int *peer_fd, + GError **error) +{ + g_autoptr(MksPaintable) self = NULL; + g_autoptr(MksQemuListener) listener = NULL; + g_autoptr(GDBusConnection) connection = NULL; + g_autoptr(GSocketConnection) io_stream = NULL; + g_autoptr(GSocket) socket = NULL; + g_autofd int us = -1; + g_autofd int them = -1; + + g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (peer_fd != NULL, NULL); + + *peer_fd = -1; + + self = g_object_new (MKS_TYPE_PAINTABLE, NULL); + + /* Create a socketpair() to use for D-Bus P2P protocol. We will be receiving + * DMA-BUF FDs over this. + */ + if (!create_socketpair (&us, &them, error)) + return NULL; + + /* Create socket for our side of the socket pair */ + if (!(socket = g_socket_new_from_fd (us, error))) + return NULL; + us = -1; + + /* And convert that socket into a GIOStream */ + io_stream = g_socket_connection_factory_create_connection (socket); + + /* Setup our GDBusConnection. We can do this synchronously because we are + * not connecting to a message bus, therefore nothing to process up front. + */ + if (!(connection = g_dbus_connection_new_sync (G_IO_STREAM (io_stream), + NULL, + G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING, + NULL, + cancellable, + error))) + return NULL; + + /* Setup our listener and callbacks to process requests */ + listener = mks_qemu_listener_skeleton_new (); + g_signal_connect_object (listener, + "handle-scanout", + G_CALLBACK (mks_paintable_listener_scanout), + self, + G_CONNECT_SWAPPED); + g_signal_connect_object (listener, + "handle-update", + G_CALLBACK (mks_paintable_listener_update), + self, + G_CONNECT_SWAPPED); + g_signal_connect_object (listener, + "handle-scanout-dmabuf", + G_CALLBACK (mks_paintable_listener_scanout_dmabuf), + self, + G_CONNECT_SWAPPED); + g_signal_connect_object (listener, + "handle-update-dmabuf", + G_CALLBACK (mks_paintable_listener_update_dmabuf), + self, + G_CONNECT_SWAPPED); + g_signal_connect_object (listener, + "handle-disable", + G_CALLBACK (mks_paintable_listener_disable), + self, + G_CONNECT_SWAPPED); + g_signal_connect_object (listener, + "handle-cursor-define", + G_CALLBACK (mks_paintable_listener_cursor_define), + self, + G_CONNECT_SWAPPED); + g_signal_connect_object (listener, + "handle-mouse-set", + G_CALLBACK (mks_paintable_listener_mouse_set), + self, + G_CONNECT_SWAPPED); + + /* Export our listener before we return back so we know that when the peer + * tries to connect, we're guaranteed to already be available. + */ + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (listener), + connection, + "/org/qemu/Display1/Listener", + error)) + return NULL; + + self->connection = g_object_ref (connection); + self->listener = g_object_ref (listener); + + g_dbus_connection_start_message_processing (connection); + + *peer_fd = g_steal_fd (&them); + + return GDK_PAINTABLE (g_steal_pointer (&self)); } diff --git a/lib/mks-paintable.h b/lib/mks-paintable.h deleted file mode 100644 index 17b6c13..0000000 --- a/lib/mks-paintable.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * mks-paintable.h - * - * Copyright 2023 Christian Hergert - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#pragma once - -#if !defined(MKS_INSIDE) && !defined(MKS_COMPILATION) -# error "Only can be included directly." -#endif - -#include - -#include "mks-types.h" -#include "mks-version-macros.h" - -G_BEGIN_DECLS - -#define MKS_TYPE_PAINTABLE (mks_paintable_get_type()) - -MKS_AVAILABLE_IN_ALL -G_DECLARE_FINAL_TYPE (MksPaintable, mks_paintable, MKS, PAINTABLE, GObject) - -MKS_AVAILABLE_IN_ALL -GdkPaintable *mks_paintable_new (MksScreen *screen); -MKS_AVAILABLE_IN_ALL -MksScreen *mks_paintable_get_screen (MksPaintable *self); - -G_END_DECLS diff --git a/lib/mks-screen.c b/lib/mks-screen.c index 8ff56ec..57f0c49 100644 --- a/lib/mks-screen.c +++ b/lib/mks-screen.c @@ -31,7 +31,6 @@ #include "mks-qemu.h" #include "mks-keyboard-private.h" #include "mks-mouse-private.h" -#include "mks-paintable-listener-private.h" #include "mks-paintable-private.h" #include "mks-screen-attributes-private.h" #include "mks-screen-private.h" @@ -564,35 +563,6 @@ mks_screen_configure_sync (MksScreen *self, error); } -static gboolean -mks_screen_create_socketpair (int *us, - int *them, - GError **error) -{ - int rv; - int fds[2]; - - g_assert (us != NULL); - g_assert (them != NULL); - - rv = socketpair (AF_UNIX, SOCK_NONBLOCK | SOCK_CLOEXEC, SOCK_STREAM, fds); - - if (rv != 0) - { - int errsv = errno; - g_set_error_literal (error, - G_IO_ERROR, - g_io_error_from_errno (errsv), - g_strerror (errsv)); - return FALSE; - } - - *us = fds[0]; - *them = fds[1]; - - return TRUE; -} - static void mks_screen_attach_cb (GObject *object, GAsyncResult *result, @@ -635,15 +605,11 @@ mks_screen_attach (MksScreen *self, GAsyncReadyCallback callback, gpointer user_data) { - g_autoptr(MksPaintableListener) listener = NULL; g_autoptr(GUnixFDList) unix_fd_list = NULL; - g_autoptr(GDBusConnection) connection = NULL; - g_autoptr(GSocketConnection) io_stream = NULL; - g_autoptr(GSocket) socket = NULL; + g_autoptr(GdkPaintable) paintable = NULL; g_autoptr(GTask) task = NULL; g_autoptr(GError) error = NULL; - g_autofd int us = -1; - g_autofd int them = -1; + g_autofd int fd = -1; g_return_if_fail (MKS_IS_SCREEN (self)); g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); @@ -652,41 +618,12 @@ mks_screen_attach (MksScreen *self, g_task_set_source_tag (task, mks_screen_attach); if (!check_console (self, &error) || - !mks_screen_create_socketpair (&us, &them, &error)) + !(paintable = _mks_paintable_new (cancellable, &fd, &error))) goto failure; - g_assert (us != -1); - g_assert (them != -1); - - if (!(socket = g_socket_new_from_fd (us, &error))) - goto failure; - - us = -1; - io_stream = g_socket_connection_factory_create_connection (socket); - connection = g_dbus_connection_new_sync (G_IO_STREAM (io_stream), - NULL, - G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING, - NULL, - cancellable, - &error); - - if (connection == NULL) - goto failure; - - unix_fd_list = g_unix_fd_list_new_from_array (&them, 1); - them = -1; - - listener = mks_paintable_listener_new (); - if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (listener), - connection, - MKS_PAINTABLE_LISTENER_OBJECT_PATH, - &error)) - goto failure; - - g_task_set_task_data (task, - _mks_paintable_new (connection, self, listener), - g_object_unref); + g_task_set_task_data (task, g_steal_pointer (&paintable), g_object_unref); + unix_fd_list = g_unix_fd_list_new_from_array (&fd, 1), fd = -1; mks_qemu_console_call_register_listener (self->console, g_variant_new_handle (0), unix_fd_list, @@ -694,8 +631,6 @@ mks_screen_attach (MksScreen *self, mks_screen_attach_cb, g_steal_pointer (&task)); - g_dbus_connection_start_message_processing (connection); - return; failure: @@ -747,47 +682,17 @@ mks_screen_attach_sync (MksScreen *self, GError **error) { g_autoptr(GUnixFDList) unix_fd_list = NULL; - g_autoptr(GDBusConnection) connection = NULL; - g_autoptr(GSocketConnection) io_stream = NULL; - g_autoptr(MksPaintableListener) listener = NULL; - g_autoptr(GSocket) socket = NULL; - g_autofd int us = -1; - g_autofd int them = -1; + g_autoptr(GdkPaintable) paintable = NULL; + g_autofd int fd = -1; g_return_val_if_fail (MKS_IS_SCREEN (self), NULL); g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL); if (!check_console (self, error) || - !mks_screen_create_socketpair (&us, &them, error)) - return NULL; - - g_assert (us != -1); - g_assert (them != -1); - - if (!(socket = g_socket_new_from_fd (us, error))) - return NULL; - - us = -1; - io_stream = g_socket_connection_factory_create_connection (socket); - connection = g_dbus_connection_new_sync (G_IO_STREAM (io_stream), - NULL, - G_DBUS_CONNECTION_FLAGS_NONE, - NULL, - cancellable, - error); - if (connection == NULL) - return FALSE; - - unix_fd_list = g_unix_fd_list_new_from_array (&them, 1); - them = -1; - - listener = mks_paintable_listener_new (); - if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (listener), - connection, - MKS_PAINTABLE_LISTENER_OBJECT_PATH, - error)) + !(paintable = _mks_paintable_new (cancellable, &fd, error))) return NULL; + unix_fd_list = g_unix_fd_list_new_from_array (&fd, 1), fd = -1; if (!mks_qemu_console_call_register_listener_sync (self->console, g_variant_new_handle (0), unix_fd_list, @@ -796,5 +701,5 @@ mks_screen_attach_sync (MksScreen *self, error)) return NULL; - return _mks_paintable_new (connection, self, listener); + return g_steal_pointer (&paintable); }