Make the OLE2 DND code selectable at run-time instead of compile-time

(It still doesn't work, though.)
This commit is contained in:
Tor Lillqvist
2009-12-17 01:50:47 +02:00
parent a5dec477e2
commit 435606a5bf

View File

@ -32,14 +32,12 @@
#include <io.h> #include <io.h>
#include <fcntl.h> #include <fcntl.h>
/* #define OLE2_DND */
/* /*
* Comment from the old OLE2 DND code that is being merged in (behind * Comment from the old OLE2 DND code that is being merged in. Note
* #ifdef OLE2_DND). Note that this comment might not fully reflect * that this comment might not fully reflect reality as the code
* reality as the code obviously will have to be modified in this * obviously will have to be modified in this merge. Especially the
* merge. Especially the talk about supporting other than UTF-8 text * talk about supporting other than UTF-8 text is bogus, that will not
* is bogus, that will not happen. * happen.
* *
* Support for OLE-2 drag and drop added at Archaeopteryx Software, 2001 * Support for OLE-2 drag and drop added at Archaeopteryx Software, 2001
* For more information, contact Stephan R.A. Deibel (sdeibel@archaeopteryx.com) * For more information, contact Stephan R.A. Deibel (sdeibel@archaeopteryx.com)
@ -79,11 +77,7 @@
#include "gdkinternals.h" #include "gdkinternals.h"
#include "gdkprivate-win32.h" #include "gdkprivate-win32.h"
#ifdef OLE2_DND
#include <ole2.h> #include <ole2.h>
#else
#include <objbase.h>
#endif
#include <shlobj.h> #include <shlobj.h>
#include <shlguid.h> #include <shlguid.h>
@ -104,12 +98,10 @@ typedef enum {
* this is used on both source and destination sides. * this is used on both source and destination sides.
*/ */
struct _GdkDragContextPrivateWin32 { struct _GdkDragContextPrivateWin32 {
#ifdef OLE2_DND
gboolean being_finalized; gboolean being_finalized;
gint ref_count; gint ref_count;
IUnknown *iface; IUnknown *iface;
DWORD last_key_state; DWORD last_key_state;
#endif
POINT last_pt; /* Coordinates from last event */ POINT last_pt; /* Coordinates from last event */
guint drag_status : 4; /* Current status of drag */ guint drag_status : 4; /* Current status of drag */
guint drop_failed : 1; /* Whether the drop was unsuccessful */ guint drop_failed : 1; /* Whether the drop was unsuccessful */
@ -117,19 +109,17 @@ struct _GdkDragContextPrivateWin32 {
#define PRIVATE_DATA(context) ((GdkDragContextPrivateWin32 *) GDK_DRAG_CONTEXT (context)->windowing_data) #define PRIVATE_DATA(context) ((GdkDragContextPrivateWin32 *) GDK_DRAG_CONTEXT (context)->windowing_data)
#ifndef OLE2_DND
static GList *contexts; static GList *contexts;
static GdkDragContext *current_dest_drag = NULL; static GdkDragContext *current_dest_drag = NULL;
#endif
static void gdk_drag_context_init (GdkDragContext *dragcontext); static void gdk_drag_context_init (GdkDragContext *dragcontext);
static void gdk_drag_context_class_init (GdkDragContextClass *klass); static void gdk_drag_context_class_init (GdkDragContextClass *klass);
static void gdk_drag_context_finalize (GObject *object); static void gdk_drag_context_finalize (GObject *object);
static gpointer parent_class = NULL; static gpointer parent_class = NULL;
static gboolean use_ole2_dnd = FALSE;
G_DEFINE_TYPE (GdkDragContext, gdk_drag_context, G_TYPE_OBJECT) G_DEFINE_TYPE (GdkDragContext, gdk_drag_context, G_TYPE_OBJECT)
static void static void
@ -143,13 +133,16 @@ gdk_drag_context_init (GdkDragContext *dragcontext)
dragcontext->windowing_data = private; dragcontext->windowing_data = private;
#ifndef OLE2_DND if (!use_ole2_dnd)
{
contexts = g_list_prepend (contexts, dragcontext); contexts = g_list_prepend (contexts, dragcontext);
#else }
else
{
private->being_finalized = FALSE; private->being_finalized = FALSE;
private->ref_count = 1; private->ref_count = 1;
private->iface = NULL; private->iface = NULL;
#endif }
GDK_NOTE (DND, g_print ("gdk_drag_context_init %p\n", dragcontext)); GDK_NOTE (DND, g_print ("gdk_drag_context_init %p\n", dragcontext));
} }
@ -181,12 +174,14 @@ gdk_drag_context_finalize (GObject *object)
if (context->dest_window) if (context->dest_window)
g_object_unref (context->dest_window); g_object_unref (context->dest_window);
#ifndef OLE2_DND if (!use_ole2_dnd)
{
contexts = g_list_remove (contexts, context); contexts = g_list_remove (contexts, context);
if (context == current_dest_drag) if (context == current_dest_drag)
current_dest_drag = NULL; current_dest_drag = NULL;
#else }
else
{ {
GdkDragContextPrivateWin32 *private = PRIVATE_DATA (context); GdkDragContextPrivateWin32 *private = PRIVATE_DATA (context);
if (private->iface) if (private->iface)
@ -196,7 +191,6 @@ gdk_drag_context_finalize (GObject *object)
private->iface = NULL; private->iface = NULL;
} }
} }
#endif
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
@ -225,8 +219,6 @@ gdk_drag_context_unref (GdkDragContext *context)
g_object_unref (context); g_object_unref (context);
} }
#ifndef OLE2_DND
static GdkDragContext * static GdkDragContext *
gdk_drag_context_find (gboolean is_source, gdk_drag_context_find (gboolean is_source,
GdkWindow *source, GdkWindow *source,
@ -252,10 +244,6 @@ gdk_drag_context_find (gboolean is_source,
return NULL; return NULL;
} }
#endif
#ifdef OLE2_DND
#define PRINT_GUID(guid) \ #define PRINT_GUID(guid) \
g_print ("%.08lx-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x", \ g_print ("%.08lx-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x", \
((gulong *) guid)[0], \ ((gulong *) guid)[0], \
@ -1290,20 +1278,14 @@ enum_formats_new (void)
return result; return result;
} }
#endif
/* Needs to be compiled (even if empty) also in the non-OLE2_DND
* case as called from gdk_property_change() in gdkproperty-win32.c
* and we want to have the OLE2_DND conditionals just in this
* source file.
*/
void void
_gdk_win32_ole2_dnd_property_change (GdkAtom type, _gdk_win32_ole2_dnd_property_change (GdkAtom type,
gint format, gint format,
const guchar *data, const guchar *data,
gint nelements) gint nelements)
{ {
#ifdef OLE2_DND if (use_ole2_dnd)
{
HGLOBAL hdata = NULL; HGLOBAL hdata = NULL;
if (active_pFormatEtc == NULL || active_pMedium == NULL) if (active_pFormatEtc == NULL || active_pMedium == NULL)
@ -1332,10 +1314,8 @@ _gdk_win32_ole2_dnd_property_change (GdkAtom type,
active_pMedium->tymed = TYMED_HGLOBAL; active_pMedium->tymed = TYMED_HGLOBAL;
active_pMedium->hGlobal = hdata; active_pMedium->hGlobal = hdata;
active_pMedium->pUnkForRelease = 0; active_pMedium->pUnkForRelease = 0;
#endif
} }
}
#ifndef OLE2_DND
/* From MS Knowledge Base article Q130698 */ /* From MS Knowledge Base article Q130698 */
@ -1578,10 +1558,6 @@ gdk_dropfiles_filter (GdkXEvent *xev,
return GDK_FILTER_CONTINUE; return GDK_FILTER_CONTINUE;
} }
#endif /* !OLE2_DND */
#ifdef OLE2_DND
static void static void
add_format (GArray *fmts, add_format (GArray *fmts,
CLIPFORMAT cf) CLIPFORMAT cf)
@ -1597,12 +1573,15 @@ add_format (GArray *fmts,
g_array_append_val (fmts, fmt); g_array_append_val (fmts, fmt);
} }
#endif
void void
_gdk_dnd_init (void) _gdk_dnd_init (void)
{ {
#ifdef OLE2_DND if (getenv ("GDK_WIN32_USE_EXPERIMENTAL_OLE2_DND"))
use_ole2_dnd = TRUE;
if (use_ole2_dnd)
{
HRESULT hr; HRESULT hr;
GArray *fmts; GArray *fmts;
@ -1634,21 +1613,20 @@ _gdk_dnd_init (void)
formats = (FORMATETC*) g_array_free (fmts, FALSE); formats = (FORMATETC*) g_array_free (fmts, FALSE);
target_ctx_for_window = g_hash_table_new (g_direct_hash, g_direct_equal); target_ctx_for_window = g_hash_table_new (g_direct_hash, g_direct_equal);
#endif }
} }
void void
_gdk_win32_dnd_exit (void) _gdk_win32_dnd_exit (void)
{ {
#ifdef OLE2_DND if (use_ole2_dnd)
{
OleUninitialize (); OleUninitialize ();
#endif }
} }
/* Source side */ /* Source side */
#ifndef OLE2_DND
static void static void
local_send_leave (GdkDragContext *context, local_send_leave (GdkDragContext *context,
guint32 time) guint32 time)
@ -1799,8 +1777,6 @@ local_send_drop (GdkDragContext *context,
} }
#endif
static void static void
gdk_drag_do_leave (GdkDragContext *context, gdk_drag_do_leave (GdkDragContext *context,
guint32 time) guint32 time)
@ -1809,10 +1785,11 @@ gdk_drag_do_leave (GdkDragContext *context,
{ {
GDK_NOTE (DND, g_print ("gdk_drag_do_leave\n")); GDK_NOTE (DND, g_print ("gdk_drag_do_leave\n"));
#ifndef OLE2_DND if (!use_ole2_dnd)
{
if (context->protocol == GDK_DRAG_PROTO_LOCAL) if (context->protocol == GDK_DRAG_PROTO_LOCAL)
local_send_leave (context, time); local_send_leave (context, time);
#endif }
g_object_unref (context->dest_window); g_object_unref (context->dest_window);
context->dest_window = NULL; context->dest_window = NULL;
@ -1823,7 +1800,8 @@ GdkDragContext *
gdk_drag_begin (GdkWindow *window, gdk_drag_begin (GdkWindow *window,
GList *targets) GList *targets)
{ {
#ifndef OLE2_DND if (!use_ole2_dnd)
{
GdkDragContext *new_context; GdkDragContext *new_context;
g_return_val_if_fail (window != NULL, NULL); g_return_val_if_fail (window != NULL, NULL);
@ -1839,7 +1817,9 @@ gdk_drag_begin (GdkWindow *window,
new_context->actions = 0; new_context->actions = 0;
return new_context; return new_context;
#else }
else
{
source_drag_context *ctx; source_drag_context *ctx;
g_return_val_if_fail (window != NULL, NULL); g_return_val_if_fail (window != NULL, NULL);
@ -1854,13 +1834,14 @@ gdk_drag_begin (GdkWindow *window,
gdk_drag_context_ref (ctx->context); gdk_drag_context_ref (ctx->context);
return ctx->context; return ctx->context;
#endif }
} }
void void
_gdk_win32_dnd_do_dragdrop (void) _gdk_win32_dnd_do_dragdrop (void)
{ {
#ifdef OLE2_DND if (use_ole2_dnd)
{
GdkDragContext* drag_ctx; GdkDragContext* drag_ctx;
GdkDragContextPrivateWin32 *private; GdkDragContextPrivateWin32 *private;
BYTE kbd_state[256]; BYTE kbd_state[256];
@ -1961,7 +1942,7 @@ _gdk_win32_dnd_do_dragdrop (void)
pending_src_context->ids.lpVtbl->Release (&pending_src_context->ids); pending_src_context->ids.lpVtbl->Release (&pending_src_context->ids);
pending_src_context = NULL; pending_src_context = NULL;
} }
#endif }
} }
GdkNativeWindow GdkNativeWindow
@ -1977,11 +1958,11 @@ gdk_drag_get_protocol_for_display (GdkDisplay *display,
{ {
if (g_object_get_data (G_OBJECT (window), "gdk-dnd-registered") != NULL) if (g_object_get_data (G_OBJECT (window), "gdk-dnd-registered") != NULL)
{ {
#ifdef OLE2_DND if (use_ole2_dnd)
*protocol = GDK_DRAG_PROTO_OLE2; *protocol = GDK_DRAG_PROTO_OLE2;
#else else
*protocol = GDK_DRAG_PROTO_LOCAL; *protocol = GDK_DRAG_PROTO_LOCAL;
#endif
return xid; return xid;
} }
} }
@ -2016,14 +1997,12 @@ gdk_drag_find_window_for_screen (GdkDragContext *context,
else else
*dest_window = gdk_window_foreign_new_for_display (_gdk_display, hwnd); *dest_window = gdk_window_foreign_new_for_display (_gdk_display, hwnd);
#ifdef OLE2_DND if (use_ole2_dnd)
*protocol = GDK_DRAG_PROTO_OLE2; *protocol = GDK_DRAG_PROTO_OLE2;
#else else if (context->source_window)
if (context->source_window)
*protocol = GDK_DRAG_PROTO_LOCAL; *protocol = GDK_DRAG_PROTO_LOCAL;
else else
*protocol = GDK_DRAG_PROTO_WIN32_DROPFILES; *protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
#endif
} }
GDK_NOTE (DND, GDK_NOTE (DND,
@ -2063,7 +2042,8 @@ gdk_drag_motion (GdkDragContext *context,
private = PRIVATE_DATA (context); private = PRIVATE_DATA (context);
#ifndef OLE2_DND if (!use_ole2_dnd)
{
if (context->dest_window == dest_window) if (context->dest_window == dest_window)
{ {
GdkDragContext *dest_context; GdkDragContext *dest_context;
@ -2160,8 +2140,7 @@ gdk_drag_motion (GdkDragContext *context,
return TRUE; return TRUE;
} }
} }
}
#endif
GDK_NOTE (DND, g_print (" returning FALSE\n" GDK_NOTE (DND, g_print (" returning FALSE\n"
" context=%p:{actions=%s,suggested=%s,action=%s}\n", " context=%p:{actions=%s,suggested=%s,action=%s}\n",
@ -2180,13 +2159,16 @@ gdk_drag_drop (GdkDragContext *context,
GDK_NOTE (DND, g_print ("gdk_drag_drop\n")); GDK_NOTE (DND, g_print ("gdk_drag_drop\n"));
#ifndef OLE2_DND if (!use_ole2_dnd)
{
if (context->dest_window && if (context->dest_window &&
context->protocol == GDK_DRAG_PROTO_LOCAL) context->protocol == GDK_DRAG_PROTO_LOCAL)
local_send_drop (context, time); local_send_drop (context, time);
#else }
else
{
_dnd_source_state = GDK_WIN32_DND_DROPPED; _dnd_source_state = GDK_WIN32_DND_DROPPED;
#endif }
} }
void void
@ -2197,9 +2179,8 @@ gdk_drag_abort (GdkDragContext *context,
GDK_NOTE (DND, g_print ("gdk_drag_abort\n")); GDK_NOTE (DND, g_print ("gdk_drag_abort\n"));
#ifdef OLE2_DND if (use_ole2_dnd)
_dnd_source_state = GDK_WIN32_DND_NONE; _dnd_source_state = GDK_WIN32_DND_NONE;
#endif
} }
/* Destination side */ /* Destination side */
@ -2210,10 +2191,8 @@ gdk_drag_status (GdkDragContext *context,
guint32 time) guint32 time)
{ {
GdkDragContextPrivateWin32 *private; GdkDragContextPrivateWin32 *private;
#ifndef OLE2_DND
GdkDragContext *src_context; GdkDragContext *src_context;
GdkEvent tmp_event; GdkEvent tmp_event;
#endif
g_return_if_fail (context != NULL); g_return_if_fail (context != NULL);
@ -2229,8 +2208,8 @@ gdk_drag_status (GdkDragContext *context,
context->action = action; context->action = action;
#ifndef OLE2_DND if (!use_ole2_dnd)
{
src_context = gdk_drag_context_find (TRUE, src_context = gdk_drag_context_find (TRUE,
context->source_window, context->source_window,
context->dest_window); context->dest_window);
@ -2256,7 +2235,7 @@ gdk_drag_status (GdkDragContext *context,
GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event)); GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
gdk_event_put (&tmp_event); gdk_event_put (&tmp_event);
} }
#endif }
} }
void void
@ -2268,14 +2247,12 @@ gdk_drop_reply (GdkDragContext *context,
GDK_NOTE (DND, g_print ("gdk_drop_reply\n")); GDK_NOTE (DND, g_print ("gdk_drop_reply\n"));
#ifndef OLE2_DND if (!use_ole2_dnd)
if (context->dest_window) if (context->dest_window)
{ {
if (context->protocol == GDK_DRAG_PROTO_WIN32_DROPFILES) if (context->protocol == GDK_DRAG_PROTO_WIN32_DROPFILES)
_gdk_dropfiles_store (NULL); _gdk_dropfiles_store (NULL);
} }
#endif
} }
void void
@ -2284,10 +2261,8 @@ gdk_drop_finish (GdkDragContext *context,
guint32 time) guint32 time)
{ {
GdkDragContextPrivateWin32 *private; GdkDragContextPrivateWin32 *private;
#ifndef OLE2_DND
GdkDragContext *src_context; GdkDragContext *src_context;
GdkEvent tmp_event; GdkEvent tmp_event;
#endif
g_return_if_fail (context != NULL); g_return_if_fail (context != NULL);
@ -2295,7 +2270,8 @@ gdk_drop_finish (GdkDragContext *context,
private = PRIVATE_DATA (context); private = PRIVATE_DATA (context);
#ifndef OLE2_DND if (!use_ole2_dnd)
{
src_context = gdk_drag_context_find (TRUE, src_context = gdk_drag_context_find (TRUE,
context->source_window, context->source_window,
context->dest_window); context->dest_window);
@ -2309,17 +2285,17 @@ gdk_drop_finish (GdkDragContext *context,
GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event)); GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
gdk_event_put (&tmp_event); gdk_event_put (&tmp_event);
} }
#else }
else
{
gdk_drag_do_leave (context, time); gdk_drag_do_leave (context, time);
if (success) if (success)
_dnd_target_state = GDK_WIN32_DND_DROPPED; _dnd_target_state = GDK_WIN32_DND_DROPPED;
else else
_dnd_target_state = GDK_WIN32_DND_FAILED; _dnd_target_state = GDK_WIN32_DND_FAILED;
#endif
} }
}
#ifdef OLE2_DND
#if 0 #if 0
@ -2346,15 +2322,11 @@ gdk_destroy_filter (GdkXEvent *xev,
#endif #endif
#endif
void void
gdk_window_register_dnd (GdkWindow *window) gdk_window_register_dnd (GdkWindow *window)
{ {
#ifdef OLE2_DND
target_drag_context *ctx; target_drag_context *ctx;
HRESULT hr; HRESULT hr;
#endif
g_return_if_fail (window != NULL); g_return_if_fail (window != NULL);
@ -2365,7 +2337,8 @@ gdk_window_register_dnd (GdkWindow *window)
GDK_NOTE (DND, g_print ("gdk_window_register_dnd: %p\n", GDK_WINDOW_HWND (window))); GDK_NOTE (DND, g_print ("gdk_window_register_dnd: %p\n", GDK_WINDOW_HWND (window)));
#ifndef OLE2_DND if (!use_ole2_dnd)
{
/* We always claim to accept dropped files, but in fact we might not, /* 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 * of course. This function is called in such a way that it cannot know
* whether the window (widget) in question actually accepts files * whether the window (widget) in question actually accepts files
@ -2373,7 +2346,9 @@ gdk_window_register_dnd (GdkWindow *window)
*/ */
gdk_window_add_filter (window, gdk_dropfiles_filter, NULL); gdk_window_add_filter (window, gdk_dropfiles_filter, NULL);
DragAcceptFiles (GDK_WINDOW_HWND (window), TRUE); DragAcceptFiles (GDK_WINDOW_HWND (window), TRUE);
#else }
else
{
/* Return if window is already setup for DND. */ /* Return if window is already setup for DND. */
if (g_hash_table_lookup (target_ctx_for_window, GDK_WINDOW_HWND (window)) != NULL) if (g_hash_table_lookup (target_ctx_for_window, GDK_WINDOW_HWND (window)) != NULL)
return; return;
@ -2404,7 +2379,7 @@ gdk_window_register_dnd (GdkWindow *window)
g_hash_table_insert (target_ctx_for_window, GDK_WINDOW_HWND (window), ctx); g_hash_table_insert (target_ctx_for_window, GDK_WINDOW_HWND (window), ctx);
} }
} }
#endif }
} }
GdkAtom GdkAtom