summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog43
-rw-r--r--ChangeLog.pre-2-1043
-rw-r--r--ChangeLog.pre-2-843
-rw-r--r--gdk/gdk.symbols6
-rw-r--r--gdk/win32/gdkdisplay-win32.c4
-rw-r--r--gdk/win32/gdkevents-win32.c58
-rw-r--r--gdk/win32/gdkglobals-win32.c9
-rw-r--r--gdk/win32/gdkmain-win32.c71
-rw-r--r--gdk/win32/gdkprivate-win32.h21
-rw-r--r--gdk/win32/gdkproperty-win32.c354
-rw-r--r--gdk/win32/gdkselection-win32.c283
-rw-r--r--gdk/win32/gdkwin32.h5
-rw-r--r--gtk/gtkselection.c19
13 files changed, 741 insertions, 218 deletions
diff --git a/ChangeLog b/ChangeLog
index 7286577da..82c25cf30 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,46 @@
+2005-04-04 Tor Lillqvist <tml@novell.com>
+
+ * gdk/win32/gdkmain.c (_gdk_win32_cf_to_string): New debugging
+ function, to log a clipboard format name symbolically.
+ (_gdk_win32_data_to_string): Also new, to log random data bytes.
+
+ Implement delayed rendering on Win32, specifically for transfering
+ images through the clipboard from GTK+ apps to other
+ apps (#168173, implementation by Ivan Wong):
+
+ * gdk/win32/gdkevents-win32.c (gdk_event_translate):
+ Handle WM_RENDERFORMAT.
+
+ * gdk/win32/gdkprivate-win32.h
+ * gdk/win32/gdkglobals-win32.c: Add _format_atom_table,
+ _delayed_rendering_data and _image_bmp.
+
+ * gdk/win32/gdkmain-win32.c: Initialize _image_bmp.
+
+ * gdk/win32/gdkproperty-win32.c (gdk_property_change):
+ Accept formats other than GDK_TARGET_STRING or _utf8_string, and
+ assume they are handled through delayed rendering.
+
+ * gdk/win32/gdkselection-win32.c (gdk_selection_convert):
+ Return all available formats (including those registered by GTK+
+ apps) on request_targets.
+ (gdk_selection_property_get): We should append a zero byte like
+ X11 does.
+ (gdk_win32_selection_add_targets): New function, for
+ gtkselection's use. Win32 requires that the clipboard owner
+ registers all valid formats even if the owner wants delayed
+ rendering.
+ (_gdk_win32_selection_convert_to_dib): New function. Convert
+ images to DIB using gdk-pixbuf.
+
+ * gdk/win32/gdkwin32.h: Declare gdk_win32_selection_add_targets().
+
+ * gtk/gtkselection.c (gtk_selection_add_target,
+ gtk_selection_add_targets): Call gdk_win32_selection_add_targets()
+ to register target formats.
+
+ * gdk/gdk.symbols: Add gdk_win32_selection_add_targets().
+
2005-04-03 Hans Breuer <hans@breuer.org>
[merged from gtk-2-6 branch]
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 7286577da..82c25cf30 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,46 @@
+2005-04-04 Tor Lillqvist <tml@novell.com>
+
+ * gdk/win32/gdkmain.c (_gdk_win32_cf_to_string): New debugging
+ function, to log a clipboard format name symbolically.
+ (_gdk_win32_data_to_string): Also new, to log random data bytes.
+
+ Implement delayed rendering on Win32, specifically for transfering
+ images through the clipboard from GTK+ apps to other
+ apps (#168173, implementation by Ivan Wong):
+
+ * gdk/win32/gdkevents-win32.c (gdk_event_translate):
+ Handle WM_RENDERFORMAT.
+
+ * gdk/win32/gdkprivate-win32.h
+ * gdk/win32/gdkglobals-win32.c: Add _format_atom_table,
+ _delayed_rendering_data and _image_bmp.
+
+ * gdk/win32/gdkmain-win32.c: Initialize _image_bmp.
+
+ * gdk/win32/gdkproperty-win32.c (gdk_property_change):
+ Accept formats other than GDK_TARGET_STRING or _utf8_string, and
+ assume they are handled through delayed rendering.
+
+ * gdk/win32/gdkselection-win32.c (gdk_selection_convert):
+ Return all available formats (including those registered by GTK+
+ apps) on request_targets.
+ (gdk_selection_property_get): We should append a zero byte like
+ X11 does.
+ (gdk_win32_selection_add_targets): New function, for
+ gtkselection's use. Win32 requires that the clipboard owner
+ registers all valid formats even if the owner wants delayed
+ rendering.
+ (_gdk_win32_selection_convert_to_dib): New function. Convert
+ images to DIB using gdk-pixbuf.
+
+ * gdk/win32/gdkwin32.h: Declare gdk_win32_selection_add_targets().
+
+ * gtk/gtkselection.c (gtk_selection_add_target,
+ gtk_selection_add_targets): Call gdk_win32_selection_add_targets()
+ to register target formats.
+
+ * gdk/gdk.symbols: Add gdk_win32_selection_add_targets().
+
2005-04-03 Hans Breuer <hans@breuer.org>
[merged from gtk-2-6 branch]
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 7286577da..82c25cf30 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,46 @@
+2005-04-04 Tor Lillqvist <tml@novell.com>
+
+ * gdk/win32/gdkmain.c (_gdk_win32_cf_to_string): New debugging
+ function, to log a clipboard format name symbolically.
+ (_gdk_win32_data_to_string): Also new, to log random data bytes.
+
+ Implement delayed rendering on Win32, specifically for transfering
+ images through the clipboard from GTK+ apps to other
+ apps (#168173, implementation by Ivan Wong):
+
+ * gdk/win32/gdkevents-win32.c (gdk_event_translate):
+ Handle WM_RENDERFORMAT.
+
+ * gdk/win32/gdkprivate-win32.h
+ * gdk/win32/gdkglobals-win32.c: Add _format_atom_table,
+ _delayed_rendering_data and _image_bmp.
+
+ * gdk/win32/gdkmain-win32.c: Initialize _image_bmp.
+
+ * gdk/win32/gdkproperty-win32.c (gdk_property_change):
+ Accept formats other than GDK_TARGET_STRING or _utf8_string, and
+ assume they are handled through delayed rendering.
+
+ * gdk/win32/gdkselection-win32.c (gdk_selection_convert):
+ Return all available formats (including those registered by GTK+
+ apps) on request_targets.
+ (gdk_selection_property_get): We should append a zero byte like
+ X11 does.
+ (gdk_win32_selection_add_targets): New function, for
+ gtkselection's use. Win32 requires that the clipboard owner
+ registers all valid formats even if the owner wants delayed
+ rendering.
+ (_gdk_win32_selection_convert_to_dib): New function. Convert
+ images to DIB using gdk-pixbuf.
+
+ * gdk/win32/gdkwin32.h: Declare gdk_win32_selection_add_targets().
+
+ * gtk/gtkselection.c (gtk_selection_add_target,
+ gtk_selection_add_targets): Call gdk_win32_selection_add_targets()
+ to register target formats.
+
+ * gdk/gdk.symbols: Add gdk_win32_selection_add_targets().
+
2005-04-03 Hans Breuer <hans@breuer.org>
[merged from gtk-2-6 branch]
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index 07b141204..34a9f7e02 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -1047,6 +1047,12 @@ gdk_win32_hdc_get
gdk_win32_hdc_release
#endif
#endif
+
+#if IN_HEADER(__GDK_WIN32_H__)
+#if IN_FILE(__GDK_SELECTION_WIN32_C__)
+gdk_win32_selection_add_targets
+#endif
+#endif
#endif
#ifdef GDK_WINDOWING_X11
diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c
index eca6de6a7..fe08e4584 100644
--- a/gdk/win32/gdkdisplay-win32.c
+++ b/gdk/win32/gdkdisplay-win32.c
@@ -375,9 +375,7 @@ _win32_on_clipboard_change (HWND hwnd,
g_print ("WM_DRAWCLIPBOARD: owner:%p formats: ", hwndOwner);
for (; 0 != (nFormat = EnumClipboardFormats (nFormat));)
{
- char sFormat[80];
- if (GetClipboardFormatName (nFormat, sFormat, G_N_ELEMENTS (sFormat)) > 0)
- g_print ("%s ", sFormat);
+ g_print ("%s ", _gdk_win32_cf_to_string (nFormat));
}
g_print ("\n");
CloseClipboard ();
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 5bf455c12..222b457c8 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -2178,6 +2178,7 @@ gdk_event_translate (GdkDisplay *display,
static gint update_colors_counter = 0;
gint button;
+ GdkAtom target;
gchar buf[256];
gboolean return_val = FALSE;
@@ -3362,7 +3363,62 @@ gdk_event_translate (GdkDisplay *display,
else
return_val = TRUE;
break;
-
+
+ case WM_RENDERFORMAT:
+ GDK_NOTE (EVENTS, g_print (" %s", _gdk_win32_cf_to_string (msg->wParam)));
+
+ if (!(target = g_hash_table_lookup (_format_atom_table, GINT_TO_POINTER (msg->wParam))))
+ {
+ GDK_NOTE (EVENTS, g_print (" (target not found)"));
+ return_val = TRUE;
+ break;
+ }
+
+ /* We need to render to clipboard immediately, don't call
+ * append_event()
+ */
+ if (_gdk_event_func)
+ {
+ event = gdk_event_new (GDK_SELECTION_REQUEST);
+ event->selection.window = window;
+ event->selection.send_event = FALSE;
+ event->selection.selection = GDK_SELECTION_CLIPBOARD;
+ event->selection.target = target;
+ event->selection.property = _gdk_selection_property;
+ event->selection.requestor = (guint32) msg->hwnd;
+ event->selection.time = msg->time;
+
+ fixup_event (event);
+ GDK_NOTE (EVENTS, g_print (" (calling gdk_event_func)"));
+ GDK_NOTE (EVENTS, print_event (event));
+ (*_gdk_event_func) (event, _gdk_event_data);
+ gdk_event_free (event);
+
+ /* Now the clipboard owner should have rendered */
+ if (!_delayed_rendering_data)
+ GDK_NOTE (EVENTS, g_print (" (no _delayed_rendering_data?)"));
+ else
+ {
+ if (msg->wParam == CF_DIB)
+ {
+ _delayed_rendering_data =
+ _gdk_win32_selection_convert_to_dib (_delayed_rendering_data,
+ target);
+ if (!_delayed_rendering_data)
+ {
+ g_warning ("Cannot convert to DIB from delayed rendered image");
+ break;
+ }
+ }
+ /* The requestor is holding the clipboard, no
+ * OpenClipboard() is required/possible
+ */
+ API_CALL (SetClipboardData, (msg->wParam, _delayed_rendering_data));
+ _delayed_rendering_data = NULL;
+ }
+ }
+ break;
+
#ifdef HAVE_WINTAB
case WM_ACTIVATE:
/* Bring any tablet contexts to the top of the overlap order when
diff --git a/gdk/win32/gdkglobals-win32.c b/gdk/win32/gdkglobals-win32.c
index 26fb20383..a178ccbf2 100644
--- a/gdk/win32/gdkglobals-win32.c
+++ b/gdk/win32/gdkglobals-win32.c
@@ -36,7 +36,7 @@ GdkWindow *_gdk_root = NULL;
gint _gdk_num_monitors;
GdkRectangle *_gdk_monitors = NULL;
-gint _gdk_offset_x, _gdk_offset_y;
+gint _gdk_offset_x, _gdk_offset_y;
HDC _gdk_display_hdc;
HINSTANCE _gdk_dll_hinstance;
@@ -50,9 +50,11 @@ WORD _cf_rtf;
WORD _cf_utf8_string;
GdkAtom _utf8_string;
-GdkAtom _text_uri_list;
GdkAtom _targets;
+GdkAtom _text_uri_list;
+GdkAtom _image_bmp;
+
GdkAtom _local_dnd;
GdkAtom _gdk_win32_dropfiles;
GdkAtom _gdk_ole2_dnd;
@@ -66,3 +68,6 @@ gint _gdk_max_colors = 0;
gboolean _sizemove_in_progress = FALSE;
gboolean _ignore_destroy_clipboard = FALSE;
+
+HGLOBAL _delayed_rendering_data = NULL;
+GHashTable *_format_atom_table = NULL;
diff --git a/gdk/win32/gdkmain-win32.c b/gdk/win32/gdkmain-win32.c
index d12e56fee..2584a2ada 100644
--- a/gdk/win32/gdkmain-win32.c
+++ b/gdk/win32/gdkmain-win32.c
@@ -112,9 +112,11 @@ _gdk_windowing_init (void)
_cf_utf8_string = RegisterClipboardFormat ("UTF8_STRING");
_utf8_string = gdk_atom_intern ("UTF8_STRING", FALSE);
- _text_uri_list = gdk_atom_intern ("text/uri-list", FALSE);
_targets = gdk_atom_intern ("TARGETS", FALSE);
+ _text_uri_list = gdk_atom_intern ("text/uri-list", FALSE);
+ _image_bmp = gdk_atom_intern ("image/bmp", FALSE);
+
_local_dnd = gdk_atom_intern ("LocalDndSelection", FALSE);
_gdk_win32_dropfiles = gdk_atom_intern ("DROPFILES_DND", FALSE);
_gdk_ole2_dnd = gdk_atom_intern ("OLE2_DND", FALSE);
@@ -250,7 +252,7 @@ gdk_notify_startup_complete (void)
*/
static gchar *
static_printf (const gchar *format,
- ...)
+ ...)
{
static gchar buf[10000];
gchar *msg;
@@ -922,6 +924,71 @@ _gdk_win32_key_to_string (LONG lParam)
return static_printf ("unk-%#lx", lParam);
}
+gchar *
+_gdk_win32_cf_to_string (UINT format)
+{
+ char buf[100];
+
+ switch (format)
+ {
+#define CASE(x) case CF_##x: return #x
+ CASE (BITMAP);
+ CASE (DIB);
+#ifdef CF_DIBV5
+ CASE (DIBV5);
+#endif
+ CASE (DIF);
+ CASE (DSPBITMAP);
+ CASE (DSPENHMETAFILE);
+ CASE (DSPMETAFILEPICT);
+ CASE (DSPTEXT);
+ CASE (ENHMETAFILE);
+ CASE (HDROP);
+ CASE (LOCALE);
+ CASE (METAFILEPICT);
+ CASE (OEMTEXT);
+ CASE (OWNERDISPLAY);
+ CASE (PALETTE);
+ CASE (PENDATA);
+ CASE (RIFF);
+ CASE (SYLK);
+ CASE (TEXT);
+ CASE (WAVE);
+ CASE (TIFF);
+ CASE (UNICODETEXT);
+ default:
+ if (format >= CF_GDIOBJFIRST &&
+ format <= CF_GDIOBJLAST)
+ return static_printf ("CF_GDIOBJ%d", format - CF_GDIOBJFIRST);
+ if (format >= CF_PRIVATEFIRST &&
+ format <= CF_PRIVATELAST)
+ return static_printf ("CF_PRIVATE%d", format - CF_PRIVATEFIRST);
+ if (GetClipboardFormatName (format, buf, sizeof (buf)))
+ return static_printf ("%s", buf);
+ else
+ return static_printf ("unk-%#lx", format);
+ }
+}
+
+gchar *
+_gdk_win32_data_to_string (const guchar *data,
+ int nbytes)
+{
+ GString *s = g_string_new ("");
+ int i;
+ gchar *retval;
+
+ for (i = 0; i < nbytes; i++)
+ if (data[i] >=' ' && data[i] <= '~')
+ g_string_append_printf (s, "%c ", data[i]);
+ else
+ g_string_append_printf (s, "%02X ", data[i]);
+
+ retval = static_printf ("%s", s->str);
+ g_string_free (s, TRUE);
+
+ return retval;
+}
gchar *
_gdk_win32_rect_to_string (const RECT *rect)
diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h
index 745d1b4ca..0d1ab272d 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -401,6 +401,9 @@ gchar *_gdk_win32_psendcap_to_string (DWORD pen_style);
gchar *_gdk_win32_psjoin_to_string (DWORD pen_style);
gchar *_gdk_win32_message_to_string (UINT msg);
gchar *_gdk_win32_key_to_string (LONG lParam);
+gchar *_gdk_win32_cf_to_string (UINT format);
+gchar *_gdk_win32_data_to_string (const guchar*data,
+ int nbytes);
gchar *_gdk_win32_rect_to_string (const RECT *rect);
gchar *_gdk_win32_gdkrectangle_to_string (const GdkRectangle *rect);
@@ -473,12 +476,13 @@ extern gboolean _gdk_keyboard_has_altgr;
extern WORD _cf_rtf;
extern WORD _cf_utf8_string;
-/* GdkAtoms: Targets */
+/* GdkAtoms: targets */
extern GdkAtom _utf8_string;
-extern GdkAtom _compound_text;
-extern GdkAtom _text_uri_list;
extern GdkAtom _targets;
+extern GdkAtom _text_uri_list;
+extern GdkAtom _image_bmp;
+
/* DND selections */
extern GdkAtom _local_dnd;
extern GdkAtom _gdk_win32_dropfiles;
@@ -500,6 +504,17 @@ extern gboolean _sizemove_in_progress;
/* TRUE when we are emptying the clipboard ourselves */
extern gboolean _ignore_destroy_clipboard;
+/* Mapping from registered clipboard format id (native) to
+ * corresponding GdkAtom
+ */
+extern GHashTable *_format_atom_table;
+
+/* Hold the result of a delayed rendering */
+extern HGLOBAL _delayed_rendering_data;
+
+HGLOBAL _gdk_win32_selection_convert_to_dib (HGLOBAL hdata,
+ GdkAtom target);
+
/* Initialization */
void _gdk_windowing_window_init (void);
void _gdk_root_window_size_init (void);
diff --git a/gdk/win32/gdkproperty-win32.c b/gdk/win32/gdkproperty-win32.c
index 5fb34bc5e..145271216 100644
--- a/gdk/win32/gdkproperty-win32.c
+++ b/gdk/win32/gdkproperty-win32.c
@@ -265,7 +265,7 @@ gdk_property_change (GdkWindow *window,
GDK_NOTE (DND,
(prop_name = gdk_atom_name (property),
type_name = gdk_atom_name (type),
- g_print ("gdk_property_change: %p %#x (%s) %#x (%s) %s %d*%d bytes %.10s\n",
+ g_print ("gdk_property_change: %p %#x (%s) %#x (%s) %s %d*%d bytes: %s\n",
GDK_WINDOW_HWND (window),
(guint) property, prop_name,
(guint) type, type_name,
@@ -273,201 +273,221 @@ gdk_property_change (GdkWindow *window,
(mode == GDK_PROP_MODE_PREPEND ? "PREPEND" :
(mode == GDK_PROP_MODE_APPEND ? "APPEND" :
"???"))),
- format, nelements, data),
+ format, nelements,
+ _gdk_win32_data_to_string (data, MIN (10, format*nelements/8))),
g_free (prop_name),
g_free (type_name)));
if (property == _gdk_selection_property
- && ((type == GDK_TARGET_STRING && GetACP () == 1252) ||
- type == _utf8_string)
&& format == 8
&& mode == GDK_PROP_MODE_REPLACE)
{
- if (!OpenClipboard (GDK_WINDOW_HWND (window)))
+ if ((type == GDK_TARGET_STRING && GetACP () == 1252) ||
+ type == _utf8_string)
{
- WIN32_API_FAILED ("OpenClipboard");
- return;
- }
+ if (!OpenClipboard (GDK_WINDOW_HWND (window)))
+ {
+ WIN32_API_FAILED ("OpenClipboard");
+ return;
+ }
- if (type == _utf8_string)
- {
- /* Check if only ASCII */
- for (i = 0; i < nelements; i++)
- if (data[i] >= 0200)
- break;
- }
- else /* if (type == GDK_TARGET_STRING) */
- {
- /* Check that no 0200..0240 chars present, as they
- * differ between ISO-8859-1 and CP1252.
- */
- for (i = 0; i < nelements; i++)
- if (data[i] >= 0200 && data[i] < 0240)
- break;
- }
- nchars = g_utf8_strlen (data, nelements);
+ if (type == _utf8_string)
+ {
+ /* Check if only ASCII */
+ for (i = 0; i < nelements; i++)
+ if (data[i] >= 0200)
+ break;
+ }
+ else /* if (type == GDK_TARGET_STRING) */
+ {
+ /* Check that no 0200..0240 chars present, as they
+ * differ between ISO-8859-1 and CP1252.
+ */
+ for (i = 0; i < nelements; i++)
+ if (data[i] >= 0200 && data[i] < 0240)
+ break;
+ }
+ nchars = g_utf8_strlen (data, nelements);
- if (i == nelements)
- {
- /* If UTF-8 and only ASCII, or if STRING (ISO-8859-1) and
- * system codepage is CP1252, use CF_TEXT and the data as
- * such.
- */
- method = SYSTEM_CODEPAGE;
- size = nelements;
- for (i = 0; i < nelements; i++)
- if (data[i] == '\n')
+ if (i == nelements)
+ {
+ /* If UTF-8 and only ASCII, or if STRING (ISO-8859-1)
+ * and system codepage is CP1252, use CF_TEXT and the
+ * data as such.
+ */
+ method = SYSTEM_CODEPAGE;
+ size = nelements;
+ for (i = 0; i < nelements; i++)
+ if (data[i] == '\n')
+ size++;
size++;
- size++;
- GDK_NOTE (DND, g_print ("... as text: %.40s\n", data));
- }
- else if (G_WIN32_IS_NT_BASED ())
- {
- /* On NT, use CF_UNICODETEXT if any non-system codepage char
- * present.
- */
- method = UNICODE_TEXT;
+ GDK_NOTE (DND, g_print ("... as text: %.40s\n", data));
+ }
+ else if (G_WIN32_IS_NT_BASED ())
+ {
+ /* On NT, use CF_UNICODETEXT if any non-system codepage
+ * char present.
+ */
+ method = UNICODE_TEXT;
- wcptr = g_utf8_to_utf16 (data, nelements, NULL, &wclen, NULL);
+ wcptr = g_utf8_to_utf16 (data, nelements, NULL, &wclen, NULL);
- wclen++; /* Terminating 0 */
- size = wclen * 2;
- GDK_NOTE (DND, g_print ("... as Unicode\n"));
- }
- else if (find_common_locale (data, nelements, nchars, &lcid, &buf, &size))
- {
- /* On Win9x, if all chars are in the default code page of
- * some installed locale, use CF_TEXT and CF_LOCALE.
- */
- method = SINGLE_LOCALE;
- GDK_NOTE (DND, g_print ("... as text in locale %#lx %d bytes\n",
- (gulong) lcid, size));
- }
- else
- {
- /* On Win9x, otherwise use RTF */
+ wclen++; /* Terminating 0 */
+ size = wclen * 2;
+ GDK_NOTE (DND, g_print ("... as Unicode\n"));
+ }
+ else if (find_common_locale (data, nelements, nchars, &lcid, &buf, &size))
+ {
+ /* On Win9x, if all chars are in the default code page
+ * of some installed locale, use CF_TEXT and CF_LOCALE.
+ */
+ method = SINGLE_LOCALE;
+ GDK_NOTE (DND, g_print ("... as text in locale %#lx %d bytes\n",
+ (gulong) lcid, size));
+ }
+ else
+ {
+ /* On Win9x, otherwise use RTF */
+
+ const guchar *p = data;
+
+ method = RICH_TEXT;
+ rtf = g_string_new ("{\\rtf1\\uc0 ");
- const guchar *p = data;
+ while (p < data + nelements)
+ {
+ if (*p == '{' ||
+ *p == '\\' ||
+ *p == '}')
+ {
+ rtf = g_string_append_c (rtf, '\\');
+ rtf = g_string_append_c (rtf, *p);
+ p++;
+ }
+ else if (*p < 0200 && *p >= ' ')
+ {
+ rtf = g_string_append_c (rtf, *p);
+ p++;
+ }
+ else
+ {
+ guchar *q;
+ gint n;
+
+ rtf = g_string_append (rtf, "\\uNNNNN ");
+ rtf->len -= 6; /* five digits and a space */
+ q = rtf->str + rtf->len;
+ n = g_sprintf (q, "%d ", g_utf8_get_char (p));
+ g_assert (n <= 6);
+ rtf->len += n;
+
+ p = g_utf8_next_char (p);
+ }
+ }
+ rtf = g_string_append (rtf, "}");
+ size = rtf->len + 1;
+ GDK_NOTE (DND, g_print ("... as RTF: %.40s\n", rtf->str));
+ }
+
+ if (!(hdata = GlobalAlloc (GMEM_MOVEABLE, size)))
+ {
+ WIN32_API_FAILED ("GlobalAlloc");
+ if (!CloseClipboard ())
+ WIN32_API_FAILED ("CloseClipboard");
+ if (buf != NULL)
+ g_free (buf);
+ if (rtf != NULL)
+ g_string_free (rtf, TRUE);
+ return;
+ }
- method = RICH_TEXT;
- rtf = g_string_new ("{\\rtf1\\uc0 ");
+ ucptr = GlobalLock (hdata);
- while (p < data + nelements)
+ switch (method)
{
- if (*p == '{' ||
- *p == '\\' ||
- *p == '}')
+ case SYSTEM_CODEPAGE:
+ cf = CF_TEXT;
+ for (i = 0; i < nelements; i++)
{
- rtf = g_string_append_c (rtf, '\\');
- rtf = g_string_append_c (rtf, *p);
- p++;
+ if (data[i] == '\n')
+ *ucptr++ = '\r';
+ *ucptr++ = data[i];
}
- else if (*p < 0200 && *p >= ' ')
+ *ucptr++ = '\0';
+ break;
+
+ case UNICODE_TEXT:
+ cf = CF_UNICODETEXT;
+ memmove (ucptr, wcptr, size);
+ g_free (wcptr);
+ break;
+
+ case SINGLE_LOCALE:
+ cf = CF_TEXT;
+ memmove (ucptr, buf, size);
+ g_free (buf);
+
+ /* Set the CF_LOCALE clipboard data, too */
+ if (!(hlcid = GlobalAlloc (GMEM_MOVEABLE, sizeof (LCID))))
+ WIN32_API_FAILED ("GlobalAlloc"), ok = FALSE;
+ if (ok)
{
- rtf = g_string_append_c (rtf, *p);
- p++;
+ lcidptr = GlobalLock (hlcid);
+ *lcidptr = lcid;
+ GlobalUnlock (hlcid);
+ if (!SetClipboardData (CF_LOCALE, hlcid))
+ WIN32_API_FAILED ("SetClipboardData (CF_LOCALE)"), ok = FALSE;
}
+ break;
+
+ case RICH_TEXT:
+ cf = _cf_rtf;
+ memmove (ucptr, rtf->str, size);
+ g_string_free (rtf, TRUE);
+
+ /* Set the UTF8_STRING clipboard data, too, for other
+ * GTK+ apps to use (won't bother reading RTF).
+ */
+ if (!(hutf8 = GlobalAlloc (GMEM_MOVEABLE, nelements)))
+ WIN32_API_FAILED ("GlobalAlloc");
else
{
- guchar *q;
- gint n;
-
- rtf = g_string_append (rtf, "\\uNNNNN ");
- rtf->len -= 6; /* five digits and a space */
- q = rtf->str + rtf->len;
- n = g_sprintf (q, "%d ", g_utf8_get_char (p));
- g_assert (n <= 6);
- rtf->len += n;
-
- p = g_utf8_next_char (p);
+ guchar *utf8ptr = GlobalLock (hutf8);
+ memmove (utf8ptr, data, nelements);
+ GlobalUnlock (hutf8);
+ if (!SetClipboardData (_cf_utf8_string, hutf8))
+ WIN32_API_FAILED ("SetClipboardData (UTF8_STRING)");
}
+ break;
+
+ default:
+ g_assert_not_reached ();
}
- rtf = g_string_append (rtf, "}");
- size = rtf->len + 1;
- GDK_NOTE (DND, g_print ("... as RTF: %.40s\n", rtf->str));
- }
-
- if (!(hdata = GlobalAlloc (GMEM_MOVEABLE, size)))
- {
- WIN32_API_FAILED ("GlobalAlloc");
+
+ GlobalUnlock (hdata);
+ if (ok && !SetClipboardData (cf, hdata))
+ WIN32_API_FAILED ("SetClipboardData"), ok = FALSE;
+
if (!CloseClipboard ())
WIN32_API_FAILED ("CloseClipboard");
- if (buf != NULL)
- g_free (buf);
- if (rtf != NULL)
- g_string_free (rtf, TRUE);
- return;
}
-
- ucptr = GlobalLock (hdata);
-
- switch (method)
- {
- case SYSTEM_CODEPAGE:
- cf = CF_TEXT;
- for (i = 0; i < nelements; i++)
- {
- if (data[i] == '\n')
- *ucptr++ = '\r';
- *ucptr++ = data[i];
- }
- *ucptr++ = '\0';
- break;
-
- case UNICODE_TEXT:
- cf = CF_UNICODETEXT;
- memmove (ucptr, wcptr, size);
- g_free (wcptr);
- break;
-
- case SINGLE_LOCALE:
- cf = CF_TEXT;
- memmove (ucptr, buf, size);
- g_free (buf);
-
- /* Set the CF_LOCALE clipboard data, too */
- if (!(hlcid = GlobalAlloc (GMEM_MOVEABLE, sizeof (LCID))))
- WIN32_API_FAILED ("GlobalAlloc"), ok = FALSE;
- if (ok)
- {
- lcidptr = GlobalLock (hlcid);
- *lcidptr = lcid;
- GlobalUnlock (hlcid);
- if (!SetClipboardData (CF_LOCALE, hlcid))
- WIN32_API_FAILED ("SetClipboardData (CF_LOCALE)"), ok = FALSE;
- }
- break;
-
- case RICH_TEXT:
- cf = _cf_rtf;
- memmove (ucptr, rtf->str, size);
- g_string_free (rtf, TRUE);
-
- /* Set the UTF8_STRING clipboard data, too, for other
- * GTK+ apps to use (won't bother reading RTF).
+ else
+ {
+ /* Delayed Rendering. We can't assign hdata to the clipboard
+ * here as type may be "image/png", "image/jpg", etc. In
+ * this case there's a further conversion afterwards.
*/
- if (!(hutf8 = GlobalAlloc (GMEM_MOVEABLE, nelements)))
- WIN32_API_FAILED ("GlobalAlloc");
- else
+ _delayed_rendering_data = NULL;
+ if (!(hdata = GlobalAlloc (GMEM_MOVEABLE, nelements > 0 ? nelements : 1)))
{
- guchar *utf8ptr = GlobalLock (hutf8);
- memmove (utf8ptr, data, nelements);
- GlobalUnlock (hutf8);
- if (!SetClipboardData (_cf_utf8_string, hutf8))
- WIN32_API_FAILED ("SetClipboardData (UTF8_STRING)");
+ WIN32_API_FAILED ("GlobalAlloc");
+ return;
}
- break;
-
- default:
- g_assert_not_reached ();
+ ucptr = GlobalLock (hdata);
+ memcpy (ucptr, data, nelements);
+ GlobalUnlock (hdata);
+ _delayed_rendering_data = hdata;
}
-
- GlobalUnlock (hdata);
- if (ok && !SetClipboardData (cf, hdata))
- WIN32_API_FAILED ("SetClipboardData"), ok = FALSE;
-
- if (!CloseClipboard ())
- WIN32_API_FAILED ("CloseClipboard");
}
else
g_warning ("gdk_property_change: General case not implemented");
@@ -592,13 +612,15 @@ gdk_screen_get_setting (GdkScreen *screen,
ncm.cbSize = sizeof(NONCLIENTMETRICS);
if (SystemParametersInfo (SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, FALSE))
{
- /* Pango finally uses GetDeviceCaps to scale, we use simple approximation here */
+ /* Pango finally uses GetDeviceCaps to scale, we use simple
+ * approximation here.
+ */
int nHeight = (0 > ncm.lfMenuFont.lfHeight ? -3*ncm.lfMenuFont.lfHeight/4 : 10);
if (OUT_STRING_PRECIS == ncm.lfMenuFont.lfOutPrecision)
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(%s) : ignoring bitmap font '%s'\n",
name, ncm.lfMenuFont.lfFaceName));
else if (ncm.lfMenuFont.lfFaceName && strlen(ncm.lfMenuFont.lfFaceName) > 0 &&
- /* avoid issues like those described in bug #135098 */
+ /* Avoid issues like those described in bug #135098 */
g_utf8_validate (ncm.lfMenuFont.lfFaceName, -1, NULL))
{
char* s = g_strdup_printf ("%s %d", ncm.lfMenuFont.lfFaceName, nHeight);
diff --git a/gdk/win32/gdkselection-win32.c b/gdk/win32/gdkselection-win32.c
index 31eab06c8..d5edb2d08 100644
--- a/gdk/win32/gdkselection-win32.c
+++ b/gdk/win32/gdkselection-win32.c
@@ -60,6 +60,7 @@ _gdk_win32_selection_init (void)
{
sel_prop_table = g_hash_table_new (NULL, NULL);
sel_owner_table = g_hash_table_new (NULL, NULL);
+ _format_atom_table = g_hash_table_new (NULL, NULL);
}
/* The specifications for COMPOUND_TEXT and STRING specify that C0 and
@@ -350,52 +351,55 @@ gdk_selection_convert (GdkWindow *requestor,
if (selection == GDK_SELECTION_CLIPBOARD && target == _targets)
{
- /* He wants to know what formats are on the clipboard. If there
+ gint formats_cnt, i, fmt;
+ GdkAtom *data;
+ gboolean has_bmp = FALSE;
+
+ /* He wants to know what formats are on the clipboard. If there
* is some kind of text, tell him so.
*/
if (!API_CALL (OpenClipboard, (GDK_WINDOW_HWND (requestor))))
return;
+ formats_cnt = CountClipboardFormats ();
+ data = g_new (GdkAtom, formats_cnt + 2);
+ i = 0;
+
if (IsClipboardFormatAvailable (CF_UNICODETEXT) ||
IsClipboardFormatAvailable (_cf_utf8_string) ||
IsClipboardFormatAvailable (CF_TEXT))
{
- GdkAtom *data = g_new (GdkAtom, 1);
- *data = _utf8_string;
- _gdk_selection_property_store (requestor, GDK_SELECTION_TYPE_ATOM,
- 32, (guchar *) data, 1 * sizeof (GdkAtom));
- }
- else if (IsClipboardFormatAvailable (CF_BITMAP) ||
- IsClipboardFormatAvailable (CF_DIB))
- {
- GdkAtom *data = g_new (GdkAtom, 1);
- GdkAtom atom = gdk_atom_intern ("image/bmp", FALSE);
- *data = atom;
- _gdk_selection_property_store (requestor, GDK_SELECTION_TYPE_ATOM,
- 32, (guchar *) data, 1 * sizeof (GdkAtom));
+ data[i++] = _utf8_string;
}
- else if (CountClipboardFormats() > 0)
+ if (formats_cnt > 0)
{
- /* if there is anything else in the clipboard, enum it all although we don't
- * offer special conversion services
+ /* If there is anything else in the clipboard, enum it all
+ * although we don't offer special conversion services.
*/
- int fmt = 0, i = 0;
- GdkAtom *data = g_new (GdkAtom, CountClipboardFormats());
-
- for ( ; 0 != (fmt = EnumClipboardFormats (fmt)); )
+ for (fmt = 0; 0 != (fmt = EnumClipboardFormats (fmt)); )
{
- char sFormat[80];
+ gchar sFormat[80];
- if (GetClipboardFormatName (fmt, sFormat, 80) > 0)
+ if (GetClipboardFormatName (fmt, sFormat, 80) > 0 &&
+ strcmp (sFormat, "UTF8_STRING"))
{
+ if (!has_bmp &&
+ (!strcmp (sFormat, "image/bmp") ||
+ !strcmp (sFormat, "image/x-bmp") ||
+ !strcmp (sFormat, "image/x-MS-bmp")))
+ has_bmp = TRUE;
GdkAtom atom = gdk_atom_intern (sFormat, FALSE);
- data[i] = atom;
- i++;
+ data[i++] = atom;
}
}
+ }
+ if (!has_bmp && (IsClipboardFormatAvailable (CF_BITMAP) ||
+ IsClipboardFormatAvailable (CF_DIB)))
+ data[i++] = _image_bmp;
+
+ if (i > 0)
_gdk_selection_property_store (requestor, GDK_SELECTION_TYPE_ATOM,
32, (guchar *) data, i * sizeof (GdkAtom));
- }
else
property = GDK_NONE;
@@ -542,21 +546,42 @@ gdk_selection_convert (GdkWindow *requestor,
API_CALL (CloseClipboard, ());
}
else if (selection == GDK_SELECTION_CLIPBOARD &&
- target == gdk_atom_intern ("image/bmp", TRUE))
+ target == _image_bmp)
{
+ guchar *data;
+
if (!API_CALL (OpenClipboard, (GDK_WINDOW_HWND (requestor))))
return;
- if ((hdata = GetClipboardData (CF_DIB)) != NULL)
+ if ((hdata = GetClipboardData (RegisterClipboardFormat ("image/bmp"))) != NULL)
+ {
+ /* "image/bmp" is the first choice. */
+ guchar *ptr;
+
+ if ((ptr = GlobalLock (hdata)) != NULL)
+ {
+ gint length = GlobalSize (hdata);
+
+ GDK_NOTE (DND, g_print ("...BITMAP (from \"image/bmp\": %d bytes\n",
+ length));
+
+ _gdk_selection_property_store (requestor, target, 8,
+ g_memdup (ptr, length), length);
+ GlobalUnlock (hdata);
+ }
+ }
+ else if ((hdata = GetClipboardData (CF_DIB)) != NULL)
{
+ /* If there's CF_DIB but not "image/bmp", the clipboard
+ * owner is probably a native Win32 application.
+ */
BITMAPINFOHEADER *ptr;
- guchar *data;
if ((ptr = GlobalLock (hdata)) != NULL)
{
- BITMAPFILEHEADER *hdr; /* need to add a file header so gdk-pixbuf can load it */
- gint length = GlobalSize (hdata) + sizeof(BITMAPFILEHEADER);
+ BITMAPFILEHEADER *hdr; /* Need to add a file header so gdk-pixbuf can load it */
+ gint length = GlobalSize (hdata) + sizeof (BITMAPFILEHEADER);
- GDK_NOTE (DND, g_print ("... BITMAP: %d bytes\n", length));
+ GDK_NOTE (DND, g_print ("... BITMAP (from CF_DIB): %d bytes\n", length));
data = g_try_malloc (length);
if (data)
@@ -564,16 +589,16 @@ gdk_selection_convert (GdkWindow *requestor,
hdr = (BITMAPFILEHEADER *)data;
hdr->bfType = 0x4d42; /* 0x42 = "B" 0x4d = "M" */
/* Compute the size of the entire file. */
- hdr->bfSize = (DWORD) (sizeof(BITMAPFILEHEADER)
+ hdr->bfSize = (DWORD) (sizeof (BITMAPFILEHEADER)
+ ptr->biSize + ptr->biClrUsed
- * sizeof(RGBQUAD) + ptr->biSizeImage);
+ * sizeof (RGBQUAD) + ptr->biSizeImage);
hdr->bfReserved1 = 0;
hdr->bfReserved2 = 0;
/* Compute the offset to the array of color indices. */
- hdr->bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER)
+ hdr->bfOffBits = (DWORD) sizeof (BITMAPFILEHEADER)
+ ptr->biSize + ptr->biClrUsed * sizeof (RGBQUAD);
- /* copy the data behind it */
- memcpy (data + sizeof(BITMAPFILEHEADER), ptr, length - sizeof(BITMAPFILEHEADER));
+ /* Copy the data behind it */
+ memcpy (data + sizeof (BITMAPFILEHEADER), ptr, length - sizeof (BITMAPFILEHEADER));
_gdk_selection_property_store (requestor, target, 8,
data, length);
}
@@ -591,7 +616,12 @@ gdk_selection_convert (GdkWindow *requestor,
if (!API_CALL (OpenClipboard, (GDK_WINDOW_HWND (requestor))))
return;
- /* check if its available */
+ /* Check if it's available. In fact, we can simply call
+ * GetClipboardData (RegisterClipboardFormat (targetname)), but
+ * the global custom format ID space is limited,
+ * (0xC000~0xFFFF), and we better not waste an format ID if we
+ * are just a requestor.
+ */
for ( ; 0 != (fmt = EnumClipboardFormats (fmt)); )
{
char sFormat[80];
@@ -601,7 +631,7 @@ gdk_selection_convert (GdkWindow *requestor,
{
if ((hdata = GetClipboardData (fmt)) != NULL)
{
- /* simply get it without conversion */
+ /* Simply get it without conversion */
guchar *ptr;
gint length;
@@ -673,7 +703,8 @@ gdk_selection_property_get (GdkWindow *requestor,
return 0;
}
- *data = g_malloc (prop->length);
+ *data = g_malloc (prop->length + 1);
+ (*data)[prop->length] = '\0';
if (prop->length > 0)
memmove (*data, prop->data, prop->length);
@@ -713,7 +744,6 @@ gdk_selection_send_notify_for_display (GdkDisplay *display,
GdkAtom property,
guint32 time)
{
- GdkEvent tmp_event;
gchar *sel_name, *tgt_name, *prop_name;
g_return_if_fail (display == _gdk_display);
@@ -968,3 +998,174 @@ gdk_free_compound_text (guchar *ctext)
*/
g_return_if_fail (ctext == NULL);
}
+
+void
+gdk_win32_selection_add_targets (GdkWindow *owner,
+ GdkAtom selection,
+ gint n_targets,
+ GdkAtom *targets)
+{
+ HWND hwnd;
+ const gchar *target_name;
+ guint formatid;
+ gint i;
+ GSList *convertable_formats, *format;
+ gboolean has_set_dib = FALSE, has_real_dib = FALSE;
+
+ if (selection != GDK_SELECTION_CLIPBOARD)
+ return;
+
+ if (owner != NULL)
+ {
+ if (GDK_WINDOW_DESTROYED (owner))
+ return;
+ hwnd = GDK_WINDOW_HWND (owner);
+ }
+
+ if (!API_CALL (OpenClipboard, (hwnd)))
+ return;
+
+ convertable_formats = gdk_pixbuf_get_formats ();
+ for (i = 0; i < n_targets; ++i)
+ {
+ if (targets[i] == _utf8_string)
+ continue;
+
+ target_name = gdk_atom_name (targets[i]);
+ if (!(formatid = RegisterClipboardFormat (target_name))) {
+ WIN32_API_FAILED ("RegisterClipboardFormat");
+ API_CALL (CloseClipboard, ());
+ return;
+ }
+ g_hash_table_replace (_format_atom_table, GINT_TO_POINTER (formatid), targets[i]);
+ SetClipboardData (formatid, NULL);
+
+ /* We should replace the previous image format associated with
+ * CF_DIB with "image/bmp" if we find "image/bmp", "image/x-bmp"
+ * or "image/x-MS-bmp" is available.
+ */
+ if (!has_real_dib &&
+ (!strcmp (target_name, "image/bmp") ||
+ !strcmp (target_name, "image/x-bmp") ||
+ !strcmp (target_name, "image/x-MS-bmp")))
+ {
+ g_hash_table_replace (_format_atom_table,
+ GINT_TO_POINTER (CF_DIB),
+ targets[i]);
+ if (!has_set_dib) {
+ SetClipboardData (CF_DIB, NULL);
+ has_set_dib = TRUE;
+ }
+ has_real_dib = TRUE;
+ continue;
+ }
+
+ for (format = convertable_formats; !has_set_dib && format; format = format->next)
+ {
+ gchar **mime_types =
+ gdk_pixbuf_format_get_mime_types ((GdkPixbufFormat *) format->data);
+
+ for (; *mime_types; ++mime_types)
+ {
+ if (!strcmp (target_name, *mime_types))
+ {
+ g_hash_table_replace (_format_atom_table,
+ GINT_TO_POINTER (CF_DIB),
+ targets[i]);
+ SetClipboardData (CF_DIB, NULL);
+ has_set_dib = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ g_slist_free (convertable_formats);
+
+ API_CALL (CloseClipboard, ());
+}
+
+/* Convert from types such as "image/jpg" or "image/png" to DIB using
+ * gdk-pixbuf so that image copied from GTK+ apps can be pasted in
+ * native apps like mspaint.exe
+ */
+HGLOBAL
+_gdk_win32_selection_convert_to_dib (HGLOBAL hdata,
+ GdkAtom target)
+{
+ GdkPixbufLoader *loader;
+ GdkPixbuf *pixbuf;
+ const gchar *target_name;
+ guchar *ptr;
+ gchar *bmp_buf;
+ gsize size;
+ gboolean ok;
+
+ if (!(target_name = gdk_atom_name (target)))
+ {
+ GlobalFree (hdata);
+ return NULL;
+ }
+
+ if (!strcmp (target_name, "image/bmp") ||
+ !strcmp (target_name, "image/x-bmp") ||
+ !strcmp (target_name, "image/x-MS-bmp"))
+ {
+ /* No conversion is needed, just strip the BITMAPFILEHEADER */
+ HGLOBAL hdatanew;
+
+ size = GlobalSize (hdata) - 1 - sizeof (BITMAPFILEHEADER);
+ ptr = GlobalLock (hdata);
+ memmove (ptr, ptr + sizeof (BITMAPFILEHEADER), size);
+ GlobalUnlock (hdata);
+ if (!(hdatanew = GlobalReAlloc (hdata, size, 0))) {
+ WIN32_API_FAILED ("GlobalReAlloc");
+ GlobalFree (hdata); /* the old hdata is not freed if error */
+ }
+ return hdatanew;
+ }
+
+ /* We actually provide image formats -other than- "image/bmp" etc
+ * and the requestor is either a native Win32 application or a GTK+
+ * client that requested "image/bmp".
+ */
+ if (!(loader = gdk_pixbuf_loader_new_with_mime_type (target_name, NULL)))
+ {
+ GlobalFree (hdata);
+ return NULL;
+ }
+
+ ptr = GlobalLock (hdata);
+ ok = gdk_pixbuf_loader_write (loader, ptr, GlobalSize (hdata) - 1, NULL) &&
+ gdk_pixbuf_loader_close (loader, NULL);
+
+ GlobalUnlock (hdata);
+ GlobalFree (hdata);
+ hdata = NULL;
+
+ if (ok && (pixbuf = gdk_pixbuf_loader_get_pixbuf (loader)) != NULL)
+ g_object_ref (pixbuf);
+
+ g_object_unref (loader);
+
+ if (ok && gdk_pixbuf_save_to_buffer (pixbuf, &bmp_buf, &size, "bmp", NULL, NULL))
+ {
+ size -= sizeof (BITMAPFILEHEADER);
+ if (!(hdata = GlobalAlloc (GMEM_MOVEABLE, size)))
+ {
+ WIN32_API_FAILED ("GlobalAlloc");
+ ok = FALSE;
+ }
+
+ if (ok)
+ {
+ ptr = GlobalLock (hdata);
+ memcpy (ptr, bmp_buf + sizeof (BITMAPFILEHEADER), size);
+ GlobalUnlock (hdata);
+ }
+
+ g_free (bmp_buf);
+ g_object_unref (pixbuf);
+ }
+
+ return hdata;
+}
diff --git a/gdk/win32/gdkwin32.h b/gdk/win32/gdkwin32.h
index bae4708ad..14c91baa4 100644
--- a/gdk/win32/gdkwin32.h
+++ b/gdk/win32/gdkwin32.h
@@ -79,6 +79,11 @@ void gdk_win32_hdc_release (GdkDrawable *drawable,
GdkGC *gc,
GdkGCValuesMask usage);
+void gdk_win32_selection_add_targets (GdkWindow *owner,
+ GdkAtom selection,
+ gint n_targets,
+ GdkAtom *targets);
+
G_END_DECLS
#endif /* __GDK_WIN32_H__ */
diff --git a/gtk/gtkselection.c b/gtk/gtkselection.c
index e119df308..328c5d390 100644
--- a/gtk/gtkselection.c
+++ b/gtk/gtkselection.c
@@ -64,6 +64,10 @@
#include "x11/gdkx.h"
#endif
+#ifdef GDK_WINDOWING_WIN32
+#include "win32/gdkwin32.h"
+#endif
+
#include "gtkalias.h"
#undef DEBUG_SELECTION
@@ -750,6 +754,9 @@ gtk_selection_add_target (GtkWidget *widget,
list = gtk_selection_target_list_get (widget, selection);
gtk_target_list_add (list, target, 0, info);
+#ifdef GDK_WINDOWING_WIN32
+ gdk_win32_selection_add_targets (widget->window, selection, 1, &target);
+#endif
}
/**
@@ -776,6 +783,18 @@ gtk_selection_add_targets (GtkWidget *widget,
list = gtk_selection_target_list_get (widget, selection);
gtk_target_list_add_table (list, targets, ntargets);
+
+#ifdef GDK_WINDOWING_WIN32
+ {
+ int i;
+ GdkAtom *atoms = g_new (GdkAtom, ntargets);
+
+ for (i = 0; i < ntargets; ++i)
+ atoms[i] = gdk_atom_intern (targets[i].target, FALSE);
+ gdk_win32_selection_add_targets (widget->window, selection, ntargets, atoms);
+ g_free (atoms);
+ }
+#endif
}