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:
@@ -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)));
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
void
|
||||
_gdk_win32_surfaceing_init (void)
|
||||
{
|
||||
_gdk_win32_clipdrop_init ();
|
||||
|
||||
gdk_dmanipulation_initialize ();
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user