diff options
author | Florian Müllner <fmuellner@gnome.org> | 2021-07-19 00:01:24 +0200 |
---|---|---|
committer | Florian Müllner <fmuellner@gnome.org> | 2021-07-19 00:03:33 +0200 |
commit | 952865a86ebb08f97263cfdbfe38b7adc20e4560 (patch) | |
tree | 1f9347628656210b03ceee4fae83beb21491d1eb /src/backends/meta-remote-desktop-session.c | |
parent | 7862f143937e43dca0513af3a24dabfb4d0db4fc (diff) | |
download | mutter-master.tar.gz |
Replace contents with redirect messagemaster
The default development branch is now `main`. This commit only exists
on `master` to point people towards that.
See https://gitlab.gnome.org/GNOME/glib/-/issues/2348 for details.
Diffstat (limited to 'src/backends/meta-remote-desktop-session.c')
-rw-r--r-- | src/backends/meta-remote-desktop-session.c | 1725 |
1 files changed, 0 insertions, 1725 deletions
diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c deleted file mode 100644 index e15bd63de..000000000 --- a/src/backends/meta-remote-desktop-session.c +++ /dev/null @@ -1,1725 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2015-2017 Red Hat Inc. - * - * 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 2 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - */ - -#include "config.h" - -#include "backends/meta-remote-desktop-session.h" - -#include <fcntl.h> -#include <gio/gunixfdlist.h> -#include <gio/gunixoutputstream.h> -#include <glib-unix.h> -#include <linux/input.h> -#include <stdlib.h> -#include <unistd.h> -#include <xkbcommon/xkbcommon.h> - -#include "backends/meta-dbus-session-watcher.h" -#include "backends/meta-screen-cast-session.h" -#include "backends/meta-remote-access-controller-private.h" -#include "backends/x11/meta-backend-x11.h" -#include "cogl/cogl.h" -#include "core/display-private.h" -#include "core/meta-selection-private.h" -#include "core/meta-selection-source-remote.h" -#include "meta/meta-backend.h" - -#include "meta-dbus-remote-desktop.h" - -#define META_REMOTE_DESKTOP_SESSION_DBUS_PATH "/org/gnome/Mutter/RemoteDesktop/Session" - -#define TRANSFER_REQUEST_CLEANUP_TIMEOUT_MS (s2ms (15)) - -typedef enum _MetaRemoteDesktopNotifyAxisFlags -{ - META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_NONE = 0, - META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_FINISH = 1 << 0, - META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_WHEEL = 1 << 1, - META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_FINGER = 1 << 2, - META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_CONTINUOUS = 1 << 3, -} MetaRemoteDesktopNotifyAxisFlags; - -typedef struct _SelectionReadData -{ - MetaRemoteDesktopSession *session; - GOutputStream *stream; - GCancellable *cancellable; -} SelectionReadData; - -struct _MetaRemoteDesktopSession -{ - MetaDBusRemoteDesktopSessionSkeleton parent; - - MetaRemoteDesktop *remote_desktop; - - GDBusConnection *connection; - char *peer_name; - - char *session_id; - char *object_path; - - MetaScreenCastSession *screen_cast_session; - gulong screen_cast_session_closed_handler_id; - guint started : 1; - - ClutterVirtualInputDevice *virtual_pointer; - ClutterVirtualInputDevice *virtual_keyboard; - ClutterVirtualInputDevice *virtual_touchscreen; - - MetaRemoteDesktopSessionHandle *handle; - - gboolean is_clipboard_enabled; - gulong owner_changed_handler_id; - SelectionReadData *read_data; - unsigned int transfer_serial; - MetaSelectionSourceRemote *current_source; - GHashTable *transfer_requests; - guint transfer_request_timeout_id; -}; - -static void -meta_remote_desktop_session_init_iface (MetaDBusRemoteDesktopSessionIface *iface); - -static void -meta_dbus_session_init_iface (MetaDbusSessionInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (MetaRemoteDesktopSession, - meta_remote_desktop_session, - META_DBUS_TYPE_REMOTE_DESKTOP_SESSION_SKELETON, - G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_REMOTE_DESKTOP_SESSION, - meta_remote_desktop_session_init_iface) - G_IMPLEMENT_INTERFACE (META_TYPE_DBUS_SESSION, - meta_dbus_session_init_iface)) - -struct _MetaRemoteDesktopSessionHandle -{ - MetaRemoteAccessHandle parent; - - MetaRemoteDesktopSession *session; -}; - -G_DEFINE_TYPE (MetaRemoteDesktopSessionHandle, - meta_remote_desktop_session_handle, - META_TYPE_REMOTE_ACCESS_HANDLE) - -static MetaRemoteDesktopSessionHandle * -meta_remote_desktop_session_handle_new (MetaRemoteDesktopSession *session); - -static gboolean -meta_remote_desktop_session_is_running (MetaRemoteDesktopSession *session) -{ - return !!session->started; -} - -static void -init_remote_access_handle (MetaRemoteDesktopSession *session) -{ - MetaBackend *backend = meta_get_backend (); - MetaRemoteAccessController *remote_access_controller; - MetaRemoteAccessHandle *remote_access_handle; - - session->handle = meta_remote_desktop_session_handle_new (session); - - remote_access_controller = meta_backend_get_remote_access_controller (backend); - remote_access_handle = META_REMOTE_ACCESS_HANDLE (session->handle); - meta_remote_access_controller_notify_new_handle (remote_access_controller, - remote_access_handle); -} - -static void -ensure_virtual_device (MetaRemoteDesktopSession *session, - ClutterInputDeviceType device_type) -{ - MetaRemoteDesktop *remote_desktop = session->remote_desktop; - MetaBackend *backend = meta_remote_desktop_get_backend (remote_desktop); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); - ClutterVirtualInputDevice **virtual_device_ptr = NULL; - - switch (device_type) - { - case CLUTTER_POINTER_DEVICE: - virtual_device_ptr = &session->virtual_pointer; - break; - case CLUTTER_KEYBOARD_DEVICE: - virtual_device_ptr = &session->virtual_keyboard; - break; - case CLUTTER_TOUCHSCREEN_DEVICE: - virtual_device_ptr = &session->virtual_touchscreen; - break; - default: - g_assert_not_reached (); - } - - g_assert (virtual_device_ptr); - - if (*virtual_device_ptr) - return; - - *virtual_device_ptr = clutter_seat_create_virtual_device (seat, device_type); -} - -static gboolean -meta_remote_desktop_session_start (MetaRemoteDesktopSession *session, - GError **error) -{ - g_assert (!session->started); - - if (session->screen_cast_session) - { - if (!meta_screen_cast_session_start (session->screen_cast_session, error)) - return FALSE; - } - - init_remote_access_handle (session); - session->started = TRUE; - - return TRUE; -} - -void -meta_remote_desktop_session_close (MetaRemoteDesktopSession *session) -{ - MetaDBusRemoteDesktopSession *skeleton = - META_DBUS_REMOTE_DESKTOP_SESSION (session); - - session->started = FALSE; - - if (session->screen_cast_session) - { - g_clear_signal_handler (&session->screen_cast_session_closed_handler_id, - session->screen_cast_session); - meta_screen_cast_session_close (session->screen_cast_session); - session->screen_cast_session = NULL; - } - - g_clear_object (&session->virtual_pointer); - g_clear_object (&session->virtual_keyboard); - g_clear_object (&session->virtual_touchscreen); - - meta_dbus_session_notify_closed (META_DBUS_SESSION (session)); - meta_dbus_remote_desktop_session_emit_closed (skeleton); - g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (session)); - - if (session->handle) - { - MetaRemoteAccessHandle *remote_access_handle = - META_REMOTE_ACCESS_HANDLE (session->handle); - - meta_remote_access_handle_notify_stopped (remote_access_handle); - } - - g_object_unref (session); -} - -char * -meta_remote_desktop_session_get_object_path (MetaRemoteDesktopSession *session) -{ - return session->object_path; -} - -char * -meta_remote_desktop_session_get_session_id (MetaRemoteDesktopSession *session) -{ - return session->session_id; -} - -static void -on_screen_cast_session_closed (MetaScreenCastSession *screen_cast_session, - MetaRemoteDesktopSession *session) -{ - session->screen_cast_session = NULL; - meta_remote_desktop_session_close (session); -} - -gboolean -meta_remote_desktop_session_register_screen_cast (MetaRemoteDesktopSession *session, - MetaScreenCastSession *screen_cast_session, - GError **error) -{ - if (session->screen_cast_session) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Remote desktop session already have an associated " - "screen cast session"); - return FALSE; - } - - session->screen_cast_session = screen_cast_session; - session->screen_cast_session_closed_handler_id = - g_signal_connect (screen_cast_session, "session-closed", - G_CALLBACK (on_screen_cast_session_closed), - session); - - return TRUE; -} - -MetaRemoteDesktopSession * -meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop, - const char *peer_name, - GError **error) -{ - MetaBackend *backend = meta_remote_desktop_get_backend (remote_desktop); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); - ClutterKeymap *keymap = clutter_seat_get_keymap (seat); - GDBusInterfaceSkeleton *interface_skeleton; - MetaRemoteDesktopSession *session; - - session = g_object_new (META_TYPE_REMOTE_DESKTOP_SESSION, NULL); - - session->remote_desktop = remote_desktop; - session->peer_name = g_strdup (peer_name); - - interface_skeleton = G_DBUS_INTERFACE_SKELETON (session); - session->connection = meta_remote_desktop_get_connection (remote_desktop); - if (!g_dbus_interface_skeleton_export (interface_skeleton, - session->connection, - session->object_path, - error)) - { - g_object_unref (session); - return NULL; - } - - g_object_bind_property (keymap, "caps-lock-state", - session, "caps-lock-state", - G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); - g_object_bind_property (keymap, "num-lock-state", - session, "num-lock-state", - G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); - - return session; -} - -static gboolean -check_permission (MetaRemoteDesktopSession *session, - GDBusMethodInvocation *invocation) -{ - return g_strcmp0 (session->peer_name, - g_dbus_method_invocation_get_sender (invocation)) == 0; -} - -static gboolean -meta_remote_desktop_session_check_can_notify (MetaRemoteDesktopSession *session, - GDBusMethodInvocation *invocation) -{ - if (!session->started) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Session not started"); - return FALSE; - } - - if (!check_permission (session, invocation)) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - "Permission denied"); - return FALSE; - } - - return TRUE; -} - -static gboolean -handle_start (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - GError *error = NULL; - - if (session->started) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Already started"); - return TRUE; - } - - if (!check_permission (session, invocation)) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - "Permission denied"); - return TRUE; - } - - if (!meta_remote_desktop_session_start (session, &error)) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Failed to start remote desktop: %s", - error->message); - g_error_free (error); - - meta_remote_desktop_session_close (session); - - return TRUE; - } - - meta_dbus_remote_desktop_session_complete_start (skeleton, invocation); - - return TRUE; -} - -static gboolean -handle_stop (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - - if (!session->started) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Session not started"); - return TRUE; - } - - if (!check_permission (session, invocation)) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - "Permission denied"); - return TRUE; - } - - meta_remote_desktop_session_close (session); - - meta_dbus_remote_desktop_session_complete_stop (skeleton, invocation); - - return TRUE; -} - -static gboolean -handle_notify_keyboard_keycode (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - unsigned int keycode, - gboolean pressed) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - ClutterKeyState state; - - if (!meta_remote_desktop_session_check_can_notify (session, invocation)) - return TRUE; - - if (pressed) - { - ensure_virtual_device (session, CLUTTER_KEYBOARD_DEVICE); - state = CLUTTER_KEY_STATE_PRESSED; - } - else - { - if (!session->virtual_keyboard) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Invalid key event"); - return TRUE; - } - - state = CLUTTER_KEY_STATE_RELEASED; - } - - clutter_virtual_input_device_notify_key (session->virtual_keyboard, - CLUTTER_CURRENT_TIME, - keycode, - state); - - meta_dbus_remote_desktop_session_complete_notify_keyboard_keycode (skeleton, - invocation); - return TRUE; -} - -static gboolean -handle_notify_keyboard_keysym (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - unsigned int keysym, - gboolean pressed) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - ClutterKeyState state; - - if (!meta_remote_desktop_session_check_can_notify (session, invocation)) - return TRUE; - - if (pressed) - { - ensure_virtual_device (session, CLUTTER_KEYBOARD_DEVICE); - state = CLUTTER_KEY_STATE_PRESSED; - } - else - { - if (!session->virtual_keyboard) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Invalid key event"); - return TRUE; - } - - state = CLUTTER_KEY_STATE_RELEASED; - } - - clutter_virtual_input_device_notify_keyval (session->virtual_keyboard, - CLUTTER_CURRENT_TIME, - keysym, - state); - - meta_dbus_remote_desktop_session_complete_notify_keyboard_keysym (skeleton, - invocation); - return TRUE; -} - -/* Translation taken from the clutter evdev backend. */ -static int -translate_to_clutter_button (int button) -{ - switch (button) - { - case BTN_LEFT: - return CLUTTER_BUTTON_PRIMARY; - case BTN_RIGHT: - return CLUTTER_BUTTON_SECONDARY; - case BTN_MIDDLE: - return CLUTTER_BUTTON_MIDDLE; - default: - /* - * For compatibility reasons, all additional buttons go after the old - * 4-7 scroll ones. - */ - return button - (BTN_LEFT - 1) + 4; - } -} - -static gboolean -handle_notify_pointer_button (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - int button_code, - gboolean pressed) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - uint32_t button; - ClutterButtonState state; - - if (!meta_remote_desktop_session_check_can_notify (session, invocation)) - return TRUE; - - button = translate_to_clutter_button (button_code); - - if (pressed) - { - ensure_virtual_device (session, CLUTTER_POINTER_DEVICE); - state = CLUTTER_BUTTON_STATE_PRESSED; - } - else - { - if (!session->virtual_pointer) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Invalid button event"); - return TRUE; - } - - state = CLUTTER_BUTTON_STATE_RELEASED; - } - - clutter_virtual_input_device_notify_button (session->virtual_pointer, - CLUTTER_CURRENT_TIME, - button, - state); - - meta_dbus_remote_desktop_session_complete_notify_pointer_button (skeleton, - invocation); - - return TRUE; -} - -static gboolean -clutter_scroll_source_from_axis_flags (MetaRemoteDesktopNotifyAxisFlags axis_flags, - ClutterScrollSource *scroll_source) -{ - MetaRemoteDesktopNotifyAxisFlags scroll_mask; - - scroll_mask = META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_WHEEL | - META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_FINGER | - META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_CONTINUOUS; - - switch (axis_flags & scroll_mask) - { - case META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_WHEEL: - *scroll_source = CLUTTER_SCROLL_SOURCE_WHEEL; - return TRUE; - case META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_NONE: - case META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_FINGER: - *scroll_source = CLUTTER_SCROLL_SOURCE_FINGER; - return TRUE; - case META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_CONTINUOUS: - *scroll_source = CLUTTER_SCROLL_SOURCE_CONTINUOUS; - return TRUE; - } - - return FALSE; -} - -static gboolean -handle_notify_pointer_axis (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - double dx, - double dy, - uint32_t flags) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE; - ClutterScrollSource scroll_source; - - if (!meta_remote_desktop_session_check_can_notify (session, invocation)) - return TRUE; - - if (!clutter_scroll_source_from_axis_flags (flags, &scroll_source)) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Invalid scroll source"); - return TRUE; - } - - if (flags & META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_FINISH) - { - finish_flags |= (CLUTTER_SCROLL_FINISHED_HORIZONTAL | - CLUTTER_SCROLL_FINISHED_VERTICAL); - } - - ensure_virtual_device (session, CLUTTER_POINTER_DEVICE); - - clutter_virtual_input_device_notify_scroll_continuous (session->virtual_pointer, - CLUTTER_CURRENT_TIME, - dx, dy, - scroll_source, - finish_flags); - - meta_dbus_remote_desktop_session_complete_notify_pointer_axis (skeleton, - invocation); - - return TRUE; -} - -static ClutterScrollDirection -discrete_steps_to_scroll_direction (unsigned int axis, - int steps) -{ - if (axis == 0 && steps < 0) - return CLUTTER_SCROLL_UP; - if (axis == 0 && steps > 0) - return CLUTTER_SCROLL_DOWN; - if (axis == 1 && steps < 0) - return CLUTTER_SCROLL_LEFT; - if (axis == 1 && steps > 0) - return CLUTTER_SCROLL_RIGHT; - - g_assert_not_reached (); - return 0; -} - -static gboolean -handle_notify_pointer_axis_discrete (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - unsigned int axis, - int steps) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - ClutterScrollDirection direction; - int step_count; - - if (!meta_remote_desktop_session_check_can_notify (session, invocation)) - return TRUE; - - if (axis > 1) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Invalid axis value"); - return TRUE; - } - - if (steps == 0) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Invalid axis steps value"); - return TRUE; - } - - ensure_virtual_device (session, CLUTTER_POINTER_DEVICE); - - /* - * We don't have the actual scroll source, but only know they should be - * considered as discrete steps. The device that produces such scroll events - * is the scroll wheel, so pretend that is the scroll source. - */ - direction = discrete_steps_to_scroll_direction (axis, steps); - - for (step_count = 0; step_count < abs (steps); step_count++) - clutter_virtual_input_device_notify_discrete_scroll (session->virtual_pointer, - CLUTTER_CURRENT_TIME, - direction, - CLUTTER_SCROLL_SOURCE_WHEEL); - - meta_dbus_remote_desktop_session_complete_notify_pointer_axis_discrete (skeleton, - invocation); - - return TRUE; -} - -static gboolean -handle_notify_pointer_motion_relative (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - double dx, - double dy) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - - if (!meta_remote_desktop_session_check_can_notify (session, invocation)) - return TRUE; - - ensure_virtual_device (session, CLUTTER_POINTER_DEVICE); - - clutter_virtual_input_device_notify_relative_motion (session->virtual_pointer, - CLUTTER_CURRENT_TIME, - dx, dy); - - meta_dbus_remote_desktop_session_complete_notify_pointer_motion_relative (skeleton, - invocation); - - return TRUE; -} - -static gboolean -handle_notify_pointer_motion_absolute (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - const char *stream_path, - double x, - double y) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - MetaScreenCastStream *stream; - double abs_x, abs_y; - - if (!meta_remote_desktop_session_check_can_notify (session, invocation)) - return TRUE; - - - if (!session->screen_cast_session) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "No screen cast active"); - return TRUE; - } - - stream = meta_screen_cast_session_get_stream (session->screen_cast_session, - stream_path); - if (!stream) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Unknown stream"); - return TRUE; - } - - ensure_virtual_device (session, CLUTTER_POINTER_DEVICE); - - if (meta_screen_cast_stream_transform_position (stream, x, y, &abs_x, &abs_y)) - { - clutter_virtual_input_device_notify_absolute_motion (session->virtual_pointer, - CLUTTER_CURRENT_TIME, - abs_x, abs_y); - } - else - { - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Dropping early absolute pointer motion (%f, %f)", x, y); - } - - meta_dbus_remote_desktop_session_complete_notify_pointer_motion_absolute (skeleton, - invocation); - - return TRUE; -} - -static gboolean -handle_notify_touch_down (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - const char *stream_path, - unsigned int slot, - double x, - double y) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - MetaScreenCastStream *stream; - double abs_x, abs_y; - - if (!meta_remote_desktop_session_check_can_notify (session, invocation)) - return TRUE; - - if (slot > CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Touch slot out of range"); - return TRUE; - } - - if (!session->screen_cast_session) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "No screen cast active"); - return TRUE; - } - - stream = meta_screen_cast_session_get_stream (session->screen_cast_session, - stream_path); - if (!stream) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Unknown stream"); - return TRUE; - } - - ensure_virtual_device (session, CLUTTER_TOUCHSCREEN_DEVICE); - - if (meta_screen_cast_stream_transform_position (stream, x, y, &abs_x, &abs_y)) - { - clutter_virtual_input_device_notify_touch_down (session->virtual_touchscreen, - CLUTTER_CURRENT_TIME, - slot, - abs_x, abs_y); - } - else - { - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Dropping early touch down (%f, %f)", x, y); - } - - meta_dbus_remote_desktop_session_complete_notify_touch_down (skeleton, - invocation); - - return TRUE; -} - -static gboolean -handle_notify_touch_motion (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - const char *stream_path, - unsigned int slot, - double x, - double y) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - MetaScreenCastStream *stream; - double abs_x, abs_y; - - if (!meta_remote_desktop_session_check_can_notify (session, invocation)) - return TRUE; - - - if (slot > CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Touch slot out of range"); - return TRUE; - } - - if (!session->screen_cast_session) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "No screen cast active"); - return TRUE; - } - - stream = meta_screen_cast_session_get_stream (session->screen_cast_session, - stream_path); - if (!stream) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Unknown stream"); - return TRUE; - } - - if (!session->virtual_touchscreen) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Invalid touch point"); - return TRUE; - } - - if (meta_screen_cast_stream_transform_position (stream, x, y, &abs_x, &abs_y)) - { - clutter_virtual_input_device_notify_touch_motion (session->virtual_touchscreen, - CLUTTER_CURRENT_TIME, - slot, - abs_x, abs_y); - } - else - { - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Dropping early touch motion (%f, %f)", x, y); - } - - meta_dbus_remote_desktop_session_complete_notify_touch_motion (skeleton, - invocation); - - return TRUE; -} - -static gboolean -handle_notify_touch_up (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - unsigned int slot) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - - if (!meta_remote_desktop_session_check_can_notify (session, invocation)) - return TRUE; - - if (slot > CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Touch slot out of range"); - return TRUE; - } - - if (!session->virtual_touchscreen) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Invalid touch point"); - return TRUE; - } - - clutter_virtual_input_device_notify_touch_up (session->virtual_touchscreen, - CLUTTER_CURRENT_TIME, - slot); - - meta_dbus_remote_desktop_session_complete_notify_touch_up (skeleton, - invocation); - - return TRUE; -} - -static MetaSelectionSourceRemote * -create_remote_desktop_source (MetaRemoteDesktopSession *session, - GVariant *mime_types_variant, - GError **error) -{ - GVariantIter iter; - char *mime_type; - GList *mime_types = NULL; - - g_variant_iter_init (&iter, mime_types_variant); - if (g_variant_iter_n_children (&iter) == 0) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, - "No mime types in mime types list"); - return NULL; - } - - while (g_variant_iter_next (&iter, "s", &mime_type)) - mime_types = g_list_prepend (mime_types, mime_type); - - mime_types = g_list_reverse (mime_types); - - return meta_selection_source_remote_new (session, mime_types); -} - -static const char * -mime_types_to_string (char **formats, - char *buf, - int buf_len) -{ - g_autofree char *mime_types_string = NULL; - int len; - - if (!formats) - return "N\\A"; - - mime_types_string = g_strjoinv (",", formats); - len = strlen (mime_types_string); - strncpy (buf, mime_types_string, buf_len - 1); - if (len >= buf_len - 1) - buf[buf_len - 2] = '*'; - buf[buf_len - 1] = '\0'; - - return buf; -} - -static gboolean -is_own_source (MetaRemoteDesktopSession *session, - MetaSelectionSource *source) -{ - return source && source == META_SELECTION_SOURCE (session->current_source); -} - -static GVariant * -generate_owner_changed_variant (char **mime_types_array, - gboolean is_own_source) -{ - GVariantBuilder builder; - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); - if (mime_types_array) - { - g_variant_builder_add (&builder, "{sv}", "mime-types", - g_variant_new ("(^as)", mime_types_array)); - g_variant_builder_add (&builder, "{sv}", "session-is-owner", - g_variant_new_boolean (is_own_source)); - } - - return g_variant_builder_end (&builder); -} - -static void -emit_owner_changed (MetaRemoteDesktopSession *session, - MetaSelectionSource *owner) -{ - char log_buf[255]; - g_autofree char **mime_types_array = NULL; - GList *l; - int i; - GVariant *options_variant; - const char *object_path; - - if (owner) - { - GList *mime_types; - - mime_types = meta_selection_source_get_mimetypes (owner); - mime_types_array = g_new0 (char *, g_list_length (mime_types) + 1); - for (l = meta_selection_source_get_mimetypes (owner), i = 0; - l; - l = l->next, i++) - mime_types_array[i] = l->data; - } - - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Clipboard owner changed, owner: %p (%s, is own? %s), mime types: [%s], " - "notifying %s", - owner, - owner ? g_type_name_from_instance ((GTypeInstance *) owner) - : "NULL", - is_own_source (session, owner) ? "yes" : "no", - mime_types_to_string (mime_types_array, log_buf, - G_N_ELEMENTS (log_buf)), - session->peer_name); - - options_variant = - generate_owner_changed_variant (mime_types_array, - is_own_source (session, owner)); - - object_path = g_dbus_interface_skeleton_get_object_path ( - G_DBUS_INTERFACE_SKELETON (session)); - g_dbus_connection_emit_signal (session->connection, - NULL, - object_path, - "org.gnome.Mutter.RemoteDesktop.Session", - "SelectionOwnerChanged", - g_variant_new ("(@a{sv})", options_variant), - NULL); -} - -static void -on_selection_owner_changed (MetaSelection *selection, - MetaSelectionType selection_type, - MetaSelectionSource *owner, - MetaRemoteDesktopSession *session) -{ - if (selection_type != META_SELECTION_CLIPBOARD) - return; - - emit_owner_changed (session, owner); -} - -static gboolean -handle_enable_clipboard (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - GVariant *arg_options) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - GVariant *mime_types_variant; - g_autoptr (GError) error = NULL; - MetaDisplay *display = meta_get_display (); - MetaSelection *selection = meta_display_get_selection (display); - g_autoptr (MetaSelectionSourceRemote) source_remote = NULL; - - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Enable clipboard for %s", - g_dbus_method_invocation_get_sender (invocation)); - - if (session->is_clipboard_enabled) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Already enabled"); - return TRUE; - } - - mime_types_variant = g_variant_lookup_value (arg_options, - "mime-types", - G_VARIANT_TYPE_STRING_ARRAY); - if (mime_types_variant) - { - source_remote = create_remote_desktop_source (session, - mime_types_variant, - &error); - if (!source_remote) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Invalid mime type list: %s", - error->message); - return TRUE; - } - } - - if (source_remote) - { - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Setting remote desktop clipboard source: %p from %s", - source_remote, session->peer_name); - - g_set_object (&session->current_source, source_remote); - meta_selection_set_owner (selection, - META_SELECTION_CLIPBOARD, - META_SELECTION_SOURCE (source_remote)); - } - else - { - MetaSelectionSource *owner; - - owner = meta_selection_get_current_owner (selection, - META_SELECTION_CLIPBOARD); - - if (owner) - emit_owner_changed (session, owner); - } - - session->is_clipboard_enabled = TRUE; - session->owner_changed_handler_id = - g_signal_connect (selection, "owner-changed", - G_CALLBACK (on_selection_owner_changed), - session); - - meta_dbus_remote_desktop_session_complete_enable_clipboard (skeleton, - invocation); - - return TRUE; -} - -static gboolean -cancel_transfer_request (gpointer key, - gpointer value, - gpointer user_data) -{ - GTask *task = G_TASK (value); - MetaRemoteDesktopSession *session = user_data; - - meta_selection_source_remote_cancel_transfer (session->current_source, - task); - - return TRUE; -} - -static void -meta_remote_desktop_session_cancel_transfer_requests (MetaRemoteDesktopSession *session) -{ - g_return_if_fail (session->current_source); - - g_hash_table_foreach_remove (session->transfer_requests, - cancel_transfer_request, - session); -} - -static gboolean -transfer_request_cleanup_timout (gpointer user_data) -{ - MetaRemoteDesktopSession *session = user_data; - - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Cancel unanswered SelectionTransfer requests for %s, " - "waited for %.02f seconds already", - session->peer_name, - TRANSFER_REQUEST_CLEANUP_TIMEOUT_MS / 1000.0); - - meta_remote_desktop_session_cancel_transfer_requests (session); - - session->transfer_request_timeout_id = 0; - return G_SOURCE_REMOVE; -} - -static void -reset_current_selection_source (MetaRemoteDesktopSession *session) -{ - MetaDisplay *display = meta_get_display (); - MetaSelection *selection = meta_display_get_selection (display); - - if (!session->current_source) - return; - - meta_selection_unset_owner (selection, - META_SELECTION_CLIPBOARD, - META_SELECTION_SOURCE (session->current_source)); - meta_remote_desktop_session_cancel_transfer_requests (session); - g_clear_handle_id (&session->transfer_request_timeout_id, g_source_remove); - g_clear_object (&session->current_source); -} - -static void -cancel_selection_read (MetaRemoteDesktopSession *session) -{ - if (!session->read_data) - return; - - g_cancellable_cancel (session->read_data->cancellable); - session->read_data->session = NULL; - session->read_data = NULL; -} - -static gboolean -handle_disable_clipboard (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - MetaDisplay *display = meta_get_display (); - MetaSelection *selection = meta_display_get_selection (display); - - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Disable clipboard for %s", - g_dbus_method_invocation_get_sender (invocation)); - - if (!session->is_clipboard_enabled) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Was not enabled"); - return TRUE; - } - - g_clear_signal_handler (&session->owner_changed_handler_id, selection); - reset_current_selection_source (session); - cancel_selection_read (session); - - meta_dbus_remote_desktop_session_complete_disable_clipboard (skeleton, - invocation); - - return TRUE; -} - -static gboolean -handle_set_selection (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - GVariant *arg_options) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - g_autoptr (GVariant) mime_types_variant = NULL; - g_autoptr (GError) error = NULL; - - if (!session->is_clipboard_enabled) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Clipboard not enabled"); - return TRUE; - } - - if (session->current_source) - { - meta_remote_desktop_session_cancel_transfer_requests (session); - g_clear_handle_id (&session->transfer_request_timeout_id, - g_source_remove); - } - - mime_types_variant = g_variant_lookup_value (arg_options, - "mime-types", - G_VARIANT_TYPE_STRING_ARRAY); - if (mime_types_variant) - { - g_autoptr (MetaSelectionSourceRemote) source_remote = NULL; - MetaDisplay *display = meta_get_display (); - - source_remote = create_remote_desktop_source (session, - mime_types_variant, - &error); - if (!source_remote) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Invalid format list: %s", - error->message); - return TRUE; - } - - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Set selection for %s to %p", - g_dbus_method_invocation_get_sender (invocation), - source_remote); - - g_set_object (&session->current_source, source_remote); - meta_selection_set_owner (meta_display_get_selection (display), - META_SELECTION_CLIPBOARD, - META_SELECTION_SOURCE (source_remote)); - } - else - { - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Unset selection for %s", - g_dbus_method_invocation_get_sender (invocation)); - - reset_current_selection_source (session); - } - - meta_dbus_remote_desktop_session_complete_set_selection (skeleton, - invocation); - - return TRUE; -} - -static void -reset_transfer_cleanup_timeout (MetaRemoteDesktopSession *session) -{ - g_clear_handle_id (&session->transfer_request_timeout_id, g_source_remove); - session->transfer_request_timeout_id = - g_timeout_add (TRANSFER_REQUEST_CLEANUP_TIMEOUT_MS, - transfer_request_cleanup_timout, - session); -} - -void -meta_remote_desktop_session_request_transfer (MetaRemoteDesktopSession *session, - const char *mime_type, - GTask *task) -{ - const char *object_path; - - session->transfer_serial++; - - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Emit SelectionTransfer ('%s', %u) for %s", - mime_type, - session->transfer_serial, - session->peer_name); - - g_hash_table_insert (session->transfer_requests, - GUINT_TO_POINTER (session->transfer_serial), - task); - reset_transfer_cleanup_timeout (session); - - object_path = g_dbus_interface_skeleton_get_object_path ( - G_DBUS_INTERFACE_SKELETON (session)); - g_dbus_connection_emit_signal (session->connection, - NULL, - object_path, - "org.gnome.Mutter.RemoteDesktop.Session", - "SelectionTransfer", - g_variant_new ("(su)", - mime_type, - session->transfer_serial), - NULL); -} - -static gboolean -handle_selection_write (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - GUnixFDList *fd_list_in, - unsigned int serial) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - g_autoptr (GError) error = NULL; - int pipe_fds[2]; - g_autoptr (GUnixFDList) fd_list = NULL; - int fd_idx; - GVariant *fd_variant; - GTask *task; - - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Write selection for %s", - g_dbus_method_invocation_get_sender (invocation)); - - if (!session->is_clipboard_enabled) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Clipboard not enabled"); - return TRUE; - } - - if (!session->current_source) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "No current selection owned"); - return TRUE; - } - - if (!g_hash_table_steal_extended (session->transfer_requests, - GUINT_TO_POINTER (serial), - NULL, - (gpointer *) &task)) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Transfer serial %u doesn't match " - "any transfer request", - serial); - return TRUE; - } - - if (!g_unix_open_pipe (pipe_fds, FD_CLOEXEC, &error)) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Failed open pipe: %s", - error->message); - return TRUE; - } - - if (!g_unix_set_fd_nonblocking (pipe_fds[0], TRUE, &error)) - { - close (pipe_fds[0]); - close (pipe_fds[1]); - - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Failed to make pipe non-blocking: %s", - error->message); - return TRUE; - } - - fd_list = g_unix_fd_list_new (); - - fd_idx = g_unix_fd_list_append (fd_list, pipe_fds[1], NULL); - close (pipe_fds[1]); - fd_variant = g_variant_new_handle (fd_idx); - - meta_selection_source_remote_complete_transfer (session->current_source, - pipe_fds[0], - task); - - meta_dbus_remote_desktop_session_complete_selection_write (skeleton, - invocation, - fd_list, - fd_variant); - - return TRUE; -} - -static gboolean -handle_selection_write_done (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - unsigned int arg_serial, - gboolean arg_success) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Write selection done for %s", - g_dbus_method_invocation_get_sender (invocation)); - - if (!session->is_clipboard_enabled) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Clipboard not enabled"); - return TRUE; - } - - meta_dbus_remote_desktop_session_complete_selection_write_done (skeleton, - invocation); - - return TRUE; -} - -static void -transfer_cb (MetaSelection *selection, - GAsyncResult *res, - SelectionReadData *read_data) -{ - g_autoptr (GError) error = NULL; - - if (!meta_selection_transfer_finish (selection, res, &error)) - { - g_warning ("Could not fetch selection data " - "for remote desktop session: %s", - error->message); - } - - if (read_data->session) - { - meta_topic (META_DEBUG_REMOTE_DESKTOP, "Finished selection transfer for %s", - read_data->session->peer_name); - } - - g_output_stream_close (read_data->stream, NULL, NULL); - g_clear_object (&read_data->stream); - g_clear_object (&read_data->cancellable); - - if (read_data->session) - read_data->session->read_data = NULL; - - g_free (read_data); -} - -static gboolean -handle_selection_read (MetaDBusRemoteDesktopSession *skeleton, - GDBusMethodInvocation *invocation, - GUnixFDList *fd_list_in, - const char *mime_type) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); - MetaDisplay *display = meta_get_display (); - MetaSelection *selection = meta_display_get_selection (display); - MetaSelectionSource *source; - g_autoptr (GError) error = NULL; - int pipe_fds[2]; - g_autoptr (GUnixFDList) fd_list = NULL; - int fd_idx; - GVariant *fd_variant; - SelectionReadData *read_data; - - meta_topic (META_DEBUG_REMOTE_DESKTOP, - "Read selection for %s", - g_dbus_method_invocation_get_sender (invocation)); - - if (!session->is_clipboard_enabled) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Clipboard not enabled"); - return TRUE; - } - - source = meta_selection_get_current_owner (selection, - META_SELECTION_CLIPBOARD); - if (!source) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FILE_NOT_FOUND, - "No selection owner available"); - return TRUE; - } - - if (is_own_source (session, source)) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Tried to read own selection"); - return TRUE; - } - - if (session->read_data) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_LIMITS_EXCEEDED, - "Tried to read in parallel"); - return TRUE; - } - - if (!g_unix_open_pipe (pipe_fds, FD_CLOEXEC, &error)) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Failed open pipe: %s", - error->message); - return TRUE; - } - - if (!g_unix_set_fd_nonblocking (pipe_fds[0], TRUE, &error)) - { - close (pipe_fds[0]); - close (pipe_fds[1]); - - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "Failed to make pipe non-blocking: %s", - error->message); - return TRUE; - } - - fd_list = g_unix_fd_list_new (); - - fd_idx = g_unix_fd_list_append (fd_list, pipe_fds[0], NULL); - close (pipe_fds[0]); - fd_variant = g_variant_new_handle (fd_idx); - - session->read_data = read_data = g_new0 (SelectionReadData, 1); - read_data->session = session; - read_data->stream = g_unix_output_stream_new (pipe_fds[1], TRUE); - read_data->cancellable = g_cancellable_new (); - meta_selection_transfer_async (selection, - META_SELECTION_CLIPBOARD, - mime_type, - -1, - read_data->stream, - read_data->cancellable, - (GAsyncReadyCallback) transfer_cb, - read_data); - - meta_dbus_remote_desktop_session_complete_selection_read (skeleton, - invocation, - fd_list, - fd_variant); - - return TRUE; -} - -static void -meta_remote_desktop_session_init_iface (MetaDBusRemoteDesktopSessionIface *iface) -{ - iface->handle_start = handle_start; - iface->handle_stop = handle_stop; - iface->handle_notify_keyboard_keycode = handle_notify_keyboard_keycode; - iface->handle_notify_keyboard_keysym = handle_notify_keyboard_keysym; - iface->handle_notify_pointer_button = handle_notify_pointer_button; - iface->handle_notify_pointer_axis = handle_notify_pointer_axis; - iface->handle_notify_pointer_axis_discrete = handle_notify_pointer_axis_discrete; - iface->handle_notify_pointer_motion_relative = handle_notify_pointer_motion_relative; - iface->handle_notify_pointer_motion_absolute = handle_notify_pointer_motion_absolute; - iface->handle_notify_touch_down = handle_notify_touch_down; - iface->handle_notify_touch_motion = handle_notify_touch_motion; - iface->handle_notify_touch_up = handle_notify_touch_up; - iface->handle_enable_clipboard = handle_enable_clipboard; - iface->handle_disable_clipboard = handle_disable_clipboard; - iface->handle_set_selection = handle_set_selection; - iface->handle_selection_write = handle_selection_write; - iface->handle_selection_write_done = handle_selection_write_done; - iface->handle_selection_read = handle_selection_read; -} - -static void -meta_remote_desktop_session_client_vanished (MetaDbusSession *dbus_session) -{ - meta_remote_desktop_session_close (META_REMOTE_DESKTOP_SESSION (dbus_session)); -} - -static void -meta_dbus_session_init_iface (MetaDbusSessionInterface *iface) -{ - iface->client_vanished = meta_remote_desktop_session_client_vanished; -} - -static void -meta_remote_desktop_session_finalize (GObject *object) -{ - MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (object); - MetaDisplay *display = meta_get_display (); - MetaSelection *selection = meta_display_get_selection (display); - - g_assert (!meta_remote_desktop_session_is_running (session)); - - g_clear_signal_handler (&session->owner_changed_handler_id, selection); - reset_current_selection_source (session); - cancel_selection_read (session); - g_hash_table_unref (session->transfer_requests); - - g_clear_object (&session->handle); - g_free (session->peer_name); - g_free (session->session_id); - g_free (session->object_path); - - G_OBJECT_CLASS (meta_remote_desktop_session_parent_class)->finalize (object); -} - -static void -meta_remote_desktop_session_init (MetaRemoteDesktopSession *session) -{ - MetaDBusRemoteDesktopSession *skeleton = - META_DBUS_REMOTE_DESKTOP_SESSION (session); - GRand *rand; - static unsigned int global_session_number = 0; - - rand = g_rand_new (); - session->session_id = meta_generate_random_id (rand, 32); - g_rand_free (rand); - - meta_dbus_remote_desktop_session_set_session_id (skeleton, session->session_id); - - session->object_path = - g_strdup_printf (META_REMOTE_DESKTOP_SESSION_DBUS_PATH "/u%u", - ++global_session_number); - - session->transfer_requests = g_hash_table_new (NULL, NULL); -} - -static void -meta_remote_desktop_session_class_init (MetaRemoteDesktopSessionClass *klass) -{ - - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = meta_remote_desktop_session_finalize; -} - -static MetaRemoteDesktopSessionHandle * -meta_remote_desktop_session_handle_new (MetaRemoteDesktopSession *session) -{ - MetaRemoteDesktopSessionHandle *handle; - - handle = g_object_new (META_TYPE_REMOTE_DESKTOP_SESSION_HANDLE, NULL); - handle->session = session; - - return handle; -} - -static void -meta_remote_desktop_session_handle_stop (MetaRemoteAccessHandle *handle) -{ - MetaRemoteDesktopSession *session; - - session = META_REMOTE_DESKTOP_SESSION_HANDLE (handle)->session; - if (!session) - return; - - meta_remote_desktop_session_close (session); -} - -static void -meta_remote_desktop_session_handle_init (MetaRemoteDesktopSessionHandle *handle) -{ -} - -static void -meta_remote_desktop_session_handle_class_init (MetaRemoteDesktopSessionHandleClass *klass) -{ - MetaRemoteAccessHandleClass *remote_access_handle_class = - META_REMOTE_ACCESS_HANDLE_CLASS (klass); - - remote_access_handle_class->stop = meta_remote_desktop_session_handle_stop; -} |