2731f0cda4
As elsewhere, make sure objects that need to have a ownership up to the context, and use this ownership chain to find relevant components, such as the backend or the Wayland compositor object instance. wayland/data-device: Hook up data devices to seats They are tied to a seat - make that connection in struct fields too, so that related objects can get to the context via it. wayland: Don't get Wayland compositor via singleton getter This means via the ownership chain or equivalent. xwayland: Hook up manager to Wayland compositor Same applies to the drag-n-drop struct. xwayland: Make X11 event handling compositor instance aware This avoids finding it via singletons in the callee. xwayland: Don't get Wayland compositor from singleton xwayland: Pass manager when handling dnd event window/xwayland: Don't get Wayland compositor from singleton xwayland/grab-keyboard: Don't get backend from singleton xwayland: Don't get backend from singleton wayland: Always get the backend from the context This means traveling up the ownership chain or equivalent when necessary. wayland: Hook up data devices, offers and sources to the compositor This allows tying them to a context without going through any singletons. wayland: Don't get display from singleton xwayland: Don't get display from singleton tablet: Don't get display from singleton Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2718>
153 lines
5.0 KiB
C
153 lines
5.0 KiB
C
/*
|
|
* Copyright © 2011 Kristian Høgsberg
|
|
* 2020 Red Hat Inc.
|
|
*
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
* the above copyright notice appear in all copies and that both that copyright
|
|
* notice and this permission notice appear in supporting documentation, and
|
|
* that the name of the copyright holders not be used in advertising or
|
|
* publicity pertaining to distribution of the software without specific,
|
|
* written prior permission. The copyright holders make no representations
|
|
* about the suitability of this software for any purpose. It is provided "as
|
|
* is" without express or implied warranty.
|
|
*
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
* OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "meta-wayland-data-offer-primary.h"
|
|
|
|
#include <gio/gunixoutputstream.h>
|
|
#include <glib-unix.h>
|
|
#include <glib.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "core/display-private.h"
|
|
#include "primary-selection-unstable-v1-server-protocol.h"
|
|
#include "wayland/meta-wayland-data-offer.h"
|
|
#include "wayland/meta-wayland-private.h"
|
|
|
|
static MetaDisplay *
|
|
display_from_offer (MetaWaylandDataOffer *offer)
|
|
{
|
|
MetaContext *context =
|
|
meta_wayland_compositor_get_context (offer->compositor);
|
|
|
|
return meta_context_get_display (context);
|
|
}
|
|
|
|
static void
|
|
transfer_cb (MetaSelection *selection,
|
|
GAsyncResult *res,
|
|
GOutputStream *stream)
|
|
{
|
|
GError *error = NULL;
|
|
|
|
if (!meta_selection_transfer_finish (selection, res, &error))
|
|
{
|
|
g_warning ("Could not fetch selection data: %s", error->message);
|
|
g_error_free (error);
|
|
}
|
|
|
|
g_output_stream_close (stream, NULL, NULL);
|
|
g_object_unref (stream);
|
|
}
|
|
|
|
static void
|
|
primary_offer_receive (struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
const char *mime_type,
|
|
int32_t fd)
|
|
{
|
|
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
|
MetaDisplay *display = display_from_offer (offer);
|
|
GOutputStream *stream;
|
|
GList *mime_types;
|
|
gboolean found;
|
|
|
|
mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
|
META_SELECTION_PRIMARY);
|
|
found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
|
|
g_list_free_full (mime_types, g_free);
|
|
|
|
if (!found)
|
|
{
|
|
close (fd);
|
|
return;
|
|
}
|
|
|
|
stream = g_unix_output_stream_new (fd, TRUE);
|
|
meta_selection_transfer_async (meta_display_get_selection (display),
|
|
META_SELECTION_PRIMARY,
|
|
mime_type,
|
|
-1,
|
|
stream,
|
|
NULL,
|
|
(GAsyncReadyCallback) transfer_cb,
|
|
stream);
|
|
}
|
|
|
|
static void
|
|
primary_offer_destroy (struct wl_client *client,
|
|
struct wl_resource *resource)
|
|
{
|
|
wl_resource_destroy (resource);
|
|
}
|
|
|
|
static const struct zwp_primary_selection_offer_v1_interface primary_offer_interface = {
|
|
primary_offer_receive,
|
|
primary_offer_destroy,
|
|
};
|
|
|
|
static void
|
|
destroy_primary_offer (struct wl_resource *resource)
|
|
{
|
|
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
|
|
|
if (offer->source)
|
|
{
|
|
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
|
|
{
|
|
meta_wayland_data_source_cancel (offer->source);
|
|
meta_wayland_data_source_set_current_offer (offer->source, NULL);
|
|
}
|
|
|
|
g_object_remove_weak_pointer (G_OBJECT (offer->source),
|
|
(gpointer *)&offer->source);
|
|
offer->source = NULL;
|
|
}
|
|
|
|
meta_display_sync_wayland_input_focus (display_from_offer (offer));
|
|
g_free (offer);
|
|
}
|
|
|
|
MetaWaylandDataOffer *
|
|
meta_wayland_data_offer_primary_new (MetaWaylandCompositor *compositor,
|
|
struct wl_resource *target)
|
|
{
|
|
MetaWaylandDataOffer *offer;
|
|
|
|
offer = g_new0 (MetaWaylandDataOffer, 1);
|
|
offer->compositor = compositor;
|
|
offer->selection_type = META_SELECTION_PRIMARY;
|
|
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
|
&zwp_primary_selection_offer_v1_interface,
|
|
wl_resource_get_version (target), 0);
|
|
wl_resource_set_implementation (offer->resource,
|
|
&primary_offer_interface,
|
|
offer,
|
|
destroy_primary_offer);
|
|
return offer;
|
|
}
|