std::string PasteboardWayland::getString(const std::string pasteboardType) { if (!std::any_of(m_dataDeviceData.dataTypes.cbegin(), m_dataDeviceData.dataTypes.cend(), [pasteboardType](std::string str){ return str == pasteboardType;})) return std::string(); int pipefd[2]; // FIXME: Should probably handle this error somehow. if (pipe2(pipefd, O_CLOEXEC) == -1) return std::string(); wl_data_offer_receive(m_dataDeviceData.data_offer, pasteboardType.c_str(), pipefd[1]); close(pipefd[1]); wl_display_roundtrip(ViewBackend::WaylandDisplay::singleton().display()); char buf[1024]; std::string readString; ssize_t length; do { length = read(pipefd[0], buf, 1024); readString.append(buf, length); } while (length > 0); close(pipefd[0]); return readString; }
const char* nsRetrievalContextWayland::GetClipboardData(const char* aMimeType, int32_t aWhichClipboard, uint32_t* aContentLength) { NS_ASSERTION(mDataOffer, "Requested data without valid data offer!"); if (!mDataOffer) { // TODO // Something went wrong. We're requested to provide clipboard data // but we haven't got any from wayland. Looks like rhbz#1455915. return nullptr; } int pipe_fd[2]; if (pipe(pipe_fd) == -1) return nullptr; wl_data_offer_receive(mDataOffer, aMimeType, pipe_fd[1]); close(pipe_fd[1]); wl_display_flush(mDisplay); struct pollfd fds; fds.fd = pipe_fd[0]; fds.events = POLLIN; // Choose some reasonable timeout here int ret = poll(&fds, 1, kClipboardTimeout / 1000); if (!ret || ret == -1) { close(pipe_fd[0]); return nullptr; } GIOChannel *channel = g_io_channel_unix_new(pipe_fd[0]); GError* error = nullptr; gchar *clipboardData = nullptr; gsize dataLength = 0; g_io_channel_set_encoding(channel, nullptr, &error); if (!error) { g_io_channel_read_to_end(channel, &clipboardData, &dataLength, &error); } if (error) { NS_WARNING( nsPrintfCString("Unexpected error when reading clipboard data: %s", error->message).get()); g_error_free(error); } g_io_channel_unref(channel); close(pipe_fd[0]); *aContentLength = dataLength; return reinterpret_cast<const char*>(clipboardData); }
static void data_device_handle_drop(void *data, struct wl_data_device *wl_data_device) { struct vo_wayland_state *wl = data; int pipefd[2]; if (pipe(pipefd) == -1) { MP_FATAL(wl, "can't create pipe for dnd communication\n"); return; } wl->input.dnd_fd = pipefd[0]; wl_data_offer_receive(wl->input.offer, "text/uri-list", pipefd[1]); close(pipefd[1]); }
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; if (!wayland_selection->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; } wl_data_offer_accept (wayland_selection->offer, _gdk_wayland_display_get_serial (GDK_WAYLAND_DISPLAY (display)), gdk_atom_name (target)); 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 *atoms = NULL; if (target == gdk_atom_intern_static_string ("TARGETS")) { gint i = 0; GList *l; natoms = g_list_length (wayland_selection->targets); atoms = g_new0 (GdkAtom, natoms); for (l = wayland_selection->targets; l; l = l->next) atoms[i++] = l->data; } else { g_unix_open_pipe (pipe_fd, FD_CLOEXEC, NULL); wl_data_offer_receive (wayland_selection->offer, gdk_atom_name (target), 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 (atoms) { /* Store directly the local atoms */ selection_buffer_append_data (buffer_data, atoms, natoms * sizeof (GdkAtom)); g_free (atoms); } g_hash_table_insert (wayland_selection->selection_buffers, GDK_ATOM_TO_POINTER (target), buffer_data); } if (!buffer_data->stream) selection_buffer_notify (buffer_data); }
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); }