GDK/Win32: Drop Clipdrop/DND global variables

Tuck the GdkWin32Clipdrop that we create in our GdkWin32Display, and
tuck the other associated global variables into GdkWin32ClipDrop and
GdkWin32Drag, as appropriate.

Also, since we are already registering "GDK_WORKER_THREAD_WAKEUP" as our
custom message to look for in our DND/clipboard ops, only register it
once, not twice, as it's not really necessary to do so since
RegisterWindowMessage() returns the same value for the same identifier
that is being used.,
This commit is contained in:
Chun-wei Fan
2024-08-26 20:29:58 +08:00
parent 1f52048e77
commit 0d4f827de8
14 changed files with 372 additions and 290 deletions

View File

@@ -19,6 +19,7 @@
#include "gdkclipboardprivate.h"
#include "gdkclipboard-win32.h"
#include "gdkdisplay-win32.h"
#include "gdkdebugprivate.h"
#include <glib/gi18n-lib.h>
@@ -62,7 +63,7 @@ gdk_win32_clipboard_request_contentformats (GdkWin32Clipboard *cb)
UINT w32_formats_allocated;
gsize i;
GArray *formatpairs;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32Clipdrop *clipdrop = gdk_win32_clipboard_get_clipdrop (GDK_CLIPBOARD (cb));
DWORD error_code;
SetLastError (0);
@@ -94,7 +95,7 @@ gdk_win32_clipboard_request_contentformats (GdkWin32Clipboard *cb)
MIN (w32_formats_len, w32_formats_allocated));
for (i = 0; i < MIN (w32_formats_len, w32_formats_allocated); i++)
_gdk_win32_add_w32format_to_pairs (w32_formats[i], formatpairs, NULL);
gdk_win32_clipdrop_add_win32_format_to_pairs (clipdrop, w32_formats[i], formatpairs, NULL);
g_free (w32_formats);
@@ -164,7 +165,7 @@ gdk_win32_clipboard_claim (GdkClipboard *clipboard,
GdkContentProvider *content)
{
if (local)
_gdk_win32_advertise_clipboard_contentformats (NULL, content ? formats : NULL);
_gdk_win32_advertise_clipboard_contentformats (clipboard, NULL, content ? formats : NULL);
return GDK_CLIPBOARD_CLASS (gdk_win32_clipboard_parent_class)->claim (clipboard, formats, local, content);
}
@@ -232,7 +233,7 @@ gdk_win32_clipboard_read_async (GdkClipboard *clipboard,
g_task_set_priority (task, io_priority);
g_task_set_source_tag (task, gdk_win32_clipboard_read_async);
_gdk_win32_retrieve_clipboard_contentformats (task, contentformats);
_gdk_win32_retrieve_clipboard_contentformats (clipboard, task, contentformats);
return;
}
@@ -296,3 +297,8 @@ gdk_win32_clipboard_new (GdkDisplay *display)
return GDK_CLIPBOARD (cb);
}
GdkWin32Clipdrop *
gdk_win32_clipboard_get_clipdrop (GdkClipboard *cb)
{
return gdk_win32_display_get_clipdrop (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)));
}

View File

@@ -18,6 +18,7 @@
#pragma once
#include "gdk/gdkclipboard.h"
#include "gdkprivate-win32.h"
G_BEGIN_DECLS
@@ -33,5 +34,7 @@ GdkClipboard * gdk_win32_clipboard_new (GdkDisplay *dis
void gdk_win32_clipboard_claim_remote (GdkWin32Clipboard *cb);
GdkWin32Clipdrop * gdk_win32_clipboard_get_clipdrop (GdkClipboard *cb);
G_END_DECLS

View File

@@ -279,6 +279,7 @@ Otherwise it's similar to how the clipboard works. Only the DnD server
#include "gdkclipboardprivate.h"
#include "gdkclipboard-win32.h"
#include "gdkclipdrop-win32.h"
#include "gdkdisplay-win32.h"
#include "gdkhdataoutputstream-win32.h"
#include "gdkwin32dnd.h"
#include "gdkwin32dnd-private.h"
@@ -300,15 +301,6 @@ Otherwise it's similar to how the clipboard works. Only the DnD server
*/
#define CLIPBOARD_RENDER_TIMEOUT (G_USEC_PER_SEC * 29)
gboolean _gdk_win32_transmute_windows_data (UINT from_w32format,
const char *to_contentformat,
HANDLE hdata,
guchar **set_data,
gsize *set_data_length);
/* Just to avoid calling RegisterWindowMessage() every time */
static UINT thread_wakeup_message;
typedef enum _GdkWin32ClipboardThreadQueueItemType GdkWin32ClipboardThreadQueueItemType;
enum _GdkWin32ClipboardThreadQueueItemType
@@ -437,11 +429,6 @@ struct _GdkWin32ClipboardThread
gboolean ignore_destroy_clipboard;
};
/* The code is much more secure if we don't rely on the OS to keep
* this around for us.
*/
static GdkWin32ClipboardThread *clipboard_thread_data = NULL;
typedef struct _GdkWin32ClipboardThreadResponse GdkWin32ClipboardThreadResponse;
struct _GdkWin32ClipboardThreadResponse
@@ -485,7 +472,7 @@ _gdk_win32_format_uses_hdata (UINT w32format)
static gboolean
clipboard_hwnd_created (gpointer user_data)
{
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_display_get_default ());
clipdrop->clipboard_hwnd = (HWND) user_data;
@@ -518,7 +505,7 @@ clipboard_render_hdata_ready (GObject *clipboard,
{
GError *error = NULL;
GdkWin32ClipboardRenderAndStream render_and_stream = *(GdkWin32ClipboardRenderAndStream *) user_data;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32Clipdrop *clipdrop = gdk_win32_clipboard_get_clipdrop (GDK_CLIPBOARD (clipboard));
g_free (user_data);
@@ -553,11 +540,11 @@ static gboolean
clipboard_render (gpointer user_data)
{
GdkWin32ClipboardThreadRender *render = (GdkWin32ClipboardThreadRender *) user_data;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkDisplay *display = gdk_display_get_default ();
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (display);
GdkClipboard *clipboard = gdk_display_get_clipboard (display);
GError *error = NULL;
GOutputStream *stream = gdk_win32_hdata_output_stream_new (&render->pair, &error);
GOutputStream *stream = gdk_win32_hdata_output_stream_new (clipdrop, &render->pair, &error);
GdkWin32ClipboardRenderAndStream *render_and_stream;
if (stream == NULL)
@@ -684,28 +671,32 @@ send_input_stream (GdkWin32ClipboardThreadQueueItemType request_type,
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_thread_response, response, NULL);
}
#define CLIPDROP_CB_THREAD_MEMBER(c,m) ((GdkWin32ClipboardThread *)(c->clipboard_thread_items))->m
static DWORD
try_open_clipboard (HWND hwnd)
try_open_clipboard (GdkWin32Clipdrop *clipdrop,
HWND hwnd)
{
if (clipboard_thread_data->clipboard_opened_for == hwnd)
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) == hwnd)
return NO_ERROR;
if (clipboard_thread_data->clipboard_opened_for != INVALID_HANDLE_VALUE)
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) != INVALID_HANDLE_VALUE)
{
API_CALL (CloseClipboard, ());
clipboard_thread_data->clipboard_opened_for = INVALID_HANDLE_VALUE;
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) = INVALID_HANDLE_VALUE;
}
if (!OpenClipboard (hwnd))
return GetLastError ();
clipboard_thread_data->clipboard_opened_for = hwnd;
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) = hwnd;
return NO_ERROR;
}
static gboolean
process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
process_advertise (GdkWin32Clipdrop *clipdrop,
GdkWin32ClipboardThreadAdvertise *adv)
{
DWORD error_code;
int i;
@@ -720,7 +711,7 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
return FALSE;
}
if (clipboard_thread_data->owner_change_time > adv->parent.start_time)
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) > adv->parent.start_time)
{
GDK_NOTE (CLIPBOARD, g_printerr ("An advertise task timed out due to ownership change\n"));
send_response (adv->parent.item_type,
@@ -730,7 +721,7 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
return FALSE;
}
error_code = try_open_clipboard (adv->unset ? NULL : clipboard_thread_data->clipboard_hwnd);
error_code = try_open_clipboard (clipdrop, adv->unset ? NULL : CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
if (error_code == ERROR_ACCESS_DENIED)
return TRUE;
@@ -744,10 +735,10 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
return FALSE;
}
clipboard_thread_data->ignore_destroy_clipboard = TRUE;
CLIPDROP_CB_THREAD_MEMBER (clipdrop, ignore_destroy_clipboard) = TRUE;
if (!EmptyClipboard ())
{
clipboard_thread_data->ignore_destroy_clipboard = FALSE;
CLIPDROP_CB_THREAD_MEMBER (clipdrop, ignore_destroy_clipboard) = FALSE;
error_code = GetLastError ();
send_response (adv->parent.item_type,
adv->parent.opaque_task,
@@ -756,7 +747,7 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
return FALSE;
}
clipboard_thread_data->ignore_destroy_clipboard = FALSE;
CLIPDROP_CB_THREAD_MEMBER (clipdrop, ignore_destroy_clipboard) = FALSE;
if (adv->unset)
return FALSE;
@@ -768,10 +759,10 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
SetClipboardData (pair->w32format, NULL);
}
if (clipboard_thread_data->cached_advertisement)
g_array_free (clipboard_thread_data->cached_advertisement, TRUE);
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement))
g_array_free (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), TRUE);
clipboard_thread_data->cached_advertisement = adv->pairs;
CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement) = adv->pairs;
/* To enure that we don't free it later on */
adv->pairs = NULL;
@@ -784,7 +775,8 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
}
static gboolean
process_store (GdkWin32ClipboardThreadStore *store)
process_store (GdkWin32Clipdrop *clipdrop,
GdkWin32ClipboardThreadStore *store)
{
DWORD error_code;
int i;
@@ -799,7 +791,7 @@ process_store (GdkWin32ClipboardThreadStore *store)
return FALSE;
}
if (clipboard_thread_data->owner_change_time > store->parent.start_time)
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) > store->parent.start_time)
{
GDK_NOTE (CLIPBOARD, g_printerr ("A store task timed out due to ownership change\n"));
send_response (store->parent.item_type,
@@ -809,7 +801,7 @@ process_store (GdkWin32ClipboardThreadStore *store)
return FALSE;
}
error_code = try_open_clipboard (clipboard_thread_data->clipboard_hwnd);
error_code = try_open_clipboard (clipdrop, CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
if (error_code == ERROR_ACCESS_DENIED)
return TRUE;
@@ -831,7 +823,7 @@ process_store (GdkWin32ClipboardThreadStore *store)
* that we already own, otherwise we're just killing stuff that some other
* process put in there, which is not nice.
*/
if (GetClipboardOwner () != clipboard_thread_data->clipboard_hwnd)
if (GetClipboardOwner () != CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd))
{
send_response (store->parent.item_type,
store->parent.opaque_task,
@@ -910,7 +902,8 @@ grab_data_from_hdata (GdkWin32ClipboardThreadRetrieve *retr,
}
static gboolean
process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
process_retrieve (GdkWin32Clipdrop *clipdrop,
GdkWin32ClipboardThreadRetrieve *retr)
{
DWORD error_code;
int i;
@@ -931,7 +924,7 @@ process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
return FALSE;
}
if (clipboard_thread_data->owner_change_time > retr->parent.start_time)
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) > retr->parent.start_time)
{
GDK_NOTE (CLIPBOARD, g_printerr ("A retrieve task timed out due to ownership change\n"));
send_response (retr->parent.item_type,
@@ -951,10 +944,10 @@ process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
return FALSE;
}
if (clipboard_thread_data->clipboard_opened_for == INVALID_HANDLE_VALUE)
error_code = try_open_clipboard (clipboard_thread_data->clipboard_hwnd);
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) == INVALID_HANDLE_VALUE)
error_code = try_open_clipboard (clipdrop, CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
else
error_code = try_open_clipboard (clipboard_thread_data->clipboard_opened_for);
error_code = try_open_clipboard (clipdrop, CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for));
if (error_code == ERROR_ACCESS_DENIED)
return TRUE;
@@ -1021,7 +1014,7 @@ process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
}
else
{
_gdk_win32_transmute_windows_data (pair->w32format, pair->contentformat, hdata, &data, &data_len);
gdk_win32_clipdrop_transmute_windows_data (clipdrop, pair->w32format, pair->contentformat, hdata, &data, &data_len);
if (data == NULL)
return FALSE;
@@ -1040,14 +1033,14 @@ process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
}
static gboolean
process_clipboard_queue ()
process_clipboard_queue (GdkWin32Clipdrop *clipdrop)
{
GdkWin32ClipboardThreadQueueItem *placeholder;
GList *p;
gboolean try_again;
GList *p_next;
for (p = clipboard_thread_data->dequeued_items, p_next = NULL; p; p = p_next)
for (p = CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items), p_next = NULL; p; p = p_next)
{
placeholder = (GdkWin32ClipboardThreadQueueItem *) p->data;
p_next = p->next;
@@ -1055,35 +1048,35 @@ process_clipboard_queue ()
switch (placeholder->item_type)
{
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_ADVERTISE:
try_again = process_advertise ((GdkWin32ClipboardThreadAdvertise *) placeholder);
try_again = process_advertise (clipdrop, (GdkWin32ClipboardThreadAdvertise *) placeholder);
break;
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_RETRIEVE:
try_again = process_retrieve ((GdkWin32ClipboardThreadRetrieve *) placeholder);
try_again = process_retrieve (clipdrop, (GdkWin32ClipboardThreadRetrieve *) placeholder);
break;
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_STORE:
try_again = process_store ((GdkWin32ClipboardThreadStore *) placeholder);
try_again = process_store (clipdrop, (GdkWin32ClipboardThreadStore *) placeholder);
break;
}
if (try_again)
return FALSE;
clipboard_thread_data->dequeued_items = g_list_delete_link (clipboard_thread_data->dequeued_items, p);
CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items) = g_list_delete_link (CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items), p);
free_queue_item (placeholder);
}
while ((placeholder = g_async_queue_try_pop (clipboard_thread_data->input_queue)) != NULL)
while ((placeholder = g_async_queue_try_pop (CLIPDROP_CB_THREAD_MEMBER (clipdrop, input_queue))) != NULL)
{
switch (placeholder->item_type)
{
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_ADVERTISE:
try_again = process_advertise ((GdkWin32ClipboardThreadAdvertise *) placeholder);
try_again = process_advertise (clipdrop, (GdkWin32ClipboardThreadAdvertise *) placeholder);
break;
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_RETRIEVE:
try_again = process_retrieve ((GdkWin32ClipboardThreadRetrieve *) placeholder);
try_again = process_retrieve (clipdrop, (GdkWin32ClipboardThreadRetrieve *) placeholder);
break;
case GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_STORE:
try_again = process_store ((GdkWin32ClipboardThreadStore *) placeholder);
try_again = process_store (clipdrop, (GdkWin32ClipboardThreadStore *) placeholder);
break;
}
@@ -1093,7 +1086,7 @@ process_clipboard_queue ()
continue;
}
clipboard_thread_data->dequeued_items = g_list_append (clipboard_thread_data->dequeued_items, placeholder);
CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items) = g_list_append (CLIPDROP_CB_THREAD_MEMBER (clipdrop, dequeued_items), placeholder);
return FALSE;
}
@@ -1124,23 +1117,37 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
WPARAM wparam,
LPARAM lparam)
{
if (message == thread_wakeup_message ||
GdkWin32Clipdrop *clipdrop = NULL;
if (message == WM_NCCREATE)
{
CREATESTRUCT *cs = (CREATESTRUCT *)lparam;
clipdrop = (GdkWin32Clipdrop *) cs->lpCreateParams;
SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) clipdrop);
return TRUE;
}
else if (message == WM_CREATE)
return DefWindowProcW (hwnd, message, wparam, lparam);
else
clipdrop = (GdkWin32Clipdrop *) GetWindowLongPtr (hwnd, GWLP_USERDATA);
if (message == clipdrop->thread_wakeup_message ||
message == WM_TIMER)
{
gboolean queue_is_empty = FALSE;
if (clipboard_thread_data == NULL)
if (clipdrop->clipboard_thread_items == NULL)
{
g_warning ("Clipboard thread got an actionable message with no thread data");
return DefWindowProcW (hwnd, message, wparam, lparam);
}
queue_is_empty = process_clipboard_queue ();
queue_is_empty = process_clipboard_queue (clipdrop);
if (queue_is_empty && clipboard_thread_data->wakeup_timer)
if (queue_is_empty && CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer))
{
API_CALL (KillTimer, (clipboard_thread_data->clipboard_hwnd, clipboard_thread_data->wakeup_timer));
clipboard_thread_data->wakeup_timer = 0;
API_CALL (KillTimer, (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd), CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer)));
CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer) = 0;
}
/* Close the clipboard after each queue run, if it's open.
@@ -1149,21 +1156,21 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
* queue_is_empty == FALSE implies that the clipboard
* is closed already, but it's better to be sure.
*/
if (clipboard_thread_data->clipboard_opened_for != INVALID_HANDLE_VALUE)
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) != INVALID_HANDLE_VALUE)
{
API_CALL (CloseClipboard, ());
clipboard_thread_data->clipboard_opened_for = INVALID_HANDLE_VALUE;
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) = INVALID_HANDLE_VALUE;
}
if (queue_is_empty ||
clipboard_thread_data->wakeup_timer != 0)
CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer) != 0)
return 0;
if (SetTimer (clipboard_thread_data->clipboard_hwnd, 1, 1000, NULL))
clipboard_thread_data->wakeup_timer = 1;
if (SetTimer (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd), 1, 1000, NULL))
CLIPDROP_CB_THREAD_MEMBER (clipdrop, wakeup_timer) = 1;
else
g_critical ("Failed to set a timer for the clipboard HWND 0x%p: %lu",
clipboard_thread_data->clipboard_hwnd,
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd),
GetLastError ());
}
@@ -1171,7 +1178,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
{
case WM_DESTROY: /* unregister the clipboard listener */
{
if (clipboard_thread_data == NULL)
if (clipdrop->clipboard_thread_items == NULL)
{
g_warning ("Clipboard thread got an actionable message with no thread data");
return DefWindowProcW (hwnd, message, wparam, lparam);
@@ -1192,7 +1199,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
/*
GdkEvent *event;
*/
if (clipboard_thread_data == NULL)
if (clipdrop->clipboard_thread_items == NULL)
{
g_warning ("Clipboard thread got an actionable message with no thread data");
return DefWindowProcW (hwnd, message, wparam, lparam);
@@ -1210,7 +1217,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
if (GDK_DEBUG_CHECK (DND))
{
/* FIXME: grab and print clipboard formats without opening the clipboard
if (clipboard_thread_data->clipboard_opened_for != INVALID_HANDLE_VALUE ||
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) != INVALID_HANDLE_VALUE ||
OpenClipboard (hwnd))
{
UINT nFormat = 0;
@@ -1218,7 +1225,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
while ((nFormat = EnumClipboardFormats (nFormat)) != 0)
g_print ("%s ", _gdk_win32_cf_to_string (nFormat));
if (clipboard_thread_data->clipboard_opened_for == INVALID_HANDLE_VALUE)
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_opened_for) == INVALID_HANDLE_VALUE)
CloseClipboard ();
}
else
@@ -1230,22 +1237,22 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
GDK_NOTE (DND, g_print (" \n"));
if (clipboard_thread_data->stored_hwnd_owner != hwnd_owner)
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, stored_hwnd_owner) != hwnd_owner)
{
clipboard_thread_data->stored_hwnd_owner = hwnd_owner;
clipboard_thread_data->owner_change_time = g_get_monotonic_time ();
CLIPDROP_CB_THREAD_MEMBER (clipdrop, stored_hwnd_owner) = hwnd_owner;
CLIPDROP_CB_THREAD_MEMBER (clipdrop, owner_change_time) = g_get_monotonic_time ();
if (hwnd_owner != clipboard_thread_data->clipboard_hwnd)
if (hwnd_owner != CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd))
{
if (clipboard_thread_data->cached_advertisement)
g_array_free (clipboard_thread_data->cached_advertisement, TRUE);
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement))
g_array_free (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), TRUE);
clipboard_thread_data->cached_advertisement = NULL;
CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement) = NULL;
}
API_CALL (PostMessage, (clipboard_thread_data->clipboard_hwnd, thread_wakeup_message, 0, 0));
API_CALL (PostMessage, (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd), clipdrop->thread_wakeup_message, 0, 0));
if (hwnd_owner != clipboard_thread_data->clipboard_hwnd)
if (hwnd_owner != CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd))
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_owner_changed, NULL, NULL);
}
@@ -1256,13 +1263,13 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
}
case WM_RENDERALLFORMATS:
{
if (clipboard_thread_data == NULL)
if (clipdrop->clipboard_thread_items == NULL)
{
g_warning ("Clipboard thread got an actionable message with no thread data");
return DefWindowProcW (hwnd, message, wparam, lparam);
}
if (clipboard_thread_data->cached_advertisement == NULL)
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement == NULL))
return DefWindowProcW (hwnd, message, wparam, lparam);
if (API_CALL (OpenClipboard, (hwnd)))
@@ -1271,10 +1278,10 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
GdkWin32ContentFormatPair *pair;
for (pair = NULL, i = 0;
i < clipboard_thread_data->cached_advertisement->len;
i < CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement)->len;
i++)
{
pair = &g_array_index (clipboard_thread_data->cached_advertisement, GdkWin32ContentFormatPair, i);
pair = &g_array_index (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), GdkWin32ContentFormatPair, i);
if (pair->w32format != 0)
SendMessage (hwnd, WM_RENDERFORMAT, pair->w32format, 0);
@@ -1295,20 +1302,20 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
GDK_NOTE (EVENTS, g_print (" %s", _gdk_win32_cf_to_string (wparam)));
if (clipboard_thread_data == NULL)
if (clipdrop->clipboard_thread_items == NULL)
{
g_warning ("Clipboard thread got an actionable message with no thread data");
return DefWindowProcW (hwnd, message, wparam, lparam);
}
if (clipboard_thread_data->cached_advertisement == NULL)
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement) == NULL)
return DefWindowProcW (hwnd, message, wparam, lparam);
for (pair = NULL, i = 0;
i < clipboard_thread_data->cached_advertisement->len;
i < CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement)->len;
i++)
{
pair = &g_array_index (clipboard_thread_data->cached_advertisement, GdkWin32ContentFormatPair, i);
pair = &g_array_index (CLIPDROP_CB_THREAD_MEMBER (clipdrop, cached_advertisement), GdkWin32ContentFormatPair, i);
if (pair->w32format == wparam)
break;
@@ -1323,13 +1330,13 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
}
/* Clear the queue */
while ((render = g_async_queue_try_pop (clipboard_thread_data->render_queue)) != NULL)
while ((render = g_async_queue_try_pop (CLIPDROP_CB_THREAD_MEMBER (clipdrop, render_queue))) != NULL)
discard_render (render, FALSE);
render = g_new0 (GdkWin32ClipboardThreadRender, 1);
render->pair = *pair;
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_render, render, NULL);
returned_render = g_async_queue_timeout_pop (clipboard_thread_data->render_queue, CLIPBOARD_RENDER_TIMEOUT);
returned_render = g_async_queue_timeout_pop (CLIPDROP_CB_THREAD_MEMBER (clipdrop, render_queue), CLIPBOARD_RENDER_TIMEOUT);
/* We should get back the same pointer, ignore everything else. */
while (returned_render != NULL && returned_render != render)
@@ -1343,7 +1350,7 @@ inner_clipboard_hwnd_procedure (HWND hwnd,
* If you get many "Clipboard rendering timed out" warnings,
* this is probably why.
*/
returned_render = g_async_queue_try_pop (clipboard_thread_data->render_queue);
returned_render = g_async_queue_try_pop (CLIPDROP_CB_THREAD_MEMBER (clipdrop, render_queue));
}
/* Just in case */
@@ -1403,7 +1410,7 @@ _clipboard_hwnd_procedure (HWND hwnd,
* Creates a hidden HWND and add a clipboard listener
*/
static gboolean
register_clipboard_notification ()
register_clipboard_notification (GdkWin32Clipdrop *clipdrop)
{
WNDCLASS wclass = { 0, };
ATOM klass;
@@ -1417,23 +1424,24 @@ register_clipboard_notification ()
if (!klass)
return FALSE;
clipboard_thread_data->clipboard_hwnd = CreateWindow (MAKEINTRESOURCE (klass),
NULL, WS_POPUP,
0, 0, 0, 0, NULL, NULL,
this_module (), NULL);
CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd) =
CreateWindow (MAKEINTRESOURCE (klass),
NULL, WS_POPUP,
0, 0, 0, 0, NULL, NULL,
this_module (), clipdrop);
if (clipboard_thread_data->clipboard_hwnd == NULL)
if (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd) == NULL)
goto failed;
SetLastError (0);
if (AddClipboardFormatListener (clipboard_thread_data->clipboard_hwnd) == FALSE)
if (AddClipboardFormatListener (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd)) == FALSE)
{
DestroyWindow (clipboard_thread_data->clipboard_hwnd);
DestroyWindow (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
goto failed;
}
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_hwnd_created, (gpointer) clipboard_thread_data->clipboard_hwnd, NULL);
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_hwnd_created, (gpointer) CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd), NULL);
return TRUE;
@@ -1447,20 +1455,21 @@ static gpointer
_gdk_win32_clipboard_thread_main (gpointer data)
{
MSG msg;
GAsyncQueue *queue = (GAsyncQueue *) data;
clipdrop_thread_items *items = (clipdrop_thread_items*) data;
GAsyncQueue *queue = items->queue;
GAsyncQueue *render_queue = (GAsyncQueue *) g_async_queue_pop (queue);
g_assert (clipboard_thread_data == NULL);
g_assert (items->clipdrop->clipboard_thread_items == NULL);
clipboard_thread_data = g_new0 (GdkWin32ClipboardThread, 1);
clipboard_thread_data->input_queue = queue;
clipboard_thread_data->render_queue = render_queue;
clipboard_thread_data->clipboard_opened_for = INVALID_HANDLE_VALUE;
items->clipdrop->clipboard_thread_items = g_new0 (GdkWin32ClipboardThread, 1);
CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, input_queue) = queue;
CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, render_queue) = render_queue;
CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, clipboard_opened_for) = INVALID_HANDLE_VALUE;
if (!register_clipboard_notification ())
if (!register_clipboard_notification (items->clipdrop))
{
g_async_queue_unref (queue);
g_clear_pointer (&clipboard_thread_data, g_free);
g_clear_pointer (&items->clipdrop->clipboard_thread_items, g_free);
return NULL;
}
@@ -1472,10 +1481,10 @@ _gdk_win32_clipboard_thread_main (gpointer data)
}
/* Just in case, as this should only happen when we shut down */
DestroyWindow (clipboard_thread_data->clipboard_hwnd);
CloseHandle (clipboard_thread_data->clipboard_hwnd);
DestroyWindow (CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, clipboard_hwnd));
CloseHandle (CLIPDROP_CB_THREAD_MEMBER (items->clipdrop, clipboard_hwnd));
g_async_queue_unref (queue);
g_clear_pointer (&clipboard_thread_data, g_free);
g_clear_pointer (&items->clipdrop->clipboard_thread_items, g_free);
return NULL;
}
@@ -1483,14 +1492,22 @@ _gdk_win32_clipboard_thread_main (gpointer data)
G_DEFINE_TYPE (GdkWin32Clipdrop, gdk_win32_clipdrop, G_TYPE_OBJECT)
static void
gdk_win32_clipdrop_class_init (GdkWin32ClipdropClass *klass)
gdk_win32_clipdrop_finalize (GObject *object)
{
GdkWin32Clipdrop *clipdrop = GDK_WIN32_CLIPDROP (object);
DestroyWindow (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
CloseHandle (CLIPDROP_CB_THREAD_MEMBER (clipdrop, clipboard_hwnd));
g_clear_pointer (&clipdrop->dnd_thread_items, g_free);
g_clear_pointer (&clipdrop->clipboard_thread_items, g_free);
}
void
_gdk_win32_clipdrop_init (void)
static void
gdk_win32_clipdrop_class_init (GdkWin32ClipdropClass *klass)
{
_win32_clipdrop = GDK_WIN32_CLIPDROP (g_object_new (GDK_TYPE_WIN32_CLIPDROP, NULL));
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gdk_win32_clipdrop_finalize;
}
static void
@@ -1504,8 +1521,9 @@ gdk_win32_clipdrop_init (GdkWin32Clipdrop *win32_clipdrop)
GArray *comp;
GdkWin32ContentFormatPair fmt;
HMODULE user32;
clipdrop_thread_items cb_items, dnd_items;
thread_wakeup_message = RegisterWindowMessage (L"GDK_WORKER_THREAD_WEAKEUP");
win32_clipdrop->thread_wakeup_message = RegisterWindowMessage (L"GDK_WORKER_THREAD_WEAKEUP");
user32 = LoadLibrary (L"user32.dll");
win32_clipdrop->GetUpdatedClipboardFormats = (GetUpdatedClipboardFormatsFunc) GetProcAddress (user32, "GetUpdatedClipboardFormats");
@@ -1797,14 +1815,17 @@ gdk_win32_clipdrop_init (GdkWin32Clipdrop *win32_clipdrop)
* pointers and then passing *that* to the thread.
*/
g_async_queue_push (win32_clipdrop->clipboard_open_thread_queue, g_async_queue_ref (win32_clipdrop->clipboard_render_queue));
cb_items.clipdrop = dnd_items.clipdrop = win32_clipdrop;
cb_items.queue = g_async_queue_ref (win32_clipdrop->clipboard_open_thread_queue);
win32_clipdrop->clipboard_open_thread = g_thread_new ("GDK Win32 Clipboard Thread",
_gdk_win32_clipboard_thread_main,
g_async_queue_ref (win32_clipdrop->clipboard_open_thread_queue));
&cb_items);
win32_clipdrop->dnd_queue = g_async_queue_new ();
dnd_items.queue = g_async_queue_ref (win32_clipdrop->dnd_queue);
win32_clipdrop->dnd_thread = g_thread_new ("GDK Win32 DnD Thread",
_gdk_win32_dnd_thread_main,
g_async_queue_ref (win32_clipdrop->dnd_queue));
&dnd_items);
win32_clipdrop->dnd_thread_id = GPOINTER_TO_UINT (g_async_queue_pop (win32_clipdrop->dnd_queue));
}
@@ -1926,11 +1947,11 @@ _gdk_win32_get_clipboard_format_name_as_interned_mimetype (char *w32format_name)
}
static GArray *
get_compatibility_w32formats_for_contentformat (const char *contentformat)
get_compatibility_w32formats_for_contentformat (GdkWin32Clipdrop *clipdrop,
const char *contentformat)
{
GArray *result = NULL;
int i;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
result = g_hash_table_lookup (clipdrop->compatibility_w32formats, contentformat);
@@ -1944,7 +1965,7 @@ get_compatibility_w32formats_for_contentformat (const char *contentformat)
/* Any format known to gdk-pixbuf can be presented as PNG or BMP */
result = g_hash_table_lookup (clipdrop->compatibility_w32formats,
_gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_PNG));
_gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_PNG));
break;
}
@@ -1952,10 +1973,10 @@ get_compatibility_w32formats_for_contentformat (const char *contentformat)
}
static GArray *
_gdk_win32_get_compatibility_contentformats_for_w32format (UINT w32format)
_gdk_win32_get_compatibility_contentformats_for_w32format (GdkWin32Clipdrop *clipdrop,
UINT w32format)
{
GArray *result = NULL;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
result = g_hash_table_lookup (clipdrop->compatibility_contentformats, GINT_TO_POINTER (w32format));
@@ -1982,9 +2003,10 @@ _gdk_win32_get_compatibility_contentformats_for_w32format (UINT w32format)
* (builder already takes care of that for itself).
*/
void
_gdk_win32_add_w32format_to_pairs (UINT w32format,
GArray *pairs,
GdkContentFormatsBuilder *builder)
gdk_win32_clipdrop_add_win32_format_to_pairs (GdkWin32Clipdrop *clipdrop,
UINT w32format,
GArray *pairs,
GdkContentFormatsBuilder *builder)
{
gboolean predef;
char *w32format_name = _gdk_win32_get_clipboard_format_name (w32format, &predef);
@@ -2016,7 +2038,7 @@ _gdk_win32_add_w32format_to_pairs (UINT w32format,
gdk_content_formats_builder_add_mime_type (builder, interned_w32format_name);
}
comp_pairs = _gdk_win32_get_compatibility_contentformats_for_w32format (w32format);
comp_pairs = _gdk_win32_get_compatibility_contentformats_for_w32format (clipdrop, w32format);
if (pairs != NULL && comp_pairs != NULL)
for (i = 0; i < comp_pairs->len; i++)
@@ -2547,11 +2569,12 @@ transmute_image_bmp_to_cf_dib (const guchar *data,
}
gboolean
_gdk_win32_transmute_windows_data (UINT from_w32format,
const char *to_contentformat,
HANDLE hdata,
guchar **set_data,
gsize *set_data_length)
gdk_win32_clipdrop_transmute_windows_data (GdkWin32Clipdrop *clipdrop,
UINT from_w32format,
const char *to_contentformat,
HANDLE hdata,
guchar **set_data,
gsize *set_data_length)
{
const guchar *data;
SIZE_T hdata_length;
@@ -2571,37 +2594,37 @@ _gdk_win32_transmute_windows_data (UINT from_w32format,
length = (gsize) hdata_length;
if ((to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_PNG) &&
from_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_PNG)) ||
(to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_JPEG) &&
from_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_JFIF)) ||
(to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_GIF) &&
from_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_GIF)))
if ((to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_PNG) &&
from_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_PNG)) ||
(to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_JPEG) &&
from_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_JFIF)) ||
(to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_GIF) &&
from_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_GIF)))
{
/* No transmutation needed */
*set_data = g_memdup2 (data, length);
*set_data_length = length;
}
else if (to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
else if (to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
from_w32format == CF_UNICODETEXT)
{
transmute_cf_unicodetext_to_utf8_string (data, length, set_data, set_data_length, NULL);
res = TRUE;
}
else if (to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
else if (to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
from_w32format == CF_TEXT)
{
transmute_cf_text_to_utf8_string (data, length, set_data, set_data_length, NULL);
res = TRUE;
}
else if (to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
else if (to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
(from_w32format == CF_DIB || from_w32format == CF_DIBV5))
{
transmute_cf_dib_to_image_bmp (data, length, set_data, set_data_length, NULL);
res = TRUE;
}
else if (to_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_URI_LIST) &&
from_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST))
else if (to_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_URI_LIST) &&
from_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST))
{
transmute_cf_shell_id_list_to_text_uri_list (data, length, set_data, set_data_length, NULL);
res = TRUE;
@@ -2620,47 +2643,48 @@ out:
}
gboolean
_gdk_win32_transmute_contentformat (const char *from_contentformat,
UINT to_w32format,
const guchar *data,
gsize length,
guchar **set_data,
gsize *set_data_length)
gdk_win32_clipdrop_transmute_contentformat (GdkWin32Clipdrop *clipdrop,
const char *from_contentformat,
UINT to_w32format,
const guchar *data,
gsize length,
guchar **set_data,
gsize *set_data_length)
{
if ((from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_PNG) &&
to_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_PNG)) ||
(from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_JPEG) &&
to_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_JFIF)) ||
(from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_GIF) &&
to_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_GIF)))
if ((from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_PNG) &&
to_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_PNG)) ||
(from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_JPEG) &&
to_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_JFIF)) ||
(from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_GIF) &&
to_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_GIF)))
{
/* No conversion needed */
*set_data = g_memdup2 (data, length);
*set_data_length = length;
}
else if (from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
else if (from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
to_w32format == CF_UNICODETEXT)
{
transmute_utf8_string_to_cf_unicodetext (data, length, set_data, set_data_length, NULL);
}
else if (from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
else if (from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8) &&
to_w32format == CF_TEXT)
{
transmute_utf8_string_to_cf_text (data, length, set_data, set_data_length, NULL);
}
else if (from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
else if (from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
to_w32format == CF_DIB)
{
transmute_image_bmp_to_cf_dib (data, length, set_data, set_data_length, NULL);
}
else if (from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
else if (from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_IMAGE_BMP) &&
to_w32format == CF_DIBV5)
{
transmute_image_bmp_to_cf_dib (data, length, set_data, set_data_length, NULL);
}
/*
else if (from_contentformat == _gdk_win32_clipdrop_atom (GDK_WIN32_ATOM_INDEX_TEXT_URI_LIST) &&
to_w32format == _gdk_win32_clipdrop_cf (GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST))
else if (from_contentformat == _gdk_win32_clipdrop_atom (clipdrop, GDK_WIN32_ATOM_INDEX_TEXT_URI_LIST) &&
to_w32format == _gdk_win32_clipdrop_cf (clipdrop, GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST))
{
transmute_text_uri_list_to_shell_id_list (data, length, set_data, set_data_length, NULL);
}
@@ -2676,8 +2700,9 @@ _gdk_win32_transmute_contentformat (const char *from_contentformat,
}
int
_gdk_win32_add_contentformat_to_pairs (const char *contentformat,
GArray *array)
_gdk_win32_add_contentformat_to_pairs (GdkWin32Clipdrop *clip_drop,
const char *contentformat,
GArray *array)
{
int added_count = 0;
wchar_t *contentformat_w;
@@ -2722,7 +2747,7 @@ _gdk_win32_add_contentformat_to_pairs (const char *contentformat,
g_array_append_val (array, fmt);
added_count += 1;
comp_pairs = get_compatibility_w32formats_for_contentformat (contentformat);
comp_pairs = get_compatibility_w32formats_for_contentformat (clip_drop, contentformat);
for (i = 0; comp_pairs != NULL && i < comp_pairs->len; i++)
{
int j;
@@ -2746,10 +2771,11 @@ _gdk_win32_add_contentformat_to_pairs (const char *contentformat,
}
void
_gdk_win32_advertise_clipboard_contentformats (GTask *task,
_gdk_win32_advertise_clipboard_contentformats (GdkClipboard *cb,
GTask *task,
GdkContentFormats *contentformats)
{
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_clipboard_get_display (cb));
GdkWin32ClipboardThreadAdvertise *adv = g_new0 (GdkWin32ClipboardThreadAdvertise, 1);
const char * const *mime_types;
gsize mime_types_len;
@@ -2774,20 +2800,21 @@ _gdk_win32_advertise_clipboard_contentformats (GTask *task,
mime_types = gdk_content_formats_get_mime_types (contentformats, &mime_types_len);
for (i = 0; i < mime_types_len; i++)
_gdk_win32_add_contentformat_to_pairs (mime_types[i], adv->pairs);
_gdk_win32_add_contentformat_to_pairs (clipdrop, mime_types[i], adv->pairs);
}
g_async_queue_push (clipdrop->clipboard_open_thread_queue, adv);
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, clipdrop->thread_wakeup_message, 0, 0));
return;
}
void
_gdk_win32_retrieve_clipboard_contentformats (GTask *task,
_gdk_win32_retrieve_clipboard_contentformats (GdkClipboard *cb,
GTask *task,
GdkContentFormats *contentformats)
{
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_clipboard_get_display (cb));
GdkWin32ClipboardThreadRetrieve *retr = g_new0 (GdkWin32ClipboardThreadRetrieve, 1);
const char * const *mime_types;
gsize mime_types_len;
@@ -2805,10 +2832,10 @@ _gdk_win32_retrieve_clipboard_contentformats (GTask *task,
mime_types = gdk_content_formats_get_mime_types (contentformats, &mime_types_len);
for (i = 0; i < mime_types_len; i++)
_gdk_win32_add_contentformat_to_pairs (mime_types[i], retr->pairs);
_gdk_win32_add_contentformat_to_pairs (clipdrop, mime_types[i], retr->pairs);
g_async_queue_push (clipdrop->clipboard_open_thread_queue, retr);
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, clipdrop->thread_wakeup_message, 0, 0));
return;
}
@@ -2878,7 +2905,7 @@ clipboard_store_hdata_ready (GObject *clipboard,
if (!no_other_streams)
return;
clipdrop = _gdk_win32_clipdrop_get ();
clipdrop = gdk_win32_clipboard_get_clipdrop (GDK_CLIPBOARD (clipboard));
store = g_new0 (GdkWin32ClipboardThreadStore, 1);
@@ -2889,7 +2916,7 @@ clipboard_store_hdata_ready (GObject *clipboard,
store->elements = prep->elements;
g_async_queue_push (clipdrop->clipboard_open_thread_queue, store);
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, clipdrop->thread_wakeup_message, 0, 0));
g_free (prep);
}
@@ -2903,7 +2930,7 @@ _gdk_win32_store_clipboard_contentformats (GdkClipboard *cb,
const char * const *mime_types;
gsize n_mime_types;
gsize i;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_clipboard_get_display (cb));
GdkWin32ClipboardStorePrep *prep;
g_assert (clipdrop->clipboard_hwnd != NULL);
@@ -2916,7 +2943,7 @@ _gdk_win32_store_clipboard_contentformats (GdkClipboard *cb,
n_mime_types);
for (i = 0; i < n_mime_types; i++)
_gdk_win32_add_contentformat_to_pairs (mime_types[i], pairs);
_gdk_win32_add_contentformat_to_pairs (clipdrop, mime_types[i], pairs);
if (pairs->len <= 0)
{
@@ -2934,7 +2961,7 @@ _gdk_win32_store_clipboard_contentformats (GdkClipboard *cb,
GdkWin32ClipboardStorePrepElement el;
GdkWin32ContentFormatPair *pair = &g_array_index (pairs, GdkWin32ContentFormatPair, i);
el.stream = gdk_win32_hdata_output_stream_new (pair, NULL);
el.stream = gdk_win32_hdata_output_stream_new (clipdrop, pair, NULL);
if (!el.stream)
continue;

View File

@@ -22,11 +22,10 @@
G_BEGIN_DECLS
#define _gdk_win32_clipdrop_get() (_win32_clipdrop)
#define _gdk_atom_array_index(a, i) (g_array_index (a, const char *, i))
#define _gdk_win32_clipdrop_atom(i) (_gdk_atom_array_index (_gdk_win32_clipdrop_get ()->known_atoms, i))
#define _gdk_win32_clipdrop_atom(c, i) (_gdk_atom_array_index (c->known_atoms, i))
#define _gdk_cf_array_index(a, i) (g_array_index (a, UINT, i))
#define _gdk_win32_clipdrop_cf(i) (_gdk_cf_array_index (_gdk_win32_clipdrop_get ()->known_clipboard_formats, i))
#define _gdk_win32_clipdrop_cf(c,i) (_gdk_cf_array_index (c->known_clipboard_formats, i))
/* Maps GDK contentformats to w32formats or vice versa, depending on the
* semantics of the array that holds these.
@@ -114,6 +113,15 @@ typedef enum _GdkWin32CFIndex GdkWin32CFIndex;
typedef struct _GdkWin32Clipdrop GdkWin32Clipdrop;
typedef struct _GdkWin32ClipdropClass GdkWin32ClipdropClass;
/* this is shared with gdkdrag-win32.c as well */
struct _clipdrop_thread_items
{
GdkWin32Clipdrop *clipdrop;
GAsyncQueue *queue;
};
typedef struct _clipdrop_thread_items clipdrop_thread_items;
typedef BOOL (WINAPI * GetUpdatedClipboardFormatsFunc)(
_Out_ PUINT lpuiFormats,
_In_ UINT cFormats,
@@ -224,6 +232,15 @@ struct _GdkWin32Clipdrop
* dnd thread is not active.
*/
GHashTable *active_source_drags;
/* our custom MSG UINT that we register once to prcoess DND/Clipbord actions */
UINT thread_wakeup_message;
/* this is a GdkWin32ClipboardThread structure */
void *clipboard_thread_items;
/* this is a GdkWin32DndThread structure */
void *dnd_thread_items;
};
struct _GdkWin32ClipdropClass
@@ -233,44 +250,46 @@ struct _GdkWin32ClipdropClass
GType gdk_win32_clipdrop_get_type (void) G_GNUC_CONST;
void _gdk_win32_clipdrop_init (void);
gboolean _gdk_win32_format_uses_hdata (UINT w32format);
char * _gdk_win32_get_clipboard_format_name (UINT fmt,
gboolean *is_predefined);
void _gdk_win32_add_w32format_to_pairs (UINT format,
GArray *array,
GdkContentFormatsBuilder *builder);
int _gdk_win32_add_contentformat_to_pairs (const char *target,
int _gdk_win32_add_contentformat_to_pairs (GdkWin32Clipdrop *clip_drop,
const char *target,
GArray *array);
void _gdk_win32_clipboard_default_output_done (GObject *clipboard,
GAsyncResult *result,
gpointer user_data);
gboolean _gdk_win32_transmute_contentformat (const char *from_contentformat,
gboolean gdk_win32_clipdrop_transmute_contentformat (GdkWin32Clipdrop *clipdrop,
const char *from_contentformat,
UINT to_w32format,
const guchar *data,
gsize length,
guchar **set_data,
gsize *set_data_length);
gboolean _gdk_win32_transmute_windows_data (UINT from_w32format,
const char *to_contentformat,
HANDLE hdata,
guchar **set_data,
gsize *set_data_length);
gboolean gdk_win32_clipdrop_transmute_windows_data (GdkWin32Clipdrop *clipdrop,
UINT from_w32format,
const char *to_contentformat,
HANDLE hdata,
guchar **set_data,
gsize *set_data_length);
gboolean _gdk_win32_store_clipboard_contentformats (GdkClipboard *cb,
GTask *task,
GdkContentFormats *contentformats);
void _gdk_win32_retrieve_clipboard_contentformats (GTask *task,
void _gdk_win32_retrieve_clipboard_contentformats (GdkClipboard *cb,
GTask *task,
GdkContentFormats *contentformats);
void _gdk_win32_advertise_clipboard_contentformats (GTask *task,
void _gdk_win32_advertise_clipboard_contentformats (GdkClipboard *cb,
GTask *task,
GdkContentFormats *contentformats);
void gdk_win32_clipdrop_add_win32_format_to_pairs (GdkWin32Clipdrop *clipdrop,
UINT format,
GArray *array,
GdkContentFormatsBuilder *builder);

View File

@@ -688,6 +688,7 @@ gdk_win32_display_finalize (GObject *object)
_gdk_win32_dnd_exit ();
gdk_win32_display_lang_notification_exit (display_win32);
g_free (display_win32->pointer_device_items);
g_object_unref (display_win32->cb_dnd_items->clipdrop);
g_free (display_win32->cb_dnd_items);
g_list_store_remove_all (G_LIST_STORE (display_win32->monitors));
@@ -1032,6 +1033,7 @@ gdk_win32_display_init (GdkWin32Display *display_win32)
display_win32->pointer_device_items = g_new0 (GdkWin32PointerDeviceItems, 1);
display_win32->cb_dnd_items = g_new0 (GdkWin32CbDnDItems, 1);
display_win32->cb_dnd_items->display_main_thread = g_thread_self ();
display_win32->cb_dnd_items->clipdrop = GDK_WIN32_CLIPDROP (g_object_new (GDK_TYPE_WIN32_CLIPDROP, NULL));
_gdk_win32_enable_hidpi (display_win32);
display_win32->running_on_arm64 = _gdk_win32_check_processor (GDK_WIN32_ARM64);
@@ -1262,6 +1264,15 @@ gdk_win32_display_get_egl_display (GdkDisplay *display)
return gdk_display_get_egl_display (display);
}
GdkWin32Clipdrop *
gdk_win32_display_get_clipdrop (GdkDisplay *display)
{
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
return display_win32->cb_dnd_items->clipdrop;
}
static void
gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
{

View File

@@ -48,6 +48,8 @@ struct _GdkWin32CbDnDItems
{
/* used to identify the main thread for this GdkWin32Display */
GThread *display_main_thread;
GdkWin32Clipdrop *clipdrop;
};
typedef struct _GdkWin32CbDnDItems GdkWin32CbDnDItems;
@@ -207,9 +209,11 @@ GPtrArray *_gdk_win32_display_get_monitor_list (GdkWin32Display *display);
void gdk_win32_display_check_composited (GdkWin32Display *display);
guint gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
GdkSurface *surface,
HMONITOR hmonitor);
guint gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
GdkSurface *surface,
HMONITOR hmonitor);
GdkWin32Clipdrop *gdk_win32_display_get_clipdrop (GdkDisplay *display);
typedef struct _GdkWin32MessageFilter GdkWin32MessageFilter;

View File

@@ -217,8 +217,8 @@
#include <gdk/gdk.h>
#include <glib/gstdio.h>
/* Just to avoid calling RegisterWindowMessage() every time */
static UINT thread_wakeup_message;
/* accessors to thread data structs in GdkWin32Clipdrop/GdkWin32Drag */
#define OBJECT_DND_THREAD_MEMBER(o,m) ((GdkWin32DnDThread *)(o->dnd_thread_items))->m
typedef struct
{
@@ -362,27 +362,22 @@ struct _GdkWin32DnDThread
data_object *src_object;
};
/* The code is much more secure if we don't rely on the OS to keep
* this around for us.
*/
static GdkWin32DnDThread *dnd_thread_data = NULL;
static gboolean
dnd_queue_is_empty ()
dnd_queue_is_empty (GdkDisplay *display)
{
return g_atomic_int_get (&_win32_clipdrop->dnd_queue_counter) == 0;
return g_atomic_int_get (&(gdk_win32_display_get_clipdrop (display)->dnd_queue_counter)) == 0;
}
static void
decrement_dnd_queue_counter ()
decrement_dnd_queue_counter (GdkDisplay *display)
{
g_atomic_int_dec_and_test (&_win32_clipdrop->dnd_queue_counter);
g_atomic_int_dec_and_test (&(gdk_win32_display_get_clipdrop (display)->dnd_queue_counter));
}
static void
increment_dnd_queue_counter ()
increment_dnd_queue_counter (GdkDisplay *display)
{
g_atomic_int_inc (&_win32_clipdrop->dnd_queue_counter);
g_atomic_int_inc (&(gdk_win32_display_get_clipdrop (display)->dnd_queue_counter));
}
static void
@@ -427,13 +422,15 @@ free_queue_item (GdkWin32DnDThreadQueueItem *item)
}
static gboolean
process_dnd_queue (gboolean timed,
process_dnd_queue (GdkDrag *drag,
gboolean timed,
guint64 end_time,
GdkWin32DnDThreadGetData *getdata_check)
{
GdkWin32DnDThreadQueueItem *item;
GdkWin32DnDThreadUpdateDragState *updatestate;
GdkWin32DnDThreadDoDragDrop *ddd;
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
while (TRUE)
{
@@ -444,17 +441,17 @@ process_dnd_queue (gboolean timed,
if (current_time >= end_time)
break;
item = g_async_queue_timeout_pop (dnd_thread_data->input_queue, end_time - current_time);
item = g_async_queue_timeout_pop (OBJECT_DND_THREAD_MEMBER (drag_win32, input_queue), end_time - current_time);
}
else
{
item = g_async_queue_try_pop (dnd_thread_data->input_queue);
item = g_async_queue_try_pop (OBJECT_DND_THREAD_MEMBER (drag_win32, input_queue));
}
if (item == NULL)
break;
decrement_dnd_queue_counter ();
decrement_dnd_queue_counter (gdk_surface_get_display (drag_win32->drag_surface));
switch (item->item_type)
{
@@ -490,7 +487,7 @@ do_drag_drop_response (gpointer user_data)
HRESULT hr = ddd->received_result;
GdkDrag *drag = GDK_DRAG (ddd->base.opaque_context);
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (drag_win32->drag_surface));
gpointer table_value = g_hash_table_lookup (clipdrop->active_source_drags, drag);
if (ddd == table_value)
@@ -546,7 +543,7 @@ received_drag_context_data (GObject *drag,
{
GError *error = NULL;
GdkWin32DnDThreadGetData *getdata = (GdkWin32DnDThreadGetData *) user_data;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface));
if (!gdk_drag_write_finish (GDK_DRAG (drag), result, &error))
{
@@ -571,17 +568,17 @@ received_drag_context_data (GObject *drag,
}
g_clear_object (&getdata->stream);
increment_dnd_queue_counter ();
increment_dnd_queue_counter (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface));
g_async_queue_push (clipdrop->dnd_queue, getdata);
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, thread_wakeup_message, 0, 0));
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
}
static gboolean
get_data_response (gpointer user_data)
{
GdkWin32DnDThreadGetData *getdata = (GdkWin32DnDThreadGetData *) user_data;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkDrag *drag = GDK_DRAG (getdata->base.opaque_context);
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (GDK_WIN32_DRAG (getdata->base.opaque_context)->drag_surface));
gpointer ddd = g_hash_table_lookup (clipdrop->active_source_drags, drag);
GDK_NOTE (DND, g_print ("idataobject_getdata will request target 0x%p (%s)",
@@ -593,7 +590,7 @@ get_data_response (gpointer user_data)
if (ddd)
{
GError *error = NULL;
GOutputStream *stream = gdk_win32_hdata_output_stream_new (&getdata->pair, &error);
GOutputStream *stream = gdk_win32_hdata_output_stream_new (clipdrop, &getdata->pair, &error);
if (stream)
{
@@ -610,9 +607,9 @@ get_data_response (gpointer user_data)
}
}
increment_dnd_queue_counter ();
increment_dnd_queue_counter (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface));
g_async_queue_push (clipdrop->dnd_queue, getdata);
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, thread_wakeup_message, 0, 0));
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
return G_SOURCE_REMOVE;
}
@@ -622,11 +619,13 @@ do_drag_drop (GdkWin32DnDThreadDoDragDrop *ddd)
{
HRESULT hr;
dnd_thread_data->src_object = ddd->src_object;
dnd_thread_data->src_context = ddd->src_context;
GdkWin32Drag *drag = ddd->base.opaque_context;
hr = DoDragDrop (&dnd_thread_data->src_object->ido,
&dnd_thread_data->src_context->ids,
OBJECT_DND_THREAD_MEMBER (drag, src_object) = ddd->src_object;
OBJECT_DND_THREAD_MEMBER (drag, src_context) = ddd->src_context;
hr = DoDragDrop (&OBJECT_DND_THREAD_MEMBER (drag, src_object->ido),
&OBJECT_DND_THREAD_MEMBER (drag, src_context->ids),
ddd->allowed_drop_effects,
&ddd->received_drop_effect);
@@ -638,15 +637,18 @@ do_drag_drop (GdkWin32DnDThreadDoDragDrop *ddd)
gpointer
_gdk_win32_dnd_thread_main (gpointer data)
{
GAsyncQueue *queue = (GAsyncQueue *) data;
clipdrop_thread_items *clipdrop_items = (clipdrop_thread_items *) data;
GAsyncQueue *queue = clipdrop_items->queue;
GdkWin32Clipdrop *clipdrop = clipdrop_items->clipdrop;
GdkWin32DnDThreadQueueItem *item;
MSG msg;
HRESULT hr;
g_assert (dnd_thread_data == NULL);
g_assert (clipdrop->dnd_thread_items == NULL);
dnd_thread_data = g_new0 (GdkWin32DnDThread, 1);
dnd_thread_data->input_queue = queue;
clipdrop->dnd_thread_items = g_new0 (GdkWin32DnDThread, 1);
OBJECT_DND_THREAD_MEMBER (clipdrop, input_queue) = queue;
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
@@ -658,8 +660,6 @@ _gdk_win32_dnd_thread_main (gpointer data)
/* Create a message queue */
PeekMessage (&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
thread_wakeup_message = RegisterWindowMessage (L"GDK_WORKER_THREAD_WEAKEUP");
/* Signal the main thread that we're ready.
* This is the only time the queue works in reverse.
*/
@@ -667,11 +667,13 @@ _gdk_win32_dnd_thread_main (gpointer data)
while (GetMessage (&msg, NULL, 0, 0))
{
if (!dnd_queue_is_empty ())
GdkDisplay *display = gdk_display_get_default ();
if (!dnd_queue_is_empty (display))
{
while ((item = g_async_queue_try_pop (queue)) != NULL)
{
decrement_dnd_queue_counter ();
decrement_dnd_queue_counter (display);
if (item->item_type != GDK_WIN32_DND_THREAD_QUEUE_ITEM_DO_DRAG_DROP)
{
@@ -680,7 +682,7 @@ _gdk_win32_dnd_thread_main (gpointer data)
}
do_drag_drop ((GdkWin32DnDThreadDoDragDrop *) item);
API_CALL (PostThreadMessage, (GetCurrentThreadId (), thread_wakeup_message, 0, 0));
API_CALL (PostThreadMessage, (GetCurrentThreadId (), clipdrop->thread_wakeup_message, 0, 0));
break;
}
}
@@ -691,7 +693,8 @@ _gdk_win32_dnd_thread_main (gpointer data)
}
g_async_queue_unref (queue);
g_clear_pointer (&dnd_thread_data, g_free);
g_clear_pointer (&clipdrop->dnd_thread_items, g_free);
OleUninitialize ();
CoUninitialize ();
@@ -803,6 +806,8 @@ gdk_drag_new (GdkDisplay *display,
else
drag_win32->scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
drag_win32->dnd_thread_items = display_win32->cb_dnd_items->clipdrop->dnd_thread_items;
return drag;
}
@@ -827,17 +832,17 @@ static enum_formats *enum_formats_new (GArray *formats);
* Does not give a reference.
*/
GdkDrag *
_gdk_win32_find_drag_for_dest_hwnd (HWND dest_hwnd)
gdk_win32_find_drag_for_dest_surface (GdkSurface *surface)
{
GHashTableIter iter;
GdkWin32Drag *drag_win32;
GdkWin32DnDThreadDoDragDrop *ddd;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (surface));
g_hash_table_iter_init (&iter, clipdrop->active_source_drags);
while (g_hash_table_iter_next (&iter, (gpointer *) &drag_win32, (gpointer *) &ddd))
if (ddd->src_context->dest_window_handle == dest_hwnd)
if (ddd->src_context->dest_window_handle == GDK_SURFACE_HWND (surface))
return GDK_DRAG (drag_win32);
return NULL;
@@ -914,8 +919,8 @@ idropsourcenotify_dragentertarget (IDropSourceNotify *This,
source_drag_context *ctx = (source_drag_context *) (((char *) This) - G_STRUCT_OFFSET (source_drag_context, idsn));
GdkWin32DnDEnterLeaveNotify *notify;
if (!dnd_queue_is_empty ())
process_dnd_queue (FALSE, 0, NULL);
if (!dnd_queue_is_empty (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
GDK_NOTE (DND, g_print ("idropsourcenotify_dragentertarget %p (SDC %p) 0x%p\n", This, ctx, hwndTarget));
@@ -935,8 +940,8 @@ idropsourcenotify_dragleavetarget (IDropSourceNotify *This)
source_drag_context *ctx = (source_drag_context *) (((char *) This) - G_STRUCT_OFFSET (source_drag_context, idsn));
GdkWin32DnDEnterLeaveNotify *notify;
if (!dnd_queue_is_empty ())
process_dnd_queue (FALSE, 0, NULL);
if (!dnd_queue_is_empty (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
GDK_NOTE (DND, g_print ("idropsourcenotify_dragleavetarget %p (SDC %p) 0x%p\n", This, ctx, ctx->dest_window_handle));
@@ -1037,8 +1042,8 @@ idropsource_querycontinuedrag (LPDROPSOURCE This,
GDK_NOTE (DND, g_print ("idropsource_querycontinuedrag %p esc=%d keystate=0x%lx with state %d\n", This, fEscapePressed, grfKeyState, ctx->util_data.state));
if (!dnd_queue_is_empty ())
process_dnd_queue (FALSE, 0, NULL);
if (!dnd_queue_is_empty (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
GDK_NOTE (DND, g_print ("idropsource_querycontinuedrag state %d\n", ctx->util_data.state));
@@ -1074,14 +1079,13 @@ static gboolean
give_feedback (gpointer user_data)
{
GdkWin32DnDThreadGiveFeedback *feedback = (GdkWin32DnDThreadGiveFeedback *) user_data;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkDrag *drag = GDK_DRAG (feedback->base.opaque_context);
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (drag_win32->drag_surface));
gpointer ddd = g_hash_table_lookup (clipdrop->active_source_drags, feedback->base.opaque_context);
if (ddd)
{
GdkDrag *drag = GDK_DRAG (feedback->base.opaque_context);
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
GDK_NOTE (DND, g_print ("gdk_dnd_handle_drag_status: 0x%p\n",
drag));
@@ -1102,8 +1106,8 @@ idropsource_givefeedback (LPDROPSOURCE This,
GDK_NOTE (DND, g_print ("idropsource_givefeedback %p with drop effect %lu S_OK\n", This, dwEffect));
if (!dnd_queue_is_empty ())
process_dnd_queue (FALSE, 0, NULL);
if (!dnd_queue_is_empty (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
feedback = g_new0 (GdkWin32DnDThreadGiveFeedback, 1);
feedback->base.item_type = GDK_WIN32_DND_THREAD_QUEUE_ITEM_GIVE_FEEDBACK;
@@ -1241,8 +1245,8 @@ idataobject_getdata (LPDATAOBJECT This,
return hr;
}
if (!dnd_queue_is_empty ())
process_dnd_queue (FALSE, 0, NULL);
if (!dnd_queue_is_empty (gdk_surface_get_display (GDK_WIN32_DRAG (ctx->drag)->drag_surface)))
process_dnd_queue (ctx->drag, FALSE, 0, NULL);
getdata = g_new0 (GdkWin32DnDThreadGetData, 1);
getdata->base.item_type = GDK_WIN32_DND_THREAD_QUEUE_ITEM_GET_DATA;
@@ -1250,7 +1254,7 @@ idataobject_getdata (LPDATAOBJECT This,
getdata->pair = *pair;
g_idle_add_full (G_PRIORITY_DEFAULT, get_data_response, getdata, NULL);
if (!process_dnd_queue (TRUE, g_get_monotonic_time () + G_USEC_PER_SEC * 30, getdata))
if (!process_dnd_queue (ctx->drag, TRUE, g_get_monotonic_time () + G_USEC_PER_SEC * 30, getdata))
return E_FAIL;
if (getdata->produced_data_medium.tymed == TYMED_NULL)
@@ -1617,7 +1621,9 @@ data_object_new (GdkDrag *drag)
GDK_NOTE (DND, g_print ("DataObject supports contentformat 0x%p (%s)\n", mime_types[i], mime_types[i]));
added_count = _gdk_win32_add_contentformat_to_pairs (mime_types[i], result->formats);
added_count = _gdk_win32_add_contentformat_to_pairs (gdk_win32_display_get_clipdrop (gdk_surface_get_display (GDK_WIN32_DRAG (drag)->drag_surface)),
mime_types[i],
result->formats);
for (j = 0; j < added_count && result->formats->len - 1 - j >= 0; j++)
GDK_NOTE (DND, g_print ("DataObject will support w32format 0x%x\n", g_array_index (result->formats, GdkWin32ContentFormatPair, j).w32format));
@@ -1673,7 +1679,7 @@ _gdk_win32_surface_drag_begin (GdkSurface *surface,
{
GdkDrag *drag;
GdkWin32Drag *drag_win32;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (surface));
double px, py;
int x_root, y_root;
GdkWin32DnDThreadDoDragDrop *ddd;
@@ -1728,9 +1734,9 @@ _gdk_win32_surface_drag_begin (GdkSurface *surface,
ddd->allowed_drop_effects |= DROPEFFECT_LINK;
g_hash_table_replace (clipdrop->active_source_drags, g_object_ref (drag), ddd);
increment_dnd_queue_counter ();
increment_dnd_queue_counter (gdk_surface_get_display (drag_win32->drag_surface));
g_async_queue_push (clipdrop->dnd_queue, ddd);
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, thread_wakeup_message, 0, 0));
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
drag_win32->util_data.state = GDK_WIN32_DND_PENDING;
@@ -1769,9 +1775,9 @@ send_source_state_update (GdkWin32Clipdrop *clipdrop,
status->base.item_type = GDK_WIN32_DND_THREAD_QUEUE_ITEM_UPDATE_DRAG_STATE;
status->opaque_ddd = ddd;
status->produced_util_data = drag_win32->util_data;
increment_dnd_queue_counter ();
increment_dnd_queue_counter (gdk_surface_get_display (drag_win32->drag_surface));
g_async_queue_push (clipdrop->dnd_queue, status);
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, thread_wakeup_message, 0, 0));
API_CALL (PostThreadMessage, (clipdrop->dnd_thread_id, clipdrop->thread_wakeup_message, 0, 0));
}
static void
@@ -1779,7 +1785,7 @@ gdk_win32_drag_drop (GdkDrag *drag,
guint32 time_)
{
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32Clipdrop *clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (drag_win32->drag_surface));
gpointer ddd;
g_assert (check_drag_display_thread_status (drag, TRUE));
@@ -1894,7 +1900,7 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
/* FIXME: This is temporary, until the code is fixed to ensure that
* gdk_drag_finish () is called by GTK.
*/
clipdrop = _gdk_win32_clipdrop_get ();
clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (drag_win32->drag_surface));
ddd = g_hash_table_lookup (clipdrop->active_source_drags, drag);
if (success)
@@ -2052,7 +2058,7 @@ gdk_dnd_handle_motion_event (GdkDrag *drag,
key_state = manufacture_keystate_from_GMT (state);
clipdrop = _gdk_win32_clipdrop_get ();
clipdrop = gdk_win32_display_get_clipdrop (gdk_surface_get_display (event->surface));
GDK_NOTE (DND, g_print ("Post WM_MOUSEMOVE keystate=%lu\n", key_state));

View File

@@ -269,7 +269,8 @@ idroptarget_release (LPDROPTARGET This)
}
static GdkContentFormats *
query_object_formats (LPDATAOBJECT pDataObj,
query_object_formats (GdkDisplay *display,
LPDATAOBJECT pDataObj,
GArray *w32format_contentformat_map)
{
IEnumFORMATETC *pfmt = NULL;
@@ -298,7 +299,7 @@ query_object_formats (LPDATAOBJECT pDataObj,
GDK_NOTE (DND, g_print ("supported unnamed? source format 0x%x\n", fmt.cfFormat));
g_free (registered_name);
_gdk_win32_add_w32format_to_pairs (fmt.cfFormat, w32format_contentformat_map, builder);
gdk_win32_clipdrop_add_win32_format_to_pairs (gdk_win32_display_get_clipdrop (display), fmt.cfFormat, w32format_contentformat_map, builder);
hr = IEnumFORMATETC_Next (pfmt, 1, &fmt, NULL);
}
@@ -490,12 +491,12 @@ idroptarget_dragenter (LPDROPTARGET This,
drag = NULL;
if (ctx->surface)
drag = _gdk_win32_find_drag_for_dest_hwnd (GDK_SURFACE_HWND (ctx->surface));
drag = gdk_win32_find_drag_for_dest_surface (ctx->surface);
display = gdk_surface_get_display (ctx->surface);
droptarget_w32format_contentformat_map = g_array_new (FALSE, FALSE, sizeof (GdkWin32ContentFormatPair));
formats = query_object_formats (pDataObj, droptarget_w32format_contentformat_map);
formats = query_object_formats (display, pDataObj, droptarget_w32format_contentformat_map);
drop = gdk_drop_new (display,
gdk_seat_get_pointer (gdk_display_get_default_seat (display)),
drag,
@@ -1110,7 +1111,12 @@ gdk_win32_drop_read_async (GdkDrop *drop,
}
else
{
_gdk_win32_transmute_windows_data (pair->w32format, pair->contentformat, storage.hGlobal, &data, &data_len);
GdkDisplay *display = gdk_drop_get_display (drop);
gdk_win32_clipdrop_transmute_windows_data (gdk_win32_display_get_clipdrop (display),
pair->w32format, pair->contentformat,
storage.hGlobal,
&data,
&data_len);
}
ReleaseStgMedium (&storage);

View File

@@ -32,6 +32,3 @@ GdkDeviceManagerWin32 *_gdk_device_manager = NULL;
GdkWin32ModalOpKind _modal_operation_in_progress = GDK_WIN32_MODAL_OP_NONE;
HWND _modal_move_resize_hwnd = NULL;
/* The singleton clipdrop object pointer */
GdkWin32Clipdrop *_win32_clipdrop = NULL;

View File

@@ -37,6 +37,7 @@ typedef struct _GdkWin32HDataOutputStreamPrivate GdkWin32HDataOutputStreamPriva
struct _GdkWin32HDataOutputStreamPrivate
{
HANDLE handle;
GdkWin32Clipdrop *clipdrop;
guchar *data;
gsize data_allocated_size;
gsize data_length;
@@ -204,12 +205,13 @@ gdk_win32_hdata_output_stream_close (GOutputStream *output_stream,
return FALSE;
}
if (!_gdk_win32_transmute_contentformat (priv->pair.contentformat,
priv->pair.w32format,
priv->data,
priv->data_length,
&transmuted_data,
&transmuted_data_length))
if (!gdk_win32_clipdrop_transmute_contentformat (priv->clipdrop,
priv->pair.contentformat,
priv->pair.w32format,
priv->data,
priv->data_length,
&transmuted_data,
&transmuted_data_length))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Failed to transmute %zu bytes of data from %s to %u"),
@@ -343,7 +345,8 @@ gdk_win32_hdata_output_stream_init (GdkWin32HDataOutputStream *stream)
}
GOutputStream *
gdk_win32_hdata_output_stream_new (GdkWin32ContentFormatPair *pair,
gdk_win32_hdata_output_stream_new (GdkWin32Clipdrop *clipdrop,
GdkWin32ContentFormatPair *pair,
GError **error)
{
GdkWin32HDataOutputStream *stream;
@@ -369,6 +372,7 @@ gdk_win32_hdata_output_stream_new (GdkWin32ContentFormatPair *pair,
stream = g_object_new (GDK_TYPE_WIN32_HDATA_OUTPUT_STREAM, NULL);
priv = gdk_win32_hdata_output_stream_get_instance_private (stream);
priv->clipdrop = clipdrop;
priv->pair = *pair;
if (hmem)

View File

@@ -51,7 +51,8 @@ struct GdkWin32HDataOutputStreamClass
GType gdk_win32_hdata_output_stream_get_type (void) G_GNUC_CONST;
GOutputStream *gdk_win32_hdata_output_stream_new (GdkWin32ContentFormatPair *pair,
GOutputStream *gdk_win32_hdata_output_stream_new (GdkWin32Clipdrop *clipdrop,
GdkWin32ContentFormatPair *pair,
GError **error);
HANDLE gdk_win32_hdata_output_stream_get_handle (GdkWin32HDataOutputStream *stream,

View File

@@ -42,8 +42,6 @@
void
_gdk_win32_surfaceing_init (void)
{
_gdk_win32_clipdrop_init ();
gdk_dmanipulation_initialize ();
}

View File

@@ -145,9 +145,6 @@ extern GdkDeviceManagerWin32 *_gdk_device_manager;
extern guint _gdk_keymap_serial;
/* The singleton clipdrop object pointer */
extern GdkWin32Clipdrop *_win32_clipdrop;
typedef enum {
GDK_WIN32_MODAL_OP_NONE = 0x0,
GDK_WIN32_MODAL_OP_SIZE = 0x1 << 0,

View File

@@ -83,6 +83,9 @@ struct _GdkWin32Drag
guint drag_status : 4; /* Current status of drag */
guint drop_failed : 1; /* Whether the drop was unsuccessful */
guint handle_events : 1; /* Whether handle_event() should do anything */
/* keep track of thread data for the DnD op, kept in the GdkDisplay that we create, a GdkWin32DndThread structure */
void *dnd_thread_items;
};
struct _GdkWin32DragClass
@@ -91,9 +94,9 @@ struct _GdkWin32DragClass
};
gpointer _gdk_win32_dnd_thread_main (gpointer data);
gpointer _gdk_win32_dnd_thread_main (gpointer data);
GdkDrag *_gdk_win32_find_drag_for_dest_hwnd (HWND dest_hwnd);
GdkDrag *gdk_win32_find_drag_for_dest_surface (GdkSurface *surface);
G_END_DECLS