void gdk_wayland_selection_set_offer (GdkDisplay *display, GdkAtom selection_atom, gpointer wl_offer) { GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display); struct wl_data_offer *prev_offer; SelectionData *selection_data; DataOfferData *info; info = g_hash_table_lookup (selection->offers, wl_offer); prev_offer = gdk_wayland_selection_get_offer (display, selection_atom); if (prev_offer) g_hash_table_remove (selection->offers, prev_offer); selection_data = selection_lookup_offer_by_atom (selection, selection_atom); if (selection_data) { selection_data->offer = info; /* Clear all buffers */ g_hash_table_remove_all (selection_data->buffers); } }
gboolean gdk_wayland_selection_set_current_offer_actions (GdkDisplay *display, uint32_t action) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); struct wl_data_offer *offer; uint32_t all_actions = 0; offer = gdk_wayland_selection_get_offer (display, atoms[ATOM_DND]); if (!offer) return FALSE; if (action != 0) all_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; if (display_wayland->data_device_manager_version >= WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) wl_data_offer_set_actions (offer, all_actions, action); return TRUE; }
void gdk_wayland_selection_set_offer (GdkDisplay *display, GdkAtom selection_atom, struct wl_data_offer *wl_offer) { GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display); struct wl_data_offer *prev_offer; DataOfferData *info; info = g_hash_table_lookup (selection->offers, wl_offer); prev_offer = gdk_wayland_selection_get_offer (display, selection_atom); if (prev_offer) g_hash_table_remove (selection->offers, prev_offer); if (selection_atom == atoms[ATOM_CLIPBOARD]) selection->clipboard_offer = info; else if (selection_atom == atoms[ATOM_DND]) selection->dnd_offer = info; /* Clear all buffers */ g_hash_table_remove_all (selection->selection_buffers); }
void _gdk_wayland_display_convert_selection (GdkDisplay *display, GdkWindow *requestor, GdkAtom selection, GdkAtom target, guint32 time) { GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display); SelectionBuffer *buffer_data; struct wl_data_offer *offer; gchar *mimetype; GList *target_list; offer = gdk_wayland_selection_get_offer (display, selection); target_list = gdk_wayland_selection_get_targets (display, selection); if (!offer) { GdkEvent *event; event = gdk_event_new (GDK_SELECTION_NOTIFY); event->selection.window = g_object_ref (requestor); event->selection.send_event = FALSE; event->selection.selection = selection; event->selection.target = target; event->selection.property = GDK_NONE; event->selection.time = GDK_CURRENT_TIME; event->selection.requestor = g_object_ref (requestor); gdk_event_put (event); gdk_event_free (event); return; } mimetype = gdk_atom_name (target); if (target != gdk_atom_intern_static_string ("TARGETS")) wl_data_offer_accept (offer, _gdk_wayland_display_get_serial (GDK_WAYLAND_DISPLAY (display)), mimetype); buffer_data = g_hash_table_lookup (wayland_selection->selection_buffers, target); if (buffer_data) selection_buffer_add_requestor (buffer_data, requestor); else { GInputStream *stream = NULL; int pipe_fd[2], natoms = 0; GdkAtom *targets = NULL; if (target == gdk_atom_intern_static_string ("TARGETS")) { gint i = 0; GList *l; natoms = g_list_length (target_list); targets = g_new0 (GdkAtom, natoms); for (l = target_list; l; l = l->next) targets[i++] = l->data; } else { g_unix_open_pipe (pipe_fd, FD_CLOEXEC, NULL); wl_data_offer_receive (offer, mimetype, pipe_fd[1]); stream = g_unix_input_stream_new (pipe_fd[0], TRUE); close (pipe_fd[1]); } buffer_data = selection_buffer_new (stream, selection, target); selection_buffer_add_requestor (buffer_data, requestor); if (stream) g_object_unref (stream); if (targets) { /* Store directly the local atoms */ selection_buffer_append_data (buffer_data, targets, natoms * sizeof (GdkAtom)); g_free (targets); } g_hash_table_insert (wayland_selection->selection_buffers, GDK_ATOM_TO_POINTER (target), buffer_data); } if (!buffer_data->stream) selection_buffer_notify (buffer_data); g_free (mimetype); }
void _gdk_wayland_display_convert_selection (GdkDisplay *display, GdkWindow *requestor, GdkAtom selection, GdkAtom target, guint32 time) { GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display); const SelectionData *selection_data; SelectionBuffer *buffer_data; gpointer offer; gchar *mimetype; GList *target_list; selection_data = selection_lookup_offer_by_atom (wayland_selection, selection); if (!selection_data) return; offer = gdk_wayland_selection_get_offer (display, selection); target_list = gdk_wayland_selection_get_targets (display, selection); if (!offer || target == gdk_atom_intern_static_string ("DELETE")) { emit_empty_selection_notify (requestor, selection, target); return; } mimetype = gdk_atom_name (target); if (target != gdk_atom_intern_static_string ("TARGETS")) { if (!g_list_find (target_list, GDK_ATOM_TO_POINTER (target))) { emit_empty_selection_notify (requestor, selection, target); return; } if (selection != atoms[ATOM_PRIMARY]) wl_data_offer_accept (offer, _gdk_wayland_display_get_serial (GDK_WAYLAND_DISPLAY (display)), mimetype); } buffer_data = g_hash_table_lookup (selection_data->buffers, target); if (buffer_data) selection_buffer_add_requestor (buffer_data, requestor); else { GInputStream *stream = NULL; int pipe_fd[2], natoms = 0; GdkAtom *targets = NULL; if (target == gdk_atom_intern_static_string ("TARGETS")) { gint i = 0; GList *l; natoms = g_list_length (target_list); targets = g_new0 (GdkAtom, natoms); for (l = target_list; l; l = l->next) targets[i++] = l->data; } else { g_unix_open_pipe (pipe_fd, FD_CLOEXEC, NULL); if (selection == atoms[ATOM_PRIMARY]) gtk_primary_selection_offer_receive (offer, mimetype, pipe_fd[1]); else wl_data_offer_receive (offer, mimetype, pipe_fd[1]); stream = g_unix_input_stream_new (pipe_fd[0], TRUE); close (pipe_fd[1]); } buffer_data = selection_buffer_new (stream, selection, target); selection_buffer_add_requestor (buffer_data, requestor); if (stream) g_object_unref (stream); if (targets) { /* Store directly the local atoms */ selection_buffer_append_data (buffer_data, targets, natoms * sizeof (GdkAtom)); g_free (targets); } g_hash_table_insert (selection_data->buffers, GDK_ATOM_TO_POINTER (target), buffer_data); } if (!buffer_data->stream) selection_buffer_notify (buffer_data); g_free (mimetype); }