diff --git a/gdk/win32/gdkclipboard-win32.c b/gdk/win32/gdkclipboard-win32.c index f6b21d422f..196bf7b58e 100644 --- a/gdk/win32/gdkclipboard-win32.c +++ b/gdk/win32/gdkclipboard-win32.c @@ -19,6 +19,7 @@ #include "gdkclipboardprivate.h" #include "gdkclipboard-win32.h" +#include "gdkdisplay-win32.h" #include "gdkdebugprivate.h" #include @@ -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))); +} \ No newline at end of file diff --git a/gdk/win32/gdkclipboard-win32.h b/gdk/win32/gdkclipboard-win32.h index 2987becdb7..328636cd21 100644 --- a/gdk/win32/gdkclipboard-win32.h +++ b/gdk/win32/gdkclipboard-win32.h @@ -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 diff --git a/gdk/win32/gdkclipdrop-win32.c b/gdk/win32/gdkclipdrop-win32.c index 5aa317c6aa..3e082b1dec 100644 --- a/gdk/win32/gdkclipdrop-win32.c +++ b/gdk/win32/gdkclipdrop-win32.c @@ -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; diff --git a/gdk/win32/gdkclipdrop-win32.h b/gdk/win32/gdkclipdrop-win32.h index 500da9ab2b..c48d9a17f2 100644 --- a/gdk/win32/gdkclipdrop-win32.h +++ b/gdk/win32/gdkclipdrop-win32.h @@ -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); diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c index db662e5391..baaffea131 100644 --- a/gdk/win32/gdkdisplay-win32.c +++ b/gdk/win32/gdkdisplay-win32.c @@ -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) { diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h index 6b2579bc59..045e137ead 100644 --- a/gdk/win32/gdkdisplay-win32.h +++ b/gdk/win32/gdkdisplay-win32.h @@ -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; diff --git a/gdk/win32/gdkdrag-win32.c b/gdk/win32/gdkdrag-win32.c index 949e1e1311..0b1799507d 100644 --- a/gdk/win32/gdkdrag-win32.c +++ b/gdk/win32/gdkdrag-win32.c @@ -217,8 +217,8 @@ #include #include -/* 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)); diff --git a/gdk/win32/gdkdrop-win32.c b/gdk/win32/gdkdrop-win32.c index 6adfb95b53..94ed2e89fb 100644 --- a/gdk/win32/gdkdrop-win32.c +++ b/gdk/win32/gdkdrop-win32.c @@ -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); diff --git a/gdk/win32/gdkglobals-win32.c b/gdk/win32/gdkglobals-win32.c index 0960ccfe98..e9063a8fd6 100644 --- a/gdk/win32/gdkglobals-win32.c +++ b/gdk/win32/gdkglobals-win32.c @@ -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; diff --git a/gdk/win32/gdkhdataoutputstream-win32.c b/gdk/win32/gdkhdataoutputstream-win32.c index b1c668f01a..9ebbf37b8c 100644 --- a/gdk/win32/gdkhdataoutputstream-win32.c +++ b/gdk/win32/gdkhdataoutputstream-win32.c @@ -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) diff --git a/gdk/win32/gdkhdataoutputstream-win32.h b/gdk/win32/gdkhdataoutputstream-win32.h index 888b134fc3..84cddc4d5c 100644 --- a/gdk/win32/gdkhdataoutputstream-win32.h +++ b/gdk/win32/gdkhdataoutputstream-win32.h @@ -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, diff --git a/gdk/win32/gdkmain-win32.c b/gdk/win32/gdkmain-win32.c index 3abb10e5fa..cb11758832 100644 --- a/gdk/win32/gdkmain-win32.c +++ b/gdk/win32/gdkmain-win32.c @@ -42,8 +42,6 @@ void _gdk_win32_surfaceing_init (void) { - _gdk_win32_clipdrop_init (); - gdk_dmanipulation_initialize (); } diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h index 8add55682f..8ff468d057 100644 --- a/gdk/win32/gdkprivate-win32.h +++ b/gdk/win32/gdkprivate-win32.h @@ -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, diff --git a/gdk/win32/gdkwin32dnd-private.h b/gdk/win32/gdkwin32dnd-private.h index 9738e8c7fe..d6d1253402 100644 --- a/gdk/win32/gdkwin32dnd-private.h +++ b/gdk/win32/gdkwin32dnd-private.h @@ -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