[gtk+] gdkdnd: Make GdkDragContext->formats a GdkContentFormats



commit d6a209816bacff89e361a580b24e847dca0bdef5
Author: Benjamin Otte <otte redhat com>
Date:   Sat Nov 18 05:53:25 2017 +0100

    gdkdnd: Make GdkDragContext->formats a GdkContentFormats
    
    Instead of it being a GList of GdkAtoms.

 docs/reference/gdk/gdk4-sections.txt |    4 +-
 gdk/broadway/gdkdnd-broadway.c       |   10 ++--
 gdk/broadway/gdkprivate-broadway.h   |   10 ++--
 gdk/gdkcontentformats.c              |   71 +++++++++++++++++------
 gdk/gdkcontentformats.h              |    9 ++-
 gdk/gdkdnd.c                         |   19 +++---
 gdk/gdkdnd.h                         |   24 ++++----
 gdk/gdkdndprivate.h                  |    2 +-
 gdk/gdkwindow.c                      |   31 +++++------
 gdk/gdkwindowimpl.h                  |   10 ++--
 gdk/wayland/gdkdnd-wayland.c         |   50 ++++++++++------
 gdk/wayland/gdkprivate-wayland.h     |   16 +++---
 gdk/wayland/gdkselection-wayland.c   |   36 +++++-------
 gdk/x11/gdkdnd-x11.c                 |  106 ++++++++++++++--------------------
 gdk/x11/gdkprivate-x11.h             |   10 ++--
 gtk/gtkdnd.c                         |   13 +----
 gtk/gtkdragdest.c                    |   15 +----
 gtk/gtktextview.c                    |   17 ++----
 tests/testdnd.c                      |   22 +++----
 19 files changed, 234 insertions(+), 241 deletions(-)
---
diff --git a/docs/reference/gdk/gdk4-sections.txt b/docs/reference/gdk/gdk4-sections.txt
index 2f55e16..2752f03 100644
--- a/docs/reference/gdk/gdk4-sections.txt
+++ b/docs/reference/gdk/gdk4-sections.txt
@@ -373,6 +373,8 @@ gdk_fullscreen_mode_get_type
 gdk_content_formats_new
 gdk_content_formats_ref
 gdk_content_formats_unref
+gdk_content_formats_print
+gdk_content_formats_to_string
 gdk_content_formats_add
 gdk_content_formats_union
 gdk_content_formats_intersects
@@ -865,7 +867,7 @@ gdk_window_get_drag_protocol
 gdk_drag_context_get_actions
 gdk_drag_context_get_suggested_action
 gdk_drag_context_get_selected_action
-gdk_drag_context_list_targets
+gdk_drag_context_get_formats
 gdk_drag_context_get_device
 gdk_drag_context_set_device
 gdk_drag_context_get_source_window
diff --git a/gdk/broadway/gdkdnd-broadway.c b/gdk/broadway/gdkdnd-broadway.c
index d280a26..ebb3679 100644
--- a/gdk/broadway/gdkdnd-broadway.c
+++ b/gdk/broadway/gdkdnd-broadway.c
@@ -84,11 +84,11 @@ gdk_broadway_drag_context_finalize (GObject *object)
 /* Drag Contexts */
 
 GdkDragContext *
-_gdk_broadway_window_drag_begin (GdkWindow *window,
-                                GdkDevice *device,
-                                GList     *targets,
-                                 gint       x_root,
-                                 gint       y_root)
+_gdk_broadway_window_drag_begin (GdkWindow         *window,
+                                GdkDevice         *device,
+                                GdkContentFormats *formats,
+                                 gint               x_root,
+                                 gint               y_root)
 {
   GdkDragContext *new_context;
 
diff --git a/gdk/broadway/gdkprivate-broadway.h b/gdk/broadway/gdkprivate-broadway.h
index 30adbfe..8df551d 100644
--- a/gdk/broadway/gdkprivate-broadway.h
+++ b/gdk/broadway/gdkprivate-broadway.h
@@ -40,11 +40,11 @@
 void _gdk_broadway_resync_windows (void);
 
 void     _gdk_broadway_window_register_dnd (GdkWindow      *window);
-GdkDragContext * _gdk_broadway_window_drag_begin (GdkWindow *window,
-                                                 GdkDevice *device,
-                                                 GList     *targets,
-                                                  gint       x_root,
-                                                  gint       y_root);
+GdkDragContext * _gdk_broadway_window_drag_begin (GdkWindow         *window,
+                                                 GdkDevice         *device,
+                                                 GdkContentFormats *formats,
+                                                  gint               x_root,
+                                                  gint               y_root);
 void     _gdk_broadway_window_translate         (GdkWindow *window,
                                                 cairo_region_t *area,
                                                 gint       dx,
diff --git a/gdk/gdkcontentformats.c b/gdk/gdkcontentformats.c
index 78fab2e..c3cd9cd 100644
--- a/gdk/gdkcontentformats.c
+++ b/gdk/gdkcontentformats.c
@@ -150,6 +150,59 @@ gdk_content_formats_unref (GdkContentFormats *formats)
 }
 
 /**
+ * gdk_content_formats_print:
+ * @formats: a #GdkContentFormats
+ * @string: a #GString to print into
+ *
+ * Prints the given @formats into a string for human consumption.
+ * This is meant for debugging and logging.
+ *
+ * The form of the representation may change at any time and is
+ * not guranteed to stay identical.
+ **/
+void
+gdk_content_formats_print (GdkContentFormats *formats,
+                           GString           *string)
+{
+  GList *l;
+
+  g_return_if_fail (formats != NULL);
+  g_return_if_fail (string != NULL);
+
+  g_string_append (string, "{ ");
+  for (l = formats->formats; l; l = l->next)
+    {
+      if (l != formats->formats)
+        g_string_append (string, ", ");
+      g_string_append (string, l->data);
+    }
+  g_string_append (string, " }");
+}
+
+/**
+ * gdk_content_formats_to_string:
+ * @formats: a #GdkContentFormats
+ *
+ * Prints the given @formats into a human-readable string.
+ * This is a small wrapper around gdk_content_formats_print() to help
+ * when debugging.
+ *
+ * Returns: (transfer full): a new string
+ **/
+char *
+gdk_content_formats_to_string (GdkContentFormats *formats)
+{
+  GString *string;
+
+  g_return_val_if_fail (formats != NULL, NULL);
+
+  string = g_string_new (NULL);
+  gdk_content_formats_print (formats, string);
+
+  return g_string_free (string, FALSE);
+}
+
+/**
  * gdk_content_formats_add:
  * @formats:  a #GdkContentFormats
  * @mime_type: the mime type to add
@@ -218,24 +271,6 @@ gdk_content_formats_intersects (const GdkContentFormats *first,
 }
 
 /**
- * gdk_content_formats_remove:
- * @formats: a #GdkContentFormats
- * @mime_type: the mime type
- * 
- * Removes a mime type. If the mime type was not part of @formats, nothing
- * happens.
- **/
-void 
-gdk_content_formats_remove (GdkContentFormats *formats,
-                            const char        *mime_type)
-{
-  g_return_if_fail (formats != NULL);
-  g_return_if_fail (mime_type != NULL);
-
-  formats->formats = g_list_remove (formats->formats, (gpointer) gdk_atom_intern (mime_type, FALSE));
-}
-
-/**
  * gdk_content_formats_contains:
  * @formats: a #GdkContentFormats
  * @mime_type: the mime type to search for
diff --git a/gdk/gdkcontentformats.h b/gdk/gdkcontentformats.h
index 8859658..f73c5b4 100644
--- a/gdk/gdkcontentformats.h
+++ b/gdk/gdkcontentformats.h
@@ -41,6 +41,12 @@ GDK_AVAILABLE_IN_3_94
 void                    gdk_content_formats_unref               (GdkContentFormats              *formats);
 
 GDK_AVAILABLE_IN_3_94
+void                    gdk_content_formats_print               (GdkContentFormats              *formats,
+                                                                 GString                        *string);
+GDK_AVAILABLE_IN_3_94
+char *                  gdk_content_formats_to_string           (GdkContentFormats              *formats);
+
+GDK_AVAILABLE_IN_3_94
 void                    gdk_content_formats_union               (GdkContentFormats              *first,
                                                                  const GdkContentFormats        *second);
 GDK_AVAILABLE_IN_3_94
@@ -50,9 +56,6 @@ GDK_AVAILABLE_IN_3_94
 void                    gdk_content_formats_add                 (GdkContentFormats              *formats,
                                                                  const char                     *mime_type);
 GDK_AVAILABLE_IN_3_94
-void                    gdk_content_formats_remove              (GdkContentFormats              *formats,
-                                                                 const char                     *mime_type);
-GDK_AVAILABLE_IN_3_94
 gboolean                gdk_content_formats_contains            (const GdkContentFormats        *formats,
                                                                  const char                     *mime_type);
 
diff --git a/gdk/gdkdnd.c b/gdk/gdkdnd.c
index 19712fd..7b9638d 100644
--- a/gdk/gdkdnd.c
+++ b/gdk/gdkdnd.c
@@ -28,8 +28,9 @@
 #include "gdkdisplay.h"
 #include "gdkwindow.h"
 #include "gdkintl.h"
-#include "gdkenumtypes.h"
+#include "gdkcontentformats.h"
 #include "gdkcursor.h"
+#include "gdkenumtypes.h"
 #include "gdkeventsprivate.h"
 
 static struct {
@@ -73,21 +74,21 @@ static GList *contexts = NULL;
  */
 
 /**
- * gdk_drag_context_list_targets:
+ * gdk_drag_context_get_formats:
  * @context: a #GdkDragContext
  *
- * Retrieves the list of targets of the context.
+ * Retrieves the formats supported by this context.
  *
- * Returns: (transfer none) (element-type GdkAtom): a #GList of targets
+ * Returns: (transfer none): a #GdkContentFormats
  *
- * Since: 2.22
+ * Since: 3.94
  **/
-GList *
-gdk_drag_context_list_targets (GdkDragContext *context)
+GdkContentFormats *
+gdk_drag_context_get_formats (GdkDragContext *context)
 {
   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
 
-  return context->targets;
+  return context->formats;
 }
 
 /**
@@ -253,7 +254,7 @@ gdk_drag_context_finalize (GObject *object)
   GdkDragContext *context = GDK_DRAG_CONTEXT (object);
 
   contexts = g_list_remove (contexts, context);
-  g_list_free (context->targets);
+  g_clear_pointer (&context->formats, gdk_content_formats_unref);
 
   if (context->source_window)
     g_object_unref (context->source_window);
diff --git a/gdk/gdkdnd.h b/gdk/gdkdnd.h
index a8b6266..b86bc7b 100644
--- a/gdk/gdkdnd.h
+++ b/gdk/gdkdnd.h
@@ -117,8 +117,8 @@ void             gdk_drag_context_set_device           (GdkDragContext *context,
 GDK_AVAILABLE_IN_ALL
 GdkDevice *      gdk_drag_context_get_device           (GdkDragContext *context);
 
-GDK_AVAILABLE_IN_ALL
-GList           *gdk_drag_context_list_targets         (GdkDragContext *context);
+GDK_AVAILABLE_IN_3_94
+GdkContentFormats *gdk_drag_context_get_formats        (GdkDragContext *context);
 GDK_AVAILABLE_IN_ALL
 GdkDragAction    gdk_drag_context_get_actions          (GdkDragContext *context);
 GDK_AVAILABLE_IN_ALL
@@ -153,19 +153,19 @@ GdkAtom          gdk_drag_get_selection (GdkDragContext   *context);
 /* Source side */
 
 GDK_AVAILABLE_IN_ALL
-GdkDragContext * gdk_drag_begin            (GdkWindow      *window,
-                                            GList          *targets);
+GdkDragContext *        gdk_drag_begin                  (GdkWindow              *window,
+                                                         GdkContentFormats      *formats);
 
 GDK_AVAILABLE_IN_ALL
-GdkDragContext * gdk_drag_begin_for_device (GdkWindow      *window,
-                                            GdkDevice      *device,
-                                            GList          *targets);
+GdkDragContext *        gdk_drag_begin_for_device       (GdkWindow              *window,
+                                                         GdkDevice              *device,
+                                                         GdkContentFormats      *formats);
 GDK_AVAILABLE_IN_3_20
-GdkDragContext * gdk_drag_begin_from_point  (GdkWindow      *window,
-                                             GdkDevice      *device,
-                                             GList          *targets,
-                                             gint            x_root,
-                                             gint            y_root);
+GdkDragContext *        gdk_drag_begin_from_point       (GdkWindow              *window,
+                                                         GdkDevice              *device,
+                                                         GdkContentFormats      *formats,
+                                                         gint                    x_root,
+                                                         gint                    y_root);
 
 GDK_AVAILABLE_IN_ALL
 void    gdk_drag_find_window (GdkDragContext   *context,
diff --git a/gdk/gdkdndprivate.h b/gdk/gdkdndprivate.h
index ad2b507..bf0ab8b 100644
--- a/gdk/gdkdndprivate.h
+++ b/gdk/gdkdndprivate.h
@@ -100,7 +100,7 @@ struct _GdkDragContext {
   GdkWindow *dest_window;
   GdkWindow *drag_window;
 
-  GList *targets;
+  GdkContentFormats *formats;
   GdkDragAction actions;
   GdkDragAction suggested_action;
   GdkDragAction action;
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 1fbd5d0..edb7d77 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -7092,8 +7092,7 @@ gdk_window_get_drag_protocol (GdkWindow  *window,
 /**
  * gdk_drag_begin:
  * @window: the source window for this drag.
- * @targets: (transfer none) (element-type GdkAtom): the offered targets,
- *     as list of #GdkAtoms
+ * @formats: (transfer none): the offered formats
  *
  * Starts a drag and creates a new drag context for it.
  * This function assumes that the drag is controlled by the
@@ -7105,8 +7104,8 @@ gdk_window_get_drag_protocol (GdkWindow  *window,
  * Returns: (transfer full): a newly created #GdkDragContext
  */
 GdkDragContext *
-gdk_drag_begin (GdkWindow     *window,
-                GList         *targets)
+gdk_drag_begin (GdkWindow         *window,
+                GdkContentFormats *formats)
 {
   GdkDisplay *display;
   GdkDevice *device;
@@ -7114,15 +7113,14 @@ gdk_drag_begin (GdkWindow     *window,
   display = gdk_window_get_display (window);
   device = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
 
-  return gdk_drag_begin_for_device (window, device, targets);
+  return gdk_drag_begin_for_device (window, device, formats);
 }
 
 /**
  * gdk_drag_begin_for_device:
  * @window: the source window for this drag
  * @device: the device that controls this drag
- * @targets: (transfer none) (element-type GdkAtom): the offered targets,
- *     as list of #GdkAtoms
+ * @formats: (transfer none): the offered formats
  *
  * Starts a drag and creates a new drag context for it.
  *
@@ -7133,21 +7131,20 @@ gdk_drag_begin (GdkWindow     *window,
 GdkDragContext *
 gdk_drag_begin_for_device (GdkWindow *window,
                            GdkDevice *device,
-                           GList     *targets)
+                           GdkContentFormats *formats)
 {
   gint x, y;
 
   gdk_device_get_position (device, &x, &y);
 
-  return gdk_drag_begin_from_point (window, device, targets, x, y);
+  return gdk_drag_begin_from_point (window, device, formats, x, y);
 }
 
 /**
  * gdk_drag_begin_from_point:
  * @window: the source window for this drag
  * @device: the device that controls this drag
- * @targets: (transfer none) (element-type GdkAtom): the offered targets,
- *     as list of #GdkAtoms
+ * @formats: (transfer none): the offered formats
  * @x_root: the x coordinate where the drag nominally started
  * @y_root: the y coordinate where the drag nominally started
  *
@@ -7160,13 +7157,13 @@ gdk_drag_begin_for_device (GdkWindow *window,
  * Since: 3.20
  */
 GdkDragContext *
-gdk_drag_begin_from_point (GdkWindow *window,
-                           GdkDevice *device,
-                           GList     *targets,
-                           gint       x_root,
-                           gint       y_root)
+gdk_drag_begin_from_point (GdkWindow         *window,
+                           GdkDevice         *device,
+                           GdkContentFormats *formats,
+                           gint               x_root,
+                           gint               y_root)
 {
-  return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->drag_begin (window, device, targets, x_root, y_root);
+  return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->drag_begin (window, device, formats, x_root, y_root);
 }
 
 /**
diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h
index 2477ad6..8c15aeb 100644
--- a/gdk/gdkwindowimpl.h
+++ b/gdk/gdkwindowimpl.h
@@ -219,11 +219,11 @@ struct _GdkWindowImplClass
   GdkDragProtocol (* get_drag_protocol) (GdkWindow *window,
                                          GdkWindow **target);
   void         (* register_dnd)         (GdkWindow *window);
-  GdkDragContext * (*drag_begin)        (GdkWindow *window,
-                                         GdkDevice *device,
-                                         GList     *targets,
-                                         gint       x_root,
-                                         gint       y_root);
+  GdkDragContext * (*drag_begin)        (GdkWindow        *window,
+                                         GdkDevice        *device,
+                                         GdkContentFormats *formats,
+                                         gint              x_root,
+                                         gint              y_root);
 
   void         (*process_updates_recurse) (GdkWindow      *window,
                                            cairo_region_t *region);
diff --git a/gdk/wayland/gdkdnd-wayland.c b/gdk/wayland/gdkdnd-wayland.c
index dd7cdaa..fb66870 100644
--- a/gdk/wayland/gdkdnd-wayland.c
+++ b/gdk/wayland/gdkdnd-wayland.c
@@ -22,6 +22,7 @@
 #include "gdkinternals.h"
 #include "gdkproperty.h"
 #include "gdkprivate-wayland.h"
+#include "gdkcontentformatsprivate.h"
 #include "gdkdisplay-wayland.h"
 #include "gdkseat-wayland.h"
 
@@ -239,22 +240,26 @@ gdk_wayland_drop_context_set_status (GdkDragContext *context,
 
   if (accepted)
     {
-      GList *l;
-
-      for (l = context->targets; l; l = l->next)
+      GdkAtom *atoms;
+      guint i, n_atoms;
+      
+      atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms);
+      for (i = 0; i < n_atoms; i++)
         {
-          if (l->data != gdk_atom_intern_static_string ("DELETE"))
+          if (atoms[i] != gdk_atom_intern_static_string ("DELETE"))
             break;
         }
 
-      if (l)
+      if (i < n_atoms)
         {
-          gchar *mimetype = gdk_atom_name (l->data);
+          gchar *mimetype = gdk_atom_name (atoms[i]);
 
           wl_data_offer_accept (wl_offer, context_wayland->serial, mimetype);
-          g_free (mimetype);
+          g_free (atoms);
           return;
         }
+      
+      g_free (atoms);
     }
 
   wl_data_offer_accept (wl_offer, context_wayland->serial, NULL);
@@ -508,22 +513,23 @@ create_dnd_window (GdkDisplay *display)
 }
 
 GdkDragContext *
-_gdk_wayland_window_drag_begin (GdkWindow *window,
-                               GdkDevice *device,
-                               GList     *targets,
-                                gint       x_root,
-                                gint       y_root)
+_gdk_wayland_window_drag_begin (GdkWindow         *window,
+                               GdkDevice         *device,
+                               GdkContentFormats *formats,
+                                gint               x_root,
+                                gint               y_root)
 {
   GdkWaylandDragContext *context_wayland;
   GdkDragContext *context;
-  GList *l;
+  GdkAtom *atoms;
+  guint i, n_atoms;
 
   context_wayland = g_object_new (GDK_TYPE_WAYLAND_DRAG_CONTEXT, NULL);
   context = GDK_DRAG_CONTEXT (context_wayland);
   context->display = gdk_window_get_display (window);
   context->source_window = g_object_ref (window);
   context->is_source = TRUE;
-  context->targets = g_list_copy (targets);
+  context->formats = gdk_content_formats_ref (formats);
 
   gdk_drag_context_set_device (context, device);
 
@@ -533,13 +539,15 @@ _gdk_wayland_window_drag_begin (GdkWindow *window,
     gdk_wayland_selection_get_data_source (window,
                                            gdk_wayland_drag_context_get_selection (context));
 
-  for (l = context->targets; l; l = l->next)
+  atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms);
+  for (i = 0; i < n_atoms; i++)
     {
-      gchar *mimetype = gdk_atom_name (l->data);
+      gchar *mimetype = gdk_atom_name (atoms[i]);
 
       wl_data_source_offer (context_wayland->data_source, mimetype);
       g_free (mimetype);
     }
+  g_free (atoms);
 
   return context;
 }
@@ -567,9 +575,13 @@ gdk_wayland_drop_context_update_targets (GdkDragContext *context)
 
   device = gdk_drag_context_get_device (context);
   display = gdk_device_get_display (device);
-  g_list_free (context->targets);
-  context->targets = g_list_copy (gdk_wayland_selection_get_targets (display,
-                                                                     gdk_drag_get_selection (context)));
+  gdk_content_formats_unref (context->formats);
+  context->formats = gdk_wayland_selection_get_targets (display,
+                                                        gdk_drag_get_selection (context));
+  if (context->formats)
+    gdk_content_formats_ref (context->formats);
+  else
+    context->formats = gdk_content_formats_new (NULL, 0);
 }
 
 void
diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index 48282fd..f987ddb 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -92,12 +92,12 @@ void       gdk_wayland_window_sync (GdkWindow *window);
 GdkDragProtocol _gdk_wayland_window_get_drag_protocol (GdkWindow *window,
                                                       GdkWindow **target);
 
-void            _gdk_wayland_window_register_dnd (GdkWindow *window);
-GdkDragContext *_gdk_wayland_window_drag_begin (GdkWindow *window,
-                                               GdkDevice *device,
-                                               GList     *targets,
-                                                gint       x_root,
-                                                gint       y_root);
+void            _gdk_wayland_window_register_dnd          (GdkWindow *window);
+GdkDragContext *_gdk_wayland_window_drag_begin            (GdkWindow *window,
+                                                          GdkDevice *device,
+                                                          GdkContentFormats *formats,
+                                                           gint       x_root,
+                                                           gint       y_root);
 void            _gdk_wayland_window_offset_next_wl_buffer (GdkWindow *window,
                                                            int        x,
                                                            int        y);
@@ -238,8 +238,8 @@ void gdk_wayland_selection_set_offer (GdkDisplay           *display,
                                       gpointer              offer);
 gpointer gdk_wayland_selection_get_offer (GdkDisplay *display,
                                           GdkAtom     selection);
-GList * gdk_wayland_selection_get_targets (GdkDisplay *display,
-                                           GdkAtom     selection);
+GdkContentFormats *gdk_wayland_selection_get_targets (GdkDisplay *display,
+                                                      GdkAtom     selection);
 
 void     gdk_wayland_selection_store   (GdkWindow    *window,
                                         GdkAtom       type,
diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c
index 2d402fc..4b2acf8 100644
--- a/gdk/wayland/gdkselection-wayland.c
+++ b/gdk/wayland/gdkselection-wayland.c
@@ -27,6 +27,7 @@
 #include "gdkwayland.h"
 #include "gdkprivate-wayland.h"
 #include "gdkdisplay-wayland.h"
+#include "gdkcontentformatsprivate.h"
 #include "gdkdndprivate.h"
 #include "gdkselection.h"
 #include "gdkproperty.h"
@@ -70,7 +71,7 @@ struct _DataOfferData
 {
   GDestroyNotify destroy_notify;
   gpointer offer_data;
-  GList *targets; /* List of GdkAtom */
+  GdkContentFormats *targets;
 };
 
 struct _AsyncWriteData
@@ -295,6 +296,7 @@ data_offer_data_new (gpointer       offer,
   info = g_slice_new0 (DataOfferData);
   info->offer_data = offer;
   info->destroy_notify = destroy_notify;
+  info->targets = gdk_content_formats_new (NULL, 0);
 
   return info;
 }
@@ -303,7 +305,7 @@ static void
 data_offer_data_free (DataOfferData *info)
 {
   info->destroy_notify (info->offer_data);
-  g_list_free (info->targets);
+  gdk_content_formats_unref (info->targets);
   g_slice_free (DataOfferData, info);
 }
 
@@ -373,17 +375,16 @@ data_offer_offer (void                 *data,
 {
   GdkWaylandSelection *selection = data;
   DataOfferData *info;
-  GdkAtom atom = gdk_atom_intern (type, FALSE);
 
   info = g_hash_table_lookup (selection->offers, wl_data_offer);
 
-  if (!info || g_list_find (info->targets, GDK_ATOM_TO_POINTER (atom)))
+  if (!info || gdk_content_formats_contains (info->targets, type))
     return;
 
   GDK_NOTE (EVENTS,
             g_message ("data offer offer, offer %p, type = %s", wl_data_offer, type));
 
-  info->targets = g_list_prepend (info->targets, GDK_ATOM_TO_POINTER (atom));
+  gdk_content_formats_add (info->targets, type);
 }
 
 static inline GdkDragAction
@@ -461,17 +462,16 @@ primary_offer_offer (void                               *data,
 {
   GdkWaylandSelection *selection = data;
   DataOfferData *info;
-  GdkAtom atom = gdk_atom_intern (type, FALSE);
 
   info = g_hash_table_lookup (selection->offers, gtk_offer);
 
-  if (!info || g_list_find (info->targets, GDK_ATOM_TO_POINTER (atom)))
+  if (!info || gdk_content_formats_contains (info->targets, type))
     return;
 
   GDK_NOTE (EVENTS,
             g_message ("primary offer offer, offer %p, type = %s", gtk_offer, type));
 
-  info->targets = g_list_prepend (info->targets, GDK_ATOM_TO_POINTER (atom));
+  gdk_content_formats_add (info->targets, type);
 }
 
 static const struct gtk_primary_selection_offer_listener primary_offer_listener = {
@@ -574,7 +574,7 @@ gdk_wayland_selection_get_offer (GdkDisplay *display,
   return NULL;
 }
 
-GList *
+GdkContentFormats *
 gdk_wayland_selection_get_targets (GdkDisplay *display,
                                    GdkAtom     selection_atom)
 {
@@ -1289,14 +1289,14 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display,
   SelectionBuffer *buffer_data;
   gpointer offer;
   gchar *mimetype;
-  GList *target_list;
+  GdkContentFormats *formats;
 
   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);
+  formats = gdk_wayland_selection_get_targets (display, selection);
 
   if (!offer || target == gdk_atom_intern_static_string ("DELETE"))
     {
@@ -1308,7 +1308,7 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display,
 
   if (target != gdk_atom_intern_static_string ("TARGETS"))
     {
-      if (!g_list_find (target_list, GDK_ATOM_TO_POINTER (target)))
+      if (!gdk_content_formats_contains (formats, GDK_ATOM_TO_POINTER (target)))
         {
           emit_empty_selection_notify (requestor, selection, target);
           return;
@@ -1327,19 +1327,13 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display,
   else
     {
       GInputStream *stream = NULL;
-      int pipe_fd[2], natoms = 0;
+      int pipe_fd[2];
+      guint 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;
+          targets = gdk_content_formats_get_atoms (formats, &natoms);
         }
       else
         {
diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c
index 4c246fd..82bb861 100644
--- a/gdk/x11/gdkdnd-x11.c
+++ b/gdk/x11/gdkdnd-x11.c
@@ -30,6 +30,7 @@
 
 #include "gdkinternals.h"
 #include "gdkasync.h"
+#include "gdkcontentformatsprivate.h"
 #include "gdkproperty.h"
 #include "gdkprivate-x11.h"
 #include "gdkscreen-x11.h"
@@ -336,23 +337,18 @@ gdk_drag_context_find (GdkDisplay *display,
 static void
 precache_target_list (GdkDragContext *context)
 {
-  if (context->targets)
+  if (context->formats)
     {
-      GPtrArray *targets = g_ptr_array_new ();
-      GList *tmp_list;
-      int i;
+      GdkAtom *atoms;
+      guint n_atoms;
 
-      for (tmp_list = context->targets; tmp_list; tmp_list = tmp_list->next)
-        g_ptr_array_add (targets, gdk_atom_name (GDK_POINTER_TO_ATOM (tmp_list->data)));
+      atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms);
 
       _gdk_x11_precache_atoms (GDK_WINDOW_DISPLAY (context->source_window),
-                               (const gchar **)targets->pdata,
-                               targets->len);
+                               (const gchar **) atoms,
+                               n_atoms);
 
-      for (i =0; i < targets->len; i++)
-        g_free (targets->pdata[i]);
-
-      g_ptr_array_free (targets, TRUE);
+      g_free (atoms);
     }
 }
 
@@ -854,15 +850,11 @@ get_client_window_at_coords (GdkWindowCache *cache,
 
 #ifdef G_ENABLE_DEBUG
 static void
-print_target_list (GList *targets)
+print_target_list (GdkContentFormats *formats)
 {
-  while (targets)
-    {
-      gchar *name = gdk_atom_name (GDK_POINTER_TO_ATOM (targets->data));
-      g_message ("\t%s", name);
-      g_free (name);
-      targets = targets->next;
-    }
+  gchar *name = gdk_content_formats_to_string (formats);
+  g_message ("DND formats: %s", name);
+  g_free (name);
 }
 #endif /* G_ENABLE_DEBUG */
 
@@ -1033,19 +1025,14 @@ xdnd_set_targets (GdkX11DragContext *context_x11)
 {
   GdkDragContext *context = GDK_DRAG_CONTEXT (context_x11);
   Atom *atomlist;
-  GList *tmp_list = context->targets;
-  gint i;
-  gint n_atoms = g_list_length (context->targets);
+  GdkAtom *atoms;
+  guint i, n_atoms;
   GdkDisplay *display = GDK_WINDOW_DISPLAY (context->source_window);
 
+  atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms);
   atomlist = g_new (Atom, n_atoms);
-  i = 0;
-  while (tmp_list)
-    {
-      atomlist[i] = gdk_x11_atom_to_xatom_for_display (display, GDK_POINTER_TO_ATOM (tmp_list->data));
-      tmp_list = tmp_list->next;
-      i++;
-    }
+  for (i = 0; i < n_atoms; i++)
+    atomlist[i] = gdk_x11_atom_to_xatom_for_display (display, atoms[i]);
 
   XChangeProperty (GDK_WINDOW_XDISPLAY (context->source_window),
                    GDK_WINDOW_XID (context->source_window),
@@ -1054,6 +1041,7 @@ xdnd_set_targets (GdkX11DragContext *context_x11)
                    (guchar *)atomlist, n_atoms);
 
   g_free (atomlist);
+  g_free (atoms);
 
   context_x11->xdnd_targets_set = 1;
 }
@@ -1234,6 +1222,8 @@ xdnd_send_enter (GdkX11DragContext *context_x11)
 {
   GdkDragContext *context = GDK_DRAG_CONTEXT (context_x11);
   GdkDisplay *display = GDK_WINDOW_DISPLAY (context->dest_window);
+  GdkAtom *atoms;
+  guint i, n_atoms;
   XEvent xev;
 
   xev.xclient.type = ClientMessage;
@@ -1251,7 +1241,9 @@ xdnd_send_enter (GdkX11DragContext *context_x11)
   GDK_NOTE(DND,
            g_message ("Sending enter source window %#lx XDND protocol version %d\n",
                       GDK_WINDOW_XID (context->source_window), context_x11->version));
-  if (g_list_length (context->targets) > 3)
+  atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms);
+
+  if (n_atoms > 3)
     {
       if (!context_x11->xdnd_targets_set)
         xdnd_set_targets (context_x11);
@@ -1259,15 +1251,9 @@ xdnd_send_enter (GdkX11DragContext *context_x11)
     }
   else
     {
-      GList *tmp_list = context->targets;
-      gint i = 2;
-
-      while (tmp_list)
+      for (i = 0; i < n_atoms; i++)
         {
-          xev.xclient.data.l[i] = gdk_x11_atom_to_xatom_for_display (display,
-                                                                     GDK_POINTER_TO_ATOM (tmp_list->data));
-          tmp_list = tmp_list->next;
-          i++;
+          xev.xclient.data.l[i + 2] = gdk_x11_atom_to_xatom_for_display (display, atoms[i]);
         }
     }
 
@@ -1654,6 +1640,7 @@ xdnd_enter_filter (GdkXEvent *xev,
   gulong nitems, after;
   guchar *data;
   Atom *atoms;
+  GPtrArray *formats;
   guint32 source_window;
   gboolean get_types;
   gint version;
@@ -1708,7 +1695,7 @@ xdnd_enter_filter (GdkXEvent *xev,
   context->dest_window = event->any.window;
   g_object_ref (context->dest_window);
 
-  context->targets = NULL;
+  formats = g_ptr_array_new ();
   if (get_types)
     {
       gdk_x11_display_error_trap_push (display);
@@ -1730,12 +1717,9 @@ xdnd_enter_filter (GdkXEvent *xev,
         }
 
       atoms = (Atom *)data;
-
       for (i = 0; i < nitems; i++)
-        context->targets =
-          g_list_append (context->targets,
-                         GDK_ATOM_TO_POINTER (gdk_x11_xatom_to_atom_for_display (display,
-                                                                                 atoms[i])));
+        g_ptr_array_add (formats, 
+                         (gpointer) gdk_x11_get_xatom_name_for_display (display, atoms[i]));
 
       XFree (atoms);
     }
@@ -1743,15 +1727,16 @@ xdnd_enter_filter (GdkXEvent *xev,
     {
       for (i = 0; i < 3; i++)
         if (xevent->xclient.data.l[2 + i])
-          context->targets =
-            g_list_append (context->targets,
-                           GDK_ATOM_TO_POINTER (gdk_x11_xatom_to_atom_for_display (display,
-                                                                                   xevent->xclient.data.l[2 
+ i])));
+          g_ptr_array_add (formats, 
+                           (gpointer) gdk_x11_get_xatom_name_for_display (display,
+                                                                          xevent->xclient.data.l[2 + i]));
     }
+  context->formats = gdk_content_formats_new ((const char **) formats->pdata, formats->len);
+  g_ptr_array_unref (formats);
 
 #ifdef G_ENABLE_DEBUG
   if (GDK_DEBUG_CHECK (DND))
-    print_target_list (context->targets);
+    print_target_list (context->formats);
 #endif /* G_ENABLE_DEBUG */
 
   xdnd_manage_source_filter (context, context->source_window, TRUE);
@@ -1994,11 +1979,11 @@ create_drag_window (GdkDisplay *display)
 }
 
 GdkDragContext *
-_gdk_x11_window_drag_begin (GdkWindow *window,
-                            GdkDevice *device,
-                            GList     *targets,
-                            gint       x_root,
-                            gint       y_root)
+_gdk_x11_window_drag_begin (GdkWindow         *window,
+                            GdkDevice         *device,
+                            GdkContentFormats *formats,
+                            gint               x_root,
+                            gint               y_root)
 {
   GdkDragContext *context;
 
@@ -2009,7 +1994,7 @@ _gdk_x11_window_drag_begin (GdkWindow *window,
   context->source_window = window;
   g_object_ref (window);
 
-  context->targets = g_list_copy (targets);
+  context->formats = gdk_content_formats_ref (formats);
   precache_target_list (context);
 
   context->actions = 0;
@@ -2325,13 +2310,8 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context,
                 /* GTK+ traditionally has used application/x-rootwin-drop,
                  * but the XDND spec specifies x-rootwindow-drop.
                  */
-                GdkAtom target1 = gdk_atom_intern_static_string ("application/x-rootwindow-drop");
-                GdkAtom target2 = gdk_atom_intern_static_string ("application/x-rootwin-drop");
-
-                if (g_list_find (context->targets,
-                                 GDK_ATOM_TO_POINTER (target1)) ||
-                    g_list_find (context->targets,
-                                 GDK_ATOM_TO_POINTER (target2)))
+                if (gdk_content_formats_contains (context->formats, "application/x-rootwindow-drop") ||
+                    gdk_content_formats_contains (context->formats, "application/x-rootwin-drop"))
                   context->action = context->suggested_action;
                 else
                   context->action = 0;
diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h
index 17c235e..b594e86 100644
--- a/gdk/x11/gdkprivate-x11.h
+++ b/gdk/x11/gdkprivate-x11.h
@@ -282,11 +282,11 @@ void _gdk_x11_cursor_display_finalize (GdkDisplay *display);
 
 void _gdk_x11_window_register_dnd (GdkWindow *window);
 
-GdkDragContext * _gdk_x11_window_drag_begin (GdkWindow *window,
-                                             GdkDevice *device,
-                                             GList     *targets,
-                                             gint       x_root,
-                                             gint       y_root);
+GdkDragContext * _gdk_x11_window_drag_begin (GdkWindow         *window,
+                                             GdkDevice         *device,
+                                             GdkContentFormats *formats,
+                                             gint               x_root,
+                                             gint               y_root);
 
 GdkGrabStatus _gdk_x11_convert_grab_status (gint status);
 
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c
index 45e6932..2e8af5a 100644
--- a/gtk/gtkdnd.c
+++ b/gtk/gtkdnd.c
@@ -1180,7 +1180,6 @@ gtk_drag_begin_internal (GtkWidget          *widget,
                          int                 y)
 {
   GtkDragSourceInfo *info;
-  GList *targets = NULL;
   guint32 time = GDK_CURRENT_TIME;
   GdkDragAction possible_actions, suggested_action;
   GdkDragContext *context;
@@ -1190,8 +1189,6 @@ gtk_drag_begin_internal (GtkWidget          *widget,
   GdkWindow *ipc_window;
   int start_x, start_y;
   GdkAtom selection;
-  GdkAtom *atoms;
-  guint i, n_atoms;
   gboolean managed;
 
   managed = gtk_drag_is_managed (widget);
@@ -1263,13 +1260,6 @@ gtk_drag_begin_internal (GtkWidget          *widget,
       gtk_device_grab_add (ipc_widget, pointer, FALSE);
     }
 
-  atoms = gdk_content_formats_get_atoms (target_list, &n_atoms);
-  for (i = 0; i < n_atoms; i++)
-    {
-      targets = g_list_prepend (targets, (gpointer) atoms[i]);
-    }
-  g_free (atoms);
-
   source_widgets = g_slist_prepend (source_widgets, ipc_widget);
 
   if (x != -1 && y != -1)
@@ -1291,10 +1281,9 @@ gtk_drag_begin_internal (GtkWidget          *widget,
   else
     gdk_device_get_position (pointer, &start_x, &start_y);
 
-  context = gdk_drag_begin_from_point (ipc_window, pointer, targets, start_x, start_y);
+  context = gdk_drag_begin_from_point (ipc_window, pointer, target_list, start_x, start_y);
 
   gdk_drag_context_set_device (context, pointer);
-  g_list_free (targets);
 
   if (managed &&
       !gdk_drag_context_manage_dnd (context, ipc_window, actions))
diff --git a/gtk/gtkdragdest.c b/gtk/gtkdragdest.c
index cd9ee3c..91afffb 100644
--- a/gtk/gtkdragdest.c
+++ b/gtk/gtkdragdest.c
@@ -411,8 +411,6 @@ gtk_drag_dest_find_target (GtkWidget         *widget,
                            GdkDragContext    *context,
                            GdkContentFormats *target_list)
 {
-  GdkContentFormats *source_list;
-  GList *tmp_source;
   GdkAtom result;
 
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
@@ -424,17 +422,8 @@ gtk_drag_dest_find_target (GtkWidget         *widget,
   if (target_list == NULL)
     return NULL;
 
-  source_list = gdk_content_formats_new (NULL, 0);
-  for (tmp_source = gdk_drag_context_list_targets (context);
-       tmp_source != NULL;
-       tmp_source = tmp_source->next)
-    {
-      gdk_content_formats_add (source_list, tmp_source->data);
-    }
-       
-  result = gdk_content_formats_intersects (target_list, source_list);
-
-  gdk_content_formats_unref (source_list);
+  result = gdk_content_formats_intersects (target_list,
+                                           gdk_drag_context_get_formats (context));
 
   return result;
 }
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index e6c5df7..8bf79a9 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -8149,25 +8149,18 @@ gtk_text_view_drag_data_received (GtkWidget        *widget,
           /*  try to find a suitable rich text target instead  */
           GdkAtom *atoms;
           gint     n_atoms;
-          GList   *list;
+          GdkContentFormats *dnd_formats, *buffer_formats;
           GdkAtom  target = NULL;
 
           copy_tags = FALSE;
 
           atoms = gtk_text_buffer_get_deserialize_formats (buffer, &n_atoms);
+          buffer_formats = gdk_content_formats_new (atoms, n_atoms);
+          dnd_formats = gdk_drag_context_get_formats (context);
 
-          for (list = gdk_drag_context_list_targets (context); list; list = list->next)
-            {
-              gint i;
-
-              for (i = 0; i < n_atoms; i++)
-                if (GUINT_TO_POINTER (atoms[i]) == list->data)
-                  {
-                    target = atoms[i];
-                    break;
-                  }
-            }
+          target = gdk_content_formats_intersects (dnd_formats, buffer_formats);
 
+          gdk_content_formats_unref (buffer_formats);
           g_free (atoms);
 
           if (target != NULL)
diff --git a/tests/testdnd.c b/tests/testdnd.c
index d405fd8..934fbe5 100644
--- a/tests/testdnd.c
+++ b/tests/testdnd.c
@@ -315,7 +315,7 @@ target_drag_motion     (GtkWidget          *widget,
                            guint               time)
 {
   GtkWidget *source_widget;
-  GList *tmp_list;
+  char *s;
 
   if (!have_drag)
     {
@@ -328,15 +328,8 @@ target_drag_motion    (GtkWidget          *widget,
           G_OBJECT_TYPE_NAME (source_widget) :
           "NULL");
 
-  tmp_list = gdk_drag_context_list_targets (context);
-  while (tmp_list)
-    {
-      char *name = gdk_atom_name (GDK_POINTER_TO_ATOM (tmp_list->data));
-      g_print ("%s\n", name);
-      g_free (name);
-      
-      tmp_list = tmp_list->next;
-    }
+  s = gdk_content_formats_to_string (gdk_drag_context_get_formats (context));
+  g_print ("%s\n", s);
 
   gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), time);
 
@@ -350,15 +343,20 @@ target_drag_drop     (GtkWidget          *widget,
                            gint                y,
                            guint               time)
 {
+  GdkContentFormats *formats;
+  GdkAtom format;
+
   g_print("drop\n");
   have_drag = FALSE;
 
   gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_closed);
 
-  if (gdk_drag_context_list_targets (context))
+  formats = gdk_drag_context_get_formats (context);
+  format = gdk_content_formats_intersects (formats, formats);
+  if (format)
     {
       gtk_drag_get_data (widget, context,
-                        GDK_POINTER_TO_ATOM (gdk_drag_context_list_targets (context)->data),
+                        format,
                         time);
       return TRUE;
     }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]