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 <fcntl.h>
/* #define OLE2_DND */
/*
* Comment from the old OLE2 DND code that is being merged in (behind
* #ifdef OLE2_DND). 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.
* 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)
@ -79,11 +77,7 @@
#include "gdkinternals.h"
#include "gdkprivate-win32.h"
#ifdef OLE2_DND
#include <ole2.h>
#else
#include <objbase.h>
#endif
#include <shlobj.h>
#include <shlguid.h>
@ -104,12 +98,10 @@ typedef enum {
* 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;
#endif
POINT last_pt; /* Coordinates from last event */
guint drag_status : 4; /* Current status of drag */
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)
#ifndef OLE2_DND
static GList *contexts;
static GdkDragContext *current_dest_drag = NULL;
#endif
static void gdk_drag_context_init (GdkDragContext *dragcontext);
static void gdk_drag_context_class_init (GdkDragContextClass *klass);
static void gdk_drag_context_finalize (GObject *object);
static gpointer parent_class = NULL;
static gboolean use_ole2_dnd = FALSE;
G_DEFINE_TYPE (GdkDragContext, gdk_drag_context, G_TYPE_OBJECT)
static void
@ -143,13 +133,16 @@ gdk_drag_context_init (GdkDragContext *dragcontext)
dragcontext->windowing_data = private;
#ifndef OLE2_DND
if (!use_ole2_dnd)
{
contexts = g_list_prepend (contexts, dragcontext);
#else
}
else
{
private->being_finalized = FALSE;
private->ref_count = 1;
private->iface = NULL;
#endif
}
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)
g_object_unref (context->dest_window);
#ifndef OLE2_DND
if (!use_ole2_dnd)
{
contexts = g_list_remove (contexts, context);
if (context == current_dest_drag)
current_dest_drag = NULL;
#else
}
else
{
GdkDragContextPrivateWin32 *private = PRIVATE_DATA (context);
if (private->iface)
@ -196,7 +191,6 @@ gdk_drag_context_finalize (GObject *object)
private->iface = NULL;
}
}
#endif
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -225,8 +219,6 @@ gdk_drag_context_unref (GdkDragContext *context)
g_object_unref (context);
}
#ifndef OLE2_DND
static GdkDragContext *
gdk_drag_context_find (gboolean is_source,
GdkWindow *source,
@ -252,10 +244,6 @@ gdk_drag_context_find (gboolean is_source,
return NULL;
}
#endif
#ifdef OLE2_DND
#define PRINT_GUID(guid) \
g_print ("%.08lx-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x", \
((gulong *) guid)[0], \
@ -1290,20 +1278,14 @@ enum_formats_new (void)
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
_gdk_win32_ole2_dnd_property_change (GdkAtom type,
gint format,
const guchar *data,
gint nelements)
{
#ifdef OLE2_DND
if (use_ole2_dnd)
{
HGLOBAL hdata = NULL;
if (active_pFormatEtc == NULL || active_pMedium == NULL)
@ -1332,11 +1314,9 @@ _gdk_win32_ole2_dnd_property_change (GdkAtom type,
active_pMedium->tymed = TYMED_HGLOBAL;
active_pMedium->hGlobal = hdata;
active_pMedium->pUnkForRelease = 0;
#endif
}
}
#ifndef OLE2_DND
/* From MS Knowledge Base article Q130698 */
static gboolean
@ -1578,10 +1558,6 @@ gdk_dropfiles_filter (GdkXEvent *xev,
return GDK_FILTER_CONTINUE;
}
#endif /* !OLE2_DND */
#ifdef OLE2_DND
static void
add_format (GArray *fmts,
CLIPFORMAT cf)
@ -1597,12 +1573,15 @@ add_format (GArray *fmts,
g_array_append_val (fmts, fmt);
}
#endif
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;
GArray *fmts;
@ -1634,21 +1613,20 @@ _gdk_dnd_init (void)
formats = (FORMATETC*) g_array_free (fmts, FALSE);
target_ctx_for_window = g_hash_table_new (g_direct_hash, g_direct_equal);
#endif
}
}
void
_gdk_win32_dnd_exit (void)
{
#ifdef OLE2_DND
if (use_ole2_dnd)
{
OleUninitialize ();
#endif
}
}
/* Source side */
#ifndef OLE2_DND
static void
local_send_leave (GdkDragContext *context,
guint32 time)
@ -1799,8 +1777,6 @@ local_send_drop (GdkDragContext *context,
}
#endif
static void
gdk_drag_do_leave (GdkDragContext *context,
guint32 time)
@ -1809,10 +1785,11 @@ gdk_drag_do_leave (GdkDragContext *context,
{
GDK_NOTE (DND, g_print ("gdk_drag_do_leave\n"));
#ifndef OLE2_DND
if (!use_ole2_dnd)
{
if (context->protocol == GDK_DRAG_PROTO_LOCAL)
local_send_leave (context, time);
#endif
}
g_object_unref (context->dest_window);
context->dest_window = NULL;
@ -1823,7 +1800,8 @@ GdkDragContext *
gdk_drag_begin (GdkWindow *window,
GList *targets)
{
#ifndef OLE2_DND
if (!use_ole2_dnd)
{
GdkDragContext *new_context;
g_return_val_if_fail (window != NULL, NULL);
@ -1839,7 +1817,9 @@ gdk_drag_begin (GdkWindow *window,
new_context->actions = 0;
return new_context;
#else
}
else
{
source_drag_context *ctx;
g_return_val_if_fail (window != NULL, NULL);
@ -1854,13 +1834,14 @@ gdk_drag_begin (GdkWindow *window,
gdk_drag_context_ref (ctx->context);
return ctx->context;
#endif
}
}
void
_gdk_win32_dnd_do_dragdrop (void)
{
#ifdef OLE2_DND
if (use_ole2_dnd)
{
GdkDragContext* drag_ctx;
GdkDragContextPrivateWin32 *private;
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 = NULL;
}
#endif
}
}
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)
{
#ifdef OLE2_DND
if (use_ole2_dnd)
*protocol = GDK_DRAG_PROTO_OLE2;
#else
else
*protocol = GDK_DRAG_PROTO_LOCAL;
#endif
return xid;
}
}
@ -2016,14 +1997,12 @@ gdk_drag_find_window_for_screen (GdkDragContext *context,
else
*dest_window = gdk_window_foreign_new_for_display (_gdk_display, hwnd);
#ifdef OLE2_DND
if (use_ole2_dnd)
*protocol = GDK_DRAG_PROTO_OLE2;
#else
if (context->source_window)
else if (context->source_window)
*protocol = GDK_DRAG_PROTO_LOCAL;
else
*protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
#endif
}
GDK_NOTE (DND,
@ -2063,7 +2042,8 @@ gdk_drag_motion (GdkDragContext *context,
private = PRIVATE_DATA (context);
#ifndef OLE2_DND
if (!use_ole2_dnd)
{
if (context->dest_window == dest_window)
{
GdkDragContext *dest_context;
@ -2160,8 +2140,7 @@ gdk_drag_motion (GdkDragContext *context,
return TRUE;
}
}
#endif
}
GDK_NOTE (DND, g_print (" returning FALSE\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"));
#ifndef OLE2_DND
if (!use_ole2_dnd)
{
if (context->dest_window &&
context->protocol == GDK_DRAG_PROTO_LOCAL)
local_send_drop (context, time);
#else
}
else
{
_dnd_source_state = GDK_WIN32_DND_DROPPED;
#endif
}
}
void
@ -2197,9 +2179,8 @@ gdk_drag_abort (GdkDragContext *context,
GDK_NOTE (DND, g_print ("gdk_drag_abort\n"));
#ifdef OLE2_DND
if (use_ole2_dnd)
_dnd_source_state = GDK_WIN32_DND_NONE;
#endif
}
/* Destination side */
@ -2210,10 +2191,8 @@ gdk_drag_status (GdkDragContext *context,
guint32 time)
{
GdkDragContextPrivateWin32 *private;
#ifndef OLE2_DND
GdkDragContext *src_context;
GdkEvent tmp_event;
#endif
g_return_if_fail (context != NULL);
@ -2229,8 +2208,8 @@ gdk_drag_status (GdkDragContext *context,
context->action = action;
#ifndef OLE2_DND
if (!use_ole2_dnd)
{
src_context = gdk_drag_context_find (TRUE,
context->source_window,
context->dest_window);
@ -2256,7 +2235,7 @@ gdk_drag_status (GdkDragContext *context,
GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
gdk_event_put (&tmp_event);
}
#endif
}
}
void
@ -2268,14 +2247,12 @@ gdk_drop_reply (GdkDragContext *context,
GDK_NOTE (DND, g_print ("gdk_drop_reply\n"));
#ifndef OLE2_DND
if (!use_ole2_dnd)
if (context->dest_window)
{
if (context->protocol == GDK_DRAG_PROTO_WIN32_DROPFILES)
_gdk_dropfiles_store (NULL);
}
#endif
}
void
@ -2284,10 +2261,8 @@ gdk_drop_finish (GdkDragContext *context,
guint32 time)
{
GdkDragContextPrivateWin32 *private;
#ifndef OLE2_DND
GdkDragContext *src_context;
GdkEvent tmp_event;
#endif
g_return_if_fail (context != NULL);
@ -2295,7 +2270,8 @@ gdk_drop_finish (GdkDragContext *context,
private = PRIVATE_DATA (context);
#ifndef OLE2_DND
if (!use_ole2_dnd)
{
src_context = gdk_drag_context_find (TRUE,
context->source_window,
context->dest_window);
@ -2309,18 +2285,18 @@ gdk_drop_finish (GdkDragContext *context,
GDK_NOTE (EVENTS, _gdk_win32_print_event (&tmp_event));
gdk_event_put (&tmp_event);
}
#else
}
else
{
gdk_drag_do_leave (context, time);
if (success)
_dnd_target_state = GDK_WIN32_DND_DROPPED;
else
_dnd_target_state = GDK_WIN32_DND_FAILED;
#endif
}
}
#ifdef OLE2_DND
#if 0
static GdkFilterReturn
@ -2346,15 +2322,11 @@ gdk_destroy_filter (GdkXEvent *xev,
#endif
#endif
void
gdk_window_register_dnd (GdkWindow *window)
{
#ifdef OLE2_DND
target_drag_context *ctx;
HRESULT hr;
#endif
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)));
#ifndef OLE2_DND
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
@ -2373,7 +2346,9 @@ gdk_window_register_dnd (GdkWindow *window)
*/
gdk_window_add_filter (window, gdk_dropfiles_filter, NULL);
DragAcceptFiles (GDK_WINDOW_HWND (window), TRUE);
#else
}
else
{
/* Return if window is already setup for DND. */
if (g_hash_table_lookup (target_ctx_for_window, GDK_WINDOW_HWND (window)) != NULL)
return;
@ -2404,7 +2379,7 @@ gdk_window_register_dnd (GdkWindow *window)
g_hash_table_insert (target_ctx_for_window, GDK_WINDOW_HWND (window), ctx);
}
}
#endif
}
}
GdkAtom