forked from AuroraMiddleware/gtk
gdk/win32/gdkdrawable-win32.c (gdk_win32_draw_text)
2004-07-07 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkdrawable-win32.c (gdk_win32_draw_text) * gdk/win32/gdkfont-win32.c (gdk_text_extents) * gdk/win32/gdkproperty-win32.c (find_common_locale, gdk_property_change) * gdk/win32/gdkselection-win32.c (gdk_selection_convert): Use g_utf8_to_utf16() instead of the removed _gdk_utf8_to_ucs2() (see below). * gdk/win32/gdkglobals-win32.c * gdk/win32/gdkmain-win32.c (_gdk_windowing_init) * gdk/win3/gdkprivate-win32.h: Add a variable for the TARGETS atom. Initialize it. Declare it. Drop the variable for the COMPOUND_TEXT atom. * gdk/win32/gdkim-win32.c (gdk_wcstombs): Don't return UTF-8. This function is supposed to return the string in the locale's charset and encoding. Use g_convert(). (gdk_mbstowcs): Similarily, don't take an UTF-8 string, but a string in the locale's charset. Use g_convert(). (_gdk_ucs2_to_utf8, _gdk_utf8_to_wcs, _gdk_utf8_to_ucs2): Delete. The UCS-2 functions didn't handle surrogates anyway. Use GLib's UTF-16 functions instead. Windows uses UTF-16. * gdk/win32/gdkprivate-win32.h: Remove declarations of the deleted functions mentioned above. * gdk/win32/gdkproperty-win32.c (gdk_property_change): Use CF_TEXT also if the string is of type STRING, i.e. ISO-8859-1, and the current codepage is 1252, and contains no C1 chars. Accept also UTF8_STRING. * gdk/win32/gdkselection-win32.c (_gdk_selection_property_store): Mark as static. When storing STRING data, convert to Latin-1. (#140537) (gdk_selection_owner_set_for_display): Now that STRING is always ISO-8859-1, use UTF8_STRING when sending the selection request to ourselves. (gdk_selection_convert): Handle also UTF8_STRING. (#140537, John Ehresman) (gdk_text_property_to_text_list_for_display): Make work more like X11 version. Do obey the encoding parameter. (gdk_string_to_compound_text_for_display, gdk_utf8_to_compound_text_for_display): Don't even pretend supporting COMPOUND_TEXT. (gdk_utf8_to_string_target): Convert to ISO-8859-1, like on X11. (sanitize_utf8): Zero-terminate string.
This commit is contained in:
parent
d1c69ab84e
commit
d8b2f46c18
56
ChangeLog
56
ChangeLog
@ -1,3 +1,59 @@
|
||||
2004-07-07 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* gdk/win32/gdkdrawable-win32.c (gdk_win32_draw_text)
|
||||
* gdk/win32/gdkfont-win32.c (gdk_text_extents)
|
||||
* gdk/win32/gdkproperty-win32.c (find_common_locale,
|
||||
gdk_property_change)
|
||||
* gdk/win32/gdkselection-win32.c (gdk_selection_convert): Use
|
||||
g_utf8_to_utf16() instead of the removed _gdk_utf8_to_ucs2() (see
|
||||
below).
|
||||
|
||||
* gdk/win32/gdkglobals-win32.c
|
||||
* gdk/win32/gdkmain-win32.c (_gdk_windowing_init)
|
||||
* gdk/win3/gdkprivate-win32.h: Add a variable for the TARGETS
|
||||
atom. Initialize it. Declare it. Drop the variable for the
|
||||
COMPOUND_TEXT atom.
|
||||
|
||||
* gdk/win32/gdkim-win32.c (gdk_wcstombs): Don't return UTF-8. This
|
||||
function is supposed to return the string in the locale's charset
|
||||
and encoding. Use g_convert().
|
||||
|
||||
(gdk_mbstowcs): Similarily, don't take an UTF-8 string, but a
|
||||
string in the locale's charset. Use g_convert().
|
||||
|
||||
(_gdk_ucs2_to_utf8, _gdk_utf8_to_wcs, _gdk_utf8_to_ucs2):
|
||||
Delete. The UCS-2 functions didn't handle surrogates anyway. Use
|
||||
GLib's UTF-16 functions instead. Windows uses UTF-16.
|
||||
|
||||
* gdk/win32/gdkprivate-win32.h: Remove declarations of the deleted
|
||||
functions mentioned above.
|
||||
|
||||
* gdk/win32/gdkproperty-win32.c (gdk_property_change): Use CF_TEXT
|
||||
also if the string is of type STRING, i.e. ISO-8859-1, and the
|
||||
current codepage is 1252, and contains no C1 chars. Accept
|
||||
also UTF8_STRING.
|
||||
|
||||
* gdk/win32/gdkselection-win32.c (_gdk_selection_property_store):
|
||||
Mark as static. When storing STRING data, convert to
|
||||
Latin-1. (#140537)
|
||||
(gdk_selection_owner_set_for_display): Now that STRING is always
|
||||
ISO-8859-1, use UTF8_STRING when sending the selection request
|
||||
to ourselves.
|
||||
|
||||
(gdk_selection_convert): Handle also UTF8_STRING. (#140537, John
|
||||
Ehresman)
|
||||
|
||||
(gdk_text_property_to_text_list_for_display): Make work more like
|
||||
X11 version. Do obey the encoding parameter.
|
||||
|
||||
(gdk_string_to_compound_text_for_display,
|
||||
gdk_utf8_to_compound_text_for_display): Don't even pretend
|
||||
supporting COMPOUND_TEXT.
|
||||
|
||||
(gdk_utf8_to_string_target): Convert to ISO-8859-1, like on X11.
|
||||
|
||||
(sanitize_utf8): Zero-terminate string.
|
||||
|
||||
2004-07-06 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/stock-icons/Makefile.am: Add stock_file_16.png,
|
||||
|
@ -1,3 +1,59 @@
|
||||
2004-07-07 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* gdk/win32/gdkdrawable-win32.c (gdk_win32_draw_text)
|
||||
* gdk/win32/gdkfont-win32.c (gdk_text_extents)
|
||||
* gdk/win32/gdkproperty-win32.c (find_common_locale,
|
||||
gdk_property_change)
|
||||
* gdk/win32/gdkselection-win32.c (gdk_selection_convert): Use
|
||||
g_utf8_to_utf16() instead of the removed _gdk_utf8_to_ucs2() (see
|
||||
below).
|
||||
|
||||
* gdk/win32/gdkglobals-win32.c
|
||||
* gdk/win32/gdkmain-win32.c (_gdk_windowing_init)
|
||||
* gdk/win3/gdkprivate-win32.h: Add a variable for the TARGETS
|
||||
atom. Initialize it. Declare it. Drop the variable for the
|
||||
COMPOUND_TEXT atom.
|
||||
|
||||
* gdk/win32/gdkim-win32.c (gdk_wcstombs): Don't return UTF-8. This
|
||||
function is supposed to return the string in the locale's charset
|
||||
and encoding. Use g_convert().
|
||||
|
||||
(gdk_mbstowcs): Similarily, don't take an UTF-8 string, but a
|
||||
string in the locale's charset. Use g_convert().
|
||||
|
||||
(_gdk_ucs2_to_utf8, _gdk_utf8_to_wcs, _gdk_utf8_to_ucs2):
|
||||
Delete. The UCS-2 functions didn't handle surrogates anyway. Use
|
||||
GLib's UTF-16 functions instead. Windows uses UTF-16.
|
||||
|
||||
* gdk/win32/gdkprivate-win32.h: Remove declarations of the deleted
|
||||
functions mentioned above.
|
||||
|
||||
* gdk/win32/gdkproperty-win32.c (gdk_property_change): Use CF_TEXT
|
||||
also if the string is of type STRING, i.e. ISO-8859-1, and the
|
||||
current codepage is 1252, and contains no C1 chars. Accept
|
||||
also UTF8_STRING.
|
||||
|
||||
* gdk/win32/gdkselection-win32.c (_gdk_selection_property_store):
|
||||
Mark as static. When storing STRING data, convert to
|
||||
Latin-1. (#140537)
|
||||
(gdk_selection_owner_set_for_display): Now that STRING is always
|
||||
ISO-8859-1, use UTF8_STRING when sending the selection request
|
||||
to ourselves.
|
||||
|
||||
(gdk_selection_convert): Handle also UTF8_STRING. (#140537, John
|
||||
Ehresman)
|
||||
|
||||
(gdk_text_property_to_text_list_for_display): Make work more like
|
||||
X11 version. Do obey the encoding parameter.
|
||||
|
||||
(gdk_string_to_compound_text_for_display,
|
||||
gdk_utf8_to_compound_text_for_display): Don't even pretend
|
||||
supporting COMPOUND_TEXT.
|
||||
|
||||
(gdk_utf8_to_string_target): Convert to ISO-8859-1, like on X11.
|
||||
|
||||
(sanitize_utf8): Zero-terminate string.
|
||||
|
||||
2004-07-06 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/stock-icons/Makefile.am: Add stock_file_16.png,
|
||||
|
@ -1,3 +1,59 @@
|
||||
2004-07-07 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* gdk/win32/gdkdrawable-win32.c (gdk_win32_draw_text)
|
||||
* gdk/win32/gdkfont-win32.c (gdk_text_extents)
|
||||
* gdk/win32/gdkproperty-win32.c (find_common_locale,
|
||||
gdk_property_change)
|
||||
* gdk/win32/gdkselection-win32.c (gdk_selection_convert): Use
|
||||
g_utf8_to_utf16() instead of the removed _gdk_utf8_to_ucs2() (see
|
||||
below).
|
||||
|
||||
* gdk/win32/gdkglobals-win32.c
|
||||
* gdk/win32/gdkmain-win32.c (_gdk_windowing_init)
|
||||
* gdk/win3/gdkprivate-win32.h: Add a variable for the TARGETS
|
||||
atom. Initialize it. Declare it. Drop the variable for the
|
||||
COMPOUND_TEXT atom.
|
||||
|
||||
* gdk/win32/gdkim-win32.c (gdk_wcstombs): Don't return UTF-8. This
|
||||
function is supposed to return the string in the locale's charset
|
||||
and encoding. Use g_convert().
|
||||
|
||||
(gdk_mbstowcs): Similarily, don't take an UTF-8 string, but a
|
||||
string in the locale's charset. Use g_convert().
|
||||
|
||||
(_gdk_ucs2_to_utf8, _gdk_utf8_to_wcs, _gdk_utf8_to_ucs2):
|
||||
Delete. The UCS-2 functions didn't handle surrogates anyway. Use
|
||||
GLib's UTF-16 functions instead. Windows uses UTF-16.
|
||||
|
||||
* gdk/win32/gdkprivate-win32.h: Remove declarations of the deleted
|
||||
functions mentioned above.
|
||||
|
||||
* gdk/win32/gdkproperty-win32.c (gdk_property_change): Use CF_TEXT
|
||||
also if the string is of type STRING, i.e. ISO-8859-1, and the
|
||||
current codepage is 1252, and contains no C1 chars. Accept
|
||||
also UTF8_STRING.
|
||||
|
||||
* gdk/win32/gdkselection-win32.c (_gdk_selection_property_store):
|
||||
Mark as static. When storing STRING data, convert to
|
||||
Latin-1. (#140537)
|
||||
(gdk_selection_owner_set_for_display): Now that STRING is always
|
||||
ISO-8859-1, use UTF8_STRING when sending the selection request
|
||||
to ourselves.
|
||||
|
||||
(gdk_selection_convert): Handle also UTF8_STRING. (#140537, John
|
||||
Ehresman)
|
||||
|
||||
(gdk_text_property_to_text_list_for_display): Make work more like
|
||||
X11 version. Do obey the encoding parameter.
|
||||
|
||||
(gdk_string_to_compound_text_for_display,
|
||||
gdk_utf8_to_compound_text_for_display): Don't even pretend
|
||||
supporting COMPOUND_TEXT.
|
||||
|
||||
(gdk_utf8_to_string_target): Convert to ISO-8859-1, like on X11.
|
||||
|
||||
(sanitize_utf8): Zero-terminate string.
|
||||
|
||||
2004-07-06 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/stock-icons/Makefile.am: Add stock_file_16.png,
|
||||
|
@ -1,3 +1,59 @@
|
||||
2004-07-07 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* gdk/win32/gdkdrawable-win32.c (gdk_win32_draw_text)
|
||||
* gdk/win32/gdkfont-win32.c (gdk_text_extents)
|
||||
* gdk/win32/gdkproperty-win32.c (find_common_locale,
|
||||
gdk_property_change)
|
||||
* gdk/win32/gdkselection-win32.c (gdk_selection_convert): Use
|
||||
g_utf8_to_utf16() instead of the removed _gdk_utf8_to_ucs2() (see
|
||||
below).
|
||||
|
||||
* gdk/win32/gdkglobals-win32.c
|
||||
* gdk/win32/gdkmain-win32.c (_gdk_windowing_init)
|
||||
* gdk/win3/gdkprivate-win32.h: Add a variable for the TARGETS
|
||||
atom. Initialize it. Declare it. Drop the variable for the
|
||||
COMPOUND_TEXT atom.
|
||||
|
||||
* gdk/win32/gdkim-win32.c (gdk_wcstombs): Don't return UTF-8. This
|
||||
function is supposed to return the string in the locale's charset
|
||||
and encoding. Use g_convert().
|
||||
|
||||
(gdk_mbstowcs): Similarily, don't take an UTF-8 string, but a
|
||||
string in the locale's charset. Use g_convert().
|
||||
|
||||
(_gdk_ucs2_to_utf8, _gdk_utf8_to_wcs, _gdk_utf8_to_ucs2):
|
||||
Delete. The UCS-2 functions didn't handle surrogates anyway. Use
|
||||
GLib's UTF-16 functions instead. Windows uses UTF-16.
|
||||
|
||||
* gdk/win32/gdkprivate-win32.h: Remove declarations of the deleted
|
||||
functions mentioned above.
|
||||
|
||||
* gdk/win32/gdkproperty-win32.c (gdk_property_change): Use CF_TEXT
|
||||
also if the string is of type STRING, i.e. ISO-8859-1, and the
|
||||
current codepage is 1252, and contains no C1 chars. Accept
|
||||
also UTF8_STRING.
|
||||
|
||||
* gdk/win32/gdkselection-win32.c (_gdk_selection_property_store):
|
||||
Mark as static. When storing STRING data, convert to
|
||||
Latin-1. (#140537)
|
||||
(gdk_selection_owner_set_for_display): Now that STRING is always
|
||||
ISO-8859-1, use UTF8_STRING when sending the selection request
|
||||
to ourselves.
|
||||
|
||||
(gdk_selection_convert): Handle also UTF8_STRING. (#140537, John
|
||||
Ehresman)
|
||||
|
||||
(gdk_text_property_to_text_list_for_display): Make work more like
|
||||
X11 version. Do obey the encoding parameter.
|
||||
|
||||
(gdk_string_to_compound_text_for_display,
|
||||
gdk_utf8_to_compound_text_for_display): Don't even pretend
|
||||
supporting COMPOUND_TEXT.
|
||||
|
||||
(gdk_utf8_to_string_target): Convert to ISO-8859-1, like on X11.
|
||||
|
||||
(sanitize_utf8): Zero-terminate string.
|
||||
|
||||
2004-07-06 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/stock-icons/Makefile.am: Add stock_file_16.png,
|
||||
|
@ -1032,7 +1032,7 @@ gdk_win32_draw_text (GdkDrawable *drawable,
|
||||
{
|
||||
const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_FONT;
|
||||
wchar_t *wcstr, wc;
|
||||
gint wlen;
|
||||
glong wlen;
|
||||
gdk_draw_text_arg arg;
|
||||
|
||||
if (text_length == 0)
|
||||
@ -1058,15 +1058,11 @@ gdk_win32_draw_text (GdkDrawable *drawable,
|
||||
}
|
||||
else
|
||||
{
|
||||
wcstr = g_new (wchar_t, text_length);
|
||||
if ((wlen = _gdk_utf8_to_ucs2 (wcstr, text, text_length, text_length)) == -1)
|
||||
g_warning ("gdk_win32_draw_text: _gdk_utf8_to_ucs2 failed");
|
||||
else
|
||||
_gdk_wchar_text_handle (font, wcstr, wlen, gdk_draw_text_handler, &arg);
|
||||
wcstr = g_utf8_to_utf16 (text, text_length, NULL, &wlen, NULL);
|
||||
_gdk_wchar_text_handle (font, wcstr, wlen, gdk_draw_text_handler, &arg);
|
||||
g_free (wcstr);
|
||||
}
|
||||
|
||||
|
||||
gdk_win32_hdc_release (drawable, gc, mask);
|
||||
}
|
||||
|
||||
|
@ -1592,8 +1592,8 @@ gdk_text_extents (GdkFont *font,
|
||||
gint *descent)
|
||||
{
|
||||
gdk_text_size_arg arg;
|
||||
gint wlen;
|
||||
wchar_t *wcstr;
|
||||
glong wlen;
|
||||
wchar_t *wcstr, wc;
|
||||
|
||||
g_return_if_fail (font != NULL);
|
||||
g_return_if_fail (text != NULL);
|
||||
@ -1617,22 +1617,18 @@ gdk_text_extents (GdkFont *font,
|
||||
|
||||
arg.total.cx = arg.total.cy = 0;
|
||||
|
||||
wcstr = g_new (wchar_t, text_length);
|
||||
if (text_length == 1)
|
||||
{
|
||||
wcstr[0] = (guchar) text[0];
|
||||
_gdk_wchar_text_handle (font, wcstr, 1, gdk_text_size_handler, &arg);
|
||||
wc = (guchar) text[0];
|
||||
_gdk_wchar_text_handle (font, &wc, 1, gdk_text_size_handler, &arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((wlen = _gdk_utf8_to_ucs2 (wcstr, text, text_length, text_length)) == -1)
|
||||
g_warning ("gdk_text_extents: _gdk_utf8_to_ucs2 failed");
|
||||
else
|
||||
_gdk_wchar_text_handle (font, wcstr, wlen, gdk_text_size_handler, &arg);
|
||||
wcstr = g_utf8_to_utf16 (text, text_length, NULL, &wlen, NULL);
|
||||
_gdk_wchar_text_handle (font, wcstr, wlen, gdk_text_size_handler, &arg);
|
||||
g_free (wcstr);
|
||||
}
|
||||
|
||||
g_free (wcstr);
|
||||
|
||||
/* XXX This is quite bogus */
|
||||
if (lbearing)
|
||||
*lbearing = 0;
|
||||
|
@ -51,8 +51,8 @@ WORD _cf_rtf;
|
||||
WORD _cf_utf8_string;
|
||||
|
||||
GdkAtom _utf8_string;
|
||||
GdkAtom _compound_text;
|
||||
GdkAtom _text_uri_list;
|
||||
GdkAtom _targets;
|
||||
|
||||
GdkAtom _local_dnd;
|
||||
GdkAtom _gdk_win32_dropfiles;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (C) 1998-2002 Tor Lillqvist
|
||||
* Copyright (C) 1998-2004 Tor Lillqvist
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -58,321 +58,35 @@ gdk_set_locale (void)
|
||||
return g_win32_getlocale ();
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_wcstombs
|
||||
*
|
||||
* Returns a multi-byte string converted from the specified array
|
||||
* of wide characters. The string is newly allocated. The array of
|
||||
* wide characters must be null-terminated. If the conversion is
|
||||
* failed, it returns NULL.
|
||||
*
|
||||
* On Win32, we always use UTF-8.
|
||||
*/
|
||||
gchar *
|
||||
gdk_wcstombs (const GdkWChar *src)
|
||||
{
|
||||
gint len;
|
||||
const GdkWChar *wcp;
|
||||
guchar *mbstr, *bp;
|
||||
gchar *utf8;
|
||||
gchar *retval;
|
||||
const gchar *charset;
|
||||
|
||||
wcp = src;
|
||||
len = 0;
|
||||
while (*wcp)
|
||||
{
|
||||
const GdkWChar c = *wcp++;
|
||||
|
||||
if (c < 0x80)
|
||||
len += 1;
|
||||
else if (c < 0x800)
|
||||
len += 2;
|
||||
else if (c < 0x10000)
|
||||
len += 3;
|
||||
else if (c < 0x200000)
|
||||
len += 4;
|
||||
else if (c < 0x4000000)
|
||||
len += 5;
|
||||
else
|
||||
len += 6;
|
||||
}
|
||||
|
||||
mbstr = g_malloc (len + 1);
|
||||
|
||||
wcp = src;
|
||||
bp = mbstr;
|
||||
while (*wcp)
|
||||
{
|
||||
int first;
|
||||
GdkWChar c = *wcp++;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
first = 0;
|
||||
len = 1;
|
||||
}
|
||||
else if (c < 0x800)
|
||||
{
|
||||
first = 0xc0;
|
||||
len = 2;
|
||||
}
|
||||
else if (c < 0x10000)
|
||||
{
|
||||
first = 0xe0;
|
||||
len = 3;
|
||||
}
|
||||
else if (c < 0x200000)
|
||||
{
|
||||
first = 0xf0;
|
||||
len = 4;
|
||||
}
|
||||
else if (c < 0x4000000)
|
||||
{
|
||||
first = 0xf8;
|
||||
len = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = 0xfc;
|
||||
len = 6;
|
||||
}
|
||||
|
||||
/* Woo-hoo! */
|
||||
switch (len)
|
||||
{
|
||||
case 6: bp[5] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 5: bp[4] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 4: bp[3] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 1: bp[0] = c | first;
|
||||
}
|
||||
|
||||
bp += len;
|
||||
}
|
||||
*bp = 0;
|
||||
return mbstr;
|
||||
g_get_charset (&charset);
|
||||
return g_convert (src, -1, charset, "UCS-4LE", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* A vesion that converts from wchar_t strings to UTF-8 */
|
||||
|
||||
gchar *
|
||||
_gdk_ucs2_to_utf8 (const wchar_t *src,
|
||||
gint src_len)
|
||||
{
|
||||
gint len;
|
||||
const wchar_t *wcp;
|
||||
guchar *mbstr, *bp;
|
||||
|
||||
wcp = src;
|
||||
len = 0;
|
||||
while (wcp < src + src_len)
|
||||
{
|
||||
const wchar_t c = *wcp++;
|
||||
|
||||
if (c < 0x80)
|
||||
len += 1;
|
||||
else if (c < 0x800)
|
||||
len += 2;
|
||||
else
|
||||
len += 3;
|
||||
}
|
||||
|
||||
mbstr = g_malloc (len + 1);
|
||||
|
||||
wcp = src;
|
||||
bp = mbstr;
|
||||
while (wcp < src + src_len)
|
||||
{
|
||||
int first;
|
||||
wchar_t c = *wcp++;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
first = 0;
|
||||
len = 1;
|
||||
}
|
||||
else if (c < 0x800)
|
||||
{
|
||||
first = 0xc0;
|
||||
len = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = 0xe0;
|
||||
len = 3;
|
||||
}
|
||||
|
||||
/* Woo-hoo! */
|
||||
switch (len)
|
||||
{
|
||||
case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
|
||||
case 1: bp[0] = c | first;
|
||||
}
|
||||
|
||||
bp += len;
|
||||
}
|
||||
*bp = 0;
|
||||
|
||||
return mbstr;
|
||||
}
|
||||
|
||||
/* Convert from UTF-8 to GdkWChar */
|
||||
|
||||
gint
|
||||
_gdk_utf8_to_wcs (GdkWChar *dest,
|
||||
const gchar *src,
|
||||
gint src_len,
|
||||
gint dest_max)
|
||||
{
|
||||
guchar *cp, *end;
|
||||
gint n;
|
||||
|
||||
cp = (guchar *) src;
|
||||
end = cp + src_len;
|
||||
n = 0;
|
||||
while (cp != end && dest != dest + dest_max)
|
||||
{
|
||||
gint i, mask = 0, len;
|
||||
guchar c = *cp;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
len = 1;
|
||||
mask = 0x7f;
|
||||
}
|
||||
else if ((c & 0xe0) == 0xc0)
|
||||
{
|
||||
len = 2;
|
||||
mask = 0x1f;
|
||||
}
|
||||
else if ((c & 0xf0) == 0xe0)
|
||||
{
|
||||
len = 3;
|
||||
mask = 0x0f;
|
||||
}
|
||||
else if ((c & 0xf8) == 0xf0)
|
||||
{
|
||||
len = 4;
|
||||
mask = 0x07;
|
||||
}
|
||||
else if ((c & 0xfc) == 0xf8)
|
||||
{
|
||||
len = 5;
|
||||
mask = 0x03;
|
||||
}
|
||||
else if ((c & 0xfc) == 0xfc)
|
||||
{
|
||||
len = 6;
|
||||
mask = 0x01;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
if (cp + len > end)
|
||||
return -1;
|
||||
|
||||
*dest = (cp[0] & mask);
|
||||
for (i = 1; i < len; i++)
|
||||
{
|
||||
if ((cp[i] & 0xc0) != 0x80)
|
||||
return -1;
|
||||
*dest <<= 6;
|
||||
*dest |= (cp[i] & 0x3f);
|
||||
}
|
||||
if (*dest == -1)
|
||||
return -1;
|
||||
|
||||
cp += len;
|
||||
dest++;
|
||||
n++;
|
||||
}
|
||||
if (cp != end)
|
||||
return -1;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_mbstowcs
|
||||
*
|
||||
* Converts the specified string into GDK wide characters, and,
|
||||
* returns the number of wide characters written. The string 'src'
|
||||
* must be null-terminated. If the conversion is failed, it returns
|
||||
* -1.
|
||||
*
|
||||
* On Win32, the string is assumed to be in UTF-8. Also note that
|
||||
* GdkWChar is 32 bits, while wchar_t, and the wide characters the
|
||||
* Windows API uses, are 16 bits!
|
||||
*/
|
||||
|
||||
gint
|
||||
gdk_mbstowcs (GdkWChar *dest,
|
||||
const gchar *src,
|
||||
gint dest_max)
|
||||
{
|
||||
return _gdk_utf8_to_wcs (dest, src, strlen (src), dest_max);
|
||||
}
|
||||
|
||||
|
||||
/* A version that converts to a wchar_t string */
|
||||
|
||||
gint
|
||||
_gdk_utf8_to_ucs2 (wchar_t *dest,
|
||||
const gchar *src,
|
||||
gint src_len,
|
||||
gint dest_max)
|
||||
{
|
||||
wchar_t *wcp;
|
||||
guchar *cp, *end;
|
||||
gint n;
|
||||
|
||||
wcp = dest;
|
||||
cp = (guchar *) src;
|
||||
end = cp + src_len;
|
||||
n = 0;
|
||||
while (cp != end && wcp != dest + dest_max)
|
||||
{
|
||||
gint i, mask = 0, len;
|
||||
guchar c = *cp;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
len = 1;
|
||||
mask = 0x7f;
|
||||
}
|
||||
else if ((c & 0xe0) == 0xc0)
|
||||
{
|
||||
len = 2;
|
||||
mask = 0x1f;
|
||||
}
|
||||
else if ((c & 0xf0) == 0xe0)
|
||||
{
|
||||
len = 3;
|
||||
mask = 0x0f;
|
||||
}
|
||||
else /* Other lengths are not possible with 16-bit wchar_t! */
|
||||
return -1;
|
||||
|
||||
if (cp + len > end)
|
||||
return -1;
|
||||
|
||||
*wcp = (cp[0] & mask);
|
||||
for (i = 1; i < len; i++)
|
||||
{
|
||||
if ((cp[i] & 0xc0) != 0x80)
|
||||
return -1;
|
||||
*wcp <<= 6;
|
||||
*wcp |= (cp[i] & 0x3f);
|
||||
}
|
||||
if (*wcp == 0xFFFF)
|
||||
return -1;
|
||||
|
||||
cp += len;
|
||||
wcp++;
|
||||
n++;
|
||||
}
|
||||
if (cp != end)
|
||||
return -1;
|
||||
|
||||
return n;
|
||||
gint retval;
|
||||
gsize nwritten;
|
||||
gint n_ucs4;
|
||||
gunichar *ucs4;
|
||||
const gchar *charset;
|
||||
|
||||
g_get_charset (&charset);
|
||||
ucs4 = g_convert (src, -1, "UCS-4LE", charset, NULL, &nwritten, NULL);
|
||||
n_ucs4 = nwritten * sizeof (GdkWChar);
|
||||
|
||||
retval = MIN (dest_max, n_ucs4);
|
||||
memmove (dest, ucs4, retval * sizeof (GdkWChar));
|
||||
g_free (ucs4);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -115,8 +115,8 @@ _gdk_windowing_init (gint *argc,
|
||||
_cf_utf8_string = RegisterClipboardFormat ("UTF8_STRING");
|
||||
|
||||
_utf8_string = gdk_atom_intern ("UTF8_STRING", FALSE);
|
||||
_compound_text = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
|
||||
_text_uri_list = gdk_atom_intern ("text/uri-list", FALSE);
|
||||
_targets = gdk_atom_intern ("TARGETS", FALSE);
|
||||
|
||||
_local_dnd = gdk_atom_intern ("LocalDndSelection", FALSE);
|
||||
_gdk_win32_dropfiles = gdk_atom_intern ("DROPFILES_DND", FALSE);
|
||||
|
@ -363,24 +363,10 @@ void _gdk_win32_adjust_client_rect (GdkWindow *window,
|
||||
void _gdk_win32_get_adjusted_client_rect (GdkWindow *window,
|
||||
RECT *RECT);
|
||||
|
||||
void _gdk_selection_property_store (GdkWindow *owner,
|
||||
GdkAtom type,
|
||||
gint format,
|
||||
guchar *data,
|
||||
gint length);
|
||||
|
||||
void _gdk_selection_property_delete (GdkWindow *);
|
||||
|
||||
void _gdk_dropfiles_store (gchar *data);
|
||||
|
||||
gint _gdk_utf8_to_ucs2 (wchar_t *dest,
|
||||
const gchar *src,
|
||||
gint src_len,
|
||||
gint dest_max);
|
||||
|
||||
gchar *_gdk_ucs2_to_utf8 (const wchar_t *src,
|
||||
gint src_len);
|
||||
|
||||
void _gdk_wchar_text_handle (GdkFont *font,
|
||||
const wchar_t *wcstr,
|
||||
int wclen,
|
||||
@ -491,6 +477,7 @@ extern WORD _cf_utf8_string;
|
||||
extern GdkAtom _utf8_string;
|
||||
extern GdkAtom _compound_text;
|
||||
extern GdkAtom _text_uri_list;
|
||||
extern GdkAtom _targets;
|
||||
|
||||
/* DND selections */
|
||||
extern GdkAtom _local_dnd;
|
||||
|
@ -198,12 +198,10 @@ find_common_locale (const guchar *data,
|
||||
* bytes for each Unicode char should be enough, Windows code pages
|
||||
* are either single- or double-byte.
|
||||
*/
|
||||
*bufp = g_malloc ((nchars+1) * 2);
|
||||
wcs = g_new (wchar_t, nchars+1);
|
||||
*bufp = g_malloc ((nchars+1)*2);
|
||||
|
||||
/* Convert to Windows wide chars into temp buf */
|
||||
_gdk_utf8_to_ucs2 (wcs, data, nelements, nchars);
|
||||
wcs[nchars] = 0;
|
||||
wcs = g_utf8_to_utf16 (data, nelements, NULL, NULL, NULL);
|
||||
|
||||
/* For each code page that is the default for an installed locale: */
|
||||
for (i = 0; i < G_N_ELEMENTS (locales); i++)
|
||||
@ -254,7 +252,8 @@ gdk_property_change (GdkWindow *window,
|
||||
gchar *prop_name, *type_name;
|
||||
guchar *ucptr, *buf = NULL;
|
||||
wchar_t *wcptr;
|
||||
enum { PLAIN_ASCII, UNICODE_TEXT, SINGLE_LOCALE, RICH_TEXT } method;
|
||||
glong wclen;
|
||||
enum { SYSTEM_CODEPAGE, UNICODE_TEXT, SINGLE_LOCALE, RICH_TEXT } method;
|
||||
gboolean ok = TRUE;
|
||||
|
||||
g_return_if_fail (window != NULL);
|
||||
@ -279,7 +278,8 @@ gdk_property_change (GdkWindow *window,
|
||||
g_free (type_name)));
|
||||
|
||||
if (property == _gdk_selection_property
|
||||
&& type == GDK_TARGET_STRING
|
||||
&& ((type == GDK_TARGET_STRING && GetACP () == 1252) ||
|
||||
type == _utf8_string)
|
||||
&& format == 8
|
||||
&& mode == GDK_PROP_MODE_REPLACE)
|
||||
{
|
||||
@ -289,22 +289,31 @@ gdk_property_change (GdkWindow *window,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if only ASCII */
|
||||
for (i = 0; i < nelements; i++)
|
||||
if (data[i] >= 0200)
|
||||
break;
|
||||
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)
|
||||
nchars = nelements;
|
||||
else
|
||||
nchars = g_utf8_strlen (data, nelements);
|
||||
|
||||
GDK_NOTE (DND, g_print ("...nchars:%d\n", nchars));
|
||||
|
||||
if (i == nelements)
|
||||
{
|
||||
/* If only ASCII, use CF_TEXT and the data as such. */
|
||||
method = PLAIN_ASCII;
|
||||
/* 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')
|
||||
@ -314,9 +323,15 @@ gdk_property_change (GdkWindow *window,
|
||||
}
|
||||
else if (IS_WIN_NT ())
|
||||
{
|
||||
/* On NT, use CF_UNICODETEXT if any non-ASCII char present */
|
||||
/* On NT, use CF_UNICODETEXT if any non-system codepage char
|
||||
* present.
|
||||
*/
|
||||
method = UNICODE_TEXT;
|
||||
size = (nchars + 1) * 2;
|
||||
|
||||
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))
|
||||
@ -347,7 +362,7 @@ gdk_property_change (GdkWindow *window,
|
||||
rtf = g_string_append_c (rtf, *p);
|
||||
p++;
|
||||
}
|
||||
else if (*p < 0200)
|
||||
else if (*p < 0200 && *p >= ' ')
|
||||
{
|
||||
rtf = g_string_append_c (rtf, *p);
|
||||
p++;
|
||||
@ -388,7 +403,7 @@ gdk_property_change (GdkWindow *window,
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case PLAIN_ASCII:
|
||||
case SYSTEM_CODEPAGE:
|
||||
cf = CF_TEXT;
|
||||
for (i = 0; i < nelements; i++)
|
||||
{
|
||||
@ -401,10 +416,8 @@ gdk_property_change (GdkWindow *window,
|
||||
|
||||
case UNICODE_TEXT:
|
||||
cf = CF_UNICODETEXT;
|
||||
wcptr = (wchar_t *) ucptr;
|
||||
if (_gdk_utf8_to_ucs2 (wcptr, data, nelements, nchars) == -1)
|
||||
g_warning ("_gdk_utf8_to_ucs2() failed");
|
||||
wcptr[nchars] = 0;
|
||||
memmove (ucptr, wcptr, size);
|
||||
g_free (wcptr);
|
||||
break;
|
||||
|
||||
case SINGLE_LOCALE:
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
typedef struct {
|
||||
guchar *data;
|
||||
gint length;
|
||||
gsize length;
|
||||
gint format;
|
||||
GdkAtom type;
|
||||
} GdkSelProp;
|
||||
@ -62,7 +62,73 @@ _gdk_win32_selection_init (void)
|
||||
sel_owner_table = g_hash_table_new (NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
/* The specifications for COMPOUND_TEXT and STRING specify that C0 and
|
||||
* C1 are not allowed except for \n and \t, however the X conversions
|
||||
* routines for COMPOUND_TEXT only enforce this in one direction,
|
||||
* causing cut-and-paste of \r and \r\n separated text to fail.
|
||||
* This routine strips out all non-allowed C0 and C1 characters
|
||||
* from the input string and also canonicalizes \r, and \r\n to \n
|
||||
*/
|
||||
static gchar *
|
||||
sanitize_utf8 (const gchar *src,
|
||||
gint length)
|
||||
{
|
||||
GString *result = g_string_sized_new (length + 1);
|
||||
const gchar *p = src;
|
||||
const gchar *endp = src + length;
|
||||
|
||||
while (p < endp)
|
||||
{
|
||||
if (*p == '\r')
|
||||
{
|
||||
p++;
|
||||
if (*p == '\n')
|
||||
p++;
|
||||
|
||||
g_string_append_c (result, '\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
gunichar ch = g_utf8_get_char (p);
|
||||
char buf[7];
|
||||
gint buflen;
|
||||
|
||||
if (!((ch < 0x20 && ch != '\t' && ch != '\n') || (ch >= 0x7f && ch < 0xa0)))
|
||||
{
|
||||
buflen = g_unichar_to_utf8 (ch, buf);
|
||||
g_string_append_len (result, buf, buflen);
|
||||
}
|
||||
|
||||
p = g_utf8_next_char (p);
|
||||
}
|
||||
}
|
||||
g_string_append_c (result, '\0');
|
||||
|
||||
return g_string_free (result, FALSE);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
_gdk_utf8_to_string_target_internal (const gchar *str,
|
||||
gint length)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
gchar *tmp_str = sanitize_utf8 (str, length);
|
||||
gchar *result = g_convert_with_fallback (tmp_str, -1,
|
||||
"ISO-8859-1", "UTF-8",
|
||||
NULL, NULL, NULL, &error);
|
||||
if (!result)
|
||||
{
|
||||
g_warning ("Error converting from UTF-8 to STRING: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_free (tmp_str);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_selection_property_store (GdkWindow *owner,
|
||||
GdkAtom type,
|
||||
gint format,
|
||||
@ -78,8 +144,27 @@ _gdk_selection_property_store (GdkWindow *owner,
|
||||
g_hash_table_remove (sel_prop_table, GDK_WINDOW_HWND (owner));
|
||||
}
|
||||
prop = g_new (GdkSelProp, 1);
|
||||
prop->data = data;
|
||||
prop->length = length;
|
||||
|
||||
if (type == GDK_TARGET_STRING)
|
||||
{
|
||||
/* We know that data is UTF-8 */
|
||||
prop->data = _gdk_utf8_to_string_target_internal (data, length);
|
||||
g_free (data);
|
||||
|
||||
if (!prop->data)
|
||||
{
|
||||
g_free (prop);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
prop->length = strlen (prop->data + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
prop->data = data;
|
||||
prop->length = length;
|
||||
}
|
||||
prop->format = format;
|
||||
prop->type = type;
|
||||
g_hash_table_insert (sel_prop_table, GDK_WINDOW_HWND (owner), prop);
|
||||
@ -120,7 +205,8 @@ gdk_selection_owner_set_for_display (GdkDisplay *display,
|
||||
GdkEvent tmp_event;
|
||||
gchar *sel_name;
|
||||
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), FALSE);
|
||||
g_return_val_if_fail (display == _gdk_display, FALSE);
|
||||
g_return_val_if_fail (selection != GDK_NONE, FALSE);
|
||||
|
||||
GDK_NOTE (DND,
|
||||
(sel_name = gdk_atom_name (selection),
|
||||
@ -176,7 +262,7 @@ gdk_selection_owner_set_for_display (GdkDisplay *display,
|
||||
tmp_event.selection.window = owner;
|
||||
tmp_event.selection.send_event = FALSE;
|
||||
tmp_event.selection.selection = selection;
|
||||
tmp_event.selection.target = GDK_TARGET_STRING;
|
||||
tmp_event.selection.target = _utf8_string;
|
||||
tmp_event.selection.property = _gdk_selection_property;
|
||||
tmp_event.selection.requestor = (guint32) hwnd;
|
||||
tmp_event.selection.time = time;
|
||||
@ -194,12 +280,13 @@ gdk_selection_owner_get_for_display (GdkDisplay *display,
|
||||
GdkWindow *window;
|
||||
gchar *sel_name;
|
||||
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), NULL);
|
||||
g_return_val_if_fail (display == _gdk_display, NULL);
|
||||
g_return_val_if_fail (selection != GDK_NONE, NULL);
|
||||
|
||||
/* Return NULL for CLIPBOARD, because otherwise cut&paste
|
||||
* inside the same application doesn't work. We must pretend to gtk
|
||||
* that we don't have the selection, so that we always fetch it from
|
||||
* the Windows clipboard. See also comments in
|
||||
/* Return NULL for CLIPBOARD, because otherwise cut&paste inside the
|
||||
* same application doesn't work. We must pretend to gtk that we
|
||||
* don't have the selection, so that we always fetch it from the
|
||||
* Windows clipboard. See also comments in
|
||||
* gdk_selection_send_notify().
|
||||
*/
|
||||
if (selection == GDK_SELECTION_CLIPBOARD)
|
||||
@ -247,8 +334,11 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
HGLOBAL hdata;
|
||||
GdkAtom property = _gdk_selection_property;
|
||||
gchar *sel_name, *tgt_name;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (selection != GDK_NONE);
|
||||
g_return_if_fail (requestor != NULL);
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (requestor))
|
||||
return;
|
||||
|
||||
@ -262,8 +352,7 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
g_free (sel_name),
|
||||
g_free (tgt_name)));
|
||||
|
||||
if (selection == GDK_SELECTION_CLIPBOARD &&
|
||||
target == gdk_atom_intern ("TARGETS", FALSE))
|
||||
if (selection == GDK_SELECTION_CLIPBOARD && target == _targets)
|
||||
{
|
||||
/* He wants to know what formats are on the clipboard. If there
|
||||
* is some kind of text, tell him so.
|
||||
@ -276,7 +365,7 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
IsClipboardFormatAvailable (CF_TEXT))
|
||||
{
|
||||
GdkAtom *data = g_new (GdkAtom, 1);
|
||||
*data = GDK_TARGET_STRING;
|
||||
*data = _utf8_string;
|
||||
_gdk_selection_property_store (requestor, GDK_SELECTION_TYPE_ATOM,
|
||||
32, (guchar *) data, 1 * sizeof (GdkAtom));
|
||||
}
|
||||
@ -286,36 +375,36 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
API_CALL (CloseClipboard, ());
|
||||
}
|
||||
else if (selection == GDK_SELECTION_CLIPBOARD &&
|
||||
(target == _compound_text ||
|
||||
target == GDK_TARGET_STRING))
|
||||
(target == GDK_TARGET_STRING ||
|
||||
target == _utf8_string))
|
||||
{
|
||||
/* Converting the CLIPBOARD selection means he wants the
|
||||
* contents of the clipboard. Get the clipboard data,
|
||||
* and store it for later.
|
||||
* contents of the clipboard. Get the clipboard data, and store
|
||||
* it for later.
|
||||
*/
|
||||
if (!API_CALL (OpenClipboard, (GDK_WINDOW_HWND (requestor))))
|
||||
return;
|
||||
|
||||
/* Try various formats. First the simplest, CF_UNICODETEXT. */
|
||||
if ((hdata = GetClipboardData (CF_UNICODETEXT)) != NULL)
|
||||
if (IS_WIN_NT () && (hdata = GetClipboardData (CF_UNICODETEXT)) != NULL)
|
||||
{
|
||||
wchar_t *ptr, *wcs, *p, *q;
|
||||
guchar *data;
|
||||
gint length, wclen;
|
||||
glong length, wclen;
|
||||
|
||||
if ((ptr = GlobalLock (hdata)) != NULL)
|
||||
{
|
||||
length = GlobalSize (hdata);
|
||||
|
||||
GDK_NOTE (DND, g_print ("...CF_UNICODETEXT: %d bytes\n",
|
||||
GDK_NOTE (DND, g_print ("...CF_UNICODETEXT: %ld bytes\n",
|
||||
length));
|
||||
|
||||
/* Strip out \r */
|
||||
wcs = g_new (wchar_t, (length + 1) * 2);
|
||||
wcs = g_new (wchar_t, length / 2 + 1);
|
||||
p = ptr;
|
||||
q = wcs;
|
||||
wclen = 0;
|
||||
while (*p)
|
||||
while (p < ptr + length / 2)
|
||||
{
|
||||
if (*p != '\r')
|
||||
{
|
||||
@ -325,11 +414,16 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
p++;
|
||||
}
|
||||
|
||||
data = _gdk_ucs2_to_utf8 (wcs, wclen);
|
||||
data = g_utf16_to_utf8 (wcs, wclen, NULL, NULL, &error);
|
||||
g_free (wcs);
|
||||
|
||||
_gdk_selection_property_store (requestor, target, 8,
|
||||
data, strlen (data) + 1);
|
||||
|
||||
if (!data)
|
||||
{
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
_gdk_selection_property_store (requestor, target, 8,
|
||||
data, strlen (data) + 1);
|
||||
GlobalUnlock (hdata);
|
||||
}
|
||||
}
|
||||
@ -347,7 +441,7 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
length, ptr));
|
||||
|
||||
_gdk_selection_property_store (requestor, target, 8,
|
||||
g_strdup (ptr), strlen (ptr) + 1);
|
||||
g_memdup (ptr, length), length);
|
||||
GlobalUnlock (hdata);
|
||||
}
|
||||
}
|
||||
@ -361,13 +455,13 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
UINT cp = CP_ACP;
|
||||
wchar_t *wcs, *wcs2, *p, *q;
|
||||
guchar *ptr, *data;
|
||||
gint length, wclen;
|
||||
glong length, wclen, wclen2;
|
||||
|
||||
if ((ptr = GlobalLock (hdata)) != NULL)
|
||||
{
|
||||
length = GlobalSize (hdata);
|
||||
|
||||
GDK_NOTE (DND, g_print ("...CF_TEXT: %d bytes: %.10s\n",
|
||||
GDK_NOTE (DND, g_print ("...CF_TEXT: %ld bytes: %.10s\n",
|
||||
length, ptr));
|
||||
|
||||
if ((hlcid = GetClipboardData (CF_LOCALE)) != NULL)
|
||||
@ -385,30 +479,33 @@ gdk_selection_convert (GdkWindow *requestor,
|
||||
}
|
||||
|
||||
wcs = g_new (wchar_t, length + 1);
|
||||
wclen = MultiByteToWideChar (cp, 0, ptr, -1,
|
||||
wclen = MultiByteToWideChar (cp, 0, ptr, length,
|
||||
wcs, length + 1);
|
||||
|
||||
/* Strip out \r */
|
||||
wcs2 = g_new (wchar_t, wclen);
|
||||
p = wcs;
|
||||
q = wcs2;
|
||||
wclen = 0;
|
||||
while (*p)
|
||||
wclen2 = 0;
|
||||
while (p < wcs + wclen)
|
||||
{
|
||||
if (*p != '\r')
|
||||
{
|
||||
*q++ = *p;
|
||||
wclen++;
|
||||
wclen2++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
g_free (wcs);
|
||||
|
||||
data = _gdk_ucs2_to_utf8 (wcs2, wclen);
|
||||
data = g_utf16_to_utf8 (wcs2, wclen2, NULL, &length, &error);
|
||||
g_free (wcs2);
|
||||
|
||||
_gdk_selection_property_store (requestor, target, 8,
|
||||
data, strlen (data) + 1);
|
||||
|
||||
if (!data)
|
||||
g_error_free (error);
|
||||
else
|
||||
_gdk_selection_property_store (requestor, target, 8,
|
||||
data, length + 1);
|
||||
GlobalUnlock (hdata);
|
||||
}
|
||||
}
|
||||
@ -498,16 +595,16 @@ _gdk_selection_property_delete (GdkWindow *window)
|
||||
|
||||
void
|
||||
gdk_selection_send_notify_for_display (GdkDisplay *display,
|
||||
guint32 requestor,
|
||||
GdkAtom selection,
|
||||
GdkAtom target,
|
||||
GdkAtom property,
|
||||
guint32 time)
|
||||
guint32 requestor,
|
||||
GdkAtom selection,
|
||||
GdkAtom target,
|
||||
GdkAtom property,
|
||||
guint32 time)
|
||||
{
|
||||
GdkEvent tmp_event;
|
||||
gchar *sel_name, *tgt_name, *prop_name;
|
||||
|
||||
g_return_if_fail (display == gdk_display_get_default ());
|
||||
g_return_if_fail (display == _gdk_display);
|
||||
|
||||
GDK_NOTE (DND,
|
||||
(sel_name = gdk_atom_name (selection),
|
||||
@ -522,12 +619,13 @@ gdk_selection_send_notify_for_display (GdkDisplay *display,
|
||||
g_free (tgt_name),
|
||||
g_free (prop_name)));
|
||||
|
||||
/* Send ourselves a selection clear message so that gtk thinks we don't
|
||||
* have the selection, and will claim it anew when needed, and
|
||||
/* Send ourselves a selection clear message so that gtk thinks we
|
||||
* don't have the selection, and will claim it anew when needed, and
|
||||
* we thus get a chance to store data in the Windows clipboard.
|
||||
* Otherwise, if a gtkeditable does a copy to CLIPBOARD several times
|
||||
* only the first one actually gets copied to the Windows clipboard,
|
||||
* as only the first one causes a call to gdk_property_change().
|
||||
* Otherwise, if a gtkeditable does a copy to CLIPBOARD several
|
||||
* times only the first one actually gets copied to the Windows
|
||||
* clipboard, as only the first one causes a call to
|
||||
* gdk_property_change().
|
||||
*
|
||||
* Hmm, there is something fishy with this. Cut and paste inside the
|
||||
* same app didn't work, the gtkeditable immediately forgot the
|
||||
@ -548,19 +646,25 @@ gdk_selection_send_notify_for_display (GdkDisplay *display,
|
||||
gdk_event_put (&tmp_event);
|
||||
}
|
||||
|
||||
/* Simplistic implementations of text list and compound text functions */
|
||||
|
||||
/* It's hard to say whether implementing this actually is of any use
|
||||
* on the Win32 platform? gtk calls only
|
||||
* gdk_text_property_to_utf8_list_for_display().
|
||||
*/
|
||||
gint
|
||||
gdk_text_property_to_text_list_for_display (GdkDisplay *display,
|
||||
gdk_text_property_to_text_list_for_display (GdkDisplay *display,
|
||||
GdkAtom encoding,
|
||||
gint format,
|
||||
const guchar *text,
|
||||
gint length,
|
||||
gchar ***list)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *enc_name;
|
||||
gchar *result;
|
||||
const gchar *charset;
|
||||
const gchar *source_charset = NULL;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
|
||||
g_return_val_if_fail (display == _gdk_display, 0);
|
||||
|
||||
GDK_NOTE (DND, (enc_name = gdk_atom_name (encoding),
|
||||
g_print ("gdk_text_property_to_text_list: %s %d %.20s %d\n",
|
||||
@ -570,8 +674,25 @@ gdk_text_property_to_text_list_for_display (GdkDisplay *display,
|
||||
if (!list)
|
||||
return 0;
|
||||
|
||||
if (encoding == GDK_TARGET_STRING)
|
||||
source_charset = "ISO-8859-1";
|
||||
else if (encoding == _utf8_string)
|
||||
source_charset = "UTF-8";
|
||||
else
|
||||
source_charset = gdk_atom_name (encoding);
|
||||
|
||||
g_get_charset (&charset);
|
||||
|
||||
result = g_convert (text, length, charset, source_charset,
|
||||
NULL, NULL, &error);
|
||||
if (!result)
|
||||
{
|
||||
g_error_free (error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*list = g_new (gchar *, 1);
|
||||
**list = g_strdup (text);
|
||||
**list = result;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -585,47 +706,6 @@ gdk_free_text_list (gchar **list)
|
||||
g_free (list);
|
||||
}
|
||||
|
||||
gint
|
||||
gdk_string_to_compound_text_for_display (GdkDisplay *display,
|
||||
const gchar *str,
|
||||
GdkAtom *encoding,
|
||||
gint *format,
|
||||
guchar **ctext,
|
||||
gint *length)
|
||||
{
|
||||
g_return_val_if_fail (str != NULL, 0);
|
||||
g_return_val_if_fail (length >= 0, 0);
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
|
||||
|
||||
GDK_NOTE (DND, g_print ("gdk_string_to_compound_text: %.20s\n", str));
|
||||
|
||||
if (encoding)
|
||||
*encoding = _compound_text;
|
||||
|
||||
if (format)
|
||||
*format = 8;
|
||||
|
||||
if (ctext)
|
||||
*ctext = g_strdup (str);
|
||||
|
||||
if (length)
|
||||
*length = strlen (str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_free_compound_text (guchar *ctext)
|
||||
{
|
||||
g_free (ctext);
|
||||
}
|
||||
|
||||
/* These are lifted from gdkselection-x11.c, just to get GTK+ to build.
|
||||
* These functions probably don't make much sense at all in Windows.
|
||||
*/
|
||||
|
||||
/* FIXME */
|
||||
|
||||
static gint
|
||||
make_list (const gchar *text,
|
||||
gint length,
|
||||
@ -705,7 +785,7 @@ gdk_text_property_to_utf8_list_for_display (GdkDisplay *display,
|
||||
{
|
||||
g_return_val_if_fail (text != NULL, 0);
|
||||
g_return_val_if_fail (length >= 0, 0);
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), 0);
|
||||
g_return_val_if_fail (display == _gdk_display, 0);
|
||||
|
||||
if (encoding == GDK_TARGET_STRING)
|
||||
{
|
||||
@ -717,164 +797,88 @@ gdk_text_property_to_utf8_list_for_display (GdkDisplay *display,
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar **local_list;
|
||||
gint local_count;
|
||||
gint i;
|
||||
const gchar *charset = NULL;
|
||||
gboolean need_conversion = g_get_charset (&charset);
|
||||
gint count = 0;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Probably COMPOUND text, we fall back to Xlib routines
|
||||
*/
|
||||
local_count = gdk_text_property_to_text_list (encoding,
|
||||
format,
|
||||
text,
|
||||
length,
|
||||
&local_list);
|
||||
if (list)
|
||||
*list = g_new (gchar *, local_count + 1);
|
||||
|
||||
for (i=0; i<local_count; i++)
|
||||
{
|
||||
/* list contains stuff in our default encoding
|
||||
*/
|
||||
if (need_conversion)
|
||||
{
|
||||
gchar *utf = g_convert (local_list[i], -1,
|
||||
"UTF-8", charset,
|
||||
NULL, NULL, &error);
|
||||
if (utf)
|
||||
{
|
||||
if (list)
|
||||
(*list)[count++] = utf;
|
||||
else
|
||||
g_free (utf);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Error converting to UTF-8 from '%s': %s",
|
||||
charset, error->message);
|
||||
g_error_free (error);
|
||||
error = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (list)
|
||||
(*list)[count++] = g_strdup (local_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_free_text_list (local_list);
|
||||
(*list)[count] = NULL;
|
||||
g_warning ("gdk_text_property_to_utf8_list_for_display: encoding %s not handled\n", gdk_atom_name (encoding));
|
||||
|
||||
return count;
|
||||
if (list)
|
||||
*list = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The specifications for COMPOUND_TEXT and STRING specify that C0 and
|
||||
* C1 are not allowed except for \n and \t, however the X conversions
|
||||
* routines for COMPOUND_TEXT only enforce this in one direction,
|
||||
* causing cut-and-paste of \r and \r\n separated text to fail.
|
||||
* This routine strips out all non-allowed C0 and C1 characters
|
||||
* from the input string and also canonicalizes \r, and \r\n to \n
|
||||
*/
|
||||
static gchar *
|
||||
sanitize_utf8 (const gchar *src)
|
||||
gint
|
||||
gdk_string_to_compound_text_for_display (GdkDisplay *display,
|
||||
const gchar *str,
|
||||
GdkAtom *encoding,
|
||||
gint *format,
|
||||
guchar **ctext,
|
||||
gint *length)
|
||||
{
|
||||
gint len = strlen (src);
|
||||
GString *result = g_string_sized_new (len);
|
||||
const gchar *p = src;
|
||||
g_return_val_if_fail (str != NULL, 0);
|
||||
g_return_val_if_fail (length >= 0, 0);
|
||||
g_return_val_if_fail (display == _gdk_display, 0);
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (*p == '\r')
|
||||
{
|
||||
p++;
|
||||
if (*p == '\n')
|
||||
p++;
|
||||
GDK_NOTE (DND, g_print ("gdk_string_to_compound_text_for_display: %.20s\n", str));
|
||||
|
||||
g_string_append_c (result, '\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
gunichar ch = g_utf8_get_char (p);
|
||||
char buf[7];
|
||||
gint buflen;
|
||||
|
||||
if (!((ch < 0x20 && ch != '\t' && ch != '\n') || (ch >= 0x7f && ch < 0xa0)))
|
||||
{
|
||||
buflen = g_unichar_to_utf8 (ch, buf);
|
||||
g_string_append_len (result, buf, buflen);
|
||||
}
|
||||
/* Always fail on Win32. No COMPOUND_TEXT support. */
|
||||
|
||||
p = g_utf8_next_char (p);
|
||||
}
|
||||
}
|
||||
if (encoding)
|
||||
*encoding = GDK_NONE;
|
||||
|
||||
return g_string_free (result, FALSE);
|
||||
if (format)
|
||||
*format = 0;
|
||||
|
||||
if (ctext)
|
||||
*ctext = NULL;
|
||||
|
||||
if (length)
|
||||
*length = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gdk_utf8_to_string_target (const gchar *str)
|
||||
{
|
||||
return sanitize_utf8 (str);
|
||||
return _gdk_utf8_to_string_target_internal (str, strlen (str));
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_utf8_to_compound_text_for_display (GdkDisplay *display,
|
||||
gdk_utf8_to_compound_text_for_display (GdkDisplay *display,
|
||||
const gchar *str,
|
||||
GdkAtom *encoding,
|
||||
gint *format,
|
||||
guchar **ctext,
|
||||
gint *length)
|
||||
{
|
||||
gboolean need_conversion;
|
||||
const gchar *charset;
|
||||
gchar *locale_str, *tmp_str;
|
||||
GError *error = NULL;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (str != NULL, FALSE);
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), FALSE);
|
||||
g_return_val_if_fail (display == _gdk_display, FALSE);
|
||||
|
||||
need_conversion = !g_get_charset (&charset);
|
||||
GDK_NOTE (DND, g_print ("gdk_utf8_to_compound_text_for_display: %.20s\n", str));
|
||||
|
||||
tmp_str = sanitize_utf8 (str);
|
||||
/* Always fail on Win32. No COMPOUND_TEXT support. */
|
||||
|
||||
if (need_conversion)
|
||||
{
|
||||
locale_str = g_convert_with_fallback (tmp_str, -1,
|
||||
charset, "UTF-8",
|
||||
NULL, NULL, NULL, &error);
|
||||
g_free (tmp_str);
|
||||
if (encoding)
|
||||
*encoding = GDK_NONE;
|
||||
|
||||
if (!locale_str)
|
||||
{
|
||||
g_warning ("Error converting from UTF-8 to '%s': %s",
|
||||
charset, error->message);
|
||||
g_error_free (error);
|
||||
|
||||
if (encoding)
|
||||
*encoding = GDK_NONE;
|
||||
if (format)
|
||||
*format = GPOINTER_TO_UINT (GDK_ATOM_TO_POINTER (GDK_NONE));
|
||||
if (ctext)
|
||||
*ctext = NULL;
|
||||
if (length)
|
||||
*length = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
locale_str = tmp_str;
|
||||
|
||||
result = gdk_string_to_compound_text (locale_str,
|
||||
encoding, format, ctext, length);
|
||||
if (format)
|
||||
*format = 0;
|
||||
|
||||
g_free (locale_str);
|
||||
if (ctext)
|
||||
*ctext = NULL;
|
||||
|
||||
return result;
|
||||
if (length)
|
||||
*length = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_free_compound_text (guchar *ctext)
|
||||
{
|
||||
/* As we never generate anything claimed to be COMPOUND_TEXT, this
|
||||
* should never be called. Or if it is called, ctext should be the
|
||||
* NULL returned for conversions to COMPOUND_TEXT above.
|
||||
*/
|
||||
g_return_if_fail (ctext == NULL);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user