Beispiel #1
0
gboolean
_gdk_wayland_display_set_selection_owner (GdkDisplay *display,
                                          GdkWindow  *owner,
                                          GdkAtom     selection,
                                          guint32     time,
                                          gboolean    send_event)
{
  GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);

  if (selection == atoms[ATOM_CLIPBOARD])
    {
      wayland_selection->clipboard_owner = owner;
      return TRUE;
    }
  else if (selection == atoms[ATOM_PRIMARY])
    {
      wayland_selection->primary_owner = owner;
      return TRUE;
    }
  else if (selection == atoms[ATOM_DND])
    {
      wayland_selection->dnd_owner = owner;
      return TRUE;
    }

  return FALSE;
}
Beispiel #2
0
void
gdk_wayland_selection_unset_data_source (GdkDisplay *display,
                                         GdkAtom     selection)
{
  GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);

  if (selection == atoms[ATOM_CLIPBOARD])
    {
      GdkDevice *device;

      device = gdk_seat_get_pointer (gdk_display_get_default_seat (display));

      gdk_wayland_device_set_selection (device, NULL);

      if (wayland_selection->clipboard_source)
        {
          wl_data_source_destroy (wayland_selection->clipboard_source);
          wayland_selection->clipboard_source = NULL;
        }
    }
  else if (selection == atoms[ATOM_DND])
    {
      wayland_selection->dnd_source = NULL;
    }
}
Beispiel #3
0
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);
    }
}
Beispiel #4
0
struct wl_data_offer *
gdk_wayland_selection_get_offer (GdkDisplay *display)
{
  GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);

  return selection->offer;
}
Beispiel #5
0
GList *
gdk_wayland_selection_get_targets (GdkDisplay *display)
{
  GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);

  return selection->targets;
}
Beispiel #6
0
void
gdk_wayland_selection_unset_data_source (GdkDisplay *display, GdkAtom selection)
{
  GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);

  if (selection == atoms[ATOM_CLIPBOARD])
    {
      GdkDeviceManager *device_manager;
      GdkDevice *device;

      device_manager = gdk_display_get_device_manager (display);
      device = gdk_device_manager_get_client_pointer (device_manager);

      gdk_wayland_device_set_selection (device, NULL);
      wayland_selection->clipboard_owner = NULL;

      if (wayland_selection->clipboard_source)
        {
          wl_data_source_destroy (wayland_selection->clipboard_source);
          wayland_selection->clipboard_source = NULL;
        }
    }
  else if (selection == atoms[ATOM_DND])
    {
      wayland_selection->dnd_owner = NULL;
      wayland_selection->dnd_source = NULL;
    }
}
Beispiel #7
0
struct wl_data_source *
gdk_wayland_selection_get_data_source (GdkWindow *owner,
                                       GdkAtom    selection)
{
  GdkDisplay *display = gdk_window_get_display (owner);
  GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
  struct wl_data_source *source = NULL;
  GdkWaylandDisplay *display_wayland;
  gboolean is_clipboard = FALSE;

  if (selection == atoms[ATOM_DND])
    {
      if (wayland_selection->dnd_source &&
          (!owner || owner == wayland_selection->dnd_owner))
        return wayland_selection->dnd_source;
    }
  else if (selection == atoms[ATOM_CLIPBOARD])
    {
      if (wayland_selection->clipboard_source &&
          (!owner || owner == wayland_selection->clipboard_owner))
        return wayland_selection->clipboard_source;

      if (wayland_selection->clipboard_source)
        {
          wl_data_source_destroy (wayland_selection->clipboard_source);
          wayland_selection->clipboard_source = NULL;
        }

      is_clipboard = TRUE;
    }
  else
    return NULL;

  if (!owner)
    return NULL;

  display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_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);

  if (is_clipboard)
    {
      wayland_selection->clipboard_source = source;
      wayland_selection->clipboard_owner = owner;
    }
  else
    {
      wayland_selection->dnd_source = source;
      wayland_selection->dnd_owner = owner;
    }

  return source;
}
Beispiel #8
0
void
gdk_wayland_selection_clear_targets (GdkDisplay *display,
                                     GdkAtom     selection)
{
  GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);

  wayland_selection->requested_target = GDK_NONE;
  g_array_set_size (wayland_selection->source_targets, 0);
  gdk_wayland_selection_unset_data_source (display, selection);
}
Beispiel #9
0
void
gdk_wayland_selection_store (GdkWindow    *window,
                             GdkAtom       type,
                             GdkPropMode   mode,
                             const guchar *data,
                             gint          len)
{
  GdkDisplay *display = gdk_window_get_display (window);
  GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
  GArray *array;

  if (type == gdk_atom_intern_static_string ("NULL"))
    return;

  array = g_array_new (TRUE, FALSE, sizeof (guchar));
  g_array_append_vals (array, data, len);

  if (selection->stored_selection.data)
    {
      if (mode != GDK_PROP_MODE_REPLACE &&
          type != selection->stored_selection.type)
        {
          gchar *type_str, *stored_str;

          type_str = gdk_atom_name (type);
          stored_str = gdk_atom_name (selection->stored_selection.type);

          g_warning (G_STRLOC ": Attempted to append/prepend selection data with "
                     "type %s into the current selection with type %s",
                     type_str, stored_str);
          g_free (type_str);
          g_free (stored_str);
          return;
        }

      /* In these cases we also replace the stored data, so we
       * apply the inverse operation into the just given data.
       */
      if (mode == GDK_PROP_MODE_APPEND)
        g_array_prepend_vals (array, selection->stored_selection.data,
                              selection->stored_selection.data_len - 1);
      else if (mode == GDK_PROP_MODE_PREPEND)
        g_array_append_vals (array, selection->stored_selection.data,
                             selection->stored_selection.data_len - 1);

      g_free (selection->stored_selection.data);
    }

  selection->stored_selection.source = window;
  selection->stored_selection.data_len = array->len;
  selection->stored_selection.data = (guchar *) g_array_free (array, FALSE);
  selection->stored_selection.type = type;

  gdk_wayland_selection_check_write (selection);
}
Beispiel #10
0
GdkWindow *
_gdk_wayland_display_get_selection_owner (GdkDisplay *display,
					  GdkAtom     selection)
{
  GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);

  if (selection == atoms[ATOM_CLIPBOARD])
    return wayland_selection->clipboard_owner;
  else if (selection == atoms[ATOM_DND])
    return wayland_selection->dnd_owner;

  return NULL;
}
Beispiel #11
0
GList *
gdk_wayland_selection_get_targets (GdkDisplay *display,
                                   GdkAtom     selection_atom)
{
  GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
  const SelectionData *data;

  data = selection_lookup_offer_by_atom (selection, selection_atom);

  if (data && data->offer)
    return data->offer->targets;

  return NULL;
}
Beispiel #12
0
GList *
gdk_wayland_selection_get_targets (GdkDisplay *display,
                                   GdkAtom     selection_atom)
{
  GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
  const DataOfferData *info;

  info = selection_lookup_offer_by_atom (selection, selection_atom);

  if (info)
    return info->targets;

  return NULL;
}
Beispiel #13
0
struct wl_data_offer *
gdk_wayland_selection_get_offer (GdkDisplay *display,
                                 GdkAtom     selection_atom)
{
  GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
  const DataOfferData *info;

  info = selection_lookup_offer_by_atom (selection, selection_atom);

  if (info)
    return info->offer;

  return NULL;
}
Beispiel #14
0
void
gdk_wayland_selection_add_targets (GdkWindow *window,
                                   GdkAtom    selection,
                                   guint      ntargets,
                                   GdkAtom   *targets)
{
  GdkDisplay *display = gdk_window_get_display (window);
  GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
  gpointer data_source;
  guint i;

  g_return_if_fail (GDK_IS_WINDOW (window));

  data_source = gdk_wayland_selection_get_data_source (window, selection);

  if (!data_source)
    return;

  g_array_append_vals (wayland_selection->source_targets, targets, ntargets);

  for (i = 0; i < ntargets; i++)
    {
      gchar *mimetype = gdk_atom_name (targets[i]);

      wl_data_source_offer (data_source, mimetype);
      g_free (mimetype);
    }

  if (selection == atoms[ATOM_CLIPBOARD])
    {
      GdkDisplay *display;
      GdkDevice *device;

      display = gdk_window_get_display (window);
      device = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
      gdk_wayland_device_set_selection (device, data_source);
    }
  else if (selection == atoms[ATOM_PRIMARY])
    {
      GdkSeat *seat;

      seat = gdk_display_get_default_seat (display);
      gdk_wayland_seat_set_primary (seat, data_source);
    }
}
Beispiel #15
0
static SelectionBuffer *
gdk_wayland_selection_lookup_requestor_buffer (GdkWindow *requestor)
{
  GdkDisplay *display = gdk_window_get_display (requestor);
  GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
  SelectionBuffer *buffer_data;
  GHashTableIter iter;

  g_hash_table_iter_init (&iter, selection->selection_buffers);

  while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &buffer_data))
    {
      if (g_list_find (buffer_data->requestors, requestor))
        return buffer_data;
    }

  return NULL;
}
Beispiel #16
0
void
gdk_wayland_selection_ensure_offer (GdkDisplay           *display,
                                    struct wl_data_offer *wl_offer)
{
  GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
  DataOfferData *info;

  info = g_hash_table_lookup (selection->offers, wl_offer);

  if (!info)
    {
      info = data_offer_data_new (wl_offer);
      g_hash_table_insert (selection->offers, wl_offer, info);
      wl_data_offer_add_listener (wl_offer,
                                  &data_offer_listener,
                                  selection);
    }
}
Beispiel #17
0
void
gdk_wayland_selection_ensure_primary_offer (GdkDisplay                         *display,
                                            struct gtk_primary_selection_offer *gtk_offer)
{
  GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
  DataOfferData *info;

  info = g_hash_table_lookup (selection->offers, gtk_offer);

  if (!info)
    {
      info = data_offer_data_new (gtk_offer,
                                  (GDestroyNotify) gtk_primary_selection_offer_destroy);
      g_hash_table_insert (selection->offers, gtk_offer, info);
      gtk_primary_selection_offer_add_listener (gtk_offer,
                                                &primary_offer_listener,
                                                selection);
    }
}
Beispiel #18
0
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);
}
Beispiel #19
0
void
gdk_wayland_selection_set_offer (GdkDisplay           *display,
                                 struct wl_data_offer *wl_offer)
{
  GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);

  if (selection->offer == wl_offer)
    return;

  if (selection->offer)
    wl_data_offer_destroy (selection->offer);

  selection->offer = wl_offer;

  if (wl_offer)
    wl_data_offer_add_listener (wl_offer,
                                &data_offer_listener,
                                selection);

  /* Clear all buffers */
  g_hash_table_remove_all (selection->selection_buffers);
  g_list_free (selection->targets);
  selection->targets = NULL;
}
Beispiel #20
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);
}
Beispiel #21
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);
}
Beispiel #22
0
struct wl_data_source *
gdk_wayland_selection_get_data_source (GdkWindow *owner,
                                       GdkAtom    selection)
{
  GdkDisplay *display = gdk_window_get_display (owner);
  GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
  gpointer source = NULL;
  GdkWaylandDisplay *display_wayland;

  if (selection == atoms[ATOM_DND])
    {
      if (wayland_selection->dnd_source &&
          (!owner || owner == wayland_selection->dnd_owner))
        return wayland_selection->dnd_source;
    }
  else if (selection == atoms[ATOM_PRIMARY])
    {
      if (wayland_selection->primary_source &&
          (!owner || owner == wayland_selection->primary_owner))
        return (gpointer) wayland_selection->primary_source;

      if (wayland_selection->primary_source)
        {
          gtk_primary_selection_source_destroy (wayland_selection->primary_source);
          wayland_selection->primary_source = NULL;
        }
    }
  else if (selection == atoms[ATOM_CLIPBOARD])
    {
      if (wayland_selection->clipboard_source &&
          (!owner || owner == wayland_selection->clipboard_owner))
        return wayland_selection->clipboard_source;

      if (wayland_selection->clipboard_source)
        {
          wl_data_source_destroy (wayland_selection->clipboard_source);
          wayland_selection->clipboard_source = NULL;
        }
    }
  else
    return NULL;

  if (!owner)
    return NULL;

  display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (owner));

  if (selection == atoms[ATOM_PRIMARY])
    {
      if (display_wayland->primary_selection_manager)
        {
          source = gtk_primary_selection_device_manager_create_source (display_wayland->primary_selection_manager);
          gtk_primary_selection_source_add_listener (source,
                                                     &primary_source_listener,
                                                     wayland_selection);
        }
    }
  else
    {
      source = wl_data_device_manager_create_data_source (display_wayland->data_device_manager);
      wl_data_source_add_listener (source,
                                   &data_source_listener,
                                   wayland_selection);
    }

  if (selection == atoms[ATOM_DND])
    wayland_selection->dnd_source = source;
  else if (selection == atoms[ATOM_PRIMARY])
    wayland_selection->primary_source = source;
  else if (selection == atoms[ATOM_CLIPBOARD])
    wayland_selection->clipboard_source = source;

  return source;
}