diff -rupN gtk+-2.20.0/gdk/win32/gdkdnd-win32.c gtk+-2.18.9/gdk/win32/gdkdnd-win32.c
--- gtk+-2.20.0/gdk/win32/gdkdnd-win32.c	2010-03-22 20:44:10.000000000 +0800
+++ gtk+-2.18.9/gdk/win32/gdkdnd-win32.c	2010-03-17 21:31:42.000000000 +0800
@@ -1,6 +1,5 @@
 /* GDK - The GIMP Drawing Kit
  * Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald
- * Copyright (C) 2001 Archaeopteryx Software Inc.
  * Copyright (C) 1998-2002 Tor Lillqvist
  *
  * This library is free software; you can redistribute it and/or
@@ -23,53 +22,14 @@
  * 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/.
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
 #include "config.h"
 #include <string.h>
 
-#include <io.h>
-#include <fcntl.h>
+/* #define OLE2_DND */
 
-/*
- * Comment from the old OLE2 DND code that is being merged in. Note
- * that this comment might not fully reflect reality as the code
- * obviously will have to be modified in this merge. Especially the
- * talk about supporting other than UTF-8 text is bogus, that will not
- * happen.
- *
- * Support for OLE-2 drag and drop added at Archaeopteryx Software, 2001
- * For more information, contact Stephan R.A. Deibel (sdeibel@archaeopteryx.com)
- *
- * Notes on implementation:
- *
- * This is a first pass at OLE2 support. It only supports text and unicode text
- * data types, and file list dnd (which is handled seperately as it predates OLE2
- * both in this implementation and on Windows in general).
- *
- * As such, the data type conversion from gdk selection targets to OLE2 CF_* data
- * type specifiers is partially hardwired. Fixing this is complicated by (a) the
- * fact that the widget's declared selection types aren't accessible in calls here
- * that need to declare the corresponding OLE2 data types, and (b) there isn't a
- * 1-1 correspondence between gdk target types and OLE2 types. The former needs
- * some redesign in gtk dnd (something a gdk/gtk expert should do; I have tried
- * and failed!). As an example of the latter: gdk STRING, TEXT, COMPOUND_TEXT map
- * to CF_TEXT, CF_OEMTEXT, and CF_UNICODETEXT but as a group and with conversions
- * necessary for various combinations. Currently, the code here (and in
- * gdkdnd-win32.c) can handle gdk STRING and TEXT but not COMPOUND_TEXT, and OLE2
- * CF_TEXT and CF_UNICODETEXT but not CF_OEMTEXT. The necessary conversions are
- * supplied by the implementation here.
- *
- * Note that in combination with another hack originated by Archaeopteryx
- * Software, the text conversions here may go to utf-8 unicode as the standard
- * within-gtk target or to single-byte ascii when the USE_ACP_TEXT compilation
- * flag is TRUE. This mode was added to support applications that aren't using
- * utf-8 across the gtk/gdk API but instead use single-byte ascii according to
- * the current Windows code page. See gdkim-win32.c for more info on that.
- *
- */
- 
 #define INITGUID
 
 #include "gdkdnd.h"
@@ -77,13 +37,16 @@
 #include "gdkinternals.h"
 #include "gdkprivate-win32.h"
 
+#ifdef OLE2_DND
 #include <ole2.h>
+#else
+#include <objbase.h>
+#endif
 
 #include <shlobj.h>
 #include <shlguid.h>
 
 #include <gdk/gdk.h>
-#include <glib/gstdio.h>
 
 typedef struct _GdkDragContextPrivateWin32 GdkDragContextPrivateWin32;
 
@@ -92,24 +55,53 @@ typedef enum {
   GDK_DRAG_STATUS_MOTION_WAIT,
   GDK_DRAG_STATUS_ACTION_WAIT,
   GDK_DRAG_STATUS_DROP
-} GdkDragStatus;
+} GtkDragStatus;
+
+typedef enum {
+  GDK_DRAG_SOURCE,
+  GDK_DRAG_TARGET
+} GdkDragKind;
+
+#ifdef OLE2_DND
+
+#define PRINT_GUID(guid) \
+  g_print ("guid = %.08lx-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x", \
+	   ((gulong *)  guid)[0], \
+	   ((gushort *) guid)[2], \
+	   ((gushort *) guid)[3], \
+	   ((guchar *)  guid)[8], \
+	   ((guchar *)  guid)[9], \
+	   ((guchar *)  guid)[10], \
+	   ((guchar *)  guid)[11], \
+	   ((guchar *)  guid)[12], \
+	   ((guchar *)  guid)[13], \
+	   ((guchar *)  guid)[14], \
+	   ((guchar *)  guid)[15]);
+
+
+static FORMATETC *formats;
+static int nformats;
+
+#endif /* OLE2_DND */
 
 /* Structure that holds information about a drag in progress.
  * this is used on both source and destination sides.
  */
 struct _GdkDragContextPrivateWin32 {
+#ifdef OLE2_DND
   gboolean being_finalized;
   gint ref_count;
   IUnknown *iface;
-  DWORD last_key_state;
-  POINT last_pt;		/* Coordinates from last event */
+#endif
+  guint16 last_x;		/* Coordinates from last event */
+  guint16 last_y;
+  HWND dest_xid;
   guint drag_status : 4;	/* Current status of drag */
   guint drop_failed : 1;	/* Whether the drop was unsuccessful */
 };
 
 #define PRIVATE_DATA(context) ((GdkDragContextPrivateWin32 *) GDK_DRAG_CONTEXT (context)->windowing_data)
 
-static GList *contexts;
 static GdkDragContext *current_dest_drag = NULL;
 
 static void gdk_drag_context_init       (GdkDragContext      *dragcontext);
@@ -117,8 +109,7 @@ static void gdk_drag_context_class_init
 static void gdk_drag_context_finalize   (GObject              *object);
 
 static gpointer parent_class = NULL;
-
-static gboolean use_ole2_dnd = FALSE;
+static GList *contexts;
 
 G_DEFINE_TYPE (GdkDragContext, gdk_drag_context, G_TYPE_OBJECT)
 
@@ -127,22 +118,18 @@ gdk_drag_context_init (GdkDragContext *d
 {
   GdkDragContextPrivateWin32 *private;
 
-  private = G_TYPE_INSTANCE_GET_PRIVATE (dragcontext,
-					 GDK_TYPE_DRAG_CONTEXT,
+  private = G_TYPE_INSTANCE_GET_PRIVATE (dragcontext, 
+					 GDK_TYPE_DRAG_CONTEXT, 
 					 GdkDragContextPrivateWin32);
-
+  
   dragcontext->windowing_data = private;
+#ifdef OLE2_DND
+  private->being_finalized = FALSE;
+  private->ref_count = 1;
+  private->iface = NULL;
+#endif
 
-  if (!use_ole2_dnd)
-    {
-      contexts = g_list_prepend (contexts, dragcontext);
-    }
-  else
-    {
-      private->being_finalized = FALSE;
-      private->ref_count = 1;
-      private->iface = NULL;
-    }
+  contexts = g_list_prepend (contexts, dragcontext);
 
   GDK_NOTE (DND, g_print ("gdk_drag_context_init %p\n", dragcontext));
 }
@@ -163,35 +150,34 @@ static void
 gdk_drag_context_finalize (GObject *object)
 {
   GdkDragContext *context = GDK_DRAG_CONTEXT (object);
-
+ 
   GDK_NOTE (DND, g_print ("gdk_drag_context_finalize %p\n", object));
-
+ 
   g_list_free (context->targets);
 
   if (context->source_window)
     g_object_unref (context->source_window);
-
+  
   if (context->dest_window)
     g_object_unref (context->dest_window);
+  
+  contexts = g_list_remove (contexts, context);
 
-  if (!use_ole2_dnd)
-    {
-      contexts = g_list_remove (contexts, context);
-
-      if (context == current_dest_drag)
-	current_dest_drag = NULL;
-    }
-  else
-    {
-      GdkDragContextPrivateWin32 *private = PRIVATE_DATA (context);
-      if (private->iface)
-	{
-	  private->being_finalized = TRUE;
-	  private->iface->lpVtbl->Release (private->iface);
-	  private->iface = NULL;
-	}
-    }
+  if (context == current_dest_drag)
+    current_dest_drag = NULL;
 
+#ifdef OLE2_DND
+  {
+    GdkDragContextPrivateWin32 *private = PRIVATE_DATA (context);
+    if (private->iface)
+      {
+	private->being_finalized = TRUE;
+	private->iface->lpVtbl->Release (private->iface);
+	private->iface = NULL;
+      }
+  }
+#endif
+      
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -237,30 +223,14 @@ gdk_drag_context_find (gboolean   is_sou
 	  ((source == NULL) || (context->source_window && (context->source_window == source))) &&
 	  ((dest == NULL) || (context->dest_window && (context->dest_window == dest))))
 	return context;
-
+      
       tmp_list = tmp_list->next;
     }
-
+  
   return NULL;
 }
 
-#define PRINT_GUID(guid) \
-  g_print ("%.08lx-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x", \
-	   ((gulong *)  guid)[0], \
-	   ((gushort *) guid)[2], \
-	   ((gushort *) guid)[3], \
-	   ((guchar *)  guid)[8], \
-	   ((guchar *)  guid)[9], \
-	   ((guchar *)  guid)[10], \
-	   ((guchar *)  guid)[11], \
-	   ((guchar *)  guid)[12], \
-	   ((guchar *)  guid)[13], \
-	   ((guchar *)  guid)[14], \
-	   ((guchar *)  guid)[15]);
-
-
-static FORMATETC *formats;
-static int nformats;
+#ifdef OLE2_DND
 
 typedef struct {
   IDropTarget idt;
@@ -275,7 +245,6 @@ typedef struct {
 typedef struct {
   IDataObject ido;
   int ref_count;
-  GdkDragContext *context;
 } data_object;
 
 typedef struct {
@@ -284,16 +253,8 @@ typedef struct {
   int ix;
 } enum_formats;
 
-static source_drag_context *pending_src_context = NULL;
-static IDataObject *dnd_data = NULL;
-
 static enum_formats *enum_formats_new (void);
 
-/* map windows -> target drag contexts. The table
- * owns a ref to both objects.
- */
-static GHashTable* target_ctx_for_window = NULL;
-
 static ULONG STDMETHODCALLTYPE
 idroptarget_addref (LPDROPTARGET This)
 {
@@ -303,7 +264,7 @@ idroptarget_addref (LPDROPTARGET This)
 
   GDK_NOTE (DND, g_print ("idroptarget_addref %p %d\n", This, ref_count));
   g_object_ref (G_OBJECT (ctx->context));
-
+  
   return ref_count;
 }
 
@@ -312,30 +273,29 @@ idroptarget_queryinterface (LPDROPTARGET
 			    REFIID       riid,
 			    LPVOID      *ppvObject)
 {
-  GDK_NOTE (DND, {
-      g_print ("idroptarget_queryinterface %p ", This);
-      PRINT_GUID (riid);
-    });
+  GDK_NOTE (DND, g_print ("idroptarget_queryinterface %p\n", This));
 
   *ppvObject = NULL;
 
+  PRINT_GUID (riid);
+
   if (IsEqualGUID (riid, &IID_IUnknown))
     {
-      GDK_NOTE (DND, g_print ("...IUnknown S_OK\n"));
+      g_print ("...IUnknown\n");
       idroptarget_addref (This);
       *ppvObject = This;
       return S_OK;
     }
   else if (IsEqualGUID (riid, &IID_IDropTarget))
     {
-      GDK_NOTE (DND, g_print ("...IDropTarget S_OK\n"));
+      g_print ("...IDropTarget\n");
       idroptarget_addref (This);
       *ppvObject = This;
       return S_OK;
     }
   else
     {
-      GDK_NOTE (DND, g_print ("...E_NOINTERFACE\n"));
+      g_print ("...Nope\n");
       return E_NOINTERFACE;
     }
 }
@@ -358,128 +318,26 @@ idroptarget_release (LPDROPTARGET This)
   return ref_count;
 }
 
-#if 0
-
-static GdkAtom
-cf_to_atom (CLIPFORMAT cf)
-{
-  switch (cf)
-    {
-    case CF_UNICODETEXT:
-      return _utf8_string;
-    case CF_HDROP:
-      return _text_uri_list;
-    case CF_DIB:
-      return _image_bmp;
-    }
-
-  if (cf == _cf_url)
-    return _text_uri_list;
-
-  if (cf == _cf_html_format || cf == _cf_text_html)
-    return _text_html;
-
-  return GDK_NONE;
-}
-
-#endif
-
-static GdkDragAction
-get_suggested_action (DWORD grfKeyState)
-{
-  /* This is the yucky Windows standard: Force link action if both
-   * Control and Alt are down, copy if Control is down alone, move if
-   * Alt is down alone, or use default of move within the app or copy
-   * when origin of the drag is in another app.
-   */
-  if (grfKeyState & MK_CONTROL && grfKeyState & MK_SHIFT)
-    return GDK_ACTION_LINK; /* Link action not supported */
-  else if (grfKeyState & MK_CONTROL)
-    return GDK_ACTION_COPY;
-  else if (grfKeyState & MK_ALT)
-    return GDK_ACTION_MOVE;
-#if 0 /* Default is always copy for now */
-  else if (_dnd_source_state == GDK_WIN32_DND_DRAGGING)
-    return GDK_ACTION_MOVE;
-#endif
-  else
-    return GDK_ACTION_COPY;
-  /* Any way to determine when to add in DROPEFFECT_SCROLL? */
-}
-
-/* Process pending events -- we don't want to service non-GUI events
- * forever so do one iteration and then do more only if there's a
- * pending GDK event.
- */
-static void
-process_pending_events ()
-{
-  g_main_context_iteration (NULL, FALSE);
-  while (_gdk_event_queue_find_first (_gdk_display))
-    g_main_context_iteration (NULL, FALSE);
-}
-
-static DWORD
-drop_effect_for_action (GdkDragAction action)
-{
-  switch (action)
-    {
-    case GDK_ACTION_MOVE:
-      return DROPEFFECT_MOVE;
-    case GDK_ACTION_LINK:
-      return DROPEFFECT_LINK;
-    case GDK_ACTION_COPY:
-      return DROPEFFECT_COPY;
-    default:
-      return DROPEFFECT_NONE;
-    }
-}
-
-static void
-dnd_event_put (GdkEventType    type,
-	       GdkDragContext *context,
-	       const POINTL    pt,
-	       gboolean        to_dest_window)
-{
-  GdkEvent e;
-  e.type = type;
-  if (to_dest_window)
-    e.dnd.window = context->dest_window;
-  else
-    e.dnd.window = context->source_window;
-  e.dnd.send_event = FALSE;
-  e.dnd.context = context;
-  e.dnd.time = GDK_CURRENT_TIME;
-  e.dnd.x_root = pt.x + _gdk_offset_x;
-  e.dnd.y_root = pt.x + _gdk_offset_y;
-
-  gdk_drag_context_ref (e.dnd.context);
-  if (e.dnd.window != NULL)
-    g_object_ref (e.dnd.window);
-
-  GDK_NOTE (EVENTS, _gdk_win32_print_event (&e));
-  gdk_event_put (&e);
-}
-
-static HRESULT STDMETHODCALLTYPE
+static HRESULT STDMETHODCALLTYPE 
 idroptarget_dragenter (LPDROPTARGET This,
 		       LPDATAOBJECT pDataObj,
 		       DWORD        grfKeyState,
 		       POINTL       pt,
 		       LPDWORD      pdwEffect)
 {
-  target_drag_context *ctx = (target_drag_context *) This;
+  IEnumFORMATETC* iefp;
+  FORMATETC formatetc;
 
-  GDK_NOTE (DND, g_print ("idroptarget_dragenter %p S_OK\n", This));
+  GDK_NOTE (DND, g_print ("idroptarget_dragenter %p formats:\n", This));
 
-  ctx->context->suggested_action = get_suggested_action (grfKeyState);
-  dnd_event_put (GDK_DRAG_ENTER, ctx->context, pt, TRUE);
-  process_pending_events ();
-  *pdwEffect = drop_effect_for_action (ctx->context->action);
-
-  /* Assume that target can accept the data: In fact it may fail but
-   * we are not really set up to query the target!
-   */
+  pDataObj->lpVtbl->EnumFormatEtc (pDataObj, DATADIR_GET, &iefp);
+  while (iefp->lpVtbl->Next (iefp, 1, &formatetc, NULL) == S_OK)
+    {
+      GDK_NOTE (DND, g_print ("  %s\n", _gdk_win32_cf_to_string (formatetc.cfFormat)));
+    }
+  iefp->lpVtbl->Release (iefp);
+  
+  *pdwEffect = DROPEFFECT_COPY;
   return S_OK;
 }
 
@@ -489,28 +347,16 @@ idroptarget_dragover (LPDROPTARGET This,
 		      POINTL       pt,
 		      LPDWORD      pdwEffect)
 {
-  target_drag_context *ctx = (target_drag_context *) This;
-
-  GDK_NOTE (DND, g_print ("idroptarget_dragover %p S_OK\n", This));
-
-  ctx->context->suggested_action = get_suggested_action (grfKeyState);
-  dnd_event_put (GDK_DRAG_MOTION, ctx->context, pt, TRUE);
-  process_pending_events ();
-  *pdwEffect = drop_effect_for_action (ctx->context->action);
+  GDK_NOTE (DND, g_print ("idroptarget_dragover %p\n", This));
 
+  *pdwEffect = DROPEFFECT_COPY;
   return S_OK;
 }
 
 static HRESULT STDMETHODCALLTYPE
 idroptarget_dragleave (LPDROPTARGET This)
 {
-  target_drag_context *ctx = (target_drag_context *) This;
-  POINTL pt = { 0, 0 };
-
-  GDK_NOTE (DND, g_print ("idroptarget_dragleave %p S_OK\n", This));
-
-  dnd_event_put (GDK_DRAG_LEAVE, ctx->context, pt, TRUE);
-  process_pending_events ();
+  GDK_NOTE (DND, g_print ("idroptarget_dragleave %p\n", This));
 
   return S_OK;
 }
@@ -522,32 +368,9 @@ idroptarget_drop (LPDROPTARGET This,
 		  POINTL       pt,
 		  LPDWORD      pdwEffect)
 {
-  target_drag_context *ctx = (target_drag_context *) This;
-
-  GDK_NOTE (DND, g_print ("idroptarget_drop %p ", This));
-
-  if (pDataObj == NULL)
-    {
-      GDK_NOTE (DND, g_print ("E_POINTER\n"));
-      return E_POINTER;
-    }
-
-  dnd_data = pDataObj;
-
-  ctx->context->suggested_action = get_suggested_action (grfKeyState);
-  dnd_event_put (GDK_DROP_START, ctx->context, pt, TRUE);
-  process_pending_events ();
-
-  dnd_data = NULL;
-
-  /* Notify OLE of copy or move */
-  if (_dnd_target_state != GDK_WIN32_DND_DROPPED)
-    *pdwEffect = DROPEFFECT_NONE;
-  else
-    *pdwEffect = drop_effect_for_action (ctx->context->action);
-
-  GDK_NOTE (DND, g_print ("S_OK\n"));
+  GDK_NOTE (DND, g_print ("idroptarget_drop %p\n", This));
 
+  *pdwEffect = DROPEFFECT_COPY;
   return S_OK;
 }
 
@@ -560,7 +383,7 @@ idropsource_addref (LPDROPSOURCE This)
 
   GDK_NOTE (DND, g_print ("idropsource_addref %p %d\n", This, ref_count));
   g_object_ref (G_OBJECT (ctx->context));
-
+  
   return ref_count;
 }
 
@@ -569,30 +392,28 @@ idropsource_queryinterface (LPDROPSOURCE
 			    REFIID       riid,
 			    LPVOID      *ppvObject)
 {
-  GDK_NOTE (DND, {
-      g_print ("idropsource_queryinterface %p ", This);
-      PRINT_GUID (riid);
-    });
+  GDK_NOTE (DND, g_print ("idropsource_queryinterface %p\n", This));
 
   *ppvObject = NULL;
 
+  PRINT_GUID (riid);
   if (IsEqualGUID (riid, &IID_IUnknown))
     {
-      GDK_NOTE (DND, g_print ("...IUnknown S_OK\n"));
+      g_print ("...IUnknown\n");
       idropsource_addref (This);
       *ppvObject = This;
       return S_OK;
     }
   else if (IsEqualGUID (riid, &IID_IDropSource))
     {
-      GDK_NOTE (DND, g_print ("...IDropSource S_OK\n"));
+      g_print ("...IDropSource\n");
       idropsource_addref (This);
       *ppvObject = This;
       return S_OK;
     }
   else
     {
-      GDK_NOTE (DND, g_print ("...E_NOINTERFACE\n"));
+      g_print ("...Nope\n");
       return E_NOINTERFACE;
     }
 }
@@ -615,149 +436,23 @@ idropsource_release (LPDROPSOURCE This)
   return ref_count;
 }
 
-/* Emit GDK events for any changes in mouse events or control key
- * state since the last recorded state. Return true if any events
- * have been emitted and false otherwise.
- */
-static gboolean
-send_change_events (GdkDragContext *ctx,
-		    DWORD           key_state,
-		    gboolean        esc_pressed)
-{
-  GdkDragContextPrivateWin32 *private = PRIVATE_DATA (ctx);
-  POINT pt;
-  gboolean changed = FALSE;
-  HWND hwnd = GDK_WINDOW_HWND (ctx->source_window);
-  LPARAM lparam;
-  WPARAM wparam;
-
-  if (!API_CALL (GetCursorPos, (&pt)))
-    return FALSE;
-
-  if (!API_CALL (ScreenToClient, (hwnd, &pt)))
-    return FALSE;
-
-  if (pt.x != private->last_pt.x || pt.y != private->last_pt.y ||
-      key_state != private->last_key_state)
-    {
-      lparam = MAKELPARAM (pt.x, pt.y);
-      wparam = key_state;
-      if (pt.x != private->last_pt.x || pt.y != private->last_pt.y)
-	{
-	  GDK_NOTE (DND, g_print ("Sending WM_MOUSEMOVE (%ld,%ld)\n", pt.x, pt.y));
-      	  SendMessage (hwnd, WM_MOUSEMOVE, wparam, lparam);
-	}
-
-      if ((key_state & MK_LBUTTON) != (private->last_key_state & MK_LBUTTON))
-	{
-	  if (key_state & MK_LBUTTON)
-	    SendMessage (hwnd, WM_LBUTTONDOWN, wparam, lparam);
-	  else
-	    SendMessage (hwnd, WM_LBUTTONUP, wparam, lparam);
-	}
-      if ((key_state & MK_MBUTTON) != (private->last_key_state & MK_MBUTTON))
-	{
-	  if (key_state & MK_MBUTTON)
-	    SendMessage (hwnd, WM_MBUTTONDOWN, wparam, lparam);
-	  else
-	    SendMessage (hwnd, WM_MBUTTONUP, wparam, lparam);
-	}
-      if ((key_state & MK_RBUTTON) != (private->last_key_state & MK_RBUTTON))
-	{
-	  if (key_state & MK_RBUTTON)
-	    SendMessage (hwnd, WM_RBUTTONDOWN, wparam, lparam);
-	  else
-	    SendMessage (hwnd, WM_RBUTTONUP, wparam, lparam);
-	}
-      if ((key_state & MK_CONTROL) != (private->last_key_state & MK_CONTROL))
-	{
-	  if (key_state & MK_CONTROL)
-	    SendMessage (hwnd, WM_KEYDOWN, VK_CONTROL, 0);
-	  else
-	    SendMessage (hwnd, WM_KEYUP, VK_CONTROL, 0);
-	}
-      if ((key_state & MK_SHIFT) != (private->last_key_state & MK_SHIFT))
-	{
-	  if (key_state & MK_CONTROL)
-	    SendMessage (hwnd, WM_KEYDOWN, VK_SHIFT, 0);
-	  else
-	    SendMessage (hwnd, WM_KEYUP, VK_SHIFT, 0);
-	}
-
-      changed = TRUE;
-      private->last_key_state = key_state;
-      private->last_pt = pt;
-    }
-
-  if (esc_pressed)
-    {
-      GDK_NOTE (DND, g_print ("Sending a escape key down message to %p\n", hwnd));
-      SendMessage (hwnd, WM_KEYDOWN, VK_ESCAPE, 0);
-      changed = TRUE;
-    }
-
-  return changed;
-}
-
 static HRESULT STDMETHODCALLTYPE
 idropsource_querycontinuedrag (LPDROPSOURCE This,
 			       BOOL         fEscapePressed,
 			       DWORD        grfKeyState)
 {
-  source_drag_context *ctx = (source_drag_context *) This;
-
-  GDK_NOTE (DND, g_print ("idropsource_querycontinuedrag %p ", This));
+  GDK_NOTE (DND, g_print ("idropsource_querycontinuedrag %p\n", This));
 
-  if (send_change_events (ctx->context, grfKeyState, fEscapePressed))
-    process_pending_events ();
-
-  if (_dnd_source_state == GDK_WIN32_DND_DROPPED)
-    {
-      GDK_NOTE (DND, g_print ("DRAGDROP_S_DROP\n"));
-      return DRAGDROP_S_DROP;
-    }
-  else if (_dnd_source_state == GDK_WIN32_DND_NONE)
-    {
-      GDK_NOTE (DND, g_print ("DRAGDROP_S_CANCEL\n"));
-      return DRAGDROP_S_CANCEL;
-    }
-  else
-    {
-      GDK_NOTE (DND, g_print ("S_OK\n"));
-      return S_OK;
-    }
+  return E_UNEXPECTED;
 }
 
 static HRESULT STDMETHODCALLTYPE
 idropsource_givefeedback (LPDROPSOURCE This,
 			  DWORD        dwEffect)
 {
-  source_drag_context *ctx = (source_drag_context *) This;
-  GdkDragAction suggested_action;
-
-  GDK_NOTE (DND, g_print ("idropsource_givefeedback %p DRAGDROP_S_USEDEFAULTCURSORS\n", This));
-
-  if (dwEffect == DROPEFFECT_MOVE)
-    suggested_action = GDK_ACTION_MOVE;
-  else
-    suggested_action = GDK_ACTION_COPY;
-  ctx->context->action = suggested_action;
+  GDK_NOTE (DND, g_print ("idropsource_givefeedback %p\n", This));
 
-  if (dwEffect == DROPEFFECT_NONE)
-    {
-      if (ctx->context->dest_window != NULL)
-	{
-	  g_object_unref (ctx->context->dest_window);
-	  ctx->context->dest_window = NULL;
-	}
-    }
-  else
-    {
-      if (ctx->context->dest_window == NULL)
-	ctx->context->dest_window = g_object_ref (_gdk_root);
-    }
-
-  return DRAGDROP_S_USEDEFAULTCURSORS;
+  return E_UNEXPECTED;
 }
 
 static ULONG STDMETHODCALLTYPE
@@ -776,30 +471,28 @@ idataobject_queryinterface (LPDATAOBJECT
 			    REFIID       riid,
 			    LPVOID      *ppvObject)
 {
-  GDK_NOTE (DND, {
-      g_print ("idataobject_queryinterface %p ", This);
-      PRINT_GUID (riid);
-    });
+  GDK_NOTE (DND, g_print ("idataobject_queryinterface %p\n", This));
 
   *ppvObject = NULL;
 
+  PRINT_GUID (riid);
   if (IsEqualGUID (riid, &IID_IUnknown))
     {
-      GDK_NOTE (DND, g_print ("...IUnknown S_OK\n"));
+      g_print ("...IUnknown\n");
       idataobject_addref (This);
       *ppvObject = This;
       return S_OK;
     }
   else if (IsEqualGUID (riid, &IID_IDataObject))
     {
-      GDK_NOTE (DND, g_print ("...IDataObject S_OK\n"));
+      g_print ("...IDataObject\n");
       idataobject_addref (This);
       *ppvObject = This;
       return S_OK;
     }
   else
     {
-      GDK_NOTE (DND, g_print ("...E_NOINTERFACE\n"));
+      g_print ("...Nope\n");
       return E_NOINTERFACE;
     }
 }
@@ -818,85 +511,14 @@ idataobject_release (LPDATAOBJECT This)
   return ref_count;
 }
 
-static HRESULT
-query (LPDATAOBJECT This,
-       LPFORMATETC  pFormatEtc)
-{
-  int i;
-
-  if (!pFormatEtc)
-    return DV_E_FORMATETC;
-
-  if (pFormatEtc->lindex != -1)
-    return DV_E_LINDEX;
-
-  if ((pFormatEtc->tymed & TYMED_HGLOBAL) == 0)
-    return DV_E_TYMED;
-
-  if ((pFormatEtc->dwAspect & DVASPECT_CONTENT) == 0)
-    return DV_E_DVASPECT;
-
-  for (i = 0; i < nformats; i++)
-    if (pFormatEtc->cfFormat == formats[i].cfFormat)
-      return S_OK;
-
-  return DV_E_FORMATETC;
-}
-
-static FORMATETC *active_pFormatEtc = NULL;
-static STGMEDIUM *active_pMedium = NULL;
-
 static HRESULT STDMETHODCALLTYPE
 idataobject_getdata (LPDATAOBJECT This,
 		     LPFORMATETC  pFormatEtc,
 		     LPSTGMEDIUM  pMedium)
 {
-  data_object *ctx = (data_object *) This;
-  GdkAtom target;
-  HRESULT hr;
-  GdkEvent e;
-
-  GDK_NOTE (DND, g_print ("idataobject_getdata %p %s ",
-			  This, _gdk_win32_cf_to_string (pFormatEtc->cfFormat)));
-
-  /* Check whether we can provide requested format */
-  hr = query (This, pFormatEtc);
-  if (hr != S_OK)
-    return hr;
-
-  /* Append a GDK_SELECTION_GET event and then hope the app sets the
-   * property associated with the _gdk_ole2_dnd atom
-   */
-
-  active_pFormatEtc = pFormatEtc;
-  active_pMedium = pMedium;
+  GDK_NOTE (DND, g_print ("idataobject_getdata %p\n", This));
 
-  target = GDK_TARGET_STRING;
-
-  e.type = GDK_SELECTION_REQUEST;
-  e.selection.window = ctx->context->source_window;
-  e.selection.send_event = FALSE; /* ??? */
-  /* FIXME: Should really both selection and property be _gdk_ole2_dnd? */
-  e.selection.selection = _gdk_ole2_dnd;
-  /* FIXME: Target? */
-  e.selection.target = _utf8_string;
-  e.selection.property = _gdk_ole2_dnd;
-  e.selection.time = GDK_CURRENT_TIME;
-
-  g_object_ref (e.selection.window);
-
-  GDK_NOTE (EVENTS, _gdk_win32_print_event (&e));
-  gdk_event_put (&e);
-  process_pending_events ();
-
-  active_pFormatEtc = NULL;
-  active_pMedium = NULL;
-
-  if (pMedium->hGlobal == NULL) {
-    return E_UNEXPECTED;
-  }
-
-  return S_OK;
+  return E_UNEXPECTED;
 }
 
 static HRESULT STDMETHODCALLTYPE
@@ -904,8 +526,7 @@ idataobject_getdatahere (LPDATAOBJECT Th
 			 LPFORMATETC  pFormatEtc,
 			 LPSTGMEDIUM  pMedium)
 {
-  GDK_NOTE (DND, g_print ("idataobject_getdatahere %p %s E_UNEXPECTED\n",
-			  This, _gdk_win32_cf_to_string (pFormatEtc->cfFormat)));
+  GDK_NOTE (DND, g_print ("idataobject_getdatahere %p\n", This));
 
   return E_UNEXPECTED;
 }
@@ -914,26 +535,19 @@ static HRESULT STDMETHODCALLTYPE
 idataobject_querygetdata (LPDATAOBJECT This,
 			  LPFORMATETC  pFormatEtc)
 {
-  HRESULT hr;
+  int i;
 
-  hr = query (This, pFormatEtc);
+  GDK_NOTE (DND, g_print ("idataobject_querygetdata %p %#x", This, pFormatEtc->cfFormat));
 
-#define CASE(x) case x: g_print (#x)
-  GDK_NOTE (DND, {
-      g_print ("idataobject_querygetdata %p %s \n",
-	       This, _gdk_win32_cf_to_string (pFormatEtc->cfFormat));
-      switch (hr)
-	{
-	CASE (DV_E_FORMATETC);
-	CASE (DV_E_LINDEX);
-	CASE (DV_E_TYMED);
-	CASE (DV_E_DVASPECT);
-	CASE (S_OK);
-	default: g_print ("%#lx", hr);
-	}
-    });
+  for (i = 0; i < nformats; i++)
+    if (pFormatEtc->cfFormat == formats[i].cfFormat)
+      {
+	GDK_NOTE (DND, g_print (" S_OK\n"));
+	return S_OK;
+      }
 
-  return hr;
+  GDK_NOTE (DND, g_print (" DV_E_FORMATETC\n"));
+  return DV_E_FORMATETC;
 }
 
 static HRESULT STDMETHODCALLTYPE
@@ -941,9 +555,9 @@ idataobject_getcanonicalformatetc (LPDAT
 				   LPFORMATETC  pFormatEtcIn,
 				   LPFORMATETC  pFormatEtcOut)
 {
-  GDK_NOTE (DND, g_print ("idataobject_getcanonicalformatetc %p E_UNEXPECTED\n", This));
+  GDK_NOTE (DND, g_print ("idataobject_getcanonicalformatetc %p\n", This));
 
-  return E_UNEXPECTED;
+  return E_FAIL;
 }
 
 static HRESULT STDMETHODCALLTYPE
@@ -952,8 +566,7 @@ idataobject_setdata (LPDATAOBJECT This,
 		     LPSTGMEDIUM  pMedium,
 		     BOOL         fRelease)
 {
-  GDK_NOTE (DND, g_print ("idataobject_setdata %p %s E_UNEXPECTED\n",
-			  This, _gdk_win32_cf_to_string (pFormatEtc->cfFormat)));
+  GDK_NOTE (DND, g_print ("idataobject_setdata %p\n", This));
 
   return E_UNEXPECTED;
 }
@@ -963,18 +576,12 @@ idataobject_enumformatetc (LPDATAOBJECT
 			   DWORD            dwDirection,
 			   LPENUMFORMATETC *ppEnumFormatEtc)
 {
-  GDK_NOTE (DND, g_print ("idataobject_enumformatetc %p ", This));
+  GDK_NOTE (DND, g_print ("idataobject_enumformatetc %p\n", This));
 
   if (dwDirection != DATADIR_GET)
-    {
-      GDK_NOTE (DND, g_print ("E_NOTIMPL\n"));
-      return E_NOTIMPL;
-    }
+    return E_NOTIMPL;
 
   *ppEnumFormatEtc = &enum_formats_new ()->ief;
-
-  GDK_NOTE (DND, g_print ("%p S_OK\n", *ppEnumFormatEtc));
-
   return S_OK;
 }
 
@@ -985,29 +592,29 @@ idataobject_dadvise (LPDATAOBJECT This,
 		     LPADVISESINK pAdvSink,
 		     DWORD       *pdwConnection)
 {
-  GDK_NOTE (DND, g_print ("idataobject_dadvise %p E_NOTIMPL\n", This));
+  GDK_NOTE (DND, g_print ("idataobject_dadvise %p\n", This));
 
-  return E_NOTIMPL;
+  return E_FAIL;
 }
 
 static HRESULT STDMETHODCALLTYPE
 idataobject_dunadvise (LPDATAOBJECT This,
 		       DWORD         dwConnection)
 {
-  GDK_NOTE (DND, g_print ("idataobject_dunadvise %p E_NOTIMPL\n", This));
+  GDK_NOTE (DND, g_print ("idataobject_dunadvise %p\n", This));
 
-  return E_NOTIMPL;
+  return E_FAIL;
 }
 
 static HRESULT STDMETHODCALLTYPE
 idataobject_enumdadvise (LPDATAOBJECT    This,
 			 LPENUMSTATDATA *ppenumAdvise)
 {
-  GDK_NOTE (DND, g_print ("idataobject_enumdadvise %p OLE_E_ADVISENOTSUPPORTED\n", This));
+  GDK_NOTE (DND, g_print ("idataobject_enumdadvise %p\n", This));
 
-  return OLE_E_ADVISENOTSUPPORTED;
+  return E_FAIL;
 }
-
+		
 static ULONG STDMETHODCALLTYPE
 ienumformatetc_addref (LPENUMFORMATETC This)
 {
@@ -1024,30 +631,28 @@ ienumformatetc_queryinterface (LPENUMFOR
 			       REFIID          riid,
 			       LPVOID         *ppvObject)
 {
-  GDK_NOTE (DND, {
-      g_print ("ienumformatetc_queryinterface %p", This);
-      PRINT_GUID (riid);
-    });
+  GDK_NOTE (DND, g_print ("ienumformatetc_queryinterface %p\n", This));
 
   *ppvObject = NULL;
 
+  PRINT_GUID (riid);
   if (IsEqualGUID (riid, &IID_IUnknown))
     {
-      GDK_NOTE (DND, g_print ("...IUnknown S_OK\n"));
+      g_print ("...IUnknown\n");
       ienumformatetc_addref (This);
       *ppvObject = This;
       return S_OK;
     }
   else if (IsEqualGUID (riid, &IID_IEnumFORMATETC))
     {
-      GDK_NOTE (DND, g_print ("...IEnumFORMATETC S_OK\n"));
+      g_print ("...IEnumFORMATETC\n");
       ienumformatetc_addref (This);
       *ppvObject = This;
       return S_OK;
     }
   else
     {
-      GDK_NOTE (DND, g_print ("...E_NOINTERFACE\n"));
+      g_print ("...Nope\n");
       return E_NOINTERFACE;
     }
 }
@@ -1075,7 +680,7 @@ ienumformatetc_next (LPENUMFORMATETC Thi
   enum_formats *en = (enum_formats *) This;
   int i, n;
 
-  GDK_NOTE (DND, g_print ("ienumformatetc_next %p %d %ld ", This, en->ix, celt));
+  GDK_NOTE (DND, g_print ("ienumformatetc_next %p %d %ld\n", This, en->ix, celt));
 
   n = 0;
   for (i = 0; i < celt; i++)
@@ -1089,8 +694,6 @@ ienumformatetc_next (LPENUMFORMATETC Thi
   if (nelt != NULL)
     *nelt = n;
 
-  GDK_NOTE (DND, g_print ("%s\n", (n == celt) ? "S_OK" : "S_FALSE"));
-
   if (n == celt)
     return S_OK;
   else
@@ -1103,8 +706,7 @@ ienumformatetc_skip (LPENUMFORMATETC Thi
 {
   enum_formats *en = (enum_formats *) This;
 
-  GDK_NOTE (DND, g_print ("ienumformatetc_skip %p %d %ld S_OK\n", This, en->ix, celt));
-
+  GDK_NOTE (DND, g_print ("ienumformatetc_skip %p %d %ld\n", This, en->ix, celt));
   en->ix += celt;
 
   return S_OK;
@@ -1115,7 +717,7 @@ ienumformatetc_reset (LPENUMFORMATETC Th
 {
   enum_formats *en = (enum_formats *) This;
 
-  GDK_NOTE (DND, g_print ("ienumformatetc_reset %p S_OK\n", This));
+  GDK_NOTE (DND, g_print ("ienumformatetc_reset %p\n", This));
 
   en->ix = 0;
 
@@ -1129,7 +731,7 @@ ienumformatetc_clone (LPENUMFORMATETC  T
   enum_formats *en = (enum_formats *) This;
   enum_formats *new;
 
-  GDK_NOTE (DND, g_print ("ienumformatetc_clone %p S_OK\n", This));
+  GDK_NOTE (DND, g_print ("ienumformatetc_clone %p\n", This));
 
   new = enum_formats_new ();
 
@@ -1185,7 +787,7 @@ static IEnumFORMATETCVtbl ief_vtbl = {
 
 
 static target_drag_context *
-target_context_new (GdkWindow *window)
+target_context_new (void)
 {
   target_drag_context *result;
   GdkDragContextPrivateWin32 *private;
@@ -1195,20 +797,8 @@ target_context_new (GdkWindow *window)
   result->idt.lpVtbl = &idt_vtbl;
 
   result->context = gdk_drag_context_new ();
-  result->context->protocol = GDK_DRAG_PROTO_OLE2;
   result->context->is_source = FALSE;
 
-  result->context->source_window = NULL;
-
-  result->context->dest_window = window;
-  g_object_ref (window);
-
-  /* FIXME: result->context->targets? */
-
-  result->context->actions = GDK_ACTION_DEFAULT | GDK_ACTION_COPY | GDK_ACTION_MOVE;
-  result->context->suggested_action = GDK_ACTION_MOVE;
-  result->context->action = GDK_ACTION_MOVE;
-
   private = result->context->windowing_data;
   private->iface = (IUnknown *) &result->idt;
   idroptarget_addref (&result->idt);
@@ -1219,8 +809,7 @@ target_context_new (GdkWindow *window)
 }
 
 static source_drag_context *
-source_context_new (GdkWindow *window,
-		    GList     *targets)
+source_context_new (void)
 {
   source_drag_context *result;
   GdkDragContextPrivateWin32 *private;
@@ -1230,15 +819,8 @@ source_context_new (GdkWindow *window,
   result->ids.lpVtbl = &ids_vtbl;
 
   result->context = gdk_drag_context_new ();
-  result->context->protocol = GDK_DRAG_PROTO_OLE2;
   result->context->is_source = TRUE;
 
-  result->context->source_window = window;
-  g_object_ref (window);
-
-  result->context->dest_window = NULL;
-  result->context->targets = g_list_copy (targets);
-
   private = result->context->windowing_data;
   private->iface = (IUnknown *) &result->ids;
   idropsource_addref (&result->ids);
@@ -1249,7 +831,7 @@ source_context_new (GdkWindow *window,
 }
 
 static data_object *
-data_object_new (GdkDragContext *context)
+data_object_new (void)
 {
   data_object *result;
 
@@ -1257,13 +839,13 @@ data_object_new (GdkDragContext *context
 
   result->ido.lpVtbl = &ido_vtbl;
   result->ref_count = 1;
-  result->context = context;
 
   GDK_NOTE (DND, g_print ("data_object_new: %p\n", result));
 
   return result;
 }
 
+
 static enum_formats *
 enum_formats_new (void)
 {
@@ -1275,47 +857,12 @@ enum_formats_new (void)
   result->ref_count = 1;
   result->ix = 0;
 
+  GDK_NOTE (DND, g_print ("enum_formats_new: %p\n", result));
+
   return result;
 }
 
-void
-_gdk_win32_ole2_dnd_property_change (GdkAtom       type,
-				     gint          format,
-				     const guchar *data,
-				     gint          nelements)
-{
-  if (use_ole2_dnd)
-    {
-      HGLOBAL hdata = NULL;
-
-      if (active_pFormatEtc == NULL || active_pMedium == NULL)
-	return;
-
-      /* Set up the data buffer for wide character text request */
-      if (active_pFormatEtc->cfFormat == CF_UNICODETEXT)
-	{
-	  gunichar2 *wdata;
-	  glong wlen;
-
-	  wdata = g_utf8_to_utf16 ((const char *) data, -1, NULL, &wlen, NULL);
-	  hdata = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (wlen + 1) * 2);
-	  if (hdata)
-	    {
-	      wchar_t *ptr = (wchar_t *) GlobalLock(hdata);
-	      memcpy (ptr, wdata, (wlen + 1) * 2);
-	      GlobalUnlock(hdata);
-	    }
-	  g_free (wdata);
-	}
-      else
-	g_warning ("Only text handled for now");
-
-      /* Pack up data */
-      active_pMedium->tymed = TYMED_HGLOBAL;
-      active_pMedium->hGlobal = hdata;
-      active_pMedium->pUnkForRelease = 0;
-    }
-}
+#endif
 
 /* From MS Knowledge Base article Q130698 */
 
@@ -1325,7 +872,7 @@ resolve_link (HWND     hWnd,
 	      gchar  **lpszPath)
 {
   WIN32_FILE_ATTRIBUTE_DATA wfad;
-  HRESULT hr;
+  HRESULT hres;
   IShellLinkW *pslW = NULL;
   IPersistFile *ppf = NULL;
 
@@ -1345,130 +892,91 @@ resolve_link (HWND     hWnd,
    * assumed that CoInitialize has been called.
    */
 
-  hr = CoCreateInstance (&CLSID_ShellLink,
-			 NULL,
-			 CLSCTX_INPROC_SERVER,
-			 &IID_IShellLinkW,
-			 (LPVOID *)&pslW);
+  hres = CoCreateInstance (&CLSID_ShellLink,
+			   NULL,
+			   CLSCTX_INPROC_SERVER,
+			   &IID_IShellLinkW,
+			   (LPVOID *)&pslW);
 
-  if (SUCCEEDED (hr))
+  if (SUCCEEDED (hres))
    {
+     
      /* The IShellLink interface supports the IPersistFile
       * interface. Get an interface pointer to it.
       */
-     hr = pslW->lpVtbl->QueryInterface (pslW,
-					&IID_IPersistFile,
-					(LPVOID *) &ppf);
-   }
+     hres = pslW->lpVtbl->QueryInterface (pslW,
+					  &IID_IPersistFile,
+					  (LPVOID *) &ppf);
+   }     
 
-  if (SUCCEEDED (hr))
+  if (SUCCEEDED (hres))
     {
       /* Load the file. */
-      hr = ppf->lpVtbl->Load (ppf, link, STGM_READ);
+      hres = ppf->lpVtbl->Load (ppf, link, STGM_READ);
     }
-
-  if (SUCCEEDED (hr))
+  
+  if (SUCCEEDED (hres))
     {
       /* Resolve the link by calling the Resolve()
        * interface function.
        */
-      hr = pslW->lpVtbl->Resolve (pslW, hWnd, SLR_ANY_MATCH | SLR_NO_UI);
+      hres = pslW->lpVtbl->Resolve (pslW, hWnd, SLR_ANY_MATCH | SLR_NO_UI);
     }
 
-  if (SUCCEEDED (hr))
+  if (SUCCEEDED (hres))
     {
       wchar_t wtarget[MAX_PATH];
 
-      hr = pslW->lpVtbl->GetPath (pslW, wtarget, MAX_PATH, NULL, 0);
-      if (SUCCEEDED (hr))
+      hres = pslW->lpVtbl->GetPath (pslW, wtarget, MAX_PATH, NULL, 0);
+      if (SUCCEEDED (hres))
 	*lpszPath = g_utf16_to_utf8 (wtarget, -1, NULL, NULL, NULL);
     }
-
+  
   if (ppf)
     ppf->lpVtbl->Release (ppf);
 
   if (pslW)
     pslW->lpVtbl->Release (pslW);
 
-  return SUCCEEDED (hr);
-}
-
-#if 0
-
-/* Check for filenames like C:\Users\tml\AppData\Local\Temp\d5qtkvvs.bmp */
-static gboolean
-filename_looks_tempish (const char *filename)
-{
-  char *dirname;
-  char *p;
-  const char *q;
-  gboolean retval = FALSE;
-
-  dirname = g_path_get_dirname (filename);
-
-  p = dirname;
-  q = g_get_tmp_dir ();
-
-  while (*p && *q &&
-	 ((G_IS_DIR_SEPARATOR (*p) && G_IS_DIR_SEPARATOR (*q)) ||
-	  g_ascii_tolower (*p) == g_ascii_tolower (*q)))
-    p++, q++;
-
-  if (!*p && !*q)
-    retval = TRUE;
-
-  g_free (dirname);
-
-  return retval;
-}
-
-static gboolean
-close_it (gpointer data)
-{
-  close (GPOINTER_TO_INT (data));
-
-  return FALSE;
+  return SUCCEEDED (hres);
 }
 
-#endif
-
 static GdkFilterReturn
 gdk_dropfiles_filter (GdkXEvent *xev,
 		      GdkEvent  *event,
 		      gpointer   data)
 {
   GdkDragContext *context;
+  GdkDragContextPrivateWin32 *private;
   GString *result;
   MSG *msg = (MSG *) xev;
   HANDLE hdrop;
   POINT pt;
   gint nfiles, i;
   gchar *fileName, *linkedFile;
-
+  
   if (msg->message == WM_DROPFILES)
     {
       GDK_NOTE (DND, g_print ("WM_DROPFILES: %p\n", msg->hwnd));
 
       context = gdk_drag_context_new ();
+      private = PRIVATE_DATA (context);
       context->protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
       context->is_source = FALSE;
-
       context->source_window = _gdk_root;
       g_object_ref (context->source_window);
-
       context->dest_window = event->any.window;
       g_object_ref (context->dest_window);
-
       /* WM_DROPFILES drops are always file names */
       context->targets =
-	g_list_append (NULL, _text_uri_list);
+	g_list_append (NULL, GUINT_TO_POINTER (_text_uri_list));
       context->actions = GDK_ACTION_COPY;
       context->suggested_action = GDK_ACTION_COPY;
       current_dest_drag = context;
 
       event->dnd.type = GDK_DROP_START;
       event->dnd.context = current_dest_drag;
-
+      
       hdrop = (HANDLE) msg->wParam;
       DragQueryPoint (hdrop, &pt);
       ClientToScreen (msg->hwnd, &pt);
@@ -1492,6 +1000,7 @@ gdk_dropfiles_filter (GdkXEvent *xev,
 	  if (resolve_link (msg->hwnd, wfn, &linkedFile))
 	    {
 	      uri = g_filename_to_uri (linkedFile, NULL, NULL);
+	      g_free (linkedFile);
 	      if (uri != NULL)
 		{
 		  g_string_append (result, uri);
@@ -1499,8 +1008,6 @@ gdk_dropfiles_filter (GdkXEvent *xev,
 					  fileName, linkedFile, uri));
 		  g_free (uri);
 		}
-	      g_free (fileName);
-	      fileName = linkedFile;
 	    }
 	  else
 	    {
@@ -1512,38 +1019,6 @@ gdk_dropfiles_filter (GdkXEvent *xev,
 		  g_free (uri);
 		}
 	    }
-
-#if 0
-	  /* Awful hack to recognize temp files corresponding to
-	   * images dragged from Firefox... Open the file right here
-	   * so that it is less likely that Firefox manages to delete
-	   * it before the GTK+-using app (typically GIMP) has opened
-	   * it.
-	   *
-	   * Not compiled in for now, because it means images dragged
-	   * from Firefox would stay around in the temp folder which
-	   * is not what Firefox intended. I don't feel comfortable
-	   * with that, both from a geenral sanity point of view, and
-	   * from a privacy point of view. It's better to wait for
-	   * Firefox to fix the problem, for instance by deleting the
-	   * temp file after a longer delay, or to wait until we
-	   * implement the OLE2_DND...
-	   */
-	  if (filename_looks_tempish (fileName))
-	    {
-	      int fd = g_open (fileName, _O_RDONLY|_O_BINARY, 0);
-	      if (fd == -1)
-		{
-		  GDK_NOTE (DND, g_print ("Could not open %s, maybe an image dragged from Firefox that it already deleted\n", fileName));
-		}
-	      else
-		{
-		  GDK_NOTE (DND, g_print ("Opened %s as %d so that Firefox won't delete it\n", fileName, fd));
-		  g_timeout_add_seconds (1, close_it, GINT_TO_POINTER (fd));
-		}
-	    }
-#endif
-
 	  g_free (fileName);
 	  g_string_append (result, "\015\012");
 	}
@@ -1551,78 +1026,50 @@ gdk_dropfiles_filter (GdkXEvent *xev,
       g_string_free (result, FALSE);
 
       DragFinish (hdrop);
-
+      
       return GDK_FILTER_TRANSLATE;
     }
   else
     return GDK_FILTER_CONTINUE;
 }
 
-static void
-add_format (GArray *fmts,
-	    CLIPFORMAT cf)
-{
-  FORMATETC fmt;
-
-  fmt.cfFormat = cf;
-  fmt.ptd = NULL;
-  fmt.dwAspect = DVASPECT_CONTENT;
-  fmt.lindex = -1;
-  fmt.tymed = TYMED_HGLOBAL;
-
-  g_array_append_val (fmts, fmt);
-}
-
+/*************************************************************
+ ************************** Public API ***********************
+ *************************************************************/
 
 void
 _gdk_dnd_init (void)
 {
-  if (getenv ("GDK_WIN32_USE_EXPERIMENTAL_OLE2_DND"))
-    use_ole2_dnd = TRUE;
-
-  if (use_ole2_dnd)
-    {
-      HRESULT hr;
-      GArray *fmts;
-
-      hr = OleInitialize (NULL);
-
-      if (! SUCCEEDED (hr))
-	g_error ("OleInitialize failed");
-
-      fmts = g_array_new (FALSE, FALSE, sizeof (FORMATETC));
-
-      /* The most important presumably */
-      add_format (fmts, CF_UNICODETEXT);
-
-      /* Used for GTK+ internal DND, I think was the intent? Anyway, code below assumes
-       * this is at index 1.
-       */
-      add_format (fmts, CF_GDIOBJFIRST);
-
-      add_format (fmts, CF_HDROP);
-
-      add_format (fmts, _cf_png);
-      add_format (fmts, CF_DIB);
-
-      add_format (fmts, _cf_url);
-      add_format (fmts, _cf_html_format);
-      add_format (fmts, _cf_text_html);
-
-      nformats = fmts->len;
-      formats = (FORMATETC*) g_array_free (fmts, FALSE);
-
-      target_ctx_for_window = g_hash_table_new (g_direct_hash, g_direct_equal);
-    }
-}
+#ifdef OLE2_DND
+  HRESULT hres;
+  hres = OleInitialize (NULL);
+
+  if (! SUCCEEDED (hres))
+    g_error ("OleInitialize failed");
+
+  nformats = 2;
+  formats = g_new (FORMATETC, nformats);
+
+  formats[0].cfFormat = CF_TEXT;
+  formats[0].ptd = NULL;
+  formats[0].dwAspect = DVASPECT_CONTENT;
+  formats[0].lindex = -1;
+  formats[0].tymed = TYMED_HGLOBAL;
+  
+  formats[1].cfFormat = CF_GDIOBJFIRST;
+  formats[1].ptd = NULL;
+  formats[1].dwAspect = DVASPECT_CONTENT;
+  formats[1].lindex = -1;
+  formats[1].tymed = TYMED_HGLOBAL;
+#endif
+}      
 
 void
 _gdk_win32_dnd_exit (void)
 {
-  if (use_ole2_dnd)
-    {
-      OleUninitialize ();
-    }
+#ifdef OLE2_DND
+  OleUninitialize ();
+#endif
 }
 
 /* Source side */
@@ -1632,7 +1079,7 @@ local_send_leave (GdkDragContext *contex
 		  guint32         time)
 {
   GdkEvent tmp_event;
-
+  
   GDK_NOTE (DND, g_print ("local_send_leave: context=%p current_dest_drag=%p\n",
 			  context,
 			  current_dest_drag));
@@ -1649,8 +1096,7 @@ local_send_leave (GdkDragContext *contex
       tmp_event.dnd.time = GDK_CURRENT_TIME; /* FIXME? */
 
       current_dest_drag = NULL;
-
-      GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
+      
       gdk_event_put (&tmp_event);
     }
 }
@@ -1668,7 +1114,7 @@ local_send_enter (GdkDragContext *contex
 			  current_dest_drag));
 
   private = PRIVATE_DATA (context);
-
+  
   if (current_dest_drag != NULL)
     {
       g_object_unref (G_OBJECT (current_dest_drag));
@@ -1681,7 +1127,6 @@ local_send_enter (GdkDragContext *contex
 
   new_context->source_window = context->source_window;
   g_object_ref (new_context->source_window);
-
   new_context->dest_window = context->dest_window;
   g_object_ref (new_context->dest_window);
 
@@ -1692,36 +1137,35 @@ local_send_enter (GdkDragContext *contex
 			 GDK_PROPERTY_CHANGE_MASK);
   new_context->actions = context->actions;
 
-  tmp_event.type = GDK_DRAG_ENTER;
+  tmp_event.dnd.type = GDK_DRAG_ENTER;
   tmp_event.dnd.window = context->dest_window;
   tmp_event.dnd.send_event = FALSE;
   tmp_event.dnd.context = new_context;
   tmp_event.dnd.time = GDK_CURRENT_TIME; /* FIXME? */
-
+  
   current_dest_drag = new_context;
-
-  GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
+  
   gdk_event_put (&tmp_event);
 }
 
 static void
 local_send_motion (GdkDragContext *context,
-		   gint            x_root,
+		   gint            x_root, 
 		   gint            y_root,
 		   GdkDragAction   action,
 		   guint32         time)
 {
   GdkEvent tmp_event;
-
-  GDK_NOTE (DND, g_print ("local_send_motion: context=%p (%d,%d) current_dest_drag=%p\n",
-			  context, x_root, y_root,
+  
+  GDK_NOTE (DND, g_print ("local_send_motion: context=%p current_dest_drag=%p\n",
+			  context,
 			  current_dest_drag));
 
   if ((current_dest_drag != NULL) &&
       (current_dest_drag->protocol == GDK_DRAG_PROTO_LOCAL) &&
       (current_dest_drag->source_window == context->source_window))
     {
-      tmp_event.type = GDK_DRAG_MOTION;
+      tmp_event.dnd.type = GDK_DRAG_MOTION;
       tmp_event.dnd.window = current_dest_drag->dest_window;
       tmp_event.dnd.send_event = FALSE;
       tmp_event.dnd.context = current_dest_drag;
@@ -1732,12 +1176,11 @@ local_send_motion (GdkDragContext *conte
       tmp_event.dnd.x_root = x_root;
       tmp_event.dnd.y_root = y_root;
 
-      PRIVATE_DATA (current_dest_drag)->last_pt.x = x_root - _gdk_offset_x;
-      PRIVATE_DATA (current_dest_drag)->last_pt.y = y_root - _gdk_offset_y;
+      PRIVATE_DATA (current_dest_drag)->last_x = x_root;
+      PRIVATE_DATA (current_dest_drag)->last_y = y_root;
 
       PRIVATE_DATA (context)->drag_status = GDK_DRAG_STATUS_MOTION_WAIT;
-
-      GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
+      
       gdk_event_put (&tmp_event);
     }
 }
@@ -1760,18 +1203,17 @@ local_send_drop (GdkDragContext *context
       private = PRIVATE_DATA (current_dest_drag);
 
       /* Pass ownership of context to the event */
-      tmp_event.type = GDK_DROP_START;
+      tmp_event.dnd.type = GDK_DROP_START;
       tmp_event.dnd.window = current_dest_drag->dest_window;
       tmp_event.dnd.send_event = FALSE;
       tmp_event.dnd.context = current_dest_drag;
       tmp_event.dnd.time = GDK_CURRENT_TIME;
-
-      tmp_event.dnd.x_root = private->last_pt.x + _gdk_offset_x;
-      tmp_event.dnd.y_root = private->last_pt.y + _gdk_offset_y;
-
+      
+      tmp_event.dnd.x_root = private->last_x;
+      tmp_event.dnd.y_root = private->last_y;
+      
       current_dest_drag = NULL;
 
-      GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
       gdk_event_put (&tmp_event);
     }
 
@@ -1785,10 +1227,13 @@ gdk_drag_do_leave (GdkDragContext *conte
     {
       GDK_NOTE (DND, g_print ("gdk_drag_do_leave\n"));
 
-      if (!use_ole2_dnd)
+      switch (context->protocol)
 	{
-	  if (context->protocol == GDK_DRAG_PROTO_LOCAL)
-	    local_send_leave (context, time);
+	case GDK_DRAG_PROTO_LOCAL:
+	  local_send_leave (context, time);
+	  break;
+	default:
+	  break;
 	}
 
       g_object_unref (context->dest_window);
@@ -1796,153 +1241,71 @@ gdk_drag_do_leave (GdkDragContext *conte
     }
 }
 
-GdkDragContext *
+GdkDragContext * 
 gdk_drag_begin (GdkWindow *window,
 		GList     *targets)
 {
-  if (!use_ole2_dnd)
-    {
-      GdkDragContext *new_context;
-
-      g_return_val_if_fail (window != NULL, NULL);
-
-      new_context = gdk_drag_context_new ();
-
-      new_context->is_source = TRUE;
-
-      new_context->source_window = window;
-      g_object_ref (window);
-
-      new_context->targets = g_list_copy (targets);
-      new_context->actions = 0;
-
-      return new_context;
-    }
-  else
-    {
-      source_drag_context *ctx;
-
-      g_return_val_if_fail (window != NULL, NULL);
-
-      GDK_NOTE (DND, g_print ("gdk_drag_begin\n"));
-
-      ctx = source_context_new (window, targets);
-
-      _dnd_source_state = GDK_WIN32_DND_PENDING;
-
-      pending_src_context = ctx;
-      gdk_drag_context_ref (ctx->context);
-
-      return ctx->context;
-    }
-}
+#ifdef OLE2_DND
+  source_drag_context *ctx;
+  data_object *dobj;
+  HRESULT hResult;
+  DWORD dwEffect;
+  HGLOBAL global;
+  STGMEDIUM medium;
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  GDK_NOTE (DND, g_print ("gdk_drag_begin\n"));
+
+  ctx = source_context_new ();
+  ctx->context->protocol = GDK_DRAG_PROTO_OLE2;
+  ctx->context->source_window = window;
+  g_object_ref (window);
 
-void
-_gdk_win32_dnd_do_dragdrop (void)
-{
-  if (use_ole2_dnd)
-    {
-      GdkDragContext* drag_ctx;
-      GdkDragContextPrivateWin32 *private;
-      BYTE kbd_state[256];
-      data_object *dobj;
-      HRESULT hr;
-      DWORD dwEffect;
-#if 0
-      HGLOBAL global;
-      STGMEDIUM medium;
-#endif
+  ctx->context->targets = g_list_copy (targets);
 
-      if (pending_src_context == NULL)
-	return;
+  ctx->context->actions = 0;
 
-      drag_ctx = pending_src_context->context;
-      private = PRIVATE_DATA (drag_ctx);
+  dobj = data_object_new ();
 
-      dobj = data_object_new (drag_ctx);
+  global = GlobalAlloc (GMEM_FIXED, sizeof (ctx));
 
-      API_CALL (GetCursorPos, (&private->last_pt));
-      API_CALL (ScreenToClient, (GDK_WINDOW_HWND (drag_ctx->source_window), &private->last_pt));
-      private->last_key_state = 0;
-      API_CALL (GetKeyboardState, (kbd_state));
-
-      if (kbd_state[VK_CONTROL])
-	private->last_key_state |= MK_CONTROL;
-      if (kbd_state[VK_SHIFT])
-	private->last_key_state |= MK_SHIFT;
-      if (kbd_state[VK_LBUTTON])
-	private->last_key_state |= MK_LBUTTON;
-      if (kbd_state[VK_MBUTTON])
-	private->last_key_state |= MK_MBUTTON;
-      if (kbd_state[VK_RBUTTON])
-	private->last_key_state |= MK_RBUTTON;
+  memcpy (&global, ctx, sizeof (ctx));
 
-#if 0
-      global = GlobalAlloc (GMEM_FIXED, sizeof (ctx));
+  medium.tymed = TYMED_HGLOBAL;
+  medium.hGlobal = global;
+  medium.pUnkForRelease = NULL;
 
-      memcpy (&global, ctx, sizeof (ctx));
+  dobj->ido.lpVtbl->SetData (&dobj->ido, &formats[1], &medium, TRUE);
 
-      medium.tymed = TYMED_HGLOBAL;
-      medium.hGlobal = global;
-      medium.pUnkForRelease = NULL;
+  hResult = DoDragDrop (&dobj->ido, &ctx->ids, DROPEFFECT_MOVE|DROPEFFECT_COPY, &dwEffect);
 
-      /* FIXME I wish I remember what I was thinking of here, i.e. what
-       * the formats[1] signifies, i.e. the CF_GDIOBJFIRST FORMATETC?
-       */
-      dobj->ido.lpVtbl->SetData (&dobj->ido, &formats[1], &medium, TRUE);
-#endif
+  GDK_NOTE (DND, g_print ("DoDragDrop returned %s\n",
+			  (hResult == DRAGDROP_S_DROP ? "DRAGDROP_S_DROP" :
+			   (hResult == DRAGDROP_S_CANCEL ? "DRAGDROP_S_CANCEL" :
+			    (hResult == E_UNEXPECTED ? "E_UNEXPECTED" :
+			     g_strdup_printf ("%#.8lx", hResult))))));
 
-      /* Start dragging with mainloop inside the OLE2 API. Exits only when done */
+  dobj->ido.lpVtbl->Release (&dobj->ido);
+  ctx->ids.lpVtbl->Release (&ctx->ids);
 
-      GDK_NOTE (DND, g_print ("Calling DoDragDrop\n"));
+  return ctx->context;
+#else
+  GdkDragContext *new_context;
 
-      _gdk_win32_begin_modal_call ();
-      hr = DoDragDrop (&dobj->ido, &pending_src_context->ids,
-		       DROPEFFECT_COPY | DROPEFFECT_MOVE,
-		       &dwEffect);
-      _gdk_win32_end_modal_call ();
-
-      GDK_NOTE (DND, g_print ("DoDragDrop returned %s\n",
-			      (hr == DRAGDROP_S_DROP ? "DRAGDROP_S_DROP" :
-			       (hr == DRAGDROP_S_CANCEL ? "DRAGDROP_S_CANCEL" :
-				(hr == E_UNEXPECTED ? "E_UNEXPECTED" :
-				 g_strdup_printf ("%#.8lx", hr))))));
+  g_return_val_if_fail (window != NULL, NULL);
 
-      /* Delete dnd selection after successful move */
-      if (hr == DRAGDROP_S_DROP && dwEffect == DROPEFFECT_MOVE)
-	{
-	  GdkEvent tmp_event;
+  new_context = gdk_drag_context_new ();
+  new_context->is_source = TRUE;
+  new_context->source_window = window;
+  g_object_ref (window);
 
-	  tmp_event.type = GDK_SELECTION_REQUEST;
-	  tmp_event.selection.window = drag_ctx->source_window;
-	  tmp_event.selection.send_event = FALSE;
-	  tmp_event.selection.selection = _gdk_ole2_dnd;
-	  tmp_event.selection.target = _delete;
-	  tmp_event.selection.property = _gdk_ole2_dnd; /* ??? */
-	  tmp_event.selection.time = GDK_CURRENT_TIME; /* ??? */
-	  g_object_ref (tmp_event.selection.window);
+  new_context->targets = g_list_copy (targets);
 
-	  GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
-	  gdk_event_put (&tmp_event);
-	}
+  new_context->actions = 0;
 
-#if 0
-      // Send a GDK_DROP_FINISHED to the source window
-      GetCursorPos (&pt);
-      ptl.x = pt.x;
-      ptl.y = pt.y;
-      if ( pending_src_context != NULL && pending_src_context->context != NULL
-	   && pending_src_context->context->source_window != NULL )
-	push_dnd_event (GDK_DROP_FINISHED, pending_src_context->context, ptl, FALSE);
+  return new_context;
 #endif
-
-      dobj->ido.lpVtbl->Release (&dobj->ido);
-      if (pending_src_context != NULL)
-	{
-	  pending_src_context->ids.lpVtbl->Release (&pending_src_context->ids);
-	  pending_src_context = NULL;
-	}
-    }
 }
 
 GdkNativeWindow
@@ -1958,11 +1321,11 @@ gdk_drag_get_protocol_for_display (GdkDi
     {
       if (g_object_get_data (G_OBJECT (window), "gdk-dnd-registered") != NULL)
 	{
-	  if (use_ole2_dnd)
-	    *protocol = GDK_DRAG_PROTO_OLE2;
-	  else
-	    *protocol = GDK_DRAG_PROTO_LOCAL;
-
+#ifdef OLE2_DND
+	  *protocol = GDK_DRAG_PROTO_OLE2;
+#else
+	  *protocol = GDK_DRAG_PROTO_LOCAL;
+#endif
 	  return xid;
 	}
     }
@@ -1970,6 +1333,43 @@ gdk_drag_get_protocol_for_display (GdkDi
   return 0;
 }
 
+typedef struct {
+  gint x;
+  gint y;
+  HWND ignore;
+  HWND result;
+} find_window_enum_arg;
+
+static BOOL CALLBACK
+find_window_enum_proc (HWND   hwnd,
+		       LPARAM lparam)
+{
+  RECT rect;
+  POINT tl, br;
+  find_window_enum_arg *a = (find_window_enum_arg *) lparam;
+
+  if (hwnd == a->ignore)
+    return TRUE;
+
+  if (!IsWindowVisible (hwnd))
+    return TRUE;
+
+  tl.x = tl.y = 0;
+  ClientToScreen (hwnd, &tl);
+  GetClientRect (hwnd, &rect);
+  br.x = rect.right;
+  br.y = rect.bottom;
+  ClientToScreen (hwnd, &br);
+
+  if (a->x >= tl.x && a->y >= tl.y && a->x < br.x && a->y < br.y)
+    {
+      a->result = hwnd;
+      return FALSE;
+    }
+  else
+    return TRUE;
+}
+
 void
 gdk_drag_find_window_for_screen (GdkDragContext  *context,
 				 GdkWindow       *drag_window,
@@ -1979,46 +1379,50 @@ gdk_drag_find_window_for_screen (GdkDrag
 				 GdkWindow      **dest_window,
 				 GdkDragProtocol *protocol)
 {
-  POINT pt;
-  HWND hwnd;
+  find_window_enum_arg a;
 
-  pt.x = x_root - _gdk_offset_x;
-  pt.y = y_root - _gdk_offset_y;
+  a.x = x_root - _gdk_offset_x;
+  a.y = y_root - _gdk_offset_y;
+  a.ignore = drag_window ? GDK_WINDOW_HWND (drag_window) : NULL;
+  a.result = NULL;
 
-  hwnd = WindowFromPoint (pt);
+  EnumWindows (find_window_enum_proc, (LPARAM) &a);
 
-  if (hwnd == NULL)
+  if (a.result == NULL)
     *dest_window = NULL;
   else
     {
-      *dest_window = gdk_win32_handle_table_lookup (hwnd);
+      *dest_window = gdk_win32_handle_table_lookup (a.result);
       if (*dest_window)
-	g_object_ref (*dest_window);
-      else
-	*dest_window = gdk_window_foreign_new_for_display (_gdk_display, hwnd);
+	{
+	  *dest_window = gdk_window_get_toplevel (*dest_window);
+	  g_object_ref (*dest_window);
+	}
 
-      if (use_ole2_dnd)
+      if (context->source_window)
+#ifdef OLE2_DND
 	*protocol = GDK_DRAG_PROTO_OLE2;
-      else if (context->source_window)
+#else
         *protocol = GDK_DRAG_PROTO_LOCAL;
+#endif
       else
-	*protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
+        *protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
     }
 
   GDK_NOTE (DND,
-	    g_print ("gdk_drag_find_window: %p %+d%+d: %p: %p %s\n",
+	    g_print ("gdk_drag_find_window: %p %+d%+d: %p: %p %d\n",
 		     (drag_window ? GDK_WINDOW_HWND (drag_window) : NULL),
 		     x_root, y_root,
-		     hwnd,
+		     a.result,
 		     (*dest_window ? GDK_WINDOW_HWND (*dest_window) : NULL),
-		     _gdk_win32_drag_protocol_to_string (*protocol)));
+		     *protocol));
 }
 
 gboolean
 gdk_drag_motion (GdkDragContext *context,
 		 GdkWindow      *dest_window,
 		 GdkDragProtocol protocol,
-		 gint            x_root,
+		 gint            x_root, 
 		 gint            y_root,
 		 GdkDragAction   suggested_action,
 		 GdkDragAction   possible_actions,
@@ -2029,9 +1433,10 @@ gdk_drag_motion (GdkDragContext *context
   g_return_val_if_fail (context != NULL, FALSE);
 
   context->actions = possible_actions;
-
-  GDK_NOTE (DND, g_print ("gdk_drag_motion: %s suggested=%s, possible=%s\n"
-			  " context=%p:{actions=%s,suggested=%s,action=%s}\n",
+ 
+  GDK_NOTE (DND, g_print ("gdk_drag_motion: protocol=%s\n"
+			  " suggested_action=%s, possible_actions=%s\n"
+			  " context=%p:actions=%s, suggested_action=%s, action=%s\n",
 			  _gdk_win32_drag_protocol_to_string (protocol),
 			  _gdk_win32_drag_action_to_string (suggested_action),
 			  _gdk_win32_drag_action_to_string (possible_actions),
@@ -2040,110 +1445,108 @@ gdk_drag_motion (GdkDragContext *context
 			  _gdk_win32_drag_action_to_string (context->suggested_action),
 			  _gdk_win32_drag_action_to_string (context->action)));
 
-  private = PRIVATE_DATA (context);
 
-  if (!use_ole2_dnd)
+  private = PRIVATE_DATA (context);
+  
+  if (context->dest_window == dest_window)
     {
-      if (context->dest_window == dest_window)
-	{
-	  GdkDragContext *dest_context;
+      GdkDragContext *dest_context;
+		    
+      dest_context = gdk_drag_context_find (FALSE,
+					    context->source_window,
+					    dest_window);
 
-	  dest_context = gdk_drag_context_find (FALSE,
-						context->source_window,
-						dest_window);
+      if (dest_context)
+	dest_context->actions = context->actions;
 
-	  if (dest_context)
-	    dest_context->actions = context->actions;
+      context->suggested_action = suggested_action;
+    }
+  else
+    {
+      GdkEvent temp_event;
 
-	  context->suggested_action = suggested_action;
-	}
-      else
-	{
-	  GdkEvent tmp_event;
+      /* Send a leave to the last destination */
+      gdk_drag_do_leave (context, time);
+      private->drag_status = GDK_DRAG_STATUS_DRAG;
 
-	  /* Send a leave to the last destination */
-	  gdk_drag_do_leave (context, time);
-	  private->drag_status = GDK_DRAG_STATUS_DRAG;
+      /* Check if new destination accepts drags, and which protocol */
+      if (dest_window)
+	{
+	  context->dest_window = dest_window;
+	  g_object_ref (context->dest_window);
+	  context->protocol = protocol;
 
-	  /* Check if new destination accepts drags, and which protocol */
-	  if (dest_window)
+	  switch (protocol)
 	    {
-	      context->dest_window = dest_window;
-	      g_object_ref (context->dest_window);
-	      context->protocol = protocol;
-
-	      switch (protocol)
-		{
-		case GDK_DRAG_PROTO_LOCAL:
-		  local_send_enter (context, time);
-		  break;
+	    case GDK_DRAG_PROTO_LOCAL:
+	      local_send_enter (context, time);
+	      break;
 
-		default:
-		  break;
-		}
-	      context->suggested_action = suggested_action;
-	    }
-	  else
-	    {
-	      context->dest_window = NULL;
-	      context->action = 0;
+	    default:
+	      break;
 	    }
+	  context->suggested_action = suggested_action;
+	}
+      else
+	{
+	  context->dest_window = NULL;
+	  context->action = 0;
+	}
 
-	  /* Push a status event, to let the client know that
-	   * the drag changed
-	   */
-	  tmp_event.type = GDK_DRAG_STATUS;
-	  tmp_event.dnd.window = context->source_window;
-	  /* We use this to signal a synthetic status. Perhaps
-	   * we should use an extra field...
-	   */
-	  tmp_event.dnd.send_event = TRUE;
+      /* Push a status event, to let the client know that
+       * the drag changed 
+       */
 
-	  tmp_event.dnd.context = context;
-	  tmp_event.dnd.time = time;
+      temp_event.dnd.type = GDK_DRAG_STATUS;
+      temp_event.dnd.window = context->source_window;
+      /* We use this to signal a synthetic status. Perhaps
+       * we should use an extra field...
+       */
+      temp_event.dnd.send_event = TRUE;
 
-	  GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
-	  gdk_event_put (&tmp_event);
-	}
+      temp_event.dnd.context = context;
+      temp_event.dnd.time = time;
 
-      /* Send a drag-motion event */
+      gdk_event_put (&temp_event);
+    }
 
-      private->last_pt.x = x_root - _gdk_offset_x;
-      private->last_pt.y = y_root - _gdk_offset_y;
+  /* Send a drag-motion event */
 
-      if (context->dest_window)
+  private->last_x = x_root;
+  private->last_y = y_root;
+      
+  if (context->dest_window)
+    {
+      if (private->drag_status == GDK_DRAG_STATUS_DRAG)
 	{
-	  if (private->drag_status == GDK_DRAG_STATUS_DRAG)
+	  switch (context->protocol)
 	    {
-	      switch (context->protocol)
-		{
-		case GDK_DRAG_PROTO_LOCAL:
-		  local_send_motion (context, x_root, y_root, suggested_action, time);
-		  break;
-
-		case GDK_DRAG_PROTO_NONE:
-		  g_warning ("GDK_DRAG_PROTO_NONE is not valid in gdk_drag_motion()");
-		  break;
+	    case GDK_DRAG_PROTO_LOCAL:
+	      local_send_motion (context, x_root, y_root, suggested_action, time);
+	      break;
+	      
+	    case GDK_DRAG_PROTO_NONE:
+	      g_warning ("GDK_DRAG_PROTO_NONE is not valid in gdk_drag_motion()");
+	      break;
 
-		default:
-		  break;
-		}
-	    }
-	  else
-	    {
-	      GDK_NOTE (DND, g_print (" returning TRUE\n"
-				      " context=%p:{actions=%s,suggested=%s,action=%s}\n",
-				      context,
-				      _gdk_win32_drag_action_to_string (context->actions),
-				      _gdk_win32_drag_action_to_string (context->suggested_action),
-				      _gdk_win32_drag_action_to_string (context->action)));
-	      return TRUE;
+	    default:
+	      break;
 	    }
 	}
+      else
+	{
+	  GDK_NOTE (DND, g_print (" returning TRUE\n"
+				  " context=%p:actions=%s, suggested_action=%s, action=%s\n",
+				  context,
+				  _gdk_win32_drag_action_to_string (context->actions),
+				  _gdk_win32_drag_action_to_string (context->suggested_action),
+				  _gdk_win32_drag_action_to_string (context->action)));
+	  return TRUE;
+	}
     }
 
   GDK_NOTE (DND, g_print (" returning FALSE\n"
-			  " context=%p:{actions=%s,suggested=%s,action=%s}\n",
+			  " context=%p:actions=%s, suggested_action=%s, action=%s\n",
 			  context,
 			  _gdk_win32_drag_action_to_string (context->actions),
 			  _gdk_win32_drag_action_to_string (context->suggested_action),
@@ -2159,15 +1562,21 @@ gdk_drag_drop (GdkDragContext *context,
 
   GDK_NOTE (DND, g_print ("gdk_drag_drop\n"));
 
-  if (!use_ole2_dnd)
-    {
-      if (context->dest_window &&
-	  context->protocol == GDK_DRAG_PROTO_LOCAL)
-	local_send_drop (context, time);
-    }
-  else
+  if (context->dest_window)
     {
-      _dnd_source_state = GDK_WIN32_DND_DROPPED;
+      switch (context->protocol)
+	{
+	case GDK_DRAG_PROTO_LOCAL:
+	  local_send_drop (context, time);
+	  break;
+
+	case GDK_DRAG_PROTO_NONE:
+	  g_warning ("GDK_DRAG_PROTO_NONE is not valid in gdk_drag_drop()");
+	  break;
+
+	default:
+	  break;
+	}
     }
 }
 
@@ -2179,8 +1588,7 @@ gdk_drag_abort (GdkDragContext *context,
 
   GDK_NOTE (DND, g_print ("gdk_drag_abort\n"));
 
-  if (use_ole2_dnd)
-    _dnd_source_state = GDK_WIN32_DND_NONE;
+  gdk_drag_do_leave (context, time);
 }
 
 /* Destination side */
@@ -2196,49 +1604,47 @@ gdk_drag_status (GdkDragContext *context
 
   g_return_if_fail (context != NULL);
 
+  GDK_NOTE (DND, g_print ("gdk_drag_status\n"));
+
   private = PRIVATE_DATA (context);
 
-  GDK_NOTE (DND, g_print ("gdk_drag_status: %s\n"
-			  " context=%p:{actions=%s,suggested=%s,action=%s}\n",
+  GDK_NOTE (DND, g_print ("gdk_drag_status: action=%s\n"
+			  " context=%p:actions=%s, suggested_action=%s, action=%s\n",
 			  _gdk_win32_drag_action_to_string (action),
 			  context,
 			  _gdk_win32_drag_action_to_string (context->actions),
 			  _gdk_win32_drag_action_to_string (context->suggested_action),
 			  _gdk_win32_drag_action_to_string (context->action)));
-
+			  
   context->action = action;
 
-  if (!use_ole2_dnd)
-    {
-      src_context = gdk_drag_context_find (TRUE,
-					   context->source_window,
-					   context->dest_window);
-
-      if (src_context)
-	{
-	  GdkDragContextPrivateWin32 *private = PRIVATE_DATA (src_context);
-
-	  if (private->drag_status == GDK_DRAG_STATUS_MOTION_WAIT)
-	    private->drag_status = GDK_DRAG_STATUS_DRAG;
-
-	  tmp_event.type = GDK_DRAG_STATUS;
-	  tmp_event.dnd.window = context->source_window;
-	  tmp_event.dnd.send_event = FALSE;
-	  tmp_event.dnd.context = src_context;
-	  tmp_event.dnd.time = GDK_CURRENT_TIME; /* FIXME? */
+  src_context = gdk_drag_context_find (TRUE,
+				       context->source_window,
+				       context->dest_window);
+
+  if (src_context)
+    {
+      GdkDragContextPrivateWin32 *private = PRIVATE_DATA (src_context);
+      
+      if (private->drag_status == GDK_DRAG_STATUS_MOTION_WAIT)
+	private->drag_status = GDK_DRAG_STATUS_DRAG;
 
-	  if (action == GDK_ACTION_DEFAULT)
-	    action = 0;
-
-	  src_context->action = action;
+      tmp_event.dnd.type = GDK_DRAG_STATUS;
+      tmp_event.dnd.window = context->source_window;
+      tmp_event.dnd.send_event = FALSE;
+      tmp_event.dnd.context = src_context;
+      tmp_event.dnd.time = GDK_CURRENT_TIME; /* FIXME? */
 
-	  GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
-	  gdk_event_put (&tmp_event);
-	}
+      if (action == GDK_ACTION_DEFAULT)
+	action = 0;
+      
+      src_context->action = action;
+      
+      gdk_event_put (&tmp_event);
     }
 }
 
-void
+void 
 gdk_drop_reply (GdkDragContext *context,
 		gboolean        ok,
 		guint32         time)
@@ -2247,12 +1653,18 @@ gdk_drop_reply (GdkDragContext *context,
 
   GDK_NOTE (DND, g_print ("gdk_drop_reply\n"));
 
-  if (!use_ole2_dnd)
-    if (context->dest_window)
-      {
-	if (context->protocol == GDK_DRAG_PROTO_WIN32_DROPFILES)
+  if (context->dest_window)
+    {
+      switch (context->protocol)
+	{
+	case GDK_DRAG_PROTO_WIN32_DROPFILES:
 	  _gdk_dropfiles_store (NULL);
-      }
+	  break;
+
+	default:
+	  break;
+	}
+    }
 }
 
 void
@@ -2263,41 +1675,28 @@ gdk_drop_finish (GdkDragContext *context
   GdkDragContextPrivateWin32 *private;
   GdkDragContext *src_context;
   GdkEvent tmp_event;
-
+	
   g_return_if_fail (context != NULL);
 
   GDK_NOTE (DND, g_print ("gdk_drop_finish\n"));
 
   private = PRIVATE_DATA (context);
 
-  if (!use_ole2_dnd)
-    {
-      src_context = gdk_drag_context_find (TRUE,
-					   context->source_window,
-					   context->dest_window);
-      if (src_context)
-	{
-	  tmp_event.type = GDK_DROP_FINISHED;
-	  tmp_event.dnd.window = src_context->source_window;
-	  tmp_event.dnd.send_event = FALSE;
-	  tmp_event.dnd.context = src_context;
-
-	  GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
-	  gdk_event_put (&tmp_event);
-	}
-    }
-  else
+  src_context = gdk_drag_context_find (TRUE,
+				       context->source_window,
+				       context->dest_window);
+  if (src_context)
     {
-      gdk_drag_do_leave (context, time);
+      tmp_event.dnd.type = GDK_DROP_FINISHED;
+      tmp_event.dnd.window = src_context->source_window;
+      tmp_event.dnd.send_event = FALSE;
+      tmp_event.dnd.context = src_context;
 
-      if (success)
-	_dnd_target_state = GDK_WIN32_DND_DROPPED;
-      else
-	_dnd_target_state = GDK_WIN32_DND_FAILED;
+      gdk_event_put (&tmp_event);
     }
 }
 
-#if 0
+#ifdef OLE2_DND
 
 static GdkFilterReturn
 gdk_destroy_filter (GdkXEvent *xev,
@@ -2319,14 +1718,15 @@ gdk_destroy_filter (GdkXEvent *xev,
     }
   return GDK_FILTER_CONTINUE;
 }
-
 #endif
 
 void
 gdk_window_register_dnd (GdkWindow *window)
 {
+#ifdef OLE2_DND
   target_drag_context *ctx;
-  HRESULT hr;
+  HRESULT hres;
+#endif
 
   g_return_if_fail (window != NULL);
 
@@ -2337,68 +1737,64 @@ gdk_window_register_dnd (GdkWindow *wind
 
   GDK_NOTE (DND, g_print ("gdk_window_register_dnd: %p\n", GDK_WINDOW_HWND (window)));
 
-  if (!use_ole2_dnd)
-    {
-      /* We always claim to accept dropped files, but in fact we might not,
-       * of course. This function is called in such a way that it cannot know
-       * whether the window (widget) in question actually accepts files
-       * (in gtk, data of type text/uri-list) or not.
-       */
-      gdk_window_add_filter (window, gdk_dropfiles_filter, NULL);
-      DragAcceptFiles (GDK_WINDOW_HWND (window), TRUE);
-    }
+  /* We always claim to accept dropped files, but in fact we might not,
+   * of course. This function is called in such a way that it cannot know
+   * whether the window (widget) in question actually accepts files
+   * (in gtk, data of type text/uri-list) or not.
+   */
+  gdk_window_add_filter (window, gdk_dropfiles_filter, NULL);
+  DragAcceptFiles (GDK_WINDOW_HWND (window), TRUE);
+
+#ifdef OLE2_DND
+  /* Register for OLE2 d&d */
+  ctx = target_context_new ();
+  ctx->context->protocol = GDK_DRAG_PROTO_OLE2;
+  hres = CoLockObjectExternal ((IUnknown *) &ctx->idt, TRUE, FALSE);
+  if (!SUCCEEDED (hres))
+    OTHER_API_FAILED ("CoLockObjectExternal");
   else
     {
-      /* Return if window is already setup for DND. */
-      if (g_hash_table_lookup (target_ctx_for_window, GDK_WINDOW_HWND (window)) != NULL)
-	return;
-
-      /* Register for OLE2 d&d : similarly, claim to accept all supported
-       * data types because we cannot know from here what the window
-       * actually accepts.
-       */
-      /* FIXME: This of course won't work with user-extensible data types! */
-      ctx = target_context_new (window);
-
-      hr = CoLockObjectExternal ((IUnknown *) &ctx->idt, TRUE, FALSE);
-      if (!SUCCEEDED (hr))
-	OTHER_API_FAILED ("CoLockObjectExternal");
+      hres = RegisterDragDrop (GDK_WINDOW_HWND (window), &ctx->idt);
+      if (hres == DRAGDROP_E_ALREADYREGISTERED)
+	{
+	  g_print ("DRAGDROP_E_ALREADYREGISTERED\n");
+#if 0
+	  ctx->idt.lpVtbl->Release (&ctx->idt);
+#endif
+	  CoLockObjectExternal ((IUnknown *) &ctx->idt, FALSE, FALSE);
+	}
+      else if (!SUCCEEDED (hres))
+	OTHER_API_FAILED ("RegisterDragDrop");
       else
 	{
-	  hr = RegisterDragDrop (GDK_WINDOW_HWND (window), &ctx->idt);
-	  if (hr == DRAGDROP_E_ALREADYREGISTERED)
-	    {
-	      g_print ("DRAGDROP_E_ALREADYREGISTERED\n");
-	      CoLockObjectExternal ((IUnknown *) &ctx->idt, FALSE, FALSE);
-	    }
-	  else if (!SUCCEEDED (hr))
-	    OTHER_API_FAILED ("RegisterDragDrop");
-	  else
-	    {
-	      gdk_window_ref (window);
-	      g_hash_table_insert (target_ctx_for_window, GDK_WINDOW_HWND (window), ctx);
-	    }
+	  gdk_window_add_filter (window, gdk_destroy_filter, &ctx->idt);
 	}
     }
+#endif
 }
 
+/*************************************************************
+ * gdk_drag_get_selection:
+ *     Returns the selection atom for the current source window
+ *   arguments:
+ *
+ *   results:
+ *************************************************************/
+
 GdkAtom
 gdk_drag_get_selection (GdkDragContext *context)
 {
-  switch (context->protocol)
-    {
-    case GDK_DRAG_PROTO_LOCAL:
-      return _local_dnd;
-    case GDK_DRAG_PROTO_WIN32_DROPFILES:
-      return _gdk_win32_dropfiles;
-    case GDK_DRAG_PROTO_OLE2:
-      return _gdk_ole2_dnd;
-    default:
-      return GDK_NONE;
-    }
+  if (context->protocol == GDK_DRAG_PROTO_LOCAL)
+    return _local_dnd;
+  else if (context->protocol == GDK_DRAG_PROTO_WIN32_DROPFILES)
+    return _gdk_win32_dropfiles;
+  else if (context->protocol == GDK_DRAG_PROTO_OLE2)
+    return _gdk_ole2_dnd;
+  else
+    return GDK_NONE;
 }
 
-gboolean
+gboolean 
 gdk_drag_drop_succeeded (GdkDragContext *context)
 {
   GdkDragContextPrivateWin32 *private;
diff -rupN gtk+-2.20.0/gdk/win32/gdkevents-win32.c gtk+-2.18.9/gdk/win32/gdkevents-win32.c
--- gtk+-2.20.0/gdk/win32/gdkevents-win32.c	2010-03-22 20:44:10.000000000 +0800
+++ gtk+-2.18.9/gdk/win32/gdkevents-win32.c	2010-03-17 21:31:42.000000000 +0800
@@ -3378,14 +3415,6 @@ gdk_event_dispatch (GSource     *source,
 	(*_gdk_event_func) (event, _gdk_event_data);
       
       gdk_event_free (event);
-
-      /* Do drag & drop if it is still pending */
-      if (_dnd_source_state == GDK_WIN32_DND_PENDING) 
-	{
-	  _dnd_source_state = GDK_WIN32_DND_DRAGGING;
-	  _gdk_win32_dnd_do_dragdrop ();
-	  _dnd_source_state = GDK_WIN32_DND_NONE;
-	}
     }
   
   GDK_THREADS_LEAVE ();
diff -rupN gtk+-2.20.0/gdk/win32/gdkproperty-win32.c gtk+-2.18.9/gdk/win32/gdkproperty-win32.c
--- gtk+-2.20.0/gdk/win32/gdkproperty-win32.c	2010-03-22 20:44:10.000000000 +0800
+++ gtk+-2.18.9/gdk/win32/gdkproperty-win32.c	2010-03-17 21:31:42.000000000 +0800
@@ -258,11 +258,6 @@ gdk_property_change (GdkWindow    *windo
 	  _delayed_rendering_data = hdata;
 	}
     }
-  else if (property == _gdk_ole2_dnd)
-    {
-      /* Will happen only if gdkdnd-win32.c has OLE2 dnd support compiled in */
-      _gdk_win32_ole2_dnd_property_change (type, format, data, nelements);
-    }
   else
     g_warning ("gdk_property_change: General case not implemented");
 }
