void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixed_t y)
{
    Q_UNUSED(time);

    QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag();

    if (!drag && !m_dragOffer)
        return;

    m_dragPoint = QPoint(wl_fixed_to_int(x), wl_fixed_to_int(y));

    QMimeData *dragData;
    Qt::DropActions supportedActions;
    if (drag) {
        dragData = drag->mimeData();
        supportedActions = drag->supportedActions();
    } else {
        dragData = m_dragOffer->mimeData();
        supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
    }

    QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions);

    if (drag) {
        static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response);
    } else {
        if (response.isAccepted()) {
            wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, m_dragOffer->firstFormat().toUtf8().constData());
        } else {
            wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, 0);
        }
    }
}
void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, wl_fixed_t x, wl_fixed_t y, wl_data_offer *id)
{
    m_enterSerial = serial;
    m_dragWindow = QWaylandWindow::fromWlSurface(surface)->window();
    m_dragPoint = QPoint(wl_fixed_to_int(x), wl_fixed_to_int(y));

    QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag();

    QMimeData *dragData;
    Qt::DropActions supportedActions;
    if (drag) {
        dragData = drag->mimeData();
        supportedActions = drag->supportedActions();
    } else {
        m_dragOffer.reset(static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id)));
        if (m_dragOffer) {
            dragData = m_dragOffer->mimeData();
            supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
        }
    }

    const QPlatformDragQtResponse &response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions);

    if (drag) {
        static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response);
    } else {
        if (response.isAccepted()) {
            wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, m_dragOffer->firstFormat().toUtf8().constData());
        } else {
            wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, 0);
        }
    }
}
示例#3
0
static void
data_device_handle_enter(void *data, struct wl_data_device *wl_data_device,
		                 uint32_t serial, struct wl_surface *surface,
                         wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id)
{
    SDL_WaylandDataDevice *data_device = data;
    SDL_bool has_mime = SDL_FALSE;
    uint32_t dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; 
        
    data_device->drag_serial = serial;

    if (id != NULL) {
        data_device->drag_offer = wl_data_offer_get_user_data(id);

        /* TODO: SDL Support more mime types */
        has_mime = Wayland_data_offer_has_mime(
            data_device->drag_offer, FILE_MIME);

        /* If drag_mime is NULL this will decline the offer */
        wl_data_offer_accept(id, serial,
                             (has_mime == SDL_TRUE) ? FILE_MIME : NULL);

        /* SDL only supports "copy" style drag and drop */
        if (has_mime == SDL_TRUE) {
            dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
        }
        wl_data_offer_set_actions(data_device->drag_offer->offer,
                                  dnd_action, dnd_action);
    }
}
示例#4
0
文件: wayland_common.c 项目: mixi/mpv
static void data_device_handle_enter(void *data,
                                     struct wl_data_device *wl_data_device,
                                     uint32_t serial,
                                     struct wl_surface *surface,
                                     wl_fixed_t x,
                                     wl_fixed_t y,
                                     struct wl_data_offer *id)
{
    struct vo_wayland_state *wl = data;
    if (wl->input.offer != id)
        MP_FATAL(wl, "Fatal dnd error (Please report this issue)\n");

    wl_data_offer_accept(id, serial, "text/uri-list");
}
示例#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);
  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);
}
示例#6
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);
}