gtk2/gdk/win32/gdkclipdrop-win32.h
2020-07-25 00:47:36 +02:00

279 lines
12 KiB
C

/* GDK - The GIMP Drawing Kit
*
* gdkclipdrop-win32.h: Private Win32-specific clipboard/DnD object
*
* Copyright © 2017 LRN
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_CLIPDROP_WIN32_H__
#define __GDK_CLIPDROP_WIN32_H__
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_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))
/* Maps GDK contentformats to w32formats or vice versa, depending on the
* semantics of the array that holds these.
* Also remembers whether the data needs to be transmuted.
*/
typedef struct {
int w32format;
/* This is assumed to be an interned string, it will be
* compared by simply comparing the pointer.
*/
const char *contentformat;
gboolean transmute;
} GdkWin32ContentFormatPair;
/* OLE-based DND state */
typedef enum {
GDK_WIN32_DND_NONE,
GDK_WIN32_DND_PENDING,
GDK_WIN32_DND_DROPPED,
GDK_WIN32_DND_FAILED,
GDK_WIN32_DND_DRAGGING,
} GdkWin32DndState;
enum _GdkWin32AtomIndex
{
/* atoms: properties, targets and types */
GDK_WIN32_ATOM_INDEX_GDK_SELECTION = 0,
GDK_WIN32_ATOM_INDEX_CLIPBOARD_MANAGER,
GDK_WIN32_ATOM_INDEX_WM_TRANSIENT_FOR,
GDK_WIN32_ATOM_INDEX_TARGETS,
GDK_WIN32_ATOM_INDEX_DELETE,
GDK_WIN32_ATOM_INDEX_SAVE_TARGETS,
GDK_WIN32_ATOM_INDEX_TEXT_PLAIN_UTF8,
GDK_WIN32_ATOM_INDEX_TEXT_PLAIN,
GDK_WIN32_ATOM_INDEX_TEXT_URI_LIST,
GDK_WIN32_ATOM_INDEX_TEXT_HTML,
GDK_WIN32_ATOM_INDEX_IMAGE_PNG,
GDK_WIN32_ATOM_INDEX_IMAGE_JPEG,
GDK_WIN32_ATOM_INDEX_IMAGE_BMP,
GDK_WIN32_ATOM_INDEX_IMAGE_GIF,
/* DND selections */
GDK_WIN32_ATOM_INDEX_LOCAL_DND_SELECTION,
GDK_WIN32_ATOM_INDEX_DROPFILES_DND,
GDK_WIN32_ATOM_INDEX_OLE2_DND,
/* Clipboard formats */
GDK_WIN32_ATOM_INDEX_PNG,
GDK_WIN32_ATOM_INDEX_JFIF,
GDK_WIN32_ATOM_INDEX_GIF,
GDK_WIN32_ATOM_INDEX_CF_DIB,
GDK_WIN32_ATOM_INDEX_CFSTR_SHELLIDLIST,
GDK_WIN32_ATOM_INDEX_CF_TEXT,
GDK_WIN32_ATOM_INDEX_CF_UNICODETEXT,
GDK_WIN32_ATOM_INDEX_LAST
};
typedef enum _GdkWin32AtomIndex GdkWin32AtomIndex;
enum _GdkWin32CFIndex
{
GDK_WIN32_CF_INDEX_PNG = 0,
GDK_WIN32_CF_INDEX_JFIF,
GDK_WIN32_CF_INDEX_GIF,
GDK_WIN32_CF_INDEX_UNIFORMRESOURCELOCATORW,
GDK_WIN32_CF_INDEX_CFSTR_SHELLIDLIST,
GDK_WIN32_CF_INDEX_HTML_FORMAT,
GDK_WIN32_CF_INDEX_TEXT_HTML,
GDK_WIN32_CF_INDEX_IMAGE_PNG,
GDK_WIN32_CF_INDEX_IMAGE_JPEG,
GDK_WIN32_CF_INDEX_IMAGE_BMP,
GDK_WIN32_CF_INDEX_IMAGE_GIF,
GDK_WIN32_CF_INDEX_TEXT_URI_LIST,
GDK_WIN32_CF_INDEX_TEXT_PLAIN_UTF8,
GDK_WIN32_CF_INDEX_LAST
};
typedef enum _GdkWin32CFIndex GdkWin32CFIndex;
#define GDK_TYPE_WIN32_CLIPDROP (gdk_win32_clipdrop_get_type ())
#define GDK_WIN32_CLIPDROP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_WIN32_CLIPDROP, GdkWin32Clipdrop))
#define GDK_WIN32_CLIPDROP_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_WIN32_CLIPDROP, GdkWin32ClipdropClass))
#define GDK_IS_WIN32_CLIPDROP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_WIN32_CLIPDROP))
#define GDK_IS_WIN32_CLIPDROP_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_WIN32_CLIPDROP))
#define GDK_WIN32_CLIPDROP_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_WIN32_CLIPDROP, GdkWin32ClipdropClass))
typedef struct _GdkWin32Clipdrop GdkWin32Clipdrop;
typedef struct _GdkWin32ClipdropClass GdkWin32ClipdropClass;
typedef BOOL (WINAPI * GetUpdatedClipboardFormatsFunc)(
_Out_ PUINT lpuiFormats,
_In_ UINT cFormats,
_Out_ PUINT pcFormatsOut
);
/* This object is just a sink to hold all the clipboard- and dnd-related data
* that otherwise would be in global variables.
*/
struct _GdkWin32Clipdrop
{
GObject *parent_instance;
/* interned strings for well-known image formats */
const char **known_pixbuf_formats;
int n_known_pixbuf_formats;
/* GArray of GdkAtoms for various known Selection and DnD strings.
* Size is guaranteed to be at least GDK_WIN32_ATOM_INDEX_LAST
*/
GArray *known_atoms;
/* GArray of UINTs for various known clipboard formats.
* Size is guaranteed to be at least GDK_WIN32_CF_INDEX_LAST.
*/
GArray *known_clipboard_formats;
GdkWin32DndState dnd_target_state;
/* A target-keyed hash table of GArrays of GdkWin32ContentFormatPairs describing compatibility w32formats for a contentformat */
GHashTable *compatibility_w32formats;
/* A format-keyed hash table of GArrays of GdkAtoms describing compatibility contentformats for a w32format */
GHashTable *compatibility_contentformats;
/* By all rights we should be able to just use this function
* normally, as our target platform is Vista-or-later.
* This pointer is manually retrieved only to allow
* GTK to be compiled with old MinGW versions, which
* don't have GetUpdatedClipboardFormats in the import libs.
*/
GetUpdatedClipboardFormatsFunc GetUpdatedClipboardFormats;
/* The thread that tries to open the clipboard and then
* do stuff with it. Since clipboard opening can
* fail, we split the code into a thread, and let
* it try to open the clipboard repeatedly until
* the operation times out.
*/
GThread *clipboard_open_thread;
/* Our primary means of communicating with the thread.
* The communication is one-way only - the thread replies
* by just queueing functions to be called in the main
* thread by using g_idle_add().
*/
GAsyncQueue *clipboard_open_thread_queue;
/* We reply to clipboard render requests via this thing.
* We can't use messages, since the clipboard thread will
* stop spinning the message loop while it waits for us
* to render the data.
*/
GAsyncQueue *clipboard_render_queue;
/* Window handle for the clipboard window tha we
* receive from the clipboard thread. We use that
* to wake up the clipboard window main loop by
* posting a message to it.
*/
HWND clipboard_window;
/* The thread that calls DoDragDrop (), which would
* normally block our main thread, as it runs its own
* Windows message loop.
*/
GThread *dnd_thread;
DWORD dnd_thread_id;
/* We reply to the various dnd thread requests via this thing.
* We can't use messages, since the dnd thread will
* stop spinning the message loop while it waits for us
* to come up with a reply.
*/
GAsyncQueue *dnd_queue;
/* This counter is atomically incremented every time
* the main thread pushes something into the queue,
* and atomically decremented every time the DnD thread
* pops something out of it.
* It can be cheaply atomically checked to see if there's
* anything in the queue. If there is, then the queue
* processing (which requires expensice locks) can happen.
*/
int dnd_queue_counter;
/* We don't actually support multiple simultaneous drags,
* for obvious reasons (though this might change with
* the advent of multitouch support?), but there may be
* circumstances where we have two drag contexts at
* the same time (one of them will grab the cursor
* and thus cancel the other drag operation, but
* there will be a point of time when both contexts
* are out there). Thus we keep them around in this hash table.
* Key is the context object (which is safe, because the main
* thread keeps a reference on each one of those), value
* is a pointer to a GdkWin32DnDThreadDoDragDrop struct,
* which we can only examine when we're sure that the
* dnd thread is not active.
*/
GHashTable *active_source_drags;
};
struct _GdkWin32ClipdropClass
{
GObjectClass parent_class;
};
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,
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,
UINT to_w32format,
const guchar *data,
int 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_store_clipboard_contentformats (GdkClipboard *cb,
GTask *task,
GdkContentFormats *contentformats);
void _gdk_win32_retrieve_clipboard_contentformats (GTask *task,
GdkContentFormats *contentformats);
void _gdk_win32_advertise_clipboard_contentformats (GTask *task,
GdkContentFormats *contentformats);
#endif /* __GDK_CLIPDROP_WIN32_H__ */