diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 3fb9fda050..b64f2f105b 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -666,8 +666,6 @@ _gdk_wayland_display_open (const gchar *display_name) return NULL; } - display_wayland->selection = gdk_wayland_selection_new (); - gdk_display_emit_opened (display); return display; @@ -693,12 +691,6 @@ gdk_wayland_display_dispose (GObject *object) display_wayland->event_source = NULL; } - if (display_wayland->selection) - { - gdk_wayland_selection_free (display_wayland->selection); - display_wayland->selection = NULL; - } - g_list_free_full (display_wayland->async_roundtrips, (GDestroyNotify) wl_callback_destroy); if (display_wayland->known_globals) @@ -1356,15 +1348,6 @@ _gdk_wayland_is_shm_surface (cairo_surface_t *surface) return cairo_surface_get_user_data (surface, &gdk_wayland_shm_surface_cairo_key) != NULL; } -GdkWaylandSelection * -gdk_wayland_display_get_selection (GdkDisplay *display) -{ - GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); - - return display_wayland->selection; -} - - typedef enum { GSD_FONT_ANTIALIASING_MODE_NONE, diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index 6b62ef8e9a..fa2647cfdb 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -139,8 +139,6 @@ struct _GdkWaylandDisplay struct xkb_context *xkb_context; - GdkWaylandSelection *selection; - GPtrArray *monitors; gint64 last_bell_time_ms; diff --git a/gdk/wayland/gdkdnd-wayland.c b/gdk/wayland/gdkdnd-wayland.c index f1767e6260..3ff57f451d 100644 --- a/gdk/wayland/gdkdnd-wayland.c +++ b/gdk/wayland/gdkdnd-wayland.c @@ -77,10 +77,7 @@ gdk_wayland_drag_context_finalize (GObject *object) contexts = g_list_remove (contexts, context); - if (context->is_source) - { - gdk_drag_context_set_cursor (context, NULL); - } + gdk_drag_context_set_cursor (context, NULL); g_clear_pointer (&wayland_context->data_source, (GDestroyNotify) wl_data_source_destroy); g_clear_pointer (&wayland_context->offer, (GDestroyNotify) wl_data_offer_destroy); @@ -240,19 +237,157 @@ create_dnd_surface (GdkDisplay *display) return surface; } +static inline GdkDragAction +_wl_to_gdk_actions (uint32_t dnd_actions) +{ + GdkDragAction actions = 0; + + if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) + actions |= GDK_ACTION_COPY; + if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) + actions |= GDK_ACTION_MOVE; + if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) + actions |= GDK_ACTION_ASK; + + return actions; +} + +static void +data_source_target (void *data, + struct wl_data_source *source, + const char *mime_type) +{ + GDK_NOTE (EVENTS, + g_message ("data source target, source = %p, mime_type = %s", + source, mime_type)); +} + +static void +gdk_wayland_drag_context_write_done (GObject *context, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + + if (!gdk_drag_context_write_finish (GDK_DRAG_CONTEXT (context), result, &error)) + { + GDK_DISPLAY_NOTE (gdk_drag_context_get_display (GDK_DRAG_CONTEXT (context)), DND, g_message ("%p: failed to write stream: %s", context, error->message)); + g_error_free (error); + } +} + +static void +data_source_send (void *data, + struct wl_data_source *source, + const char *mime_type, + int32_t fd) +{ + GdkDragContext *context = data; + GOutputStream *stream; + + GDK_DISPLAY_NOTE (gdk_drag_context_get_display (context), DND, g_message ("%p: data source send request for %s on fd %d\n", + source, mime_type, fd)); + + //mime_type = gdk_intern_mime_type (mime_type); + mime_type = g_intern_string (mime_type); + stream = g_unix_output_stream_new (fd, TRUE); + + gdk_drag_context_write_async (context, + mime_type, + stream, + G_PRIORITY_DEFAULT, + NULL, + gdk_wayland_drag_context_write_done, + context); + g_object_unref (stream); +} + +static void +data_source_cancelled (void *data, + struct wl_data_source *source) +{ + GdkDragContext *context = data; + + GDK_DISPLAY_NOTE (gdk_drag_context_get_display (context), EVENTS, + g_message ("data source cancelled, source = %p", source)); + + gdk_drag_context_cancel (context, GDK_DRAG_CANCEL_ERROR); +} + +static void +data_source_dnd_drop_performed (void *data, + struct wl_data_source *source) +{ + GdkDragContext *context = data; + + g_signal_emit_by_name (context, "drop-performed", GDK_CURRENT_TIME); +} + +static void +data_source_dnd_finished (void *data, + struct wl_data_source *source) +{ + GdkDragContext *context = data; + + g_signal_emit_by_name (context, "dnd-finished"); +} + +static void +data_source_action (void *data, + struct wl_data_source *source, + uint32_t action) +{ + GdkDragContext *context = data; + + GDK_DISPLAY_NOTE (gdk_drag_context_get_display (context), EVENTS, + g_message ("data source action, source = %p action=%x", + source, action)); + + context->action = _wl_to_gdk_actions (action); + g_signal_emit_by_name (context, "action-changed", context->action); +} + +static const struct wl_data_source_listener data_source_listener = { + data_source_target, + data_source_send, + data_source_cancelled, + data_source_dnd_drop_performed, + data_source_dnd_finished, + data_source_action, +}; + +static void +gdk_wayland_drag_context_create_data_source (GdkDragContext *context) +{ + GdkWaylandDragContext *context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context); + GdkDisplay *display = gdk_drag_context_get_display (context); + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); + const char *const *mimetypes; + gsize i, n_mimetypes; + + context_wayland->data_source = wl_data_device_manager_create_data_source (display_wayland->data_device_manager); + wl_data_source_add_listener (context_wayland->data_source, + &data_source_listener, + context); + + mimetypes = gdk_content_formats_get_mime_types (gdk_drag_context_get_formats (context), &n_mimetypes); + for (i = 0; i < n_mimetypes; i++) + { + wl_data_source_offer (context_wayland->data_source, mimetypes[i]); + } +} + GdkDragContext * _gdk_wayland_surface_drag_begin (GdkSurface *surface, - GdkDevice *device, - GdkContentProvider *content, - GdkDragAction actions, - gint dx, - gint dy) + GdkDevice *device, + GdkContentProvider *content, + GdkDragAction actions, + gint dx, + gint dy) { GdkWaylandDragContext *context_wayland; GdkDragContext *context; GdkWaylandDisplay *display_wayland; - const char *const *mimetypes; - gsize i, n_mimetypes; display_wayland = GDK_WAYLAND_DISPLAY (gdk_device_get_display (device)); @@ -266,13 +401,8 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface, context_wayland->dnd_surface = create_dnd_surface (gdk_surface_get_display (surface)); context_wayland->dnd_wl_surface = gdk_wayland_surface_get_wl_surface (context_wayland->dnd_surface); - context_wayland->data_source = gdk_wayland_selection_get_data_source (surface); - - mimetypes = gdk_content_formats_get_mime_types (gdk_drag_context_get_formats (context), &n_mimetypes); - for (i = 0; i < n_mimetypes; i++) - { - wl_data_source_offer (context_wayland->data_source, mimetypes[i]); - } + + gdk_wayland_drag_context_create_data_source (context); if (display_wayland->data_device_manager_version >= WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION) @@ -302,19 +432,3 @@ _gdk_wayland_drag_context_set_source_surface (GdkDragContext *context, context->source_surface = surface ? g_object_ref (surface) : NULL; } -GdkDragContext * -gdk_wayland_drag_context_lookup_by_data_source (struct wl_data_source *source) -{ - GList *l; - - for (l = contexts; l; l = l->next) - { - GdkWaylandDragContext *wayland_context = l->data; - - if (wayland_context->data_source == source) - return l->data; - } - - return NULL; -} - diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index 70af449156..14dc4d4e5c 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -117,8 +117,6 @@ void gdk_wayland_drop_set_action (GdkDrop void _gdk_wayland_drag_context_set_source_surface (GdkDragContext *context, GdkSurface *surface); -GdkDragContext * gdk_wayland_drag_context_lookup_by_data_source (struct wl_data_source *source); - void _gdk_wayland_display_create_surface_impl (GdkDisplay *display, GdkSurface *surface, GdkSurface *real_parent, @@ -185,14 +183,6 @@ cairo_surface_t * _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *di struct wl_buffer *_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface_t *surface); gboolean _gdk_wayland_is_shm_surface (cairo_surface_t *surface); -GdkWaylandSelection * gdk_wayland_display_get_selection (GdkDisplay *display); -GdkWaylandSelection * gdk_wayland_selection_new (void); -void gdk_wayland_selection_free (GdkWaylandSelection *selection); - - -struct wl_data_source * gdk_wayland_selection_get_data_source (GdkSurface *owner); -void gdk_wayland_selection_unset_data_source (GdkDisplay *display); - EGLSurface gdk_wayland_surface_get_egl_surface (GdkSurface *surface, EGLConfig config); EGLSurface gdk_wayland_surface_get_dummy_egl_surface (GdkSurface *surface, diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c index ba9dc49bb0..39380537a2 100644 --- a/gdk/wayland/gdkselection-wayland.c +++ b/gdk/wayland/gdkselection-wayland.c @@ -33,210 +33,6 @@ #include -struct _GdkWaylandSelection -{ - struct wl_data_source *dnd_source; /* Owned by the GdkDragContext */ -}; - -GdkWaylandSelection * -gdk_wayland_selection_new (void) -{ - GdkWaylandSelection *selection; - - selection = g_new0 (GdkWaylandSelection, 1); - - return selection; -} - -void -gdk_wayland_selection_free (GdkWaylandSelection *selection) -{ - if (selection->dnd_source) - wl_data_source_destroy (selection->dnd_source); - - g_free (selection); -} - -static inline GdkDragAction -_wl_to_gdk_actions (uint32_t dnd_actions) -{ - GdkDragAction actions = 0; - - if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) - actions |= GDK_ACTION_COPY; - if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) - actions |= GDK_ACTION_MOVE; - if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) - actions |= GDK_ACTION_ASK; - - return actions; -} - -static void -data_source_target (void *data, - struct wl_data_source *source, - const char *mime_type) -{ - GDK_NOTE (EVENTS, - g_message ("data source target, source = %p, mime_type = %s", - source, mime_type)); -} - -static void -gdk_wayland_drag_context_write_done (GObject *context, - GAsyncResult *result, - gpointer user_data) -{ - GError *error = NULL; - - if (!gdk_drag_context_write_finish (GDK_DRAG_CONTEXT (context), result, &error)) - { - GDK_DISPLAY_NOTE (gdk_drag_context_get_display (GDK_DRAG_CONTEXT (context)), DND, g_message ("%p: failed to write stream: %s", context, error->message)); - g_error_free (error); - } -} - -static void -data_source_send (void *data, - struct wl_data_source *source, - const char *mime_type, - int32_t fd) -{ - GdkDragContext *context; - GOutputStream *stream; - - context = gdk_wayland_drag_context_lookup_by_data_source (source); - if (!context) - return; - - GDK_DISPLAY_NOTE (gdk_drag_context_get_display (context), DND, g_message ("%p: data source send request for %s on fd %d\n", - source, mime_type, fd)); - - //mime_type = gdk_intern_mime_type (mime_type); - mime_type = g_intern_string (mime_type); - stream = g_unix_output_stream_new (fd, TRUE); - - gdk_drag_context_write_async (context, - mime_type, - stream, - G_PRIORITY_DEFAULT, - NULL, - gdk_wayland_drag_context_write_done, - context); - g_object_unref (stream); -} - -static void -data_source_cancelled (void *data, - struct wl_data_source *source) -{ - GdkWaylandSelection *wayland_selection = data; - GdkDragContext *context; - GdkDisplay *display; - - display = gdk_display_get_default (); - - GDK_DISPLAY_NOTE (display, EVENTS, - g_message ("data source cancelled, source = %p", source)); - - if (source != wayland_selection->dnd_source) - return; - - context = gdk_wayland_drag_context_lookup_by_data_source (source); - - if (context) - gdk_drag_context_cancel (context, GDK_DRAG_CANCEL_ERROR); - - gdk_wayland_selection_unset_data_source (display); -} - -static void -data_source_dnd_drop_performed (void *data, - struct wl_data_source *source) -{ - GdkDragContext *context; - - context = gdk_wayland_drag_context_lookup_by_data_source (source); - - if (!context) - return; - - g_signal_emit_by_name (context, "drop-performed", GDK_CURRENT_TIME); -} - -static void -data_source_dnd_finished (void *data, - struct wl_data_source *source) -{ - GdkDragContext *context; - - context = gdk_wayland_drag_context_lookup_by_data_source (source); - - if (!context) - return; - - g_signal_emit_by_name (context, "dnd-finished"); -} - -static void -data_source_action (void *data, - struct wl_data_source *source, - uint32_t action) -{ - GdkDragContext *context; - - context = gdk_wayland_drag_context_lookup_by_data_source (source); - if (!context) - return; - - GDK_DISPLAY_NOTE (gdk_drag_context_get_display (context), EVENTS, - g_message ("data source action, source = %p action=%x", - source, action)); - - context->action = _wl_to_gdk_actions (action); - g_signal_emit_by_name (context, "action-changed", context->action); -} - -static const struct wl_data_source_listener data_source_listener = { - data_source_target, - data_source_send, - data_source_cancelled, - data_source_dnd_drop_performed, - data_source_dnd_finished, - data_source_action, -}; - -struct wl_data_source * -gdk_wayland_selection_get_data_source (GdkSurface *owner) -{ - GdkDisplay *display = gdk_surface_get_display (owner); - GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display); - gpointer source = NULL; - GdkWaylandDisplay *display_wayland; - - if (wayland_selection->dnd_source) - return wayland_selection->dnd_source; - - display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (owner)); - - source = wl_data_device_manager_create_data_source (display_wayland->data_device_manager); - wl_data_source_add_listener (source, - &data_source_listener, - wayland_selection); - - wayland_selection->dnd_source = source; - - return source; -} - -void -gdk_wayland_selection_unset_data_source (GdkDisplay *display) -{ - GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display); - - wayland_selection->dnd_source = NULL; -} - gint _gdk_wayland_display_text_property_to_utf8_list (GdkDisplay *display, GdkAtom encoding,