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); }