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;
}
예제 #2
0
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);
}
예제 #3
0
파일: wayland_common.c 프로젝트: mixi/mpv
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]);
}
예제 #4
0
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);
}
예제 #5
0
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);
}