[gtk+] dnd: Move GtkDragDest to a separate file



commit 6ac7b54378ad1a8468df889744321bd61ab9e565
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Dec 13 18:43:10 2015 -0500

    dnd: Move GtkDragDest to a separate file
    
    This follows what was done for GtkDragSource in
    415030d25f2552d3937ee3c394c50d22c5382982 and shaves another
    500 lines off gtkdnd.c.

 gtk/Makefile.am              |    2 +
 gtk/deprecated/gtkcolorsel.c |    1 +
 gtk/gtk.h                    |    1 +
 gtk/gtkcalendar.c            |    1 +
 gtk/gtkcolorbutton.c         |    1 +
 gtk/gtkdnd.c                 |  495 +-----------------------------------------
 gtk/gtkdnd.h                 |   88 --------
 gtk/gtkdndprivate.h          |   15 ++
 gtk/gtkdragdest.c            |  500 ++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkdragdest.h            |  110 +++++++++
 gtk/gtkfilechooserbutton.c   |    1 +
 gtk/gtkfilechooserwidget.c   |    1 +
 gtk/gtkplacessidebar.c       |    1 +
 gtk/gtkselection.h           |   21 ++
 gtk/gtksocket.c              |    1 +
 15 files changed, 659 insertions(+), 580 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 6a53a2b..d2b91d6 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -173,6 +173,7 @@ gtk_public_h_sources =              \
        gtkdebug.h              \
        gtkdialog.h             \
        gtkdnd.h                \
+       gtkdragdest.h           \
        gtkdragsource.h         \
        gtkdrawingarea.h        \
        gtkeditable.h           \
@@ -724,6 +725,7 @@ gtk_base_c_sources =                \
        gtkcsswidgetnode.c      \
         gtkcsswin32sizevalue.c  \
        gtkdialog.c             \
+       gtkdragdest.c           \
        gtkdragsource.c         \
        gtkdrawingarea.c        \
        gtkeditable.c           \
diff --git a/gtk/deprecated/gtkcolorsel.c b/gtk/deprecated/gtkcolorsel.c
index edc1f5b..f43edf2 100644
--- a/gtk/deprecated/gtkcolorsel.c
+++ b/gtk/deprecated/gtkcolorsel.c
@@ -41,6 +41,7 @@
 #include "gtkcolorutils.h"
 #include "gtkdnd.h"
 #include "gtkdragsource.h"
+#include "gtkdragdest.h"
 #include "gtkdrawingarea.h"
 #include "gtkframe.h"
 #include "gtkgrid.h"
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 148d52f..a7233da 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -84,6 +84,7 @@
 #include <gtk/gtkdebug.h>
 #include <gtk/gtkdialog.h>
 #include <gtk/gtkdnd.h>
+#include <gtk/gtkdragdest.h>
 #include <gtk/gtkdragsource.h>
 #include <gtk/gtkdrawingarea.h>
 #include <gtk/gtkeditable.h>
diff --git a/gtk/gtkcalendar.c b/gtk/gtkcalendar.c
index 94f9363..da319b1 100644
--- a/gtk/gtkcalendar.c
+++ b/gtk/gtkcalendar.c
@@ -73,6 +73,7 @@
 
 #include "gtkcalendar.h"
 #include "gtkdnd.h"
+#include "gtkdragdest.h"
 #include "gtkintl.h"
 #include "gtkmain.h"
 #include "gtkmarshalers.h"
diff --git a/gtk/gtkcolorbutton.c b/gtk/gtkcolorbutton.c
index 5418342..96a5bc1 100644
--- a/gtk/gtkcolorbutton.c
+++ b/gtk/gtkcolorbutton.c
@@ -37,6 +37,7 @@
 #include "gtkcolorchooserdialog.h"
 #include "gtkcolorswatchprivate.h"
 #include "gtkdnd.h"
+#include "gtkdragdest.h"
 #include "gtkdragsource.h"
 #include "gtkmarshalers.h"
 #include "gtkprivate.h"
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c
index 48be48c..71913b0 100644
--- a/gtk/gtkdnd.c
+++ b/gtk/gtkdnd.c
@@ -46,6 +46,7 @@
 #include <gdk/wayland/gdkwayland.h>
 #endif
 
+#include "gtkdragdest.h"
 #include "gtkgesturedrag.h"
 #include "gtkgesturesingle.h"
 #include "gtkicontheme.h"
@@ -79,7 +80,6 @@
 static GSList *source_widgets = NULL;
 
 typedef struct _GtkDragSourceInfo GtkDragSourceInfo;
-typedef struct _GtkDragDestSite GtkDragDestSite;
 typedef struct _GtkDragDestInfo GtkDragDestInfo;
 
 
@@ -121,19 +121,6 @@ struct _GtkDragSourceInfo
   guint              have_grab    : 1; /* Do we still have the pointer grab */
 };
 
-struct _GtkDragDestSite
-{
-  GtkDestDefaults    flags;
-  GtkTargetList     *target_list;
-  GdkDragAction      actions;
-  GdkWindow         *proxy_window;
-  GdkDragProtocol    proxy_protocol;
-  guint              do_proxy     : 1;
-  guint              proxy_coords : 1;
-  guint              have_drag    : 1;
-  guint              track_motion : 1;
-};
-
 struct _GtkDragDestInfo
 {
   GtkWidget         *widget;              /* Widget in which drag is in */
@@ -192,10 +179,6 @@ static gboolean gtk_drag_find_widget            (GtkWidget        *widget,
 static void     gtk_drag_proxy_begin            (GtkWidget        *widget,
                                                  GtkDragDestInfo  *dest_info,
                                                  guint32           time);
-static void     gtk_drag_dest_realized          (GtkWidget        *widget);
-static void     gtk_drag_dest_hierarchy_changed (GtkWidget        *widget,
-                                                 GtkWidget        *previous_toplevel);
-static void     gtk_drag_dest_site_destroy      (gpointer          data);
 static void     gtk_drag_dest_leave             (GtkWidget        *widget,
                                                  GdkDragContext   *context,
                                                  guint             time);
@@ -1025,381 +1008,6 @@ gtk_drag_unhighlight (GtkWidget *widget)
   gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE);
 }
 
-static void
-gtk_drag_dest_set_internal (GtkWidget       *widget,
-                            GtkDragDestSite *site)
-{
-  GtkDragDestSite *old_site;
-  
-  g_return_if_fail (widget != NULL);
-
-  /* HACK, do this in the destroy */
-  old_site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");
-  if (old_site)
-    {
-      g_signal_handlers_disconnect_by_func (widget,
-                                            gtk_drag_dest_realized,
-                                            old_site);
-      g_signal_handlers_disconnect_by_func (widget,
-                                            gtk_drag_dest_hierarchy_changed,
-                                            old_site);
-
-      site->track_motion = old_site->track_motion;
-    }
-
-  if (gtk_widget_get_realized (widget))
-    gtk_drag_dest_realized (widget);
-
-  g_signal_connect (widget, "realize",
-                    G_CALLBACK (gtk_drag_dest_realized), site);
-  g_signal_connect (widget, "hierarchy-changed",
-                    G_CALLBACK (gtk_drag_dest_hierarchy_changed), site);
-
-  g_object_set_data_full (G_OBJECT (widget), I_("gtk-drag-dest"),
-                          site, gtk_drag_dest_site_destroy);
-}
-
-/**
- * gtk_drag_dest_set: (method)
- * @widget: a #GtkWidget
- * @flags: which types of default drag behavior to use
- * @targets: (allow-none) (array length=n_targets): a pointer to an array of
- *     #GtkTargetEntrys indicating the drop types that this @widget will
- *     accept, or %NULL. Later you can access the list with
- *     gtk_drag_dest_get_target_list() and gtk_drag_dest_find_target().
- * @n_targets: the number of entries in @targets
- * @actions: a bitmask of possible actions for a drop onto this @widget.
- *
- * Sets a widget as a potential drop destination, and adds default behaviors.
- *
- * The default behaviors listed in @flags have an effect similar
- * to installing default handlers for the widget’s drag-and-drop signals
- * (#GtkWidget::drag-motion, #GtkWidget::drag-drop, ...). They all exist
- * for convenience. When passing #GTK_DEST_DEFAULT_ALL for instance it is
- * sufficient to connect to the widget’s #GtkWidget::drag-data-received
- * signal to get primitive, but consistent drag-and-drop support.
- *
- * Things become more complicated when you try to preview the dragged data,
- * as described in the documentation for #GtkWidget::drag-motion. The default
- * behaviors described by @flags make some assumptions, that can conflict
- * with your own signal handlers. For instance #GTK_DEST_DEFAULT_DROP causes
- * invokations of gdk_drag_status() in the context of #GtkWidget::drag-motion,
- * and invokations of gtk_drag_finish() in #GtkWidget::drag-data-received.
- * Especially the later is dramatic, when your own #GtkWidget::drag-motion
- * handler calls gtk_drag_get_data() to inspect the dragged data.
- *
- * There’s no way to set a default action here, you can use the
- * #GtkWidget::drag-motion callback for that. Here’s an example which selects
- * the action to use depending on whether the control key is pressed or not:
- * |[<!-- language="C" -->
- * static void
- * drag_motion (GtkWidget *widget,
- *              GdkDragContext *context,
- *              gint x,
- *              gint y,
- *              guint time)
- * {
- *   GdkModifierType mask;
- *
- *   gdk_window_get_pointer (gtk_widget_get_window (widget),
- *                           NULL, NULL, &mask);
- *   if (mask & GDK_CONTROL_MASK)
- *     gdk_drag_status (context, GDK_ACTION_COPY, time);
- *   else
- *     gdk_drag_status (context, GDK_ACTION_MOVE, time);
- * }
- * ]|
- */
-void
-gtk_drag_dest_set (GtkWidget            *widget,
-                   GtkDestDefaults       flags,
-                   const GtkTargetEntry *targets,
-                   gint                  n_targets,
-                   GdkDragAction         actions)
-{
-  GtkDragDestSite *site;
-  
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-
-  site = g_slice_new0 (GtkDragDestSite);
-
-  site->flags = flags;
-  site->have_drag = FALSE;
-  if (targets)
-    site->target_list = gtk_target_list_new (targets, n_targets);
-  else
-    site->target_list = NULL;
-  site->actions = actions;
-  site->do_proxy = FALSE;
-  site->proxy_window = NULL;
-  site->track_motion = FALSE;
-
-  gtk_drag_dest_set_internal (widget, site);
-}
-
-/**
- * gtk_drag_dest_set_proxy: (method)
- * @widget: a #GtkWidget
- * @proxy_window: the window to which to forward drag events
- * @protocol: the drag protocol which the @proxy_window accepts
- *   (You can use gdk_drag_get_protocol() to determine this)
- * @use_coordinates: If %TRUE, send the same coordinates to the
- *   destination, because it is an embedded
- *   subwindow.
- *
- * Sets this widget as a proxy for drops to another window.
- */
-void 
-gtk_drag_dest_set_proxy (GtkWidget      *widget,
-                         GdkWindow      *proxy_window,
-                         GdkDragProtocol protocol,
-                         gboolean        use_coordinates)
-{
-  GtkDragDestSite *site;
-  
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-  g_return_if_fail (!proxy_window || GDK_IS_WINDOW (proxy_window));
-
-  site = g_slice_new (GtkDragDestSite);
-
-  site->flags = 0;
-  site->have_drag = FALSE;
-  site->target_list = NULL;
-  site->actions = 0;
-  site->proxy_window = proxy_window;
-  if (proxy_window)
-    g_object_ref (proxy_window);
-  site->do_proxy = TRUE;
-  site->proxy_protocol = protocol;
-  site->proxy_coords = use_coordinates;
-  site->track_motion = FALSE;
-
-  gtk_drag_dest_set_internal (widget, site);
-}
-
-/**
- * gtk_drag_dest_unset: (method)
- * @widget: a #GtkWidget
- *
- * Clears information about a drop destination set with
- * gtk_drag_dest_set(). The widget will no longer receive
- * notification of drags.
- */
-void 
-gtk_drag_dest_unset (GtkWidget *widget)
-{
-  GtkDragDestSite *old_site;
-
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-
-  old_site = g_object_get_data (G_OBJECT (widget),
-                                "gtk-drag-dest");
-  if (old_site)
-    {
-      g_signal_handlers_disconnect_by_func (widget,
-                                            gtk_drag_dest_realized,
-                                            old_site);
-      g_signal_handlers_disconnect_by_func (widget,
-                                            gtk_drag_dest_hierarchy_changed,
-                                            old_site);
-    }
-
-  g_object_set_data (G_OBJECT (widget), I_("gtk-drag-dest"), NULL);
-}
-
-/**
- * gtk_drag_dest_get_target_list: (method)
- * @widget: a #GtkWidget
- * 
- * Returns the list of targets this widget can accept from
- * drag-and-drop.
- * 
- * Returns: (nullable) (transfer none): the #GtkTargetList, or %NULL if none
- */
-GtkTargetList*
-gtk_drag_dest_get_target_list (GtkWidget *widget)
-{
-  GtkDragDestSite *site;
-
-  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-  
-  site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");
-
-  return site ? site->target_list : NULL;  
-}
-
-/**
- * gtk_drag_dest_set_target_list: (method)
- * @widget: a #GtkWidget that’s a drag destination
- * @target_list: (allow-none): list of droppable targets, or %NULL for none
- * 
- * Sets the target types that this widget can accept from drag-and-drop.
- * The widget must first be made into a drag destination with
- * gtk_drag_dest_set().
- */
-void
-gtk_drag_dest_set_target_list (GtkWidget     *widget,
-                               GtkTargetList *target_list)
-{
-  GtkDragDestSite *site;
-
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-  
-  site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");
-  
-  if (!site)
-    {
-      g_warning ("Can't set a target list on a widget until you've called gtk_drag_dest_set() "
-                 "to make the widget into a drag destination");
-      return;
-    }
-
-  if (target_list)
-    gtk_target_list_ref (target_list);
-  
-  if (site->target_list)
-    gtk_target_list_unref (site->target_list);
-
-  site->target_list = target_list;
-}
-
-/**
- * gtk_drag_dest_add_text_targets: (method)
- * @widget: a #GtkWidget that’s a drag destination
- *
- * Add the text targets supported by #GtkSelectionData to
- * the target list of the drag destination. The targets
- * are added with @info = 0. If you need another value, 
- * use gtk_target_list_add_text_targets() and
- * gtk_drag_dest_set_target_list().
- * 
- * Since: 2.6
- */
-void
-gtk_drag_dest_add_text_targets (GtkWidget *widget)
-{
-  GtkTargetList *target_list;
-
-  target_list = gtk_drag_dest_get_target_list (widget);
-  if (target_list)
-    gtk_target_list_ref (target_list);
-  else
-    target_list = gtk_target_list_new (NULL, 0);
-  gtk_target_list_add_text_targets (target_list, 0);
-  gtk_drag_dest_set_target_list (widget, target_list);
-  gtk_target_list_unref (target_list);
-}
-
-/**
- * gtk_drag_dest_add_image_targets: (method)
- * @widget: a #GtkWidget that’s a drag destination
- *
- * Add the image targets supported by #GtkSelectionData to
- * the target list of the drag destination. The targets
- * are added with @info = 0. If you need another value, 
- * use gtk_target_list_add_image_targets() and
- * gtk_drag_dest_set_target_list().
- * 
- * Since: 2.6
- */
-void
-gtk_drag_dest_add_image_targets (GtkWidget *widget)
-{
-  GtkTargetList *target_list;
-
-  target_list = gtk_drag_dest_get_target_list (widget);
-  if (target_list)
-    gtk_target_list_ref (target_list);
-  else
-    target_list = gtk_target_list_new (NULL, 0);
-  gtk_target_list_add_image_targets (target_list, 0, FALSE);
-  gtk_drag_dest_set_target_list (widget, target_list);
-  gtk_target_list_unref (target_list);
-}
-
-/**
- * gtk_drag_dest_add_uri_targets: (method)
- * @widget: a #GtkWidget that’s a drag destination
- *
- * Add the URI targets supported by #GtkSelectionData to
- * the target list of the drag destination. The targets
- * are added with @info = 0. If you need another value, 
- * use gtk_target_list_add_uri_targets() and
- * gtk_drag_dest_set_target_list().
- * 
- * Since: 2.6
- */
-void
-gtk_drag_dest_add_uri_targets (GtkWidget *widget)
-{
-  GtkTargetList *target_list;
-
-  target_list = gtk_drag_dest_get_target_list (widget);
-  if (target_list)
-    gtk_target_list_ref (target_list);
-  else
-    target_list = gtk_target_list_new (NULL, 0);
-  gtk_target_list_add_uri_targets (target_list, 0);
-  gtk_drag_dest_set_target_list (widget, target_list);
-  gtk_target_list_unref (target_list);
-}
-
-/**
- * gtk_drag_dest_set_track_motion: (method)
- * @widget: a #GtkWidget that’s a drag destination
- * @track_motion: whether to accept all targets
- *
- * Tells the widget to emit #GtkWidget::drag-motion and
- * #GtkWidget::drag-leave events regardless of the targets and the
- * %GTK_DEST_DEFAULT_MOTION flag.
- *
- * This may be used when a widget wants to do generic
- * actions regardless of the targets that the source offers.
- *
- * Since: 2.10
- */
-void
-gtk_drag_dest_set_track_motion (GtkWidget *widget,
-                                gboolean   track_motion)
-{
-  GtkDragDestSite *site;
-
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-
-  site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");
-  
-  g_return_if_fail (site != NULL);
-
-  site->track_motion = track_motion != FALSE;
-}
-
-/**
- * gtk_drag_dest_get_track_motion: (method)
- * @widget: a #GtkWidget that’s a drag destination
- *
- * Returns whether the widget has been configured to always
- * emit #GtkWidget::drag-motion signals.
- *
- * Returns: %TRUE if the widget always emits
- *   #GtkWidget::drag-motion events
- *
- * Since: 2.10
- */
-gboolean
-gtk_drag_dest_get_track_motion (GtkWidget *widget)
-{
-  GtkDragDestSite *site;
-
-  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
-
-  site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");
-
-  if (site)
-    return site->track_motion;
-
-  return FALSE;
-}
-
 /*
  * _gtk_drag_dest_handle_event:
  * @toplevel: Toplevel widget that received the event
@@ -1506,70 +1114,6 @@ _gtk_drag_dest_handle_event (GtkWidget *toplevel,
     }
 }
 
-/**
- * gtk_drag_dest_find_target: (method)
- * @widget: drag destination widget
- * @context: drag context
- * @target_list: (allow-none): list of droppable targets, or %NULL to use
- *    gtk_drag_dest_get_target_list (@widget).
- *
- * Looks for a match between the supported targets of @context and the
- * @dest_target_list, returning the first matching target, otherwise
- * returning %GDK_NONE. @dest_target_list should usually be the return
- * value from gtk_drag_dest_get_target_list(), but some widgets may
- * have different valid targets for different parts of the widget; in
- * that case, they will have to implement a drag_motion handler that
- * passes the correct target list to this function.
- *
- * Returns: (transfer none): first target that the source offers
- *     and the dest can accept, or %GDK_NONE
- */
-GdkAtom
-gtk_drag_dest_find_target (GtkWidget      *widget,
-                           GdkDragContext *context,
-                           GtkTargetList  *target_list)
-{
-  GList *tmp_target;
-  GList *tmp_source = NULL;
-  GtkWidget *source_widget;
-
-  g_return_val_if_fail (GTK_IS_WIDGET (widget), GDK_NONE);
-  g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), GDK_NONE);
-
-
-  source_widget = gtk_drag_get_source_widget (context);
-
-  if (target_list == NULL)
-    target_list = gtk_drag_dest_get_target_list (widget);
-  
-  if (target_list == NULL)
-    return GDK_NONE;
-  
-  tmp_target = target_list->list;
-  while (tmp_target)
-    {
-      GtkTargetPair *pair = tmp_target->data;
-      tmp_source = gdk_drag_context_list_targets (context);
-      while (tmp_source)
-        {
-          if (tmp_source->data == GUINT_TO_POINTER (pair->target))
-            {
-              if ((!(pair->flags & GTK_TARGET_SAME_APP) || source_widget) &&
-                  (!(pair->flags & GTK_TARGET_SAME_WIDGET) || (source_widget == widget)) &&
-                  (!(pair->flags & GTK_TARGET_OTHER_APP) || !source_widget) &&
-                  (!(pair->flags & GTK_TARGET_OTHER_WIDGET) || (source_widget != widget)))
-                return pair->target;
-              else
-                break;
-            }
-          tmp_source = tmp_source->next;
-        }
-      tmp_target = tmp_target->next;
-    }
-
-  return GDK_NONE;
-}
-
 static void
 gtk_drag_selection_received (GtkWidget        *widget,
                              GtkSelectionData *selection_data,
@@ -1875,39 +1419,6 @@ gtk_drag_clear_source_info (GdkDragContext *context)
   g_object_set_qdata (G_OBJECT (context), dest_info_quark, NULL);
 }
 
-static void
-gtk_drag_dest_realized (GtkWidget *widget)
-{
-  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
-
-  if (gtk_widget_is_toplevel (toplevel))
-    gdk_window_register_dnd (gtk_widget_get_window (toplevel));
-}
-
-static void
-gtk_drag_dest_hierarchy_changed (GtkWidget *widget,
-                                 GtkWidget *previous_toplevel)
-{
-  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
-
-  if (gtk_widget_is_toplevel (toplevel) && gtk_widget_get_realized (toplevel))
-    gdk_window_register_dnd (gtk_widget_get_window (toplevel));
-}
-
-static void
-gtk_drag_dest_site_destroy (gpointer data)
-{
-  GtkDragDestSite *site = data;
-
-  if (site->proxy_window)
-    g_object_unref (site->proxy_window);
-    
-  if (site->target_list)
-    gtk_target_list_unref (site->target_list);
-
-  g_slice_free (GtkDragDestSite, site);
-}
-
 /*
  * Default drag handlers
  */
@@ -2765,7 +2276,6 @@ gtk_drag_set_icon_surface (GdkDragContext  *context,
     rgba_visual != NULL &&
     gdk_screen_is_composited (screen);
 
-
   gtk_window_set_screen (GTK_WINDOW (window), screen);
 
   if (has_rgba)
@@ -2793,7 +2303,8 @@ gtk_drag_set_icon_surface (GdkDragContext  *context,
       cairo_region_destroy (region);
 
       /* Need to saturate the colors, so it doesn't look like semi-transparent
-       * pixels were painted on black. */
+       * pixels were painted on black.
+       */
       saturated = gdk_window_create_similar_surface (gtk_widget_get_window (window),
                                                      CAIRO_CONTENT_COLOR,
                                                      extents.width,
diff --git a/gtk/gtkdnd.h b/gtk/gtkdnd.h
index db42c8c..a5c7f2c 100644
--- a/gtk/gtkdnd.h
+++ b/gtk/gtkdnd.h
@@ -37,56 +37,6 @@
 
 G_BEGIN_DECLS
 
-/**
- * GtkDestDefaults:
- * @GTK_DEST_DEFAULT_MOTION: If set for a widget, GTK+, during a drag over this
- *   widget will check if the drag matches this widget’s list of possible targets
- *   and actions.
- *   GTK+ will then call gdk_drag_status() as appropriate.
- * @GTK_DEST_DEFAULT_HIGHLIGHT: If set for a widget, GTK+ will draw a highlight on
- *   this widget as long as a drag is over this widget and the widget drag format
- *   and action are acceptable.
- * @GTK_DEST_DEFAULT_DROP: If set for a widget, when a drop occurs, GTK+ will
- *   will check if the drag matches this widget’s list of possible targets and
- *   actions. If so, GTK+ will call gtk_drag_get_data() on behalf of the widget.
- *   Whether or not the drop is successful, GTK+ will call gtk_drag_finish(). If
- *   the action was a move, then if the drag was successful, then %TRUE will be
- *   passed for the @delete parameter to gtk_drag_finish().
- * @GTK_DEST_DEFAULT_ALL: If set, specifies that all default actions should
- *   be taken.
- *
- * The #GtkDestDefaults enumeration specifies the various
- * types of action that will be taken on behalf
- * of the user for a drag destination site.
- */
-typedef enum {
-  GTK_DEST_DEFAULT_MOTION     = 1 << 0,
-  GTK_DEST_DEFAULT_HIGHLIGHT  = 1 << 1,
-  GTK_DEST_DEFAULT_DROP       = 1 << 2,
-  GTK_DEST_DEFAULT_ALL        = 0x07
-} GtkDestDefaults;
-
-/**
- * GtkTargetFlags:
- * @GTK_TARGET_SAME_APP: If this is set, the target will only be selected
- *   for drags within a single application.
- * @GTK_TARGET_SAME_WIDGET: If this is set, the target will only be selected
- *   for drags within a single widget.
- * @GTK_TARGET_OTHER_APP: If this is set, the target will not be selected
- *   for drags within a single application.
- * @GTK_TARGET_OTHER_WIDGET: If this is set, the target will not be selected
- *   for drags withing a single widget.
- *
- * The #GtkTargetFlags enumeration is used to specify
- * constraints on a #GtkTargetEntry.
- */
-typedef enum {
-  GTK_TARGET_SAME_APP = 1 << 0,    /*< nick=same-app >*/
-  GTK_TARGET_SAME_WIDGET = 1 << 1, /*< nick=same-widget >*/
-  GTK_TARGET_OTHER_APP = 1 << 2,   /*< nick=other-app >*/
-  GTK_TARGET_OTHER_WIDGET = 1 << 3 /*< nick=other-widget >*/
-} GtkTargetFlags;
-
 /* Destination side */
 
 GDK_AVAILABLE_IN_ALL
@@ -108,44 +58,6 @@ void gtk_drag_highlight   (GtkWidget  *widget);
 GDK_AVAILABLE_IN_ALL
 void gtk_drag_unhighlight (GtkWidget  *widget);
 
-GDK_AVAILABLE_IN_ALL
-void gtk_drag_dest_set   (GtkWidget            *widget,
-                         GtkDestDefaults       flags,
-                         const GtkTargetEntry *targets,
-                         gint                  n_targets,
-                         GdkDragAction         actions);
-
-GDK_AVAILABLE_IN_ALL
-void gtk_drag_dest_set_proxy (GtkWidget      *widget,
-                             GdkWindow      *proxy_window,
-                             GdkDragProtocol protocol,
-                             gboolean        use_coordinates);
-
-GDK_AVAILABLE_IN_ALL
-void gtk_drag_dest_unset (GtkWidget          *widget);
-
-GDK_AVAILABLE_IN_ALL
-GdkAtom        gtk_drag_dest_find_target     (GtkWidget      *widget,
-                                              GdkDragContext *context,
-                                              GtkTargetList  *target_list);
-GDK_AVAILABLE_IN_ALL
-GtkTargetList* gtk_drag_dest_get_target_list (GtkWidget      *widget);
-GDK_AVAILABLE_IN_ALL
-void           gtk_drag_dest_set_target_list (GtkWidget      *widget,
-                                              GtkTargetList  *target_list);
-GDK_AVAILABLE_IN_ALL
-void           gtk_drag_dest_add_text_targets  (GtkWidget    *widget);
-GDK_AVAILABLE_IN_ALL
-void           gtk_drag_dest_add_image_targets (GtkWidget    *widget);
-GDK_AVAILABLE_IN_ALL
-void           gtk_drag_dest_add_uri_targets   (GtkWidget    *widget);
-
-GDK_AVAILABLE_IN_ALL
-void           gtk_drag_dest_set_track_motion  (GtkWidget *widget,
-                                               gboolean   track_motion);
-GDK_AVAILABLE_IN_ALL
-gboolean       gtk_drag_dest_get_track_motion  (GtkWidget *widget);
-
 /* Source side */
 
 GDK_AVAILABLE_IN_3_10
diff --git a/gtk/gtkdndprivate.h b/gtk/gtkdndprivate.h
index 016f263..f14a456 100644
--- a/gtk/gtkdndprivate.h
+++ b/gtk/gtkdndprivate.h
@@ -22,9 +22,24 @@
 
 #include <gtk/gtkwidget.h>
 #include <gtk/gtkselection.h>
+#include <gtk/gtkdragdest.h>
 
 #include "gtkimagedefinitionprivate.h"
 
+typedef struct _GtkDragDestSite GtkDragDestSite;
+struct _GtkDragDestSite
+{
+  GtkDestDefaults    flags;
+  GtkTargetList     *target_list;
+  GdkDragAction      actions;
+  GdkWindow         *proxy_window;
+  GdkDragProtocol    proxy_protocol;
+  guint              do_proxy     : 1;
+  guint              proxy_coords : 1;
+  guint              have_drag    : 1;
+  guint              track_motion : 1;
+};
+
 G_BEGIN_DECLS
 
 GdkDragContext *        gtk_drag_begin_internal         (GtkWidget              *widget,
diff --git a/gtk/gtkdragdest.c b/gtk/gtkdragdest.c
new file mode 100644
index 0000000..9a679e7
--- /dev/null
+++ b/gtk/gtkdragdest.c
@@ -0,0 +1,500 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+#include "gtkdragdest.h"
+
+#include "gtkdnd.h"
+#include "gtkdndprivate.h"
+#include "gtkselectionprivate.h"
+#include "gtkintl.h"
+
+
+static void
+gtk_drag_dest_realized (GtkWidget *widget)
+{
+  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+
+  if (gtk_widget_is_toplevel (toplevel))
+    gdk_window_register_dnd (gtk_widget_get_window (toplevel));
+}
+
+static void
+gtk_drag_dest_hierarchy_changed (GtkWidget *widget,
+                                 GtkWidget *previous_toplevel)
+{
+  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+
+  if (gtk_widget_is_toplevel (toplevel) && gtk_widget_get_realized (toplevel))
+    gdk_window_register_dnd (gtk_widget_get_window (toplevel));
+}
+
+static void
+gtk_drag_dest_site_destroy (gpointer data)
+{
+  GtkDragDestSite *site = data;
+
+  if (site->proxy_window)
+    g_object_unref (site->proxy_window);
+
+  if (site->target_list)
+    gtk_target_list_unref (site->target_list);
+
+  g_slice_free (GtkDragDestSite, site);
+}
+
+static void
+gtk_drag_dest_set_internal (GtkWidget       *widget,
+                            GtkDragDestSite *site)
+{
+  GtkDragDestSite *old_site;
+
+  old_site = g_object_get_data (G_OBJECT (widget), I_("gtk-drag-dest"));
+  if (old_site)
+    {
+      g_signal_handlers_disconnect_by_func (widget,
+                                            gtk_drag_dest_realized,
+                                            old_site);
+      g_signal_handlers_disconnect_by_func (widget,
+                                            gtk_drag_dest_hierarchy_changed,
+                                            old_site);
+
+      site->track_motion = old_site->track_motion;
+    }
+
+  if (gtk_widget_get_realized (widget))
+    gtk_drag_dest_realized (widget);
+
+  g_signal_connect (widget, "realize",
+                    G_CALLBACK (gtk_drag_dest_realized), site);
+  g_signal_connect (widget, "hierarchy-changed",
+                    G_CALLBACK (gtk_drag_dest_hierarchy_changed), site);
+
+  g_object_set_data_full (G_OBJECT (widget), I_("gtk-drag-dest"),
+                          site, gtk_drag_dest_site_destroy);
+}
+
+/**
+ * gtk_drag_dest_set: (method)
+ * @widget: a #GtkWidget
+ * @flags: which types of default drag behavior to use
+ * @targets: (allow-none) (array length=n_targets): a pointer to an array of
+ *     #GtkTargetEntrys indicating the drop types that this @widget will
+ *     accept, or %NULL. Later you can access the list with
+ *     gtk_drag_dest_get_target_list() and gtk_drag_dest_find_target().
+ * @n_targets: the number of entries in @targets
+ * @actions: a bitmask of possible actions for a drop onto this @widget.
+ *
+ * Sets a widget as a potential drop destination, and adds default behaviors.
+ *
+ * The default behaviors listed in @flags have an effect similar
+ * to installing default handlers for the widget’s drag-and-drop signals
+ * (#GtkWidget::drag-motion, #GtkWidget::drag-drop, ...). They all exist
+ * for convenience. When passing #GTK_DEST_DEFAULT_ALL for instance it is
+ * sufficient to connect to the widget’s #GtkWidget::drag-data-received
+ * signal to get primitive, but consistent drag-and-drop support.
+ *
+ * Things become more complicated when you try to preview the dragged data,
+ * as described in the documentation for #GtkWidget::drag-motion. The default
+ * behaviors described by @flags make some assumptions, that can conflict
+ * with your own signal handlers. For instance #GTK_DEST_DEFAULT_DROP causes
+ * invokations of gdk_drag_status() in the context of #GtkWidget::drag-motion,
+ * and invokations of gtk_drag_finish() in #GtkWidget::drag-data-received.
+ * Especially the later is dramatic, when your own #GtkWidget::drag-motion
+ * handler calls gtk_drag_get_data() to inspect the dragged data.
+ *
+ * There’s no way to set a default action here, you can use the
+ * #GtkWidget::drag-motion callback for that. Here’s an example which selects
+ * the action to use depending on whether the control key is pressed or not:
+ * |[<!-- language="C" -->
+ * static void
+ * drag_motion (GtkWidget *widget,
+ *              GdkDragContext *context,
+ *              gint x,
+ *              gint y,
+ *              guint time)
+ * {
+*   GdkModifierType mask;
+ *
+ *   gdk_window_get_pointer (gtk_widget_get_window (widget),
+ *                           NULL, NULL, &mask);
+ *   if (mask & GDK_CONTROL_MASK)
+ *     gdk_drag_status (context, GDK_ACTION_COPY, time);
+ *   else
+ *     gdk_drag_status (context, GDK_ACTION_MOVE, time);
+ * }
+ * ]|
+ */
+void
+gtk_drag_dest_set (GtkWidget            *widget,
+                   GtkDestDefaults       flags,
+                   const GtkTargetEntry *targets,
+                   gint                  n_targets,
+                   GdkDragAction         actions)
+{
+  GtkDragDestSite *site;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  site = g_slice_new0 (GtkDragDestSite);
+
+  site->flags = flags;
+  site->have_drag = FALSE;
+  if (targets)
+    site->target_list = gtk_target_list_new (targets, n_targets);
+  else
+    site->target_list = NULL;
+  site->actions = actions;
+  site->do_proxy = FALSE;
+  site->proxy_window = NULL;
+  site->track_motion = FALSE;
+
+  gtk_drag_dest_set_internal (widget, site);
+}
+
+/**
+ * gtk_drag_dest_set_proxy: (method)
+ * @widget: a #GtkWidget
+ * @proxy_window: the window to which to forward drag events
+ * @protocol: the drag protocol which the @proxy_window accepts
+ *   (You can use gdk_drag_get_protocol() to determine this)
+ * @use_coordinates: If %TRUE, send the same coordinates to the
+ *   destination, because it is an embedded
+ *   subwindow.
+ *
+ * Sets this widget as a proxy for drops to another window.
+ */
+void
+gtk_drag_dest_set_proxy (GtkWidget       *widget,
+                         GdkWindow       *proxy_window,
+                         GdkDragProtocol  protocol,
+                         gboolean         use_coordinates)
+{
+  GtkDragDestSite *site;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (!proxy_window || GDK_IS_WINDOW (proxy_window));
+
+  site = g_slice_new (GtkDragDestSite);
+
+  site->flags = 0;
+  site->have_drag = FALSE;
+  site->target_list = NULL;
+  site->actions = 0;
+  site->proxy_window = proxy_window;
+  if (proxy_window)
+    g_object_ref (proxy_window);
+  site->do_proxy = TRUE;
+  site->proxy_protocol = protocol;
+  site->proxy_coords = use_coordinates;
+  site->track_motion = FALSE;
+
+  gtk_drag_dest_set_internal (widget, site);
+}
+
+/**
+ * gtk_drag_dest_unset: (method)
+ * @widget: a #GtkWidget
+ *
+ * Clears information about a drop destination set with
+ * gtk_drag_dest_set(). The widget will no longer receive
+ * notification of drags.
+ */
+void
+gtk_drag_dest_unset (GtkWidget *widget)
+{
+  GtkDragDestSite *old_site;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  old_site = g_object_get_data (G_OBJECT (widget), I_("gtk-drag-dest"));
+  if (old_site)
+    {
+      g_signal_handlers_disconnect_by_func (widget,
+                                            gtk_drag_dest_realized,
+                                            old_site);
+      g_signal_handlers_disconnect_by_func (widget,
+                                            gtk_drag_dest_hierarchy_changed,
+                                            old_site);
+    }
+
+  g_object_set_data (G_OBJECT (widget), I_("gtk-drag-dest"), NULL);
+}
+
+/**
+ * gtk_drag_dest_get_target_list: (method)
+ * @widget: a #GtkWidget
+ *
+ * Returns the list of targets this widget can accept from
+ * drag-and-drop.
+ *
+ * Returns: (transfer none): the #GtkTargetList, or %NULL if none
+ */
+GtkTargetList *
+gtk_drag_dest_get_target_list (GtkWidget *widget)
+{
+  GtkDragDestSite *site;
+
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+  site = g_object_get_data (G_OBJECT (widget), I_("gtk-drag-dest"));
+
+  return site ? site->target_list : NULL;
+}
+
+/**
+ * gtk_drag_dest_set_target_list: (method)
+ * @widget: a #GtkWidget that’s a drag destination
+ * @target_list: (allow-none): list of droppable targets, or %NULL for none
+ *
+ * Sets the target types that this widget can accept from drag-and-drop.
+ * The widget must first be made into a drag destination with
+ * gtk_drag_dest_set().
+ */
+void
+gtk_drag_dest_set_target_list (GtkWidget     *widget,
+                               GtkTargetList *target_list)
+{
+  GtkDragDestSite *site;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  site = g_object_get_data (G_OBJECT (widget), I_("gtk-drag-dest"));
+
+  if (!site)
+    {
+      g_warning ("Can't set a target list on a widget until you've called gtk_drag_dest_set() "
+                 "to make the widget into a drag destination");
+      return;
+    }
+
+  if (target_list)
+    gtk_target_list_ref (target_list);
+
+  if (site->target_list)
+    gtk_target_list_unref (site->target_list);
+
+  site->target_list = target_list;
+}
+
+/**
+ * gtk_drag_dest_add_text_targets: (method)
+ * @widget: a #GtkWidget that’s a drag destination
+ *
+ * Add the text targets supported by #GtkSelectionData to
+ * the target list of the drag destination. The targets
+ * are added with @info = 0. If you need another value,
+ * use gtk_target_list_add_text_targets() and
+ * gtk_drag_dest_set_target_list().
+ *
+ * Since: 2.6
+ */
+void
+gtk_drag_dest_add_text_targets (GtkWidget *widget)
+{
+  GtkTargetList *target_list;
+
+  target_list = gtk_drag_dest_get_target_list (widget);
+  if (target_list)
+    gtk_target_list_ref (target_list);
+  else
+    target_list = gtk_target_list_new (NULL, 0);
+  gtk_target_list_add_text_targets (target_list, 0);
+  gtk_drag_dest_set_target_list (widget, target_list);
+  gtk_target_list_unref (target_list);
+}
+
+/**
+ * gtk_drag_dest_add_image_targets: (method)
+ * @widget: a #GtkWidget that’s a drag destination
+ *
+ * Add the image targets supported by #GtkSelectionData to
+ * the target list of the drag destination. The targets
+ * are added with @info = 0. If you need another value,
+ * use gtk_target_list_add_image_targets() and
+ * gtk_drag_dest_set_target_list().
+ *
+ * Since: 2.6
+ */
+void
+gtk_drag_dest_add_image_targets (GtkWidget *widget)
+{
+  GtkTargetList *target_list;
+
+  target_list = gtk_drag_dest_get_target_list (widget);
+  if (target_list)
+    gtk_target_list_ref (target_list);
+  else
+    target_list = gtk_target_list_new (NULL, 0);
+  gtk_target_list_add_image_targets (target_list, 0, FALSE);
+  gtk_drag_dest_set_target_list (widget, target_list);
+  gtk_target_list_unref (target_list);
+}
+
+/**
+ * gtk_drag_dest_add_uri_targets: (method)
+ * @widget: a #GtkWidget that’s a drag destination
+ *
+ * Add the URI targets supported by #GtkSelectionData to
+ * the target list of the drag destination. The targets
+ * are added with @info = 0. If you need another value,
+ * use gtk_target_list_add_uri_targets() and
+ * gtk_drag_dest_set_target_list().
+ *
+ * Since: 2.6
+ */
+void
+gtk_drag_dest_add_uri_targets (GtkWidget *widget)
+{
+  GtkTargetList *target_list;
+
+  target_list = gtk_drag_dest_get_target_list (widget);
+  if (target_list)
+    gtk_target_list_ref (target_list);
+  else
+    target_list = gtk_target_list_new (NULL, 0);
+  gtk_target_list_add_uri_targets (target_list, 0);
+  gtk_drag_dest_set_target_list (widget, target_list);
+  gtk_target_list_unref (target_list);
+}
+
+/**
+ * gtk_drag_dest_set_track_motion: (method)
+ * @widget: a #GtkWidget that’s a drag destination
+ * @track_motion: whether to accept all targets
+ *
+ * Tells the widget to emit #GtkWidget::drag-motion and
+ * #GtkWidget::drag-leave events regardless of the targets and the
+ * %GTK_DEST_DEFAULT_MOTION flag.
+ *
+ * This may be used when a widget wants to do generic
+ * actions regardless of the targets that the source offers.
+ *
+ * Since: 2.10
+ */
+void
+gtk_drag_dest_set_track_motion (GtkWidget *widget,
+                                gboolean   track_motion)
+{
+  GtkDragDestSite *site;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  site = g_object_get_data (G_OBJECT (widget), I_("gtk-drag-dest"));
+
+  g_return_if_fail (site != NULL);
+
+  site->track_motion = track_motion != FALSE;
+}
+
+/**
+ * gtk_drag_dest_get_track_motion: (method)
+ * @widget: a #GtkWidget that’s a drag destination
+ *
+ * Returns whether the widget has been configured to always
+ * emit #GtkWidget::drag-motion signals.
+ *
+ * Returns: %TRUE if the widget always emits
+ *   #GtkWidget::drag-motion events
+ *
+ * Since: 2.10
+ */
+gboolean
+gtk_drag_dest_get_track_motion (GtkWidget *widget)
+{
+  GtkDragDestSite *site;
+
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+  site = g_object_get_data (G_OBJECT (widget), I_("gtk-drag-dest"));
+
+  if (site)
+    return site->track_motion;
+
+  return FALSE;
+}
+
+/**
+ * gtk_drag_dest_find_target: (method)
+ * @widget: drag destination widget
+ * @context: drag context
+ * @target_list: (allow-none): list of droppable targets, or %NULL to use
+ *    gtk_drag_dest_get_target_list (@widget).
+ *
+ * Looks for a match between the supported targets of @context and the
+ * @dest_target_list, returning the first matching target, otherwise
+ * returning %GDK_NONE. @dest_target_list should usually be the return
+ * value from gtk_drag_dest_get_target_list(), but some widgets may
+ * have different valid targets for different parts of the widget; in
+ * that case, they will have to implement a drag_motion handler that
+ * passes the correct target list to this function.
+ *
+ * Returns: (transfer none): first target that the source offers
+ *     and the dest can accept, or %GDK_NONE
+ */
+GdkAtom
+gtk_drag_dest_find_target (GtkWidget      *widget,
+                           GdkDragContext *context,
+                           GtkTargetList  *target_list)
+{
+  GList *tmp_target;
+  GList *tmp_source = NULL;
+  GtkWidget *source_widget;
+
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), GDK_NONE);
+  g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), GDK_NONE);
+
+  source_widget = gtk_drag_get_source_widget (context);
+  if (target_list == NULL)
+    target_list = gtk_drag_dest_get_target_list (widget);
+
+  if (target_list == NULL)
+    return GDK_NONE;
+
+  tmp_target = target_list->list;
+  while (tmp_target)
+    {
+      GtkTargetPair *pair = tmp_target->data;
+      tmp_source = gdk_drag_context_list_targets (context);
+      while (tmp_source)
+        {
+          if (tmp_source->data == GUINT_TO_POINTER (pair->target))
+            {
+              if ((!(pair->flags & GTK_TARGET_SAME_APP) || source_widget) &&
+                  (!(pair->flags & GTK_TARGET_SAME_WIDGET) || (source_widget == widget)) &&
+                  (!(pair->flags & GTK_TARGET_OTHER_APP) || !source_widget) &&
+                  (!(pair->flags & GTK_TARGET_OTHER_WIDGET) || (source_widget != widget)))
+                return pair->target;
+              else
+                break;
+            }
+          tmp_source = tmp_source->next;
+        }
+      tmp_target = tmp_target->next;
+    }
+
+  return GDK_NONE;
+}
+
diff --git a/gtk/gtkdragdest.h b/gtk/gtkdragdest.h
new file mode 100644
index 0000000..6a91404
--- /dev/null
+++ b/gtk/gtkdragdest.h
@@ -0,0 +1,110 @@
+/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __GTK_DRAG_DEST_H__
+#define __GTK_DRAG_DEST_H__
+
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtkselection.h>
+#include <gtk/gtkwidget.h>
+
+
+G_BEGIN_DECLS
+
+/**
+ * GtkDestDefaults:
+ * @GTK_DEST_DEFAULT_MOTION: If set for a widget, GTK+, during a drag over this
+ *   widget will check if the drag matches this widget’s list of possible targets
+ *   and actions.
+ *   GTK+ will then call gdk_drag_status() as appropriate.
+ * @GTK_DEST_DEFAULT_HIGHLIGHT: If set for a widget, GTK+ will draw a highlight on
+ *   this widget as long as a drag is over this widget and the widget drag format
+ *   and action are acceptable.
+ * @GTK_DEST_DEFAULT_DROP: If set for a widget, when a drop occurs, GTK+ will
+ *   will check if the drag matches this widget’s list of possible targets and
+ *   actions. If so, GTK+ will call gtk_drag_get_data() on behalf of the widget.
+ *   Whether or not the drop is successful, GTK+ will call gtk_drag_finish(). If
+ *   the action was a move, then if the drag was successful, then %TRUE will be
+ *   passed for the @delete parameter to gtk_drag_finish().
+ * @GTK_DEST_DEFAULT_ALL: If set, specifies that all default actions should
+ *   be taken.
+ *
+ * The #GtkDestDefaults enumeration specifies the various
+ * types of action that will be taken on behalf
+ * of the user for a drag destination site.
+ */
+typedef enum {
+  GTK_DEST_DEFAULT_MOTION     = 1 << 0,
+  GTK_DEST_DEFAULT_HIGHLIGHT  = 1 << 1,
+  GTK_DEST_DEFAULT_DROP       = 1 << 2,
+  GTK_DEST_DEFAULT_ALL        = 0x07
+} GtkDestDefaults;
+
+GDK_AVAILABLE_IN_ALL
+void gtk_drag_dest_set   (GtkWidget            *widget,
+                          GtkDestDefaults       flags,
+                          const GtkTargetEntry *targets,
+                          gint                  n_targets,
+                          GdkDragAction         actions);
+
+GDK_AVAILABLE_IN_ALL
+void gtk_drag_dest_set_proxy (GtkWidget      *widget,
+                              GdkWindow      *proxy_window,
+                              GdkDragProtocol protocol,
+                              gboolean        use_coordinates);
+
+GDK_AVAILABLE_IN_ALL
+void gtk_drag_dest_unset (GtkWidget          *widget);
+
+GDK_AVAILABLE_IN_ALL
+GdkAtom        gtk_drag_dest_find_target     (GtkWidget      *widget,
+                                              GdkDragContext *context,
+                                              GtkTargetList  *target_list);
+GDK_AVAILABLE_IN_ALL
+GtkTargetList* gtk_drag_dest_get_target_list (GtkWidget      *widget);
+GDK_AVAILABLE_IN_ALL
+void           gtk_drag_dest_set_target_list (GtkWidget      *widget,
+                                              GtkTargetList  *target_list);
+GDK_AVAILABLE_IN_ALL
+void           gtk_drag_dest_add_text_targets  (GtkWidget    *widget);
+GDK_AVAILABLE_IN_ALL
+void           gtk_drag_dest_add_image_targets (GtkWidget    *widget);
+GDK_AVAILABLE_IN_ALL
+void           gtk_drag_dest_add_uri_targets   (GtkWidget    *widget);
+
+GDK_AVAILABLE_IN_ALL
+void           gtk_drag_dest_set_track_motion  (GtkWidget *widget,
+                                                gboolean   track_motion);
+GDK_AVAILABLE_IN_ALL
+gboolean       gtk_drag_dest_get_track_motion  (GtkWidget *widget);
+
+
+G_END_DECLS
+
+#endif /* __GTK_DRAG_DEST_H__ */
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c
index 5178b77..e4fdb61 100644
--- a/gtk/gtkfilechooserbutton.c
+++ b/gtk/gtkfilechooserbutton.c
@@ -36,6 +36,7 @@
 #include "gtkcombobox.h"
 #include "gtkcssiconthemevalueprivate.h"
 #include "gtkdnd.h"
+#include "gtkdragdest.h"
 #include "gtkicontheme.h"
 #include "deprecated/gtkiconfactory.h"
 #include "gtkimage.h"
diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c
index 653c11d..f026191 100644
--- a/gtk/gtkfilechooserwidget.c
+++ b/gtk/gtkfilechooserwidget.c
@@ -31,6 +31,7 @@
 #include "gtkclipboard.h"
 #include "gtkcomboboxtext.h"
 #include "gtkdragsource.h"
+#include "gtkdragdest.h"
 #include "gtkentry.h"
 #include "gtkexpander.h"
 #include "gtkfilechooserprivate.h"
diff --git a/gtk/gtkplacessidebar.c b/gtk/gtkplacessidebar.c
index 16d2ef2..958c3a7 100644
--- a/gtk/gtkplacessidebar.c
+++ b/gtk/gtkplacessidebar.c
@@ -52,6 +52,7 @@
 #include "gtkbutton.h"
 #include "gtklistbox.h"
 #include "gtkselection.h"
+#include "gtkdragdest.h"
 #include "gtkdnd.h"
 #include "gtkseparator.h"
 #include "gtkentry.h"
diff --git a/gtk/gtkselection.h b/gtk/gtkselection.h
index 6c338d0..678b3ac 100644
--- a/gtk/gtkselection.h
+++ b/gtk/gtkselection.h
@@ -70,6 +70,27 @@ typedef struct _GtkTargetEntry GtkTargetEntry;
 #define GTK_TYPE_TARGET_LIST    (gtk_target_list_get_type ())
 
 /**
+ * GtkTargetFlags:
+ * @GTK_TARGET_SAME_APP: If this is set, the target will only be selected
+ *   for drags within a single application.
+ * @GTK_TARGET_SAME_WIDGET: If this is set, the target will only be selected
+ *   for drags within a single widget.
+ * @GTK_TARGET_OTHER_APP: If this is set, the target will not be selected
+ *   for drags within a single application.
+ * @GTK_TARGET_OTHER_WIDGET: If this is set, the target will not be selected
+ *   for drags withing a single widget.
+ *
+ * The #GtkTargetFlags enumeration is used to specify
+ * constraints on a #GtkTargetEntry.
+ */
+typedef enum {
+  GTK_TARGET_SAME_APP = 1 << 0,    /*< nick=same-app >*/
+  GTK_TARGET_SAME_WIDGET = 1 << 1, /*< nick=same-widget >*/
+  GTK_TARGET_OTHER_APP = 1 << 2,   /*< nick=other-app >*/
+  GTK_TARGET_OTHER_WIDGET = 1 << 3 /*< nick=other-widget >*/
+} GtkTargetFlags;
+
+/**
  * GtkTargetEntry:
  * @target: a string representation of the target type
  * @flags: #GtkTargetFlags for DND
diff --git a/gtk/gtksocket.c b/gtk/gtksocket.c
index c71ee72..876d5aa 100644
--- a/gtk/gtksocket.c
+++ b/gtk/gtksocket.c
@@ -36,6 +36,7 @@
 #include "gtkprivate.h"
 #include "gtkrender.h"
 #include "gtkdnd.h"
+#include "gtkdragdest.h"
 #include "gtkdebug.h"
 #include "gtkintl.h"
 #include "gtkmain.h"


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