mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-09-20 14:00:10 +00:00
New debugging function, to log a clipboard format name symbolically.
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().
This commit is contained in:
parent
ba433af9fb
commit
0b2ac32cf5
43
ChangeLog
43
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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
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 */
|
||||
|
||||
const guchar *p = data;
|
||||
|
||||
method = RICH_TEXT;
|
||||
rtf = g_string_new ("{\\rtf1\\uc0 ");
|
||||
|
||||
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);
|
||||
}
|
||||
GDK_NOTE (DND, g_print ("... as text: %.40s\n", data));
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
ucptr = GlobalLock (hdata);
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case SYSTEM_CODEPAGE:
|
||||
cf = CF_TEXT;
|
||||
for (i = 0; i < nelements; i++)
|
||||
else if (G_WIN32_IS_NT_BASED ())
|
||||
{
|
||||
if (data[i] == '\n')
|
||||
*ucptr++ = '\r';
|
||||
*ucptr++ = data[i];
|
||||
/* 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);
|
||||
|
||||
wclen++; /* Terminating 0 */
|
||||
size = wclen * 2;
|
||||
GDK_NOTE (DND, g_print ("... as Unicode\n"));
|
||||
}
|
||||
*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)
|
||||
else if (find_common_locale (data, nelements, nchars, &lcid, &buf, &size))
|
||||
{
|
||||
lcidptr = GlobalLock (hlcid);
|
||||
*lcidptr = lcid;
|
||||
GlobalUnlock (hlcid);
|
||||
if (!SetClipboardData (CF_LOCALE, hlcid))
|
||||
WIN32_API_FAILED ("SetClipboardData (CF_LOCALE)"), ok = FALSE;
|
||||
/* 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));
|
||||
}
|
||||
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 *utf8ptr = GlobalLock (hutf8);
|
||||
memmove (utf8ptr, data, nelements);
|
||||
GlobalUnlock (hutf8);
|
||||
if (!SetClipboardData (_cf_utf8_string, hutf8))
|
||||
WIN32_API_FAILED ("SetClipboardData (UTF8_STRING)");
|
||||
/* On Win9x, otherwise use RTF */
|
||||
|
||||
const guchar *p = data;
|
||||
|
||||
method = RICH_TEXT;
|
||||
rtf = g_string_new ("{\\rtf1\\uc0 ");
|
||||
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
ucptr = GlobalLock (hdata);
|
||||
|
||||
GlobalUnlock (hdata);
|
||||
if (ok && !SetClipboardData (cf, hdata))
|
||||
WIN32_API_FAILED ("SetClipboardData"), ok = FALSE;
|
||||
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).
|
||||
*/
|
||||
if (!(hutf8 = GlobalAlloc (GMEM_MOVEABLE, nelements)))
|
||||
WIN32_API_FAILED ("GlobalAlloc");
|
||||
else
|
||||
{
|
||||
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 ();
|
||||
}
|
||||
|
||||
GlobalUnlock (hdata);
|
||||
if (ok && !SetClipboardData (cf, hdata))
|
||||
WIN32_API_FAILED ("SetClipboardData"), ok = FALSE;
|
||||
|
||||
if (!CloseClipboard ())
|
||||
WIN32_API_FAILED ("CloseClipboard");
|
||||
if (!CloseClipboard ())
|
||||
WIN32_API_FAILED ("CloseClipboard");
|
||||
}
|
||||
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.
|
||||
*/
|
||||
_delayed_rendering_data = NULL;
|
||||
if (!(hdata = GlobalAlloc (GMEM_MOVEABLE, nelements > 0 ? nelements : 1)))
|
||||
{
|
||||
WIN32_API_FAILED ("GlobalAlloc");
|
||||
return;
|
||||
}
|
||||
ucptr = GlobalLock (hdata);
|
||||
memcpy (ucptr, data, nelements);
|
||||
GlobalUnlock (hdata);
|
||||
_delayed_rendering_data = hdata;
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
@ -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));
|
||||
data[i++] = _utf8_string;
|
||||
}
|
||||
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));
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user