Commit eb21a7df authored by Tor Lillqvist's avatar Tor Lillqvist
Browse files

Work on OLE2-based generic DND

Intermediate commit of work in progress on integrating the old code
for OLE2-based generic drag and drop from Arhaeopteryx Software, from
a long time ago in the GTK+ 1.3 timeframe. Does still not work and is
as before not compiled in unless OLE2_DND is defined in
gdkdnd-win32.c. (Thus, for inter-process DND, still only WM_DROPFILES
style dropping of files on GTK+ apps works.)

Related slight refactoring of other code that shouldn't change how it
works. Add more global variables for run-time constants (once
initialized) representing well-known GdkAtoms and registered Windows
clipboard formats, as they with the generic DND code will be needed in
several source files. Some improved debugging output.
parent c196ac2b
This diff is collapsed.
......@@ -825,7 +825,7 @@ _gdk_win32_print_event (const GdkEvent *event)
default: g_assert_not_reached ();
}
g_print (" %p ", GDK_WINDOW_HWND (event->any.window));
g_print (" %p ", event->any.window ? GDK_WINDOW_HWND (event->any.window) : NULL);
switch (event->any.type)
{
......@@ -889,9 +889,14 @@ _gdk_win32_print_event (const GdkEvent *event)
case GDK_FOCUS_CHANGE:
g_print ("%s", (event->focus_change.in ? "IN" : "OUT"));
break;
case GDK_CONFIGURE:
g_print ("x:%d y:%d w:%d h:%d",
event->configure.x, event->configure.y,
event->configure.width, event->configure.height);
break;
case GDK_SELECTION_CLEAR:
case GDK_SELECTION_REQUEST:
case GDK_SELECTION_NOTIFY:
case GDK_SELECTION_CLEAR:
selection_name = gdk_atom_name (event->selection.selection);
target_name = gdk_atom_name (event->selection.target);
property_name = gdk_atom_name (event->selection.property);
......@@ -901,10 +906,19 @@ _gdk_win32_print_event (const GdkEvent *event)
g_free (target_name);
g_free (property_name);
break;
case GDK_CONFIGURE:
g_print ("x:%d y:%d w:%d h:%d",
event->configure.x, event->configure.y,
event->configure.width, event->configure.height);
case GDK_DRAG_ENTER:
case GDK_DRAG_LEAVE:
case GDK_DRAG_MOTION:
case GDK_DRAG_STATUS:
case GDK_DROP_START:
case GDK_DROP_FINISHED:
if (event->dnd.context != NULL)
g_print ("ctx:%p: %s %s src:%p dest:%p",
event->dnd.context,
_gdk_win32_drag_protocol_to_string (event->dnd.context->protocol),
event->dnd.context->is_source ? "SOURCE" : "DEST",
event->dnd.context->source_window == NULL ? NULL : GDK_WINDOW_HWND (event->dnd.context->source_window),
event->dnd.context->dest_window == NULL ? NULL : GDK_WINDOW_HWND (event->dnd.context->dest_window));
break;
case GDK_CLIENT_EVENT:
g_print ("%s %d %ld %ld %ld %ld %ld",
......@@ -1628,22 +1642,44 @@ handle_wm_paint (MSG *msg,
DeleteObject (hrgn);
}
static void
handle_stuff_while_moving_or_resizing (void)
static VOID CALLBACK
modal_timer_proc (HWND hwnd,
UINT msg,
UINT_PTR id,
DWORD time)
{
int arbitrary_limit = 1;
while (g_main_context_pending (NULL) && arbitrary_limit--)
while (_modal_operation_in_progress &&
g_main_context_pending (NULL) &&
arbitrary_limit--)
g_main_context_iteration (NULL, FALSE);
}
static VOID CALLBACK
modal_timer_proc (HWND hwnd,
UINT msg,
UINT_PTR id,
DWORD time)
void
_gdk_win32_begin_modal_call (void)
{
if (_sizemove_in_progress)
handle_stuff_while_moving_or_resizing ();
g_assert (!_modal_operation_in_progress);
_modal_operation_in_progress = TRUE;
modal_timer = SetTimer (NULL, 0, 10, modal_timer_proc);
if (modal_timer == 0)
WIN32_API_FAILED ("SetTimer");
}
void
_gdk_win32_end_modal_call (void)
{
g_assert (_modal_operation_in_progress);
_modal_operation_in_progress = FALSE;
if (modal_timer != 0)
{
API_CALL (KillTimer, (NULL, modal_timer));
modal_timer = 0;
}
}
static VOID CALLBACK
......@@ -2702,23 +2738,13 @@ gdk_event_translate (MSG *msg,
break;
case WM_ENTERSIZEMOVE:
_sizemove_in_progress = TRUE;
modal_timer = SetTimer (NULL, 0, 20, modal_timer_proc);
break;
case WM_EXITSIZEMOVE:
_sizemove_in_progress = FALSE;
KillTimer (NULL, modal_timer);
break;
case WM_ENTERMENULOOP:
_sizemove_in_progress = TRUE;
modal_timer = SetTimer (NULL, 0, 20, modal_timer_proc);
_gdk_win32_begin_modal_call ();
break;
case WM_EXITSIZEMOVE:
case WM_EXITMENULOOP:
_sizemove_in_progress = FALSE;
KillTimer (NULL, modal_timer);
_gdk_win32_end_modal_call ();
break;
case WM_WINDOWPOSCHANGING:
......@@ -2751,7 +2777,7 @@ gdk_event_translate (MSG *msg,
windowpos->cx, windowpos->cy, windowpos->x, windowpos->y));
/* If position and size haven't changed, don't do anything */
if (_sizemove_in_progress &&
if (_modal_operation_in_progress &&
(windowpos->flags & SWP_NOMOVE) &&
(windowpos->flags & SWP_NOSIZE))
break;
......@@ -2759,7 +2785,7 @@ gdk_event_translate (MSG *msg,
/* Once we've entered the moving or sizing modal loop, we won't
* return to the main loop until we're done sizing or moving.
*/
if (_sizemove_in_progress &&
if (_modal_operation_in_progress &&
GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
!GDK_WINDOW_DESTROYED (window))
{
......@@ -2768,13 +2794,13 @@ gdk_event_translate (MSG *msg,
GDK_NOTE (EVENTS, g_print (" do magic"));
if (((GdkWindowObject *) window)->resize_count > 1)
((GdkWindowObject *) window)->resize_count -= 1;
handle_configure_event (msg, window);
g_main_context_iteration (NULL, FALSE);
#if 0
/* Dispatch main loop - to realize resizes... */
handle_stuff_while_moving_or_resizing ();
modal_timer_proc (msg->hwnd, msg->message, 0, msg->time);
#endif
/* Claim as handled, so that WM_SIZE and WM_MOVE are avoided */
return_val = TRUE;
*ret_valp = 1;
......@@ -3352,6 +3378,14 @@ 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 ();
......
......@@ -49,11 +49,13 @@ UINT _gdk_input_codepage;
GdkAtom _gdk_selection;
GdkAtom _wm_transient_for;
GdkAtom _targets;
GdkAtom _delete;
GdkAtom _save_targets;
GdkAtom _utf8_string;
GdkAtom _text;
GdkAtom _compound_text;
GdkAtom _text_uri_list;
GdkAtom _text_html;
GdkAtom _image_png;
GdkAtom _image_jpeg;
GdkAtom _image_bmp;
......@@ -63,10 +65,20 @@ GdkAtom _local_dnd;
GdkAtom _gdk_win32_dropfiles;
GdkAtom _gdk_ole2_dnd;
UINT _cf_png;
UINT _cf_jfif;
UINT _cf_gif;
UINT _cf_url;
UINT _cf_html_format;
UINT _cf_text_html;
GdkWin32DndState _dnd_target_state = GDK_WIN32_DND_NONE;
GdkWin32DndState _dnd_source_state = GDK_WIN32_DND_NONE;
gint _gdk_input_ignore_wintab = FALSE;
gint _gdk_max_colors = 0;
gboolean _sizemove_in_progress = FALSE;
gboolean _modal_operation_in_progress = FALSE;
gboolean _ignore_destroy_clipboard = FALSE;
HGLOBAL _delayed_rendering_data = NULL;
......
......@@ -898,7 +898,7 @@ _gdk_input_other_event (GdkEvent *event,
/* Don't produce any button or motion events while a window is being
* moved or resized, see bug #151090.
*/
if (_sizemove_in_progress)
if (_modal_operation_in_progress)
{
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
return FALSE;
......
......@@ -100,22 +100,37 @@ _gdk_windowing_init (void)
CoInitialize (NULL);
_gdk_selection = gdk_atom_intern ("GDK_SELECTION", FALSE);
_wm_transient_for = gdk_atom_intern ("WM_TRANSIENT_FOR", FALSE);
_targets = gdk_atom_intern ("TARGETS", FALSE);
_save_targets = gdk_atom_intern ("SAVE_TARGETS", FALSE);
_utf8_string = gdk_atom_intern ("UTF8_STRING", FALSE);
_text = gdk_atom_intern ("TEXT", FALSE);
_compound_text = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
_text_uri_list = gdk_atom_intern ("text/uri-list", FALSE);
_image_png = gdk_atom_intern ("image/png", FALSE);
_image_jpeg = gdk_atom_intern ("image/jpeg", FALSE);
_image_bmp = gdk_atom_intern ("image/bmp", FALSE);
_image_gif = gdk_atom_intern ("image/gif", FALSE);
_local_dnd = gdk_atom_intern ("LocalDndSelection", FALSE);
_gdk_win32_dropfiles = gdk_atom_intern ("DROPFILES_DND", FALSE);
_gdk_ole2_dnd = gdk_atom_intern ("OLE2_DND", FALSE);
_gdk_selection = gdk_atom_intern_static_string ("GDK_SELECTION");
_wm_transient_for = gdk_atom_intern_static_string ("WM_TRANSIENT_FOR");
_targets = gdk_atom_intern_static_string ("TARGETS");
_delete = gdk_atom_intern_static_string ("DELETE");
_save_targets = gdk_atom_intern_static_string ("SAVE_TARGETS");
_utf8_string = gdk_atom_intern_static_string ("UTF8_STRING");
_text = gdk_atom_intern_static_string ("TEXT");
_compound_text = gdk_atom_intern_static_string ("COMPOUND_TEXT");
_text_uri_list = gdk_atom_intern_static_string ("text/uri-list");
_text_html = gdk_atom_intern_static_string ("text/html");
_image_png = gdk_atom_intern_static_string ("image/png");
_image_jpeg = gdk_atom_intern_static_string ("image/jpeg");
_image_bmp = gdk_atom_intern_static_string ("image/bmp");
_image_gif = gdk_atom_intern_static_string ("image/gif");
_local_dnd = gdk_atom_intern_static_string ("LocalDndSelection");
_gdk_win32_dropfiles = gdk_atom_intern_static_string ("DROPFILES_DND");
_gdk_ole2_dnd = gdk_atom_intern_static_string ("OLE2_DND");
/* MS Office 2007, at least, offers images in common file formats
* using clipboard format names like "PNG" and "JFIF". So we follow
* the lead and map the GDK target name "image/png" to the clipboard
* format name "PNG" etc.
*/
_cf_png = RegisterClipboardFormat ("PNG");
_cf_jfif = RegisterClipboardFormat ("JFIF");
_cf_gif = RegisterClipboardFormat ("GIF");
_cf_url = RegisterClipboardFormat ("UniformResourceLocatorW");
_cf_html_format = RegisterClipboardFormat ("HTML Format");
_cf_text_html = RegisterClipboardFormat ("text/html");
_gdk_win32_selection_init ();
}
......
......@@ -304,7 +304,7 @@ void _gdk_wchar_text_handle (GdkFont *font,
void _gdk_push_modal_window (GdkWindow *window);
void _gdk_remove_modal_window (GdkWindow *window);
GdkWindow *_gdk_modal_current ();
GdkWindow *_gdk_modal_current (void);
#ifdef G_ENABLE_DEBUG
......@@ -411,11 +411,13 @@ extern guint _scancode_rshift;
extern GdkAtom _gdk_selection;
extern GdkAtom _wm_transient_for;
extern GdkAtom _targets;
extern GdkAtom _delete;
extern GdkAtom _save_targets;
extern GdkAtom _utf8_string;
extern GdkAtom _text;
extern GdkAtom _compound_text;
extern GdkAtom _text_uri_list;
extern GdkAtom _text_html;
extern GdkAtom _image_png;
extern GdkAtom _image_jpeg;
extern GdkAtom _image_bmp;
......@@ -426,14 +428,44 @@ extern GdkAtom _local_dnd;
extern GdkAtom _gdk_win32_dropfiles;
extern GdkAtom _gdk_ole2_dnd;
/* Clipboard formats */
extern UINT _cf_png;
extern UINT _cf_jfif;
extern UINT _cf_gif;
extern UINT _cf_url;
extern UINT _cf_html_format;
extern UINT _cf_text_html;
/* OLE-based DND state */
typedef enum {
GDK_WIN32_DND_NONE,
GDK_WIN32_DND_PENDING,
GDK_WIN32_DND_DROPPED,
GDK_WIN32_DND_FAILED,
GDK_WIN32_DND_DRAGGING,
} GdkWin32DndState;
extern GdkWin32DndState _dnd_target_state;
extern GdkWin32DndState _dnd_source_state;
void _gdk_win32_dnd_do_dragdrop (void);
void _gdk_win32_ole2_dnd_property_change (GdkAtom type,
gint format,
const guchar *data,
gint nelements);
void _gdk_win32_begin_modal_call (void);
void _gdk_win32_end_modal_call (void);
/* Options */
extern gboolean _gdk_input_ignore_wintab;
extern gint _gdk_max_colors;
#define GDK_WIN32_COLORMAP_DATA(cmap) ((GdkColormapPrivateWin32 *) GDK_COLORMAP (cmap)->windowing_data)
/* TRUE while a user-initiated window move or resize operation is in progress */
extern gboolean _sizemove_in_progress;
/* TRUE while a modal sizing, moving, or dnd operation is in progress */
extern gboolean _modal_operation_in_progress;
/* TRUE when we are emptying the clipboard ourselves */
extern gboolean _ignore_destroy_clipboard;
......
......@@ -258,6 +258,11 @@ gdk_property_change (GdkWindow *window,
_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");
}
......
......@@ -55,11 +55,6 @@ static GdkSelProp *dropfiles_prop = NULL;
*/
static GHashTable *sel_owner_table = NULL;
/* Well-known registered clipboard image formats */
static UINT cf_png;
static UINT cf_jfif;
static UINT cf_gif;
/* GdkAtoms for well-known image formats */
static GdkAtom *known_pixbuf_formats;
static int n_known_pixbuf_formats;
......@@ -79,15 +74,6 @@ _gdk_win32_selection_init (void)
sel_owner_table = g_hash_table_new (NULL, NULL);
_format_atom_table = g_hash_table_new (NULL, NULL);
/* MS Office 2007, at least, offers images in common file formats
* using clipboard format names like "PNG" and "JFIF". So we follow
* the lead and map the GDK target name "image/png" to the clipboard
* format name "PNG" etc.
*/
cf_png = RegisterClipboardFormat ("PNG");
cf_jfif = RegisterClipboardFormat ("JFIF");
cf_gif = RegisterClipboardFormat ("GIF");
pixbuf_formats = gdk_pixbuf_get_formats ();
n_known_pixbuf_formats = 0;
......@@ -123,7 +109,7 @@ _gdk_win32_selection_init (void)
text_plain_charset_CP1252 = gdk_atom_intern ("text/plain;charset=CP1252", FALSE);
g_hash_table_replace (_format_atom_table,
GINT_TO_POINTER (cf_png),
GINT_TO_POINTER (_cf_png),
_image_png);
g_hash_table_replace (_format_atom_table,
......@@ -442,7 +428,7 @@ gdk_selection_convert (GdkWindow *requestor,
for (fmt = 0; 0 != (fmt = EnumClipboardFormats (fmt)); )
{
if (fmt == cf_png)
if (fmt == _cf_png)
{
targets[ntargets++] = _image_png;
has_png = TRUE;
......@@ -460,7 +446,7 @@ gdk_selection_convert (GdkWindow *requestor,
targets[ntargets++] = _utf8_string;
has_text = TRUE;
}
else if (fmt == cf_png)
else if (fmt == _cf_png)
{
/* Already handled above */
}
......@@ -475,13 +461,13 @@ gdk_selection_convert (GdkWindow *requestor,
targets[ntargets++] = _image_bmp;
has_bmp = TRUE;
}
else if (fmt == cf_jfif)
else if (fmt == _cf_jfif)
{
/* Ditto for JPEG */
if (!has_png)
targets[ntargets++] = _image_jpeg;
}
else if (fmt == cf_gif)
else if (fmt == _cf_gif)
{
/* Ditto for GIF.
*/
......@@ -1215,7 +1201,7 @@ gdk_win32_selection_add_targets (GdkWindow *owner,
if (!has_image)
{
GDK_NOTE (DND, g_print ("... SetClipboardData(PNG,NULL)\n"));
SetClipboardData (cf_png, NULL);
SetClipboardData (_cf_png, NULL);
GDK_NOTE (DND, g_print ("... SetClipboardData(CF_DIB,NULL)\n"));
SetClipboardData (CF_DIB, NULL);
......
......@@ -1835,7 +1835,7 @@ _gdk_remove_modal_window (GdkWindow *window)
}
GdkWindow *
_gdk_modal_current ()
_gdk_modal_current (void)
{
if (modal_window_stack != NULL)
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment