summaryrefslogtreecommitdiff
path: root/src/wayland/meta-wayland-data-offer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wayland/meta-wayland-data-offer.c')
-rw-r--r--src/wayland/meta-wayland-data-offer.c327
1 files changed, 0 insertions, 327 deletions
diff --git a/src/wayland/meta-wayland-data-offer.c b/src/wayland/meta-wayland-data-offer.c
deleted file mode 100644
index c686aee6f..000000000
--- a/src/wayland/meta-wayland-data-offer.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * 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 <gio/gunixoutputstream.h>
-#include <glib-unix.h>
-#include <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "meta/meta-selection.h"
-#include "wayland/meta-wayland-data-device.h"
-#include "wayland/meta-wayland-private.h"
-
-#include "meta-wayland-data-offer.h"
-
-#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \
- WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \
- WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
-
-static void
-data_offer_accept (struct wl_client *client,
- struct wl_resource *resource,
- guint32 serial,
- const char *mime_type)
-{
- MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
-
- /* FIXME: Check that client is currently focused by the input
- * device that is currently dragging this data source. Should
- * this be a wl_data_device request? */
-
- if (offer->source)
- {
- meta_wayland_data_source_target (offer->source, mime_type);
- meta_wayland_data_source_set_has_target (offer->source,
- mime_type != NULL);
- }
-
- offer->accepted = mime_type != NULL;
-}
-
-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
-data_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 = meta_get_display ();
- MetaSelectionType selection_type;
- GList *mime_types;
- gboolean found;
-
- selection_type = offer->selection_type;
- mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
- selection_type);
- found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
- g_list_free_full (mime_types, g_free);
-
- if (found)
- {
- GOutputStream *stream;
-
- stream = g_unix_output_stream_new (fd, TRUE);
- meta_selection_transfer_async (meta_display_get_selection (display),
- selection_type,
- mime_type,
- -1,
- stream,
- NULL,
- (GAsyncReadyCallback) transfer_cb,
- stream);
- }
- else
- {
- close (fd);
- }
-}
-
-static void
-data_offer_destroy (struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy (resource);
-}
-
-static void
-data_offer_finish (struct wl_client *client,
- struct wl_resource *resource)
-{
- MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
- enum wl_data_device_manager_dnd_action current_action;
-
- if (!offer->source ||
- offer != meta_wayland_data_source_get_current_offer (offer->source))
- return;
-
- if (!offer->accepted || !offer->action_sent)
- {
- wl_resource_post_error (offer->resource,
- WL_DATA_OFFER_ERROR_INVALID_FINISH,
- "premature finish request");
- return;
- }
-
- current_action = meta_wayland_data_source_get_current_action (offer->source);
-
- if (current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE ||
- current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
- {
- wl_resource_post_error (offer->resource,
- WL_DATA_OFFER_ERROR_INVALID_OFFER,
- "offer finished with an invalid action");
- return;
- }
-
- meta_wayland_data_source_notify_finish (offer->source);
-}
-
-static void
-data_offer_set_actions (struct wl_client *client,
- struct wl_resource *resource,
- uint32_t dnd_actions,
- uint32_t preferred_action)
-{
- MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
-
- if (dnd_actions & ~(ALL_ACTIONS))
- {
- wl_resource_post_error (offer->resource,
- WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK,
- "invalid actions mask %x", dnd_actions);
- return;
- }
-
- if (preferred_action &&
- (!(preferred_action & dnd_actions) ||
- __builtin_popcount (preferred_action) > 1))
- {
- wl_resource_post_error (offer->resource,
- WL_DATA_OFFER_ERROR_INVALID_ACTION,
- "invalid action %x", preferred_action);
- return;
- }
-
- offer->dnd_actions = dnd_actions;
- offer->preferred_dnd_action = preferred_action;
-
- meta_wayland_data_offer_update_action (offer);
-}
-
-static const struct wl_data_offer_interface data_offer_interface = {
- data_offer_accept,
- data_offer_receive,
- data_offer_destroy,
- data_offer_finish,
- data_offer_set_actions,
-};
-
-static void
-destroy_data_offer (struct wl_resource *resource)
-{
- MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
- MetaWaylandSeat *seat;
-
- if (offer->source)
- {
- seat = meta_wayland_data_source_get_seat (offer->source);
-
- if (offer == meta_wayland_data_source_get_current_offer (offer->source))
- {
- if (seat->data_device.dnd_data_source == offer->source)
- {
- if (wl_resource_get_version (offer->resource) <
- WL_DATA_OFFER_ACTION_SINCE_VERSION)
- meta_wayland_data_source_notify_finish (offer->source);
- else if (meta_wayland_data_source_get_drop_performed (offer->source))
- meta_wayland_data_source_cancel (offer->source);
- }
- else
- {
- meta_wayland_data_source_set_current_offer (offer->source, NULL);
- meta_wayland_data_source_set_has_target (offer->source, FALSE);
- }
- }
-
- g_object_remove_weak_pointer (G_OBJECT (offer->source),
- (gpointer *)&offer->source);
- offer->source = NULL;
- }
-
- meta_display_sync_wayland_input_focus (meta_get_display ());
- g_free (offer);
-}
-
-MetaWaylandDataOffer *
-meta_wayland_data_offer_new (MetaSelectionType selection_type,
- MetaWaylandDataSource *source,
- struct wl_resource *target)
-{
- MetaWaylandDataOffer *offer;
-
- offer = g_new0 (MetaWaylandDataOffer, 1);
- offer->selection_type = selection_type;
- offer->resource = wl_resource_create (wl_resource_get_client (target),
- &wl_data_offer_interface,
- wl_resource_get_version (target), 0);
- wl_resource_set_implementation (offer->resource,
- &data_offer_interface,
- offer,
- destroy_data_offer);
- if (source)
- {
- offer->source = source;
- g_object_add_weak_pointer (G_OBJECT (source), (gpointer *)&offer->source);
- }
-
- return offer;
-}
-
-static enum wl_data_device_manager_dnd_action
-data_offer_choose_action (MetaWaylandDataOffer *offer)
-{
- MetaWaylandDataSource *source = offer->source;
- uint32_t actions, user_action, available_actions;
-
- if (wl_resource_get_version (offer->resource) <
- WL_DATA_OFFER_ACTION_SINCE_VERSION)
- return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
-
- meta_wayland_data_source_get_actions (source, &actions);
- user_action = meta_wayland_data_source_get_user_action (source);
-
- available_actions = actions & offer->dnd_actions;
-
- if (!available_actions)
- return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
-
- /* If the user is forcing an action, go for it */
- if ((user_action & available_actions) != 0)
- return user_action;
-
- /* If the dest side has a preferred DnD action, use it */
- if ((offer->preferred_dnd_action & available_actions) != 0)
- return offer->preferred_dnd_action;
-
- /* Use the first found action, in bit order */
- return 1 << (ffs (available_actions) - 1);
-}
-
-void
-meta_wayland_data_offer_update_action (MetaWaylandDataOffer *offer)
-{
- enum wl_data_device_manager_dnd_action current_action, action;
- MetaWaylandDataSource *source;
-
- if (!offer->source)
- return;
-
- source = offer->source;
- current_action = meta_wayland_data_source_get_current_action (source);
- action = data_offer_choose_action (offer);
-
- if (current_action == action)
- return;
-
- meta_wayland_data_source_set_current_action (source, action);
-
- if (!meta_wayland_data_source_get_in_ask (source) &&
- wl_resource_get_version (offer->resource) >=
- WL_DATA_OFFER_ACTION_SINCE_VERSION)
- {
- wl_data_offer_send_action (offer->resource, action);
- offer->action_sent = TRUE;
- }
-}
-
-struct wl_resource *
-meta_wayland_data_offer_get_resource (MetaWaylandDataOffer *offer)
-{
- return offer->resource;
-}
-
-MetaWaylandDataSource *
-meta_wayland_data_offer_get_source (MetaWaylandDataOffer *offer)
-{
- return offer->source;
-}