diff options
author | Tor Lillqvist <tml@iki.fi> | 2004-07-07 00:10:03 +0000 |
---|---|---|
committer | Tor Lillqvist <tml@src.gnome.org> | 2004-07-07 00:10:03 +0000 |
commit | d8b2f46c18a85929f6a860b5161cf3d12d589614 (patch) | |
tree | dc4d750ba15d2dbc38344f12fe36364f01bb1f33 | |
parent | d1c69ab84eb2880b83e712bb5d5fd0a3ae3f10ec (diff) | |
download | gtk+-d8b2f46c18a85929f6a860b5161cf3d12d589614.tar.gz |
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.
-rw-r--r-- | ChangeLog | 56 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 56 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 56 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 56 | ||||
-rw-r--r-- | gdk/win32/gdkdrawable-win32.c | 10 | ||||
-rw-r--r-- | gdk/win32/gdkfont-win32.c | 18 | ||||
-rw-r--r-- | gdk/win32/gdkglobals-win32.c | 2 | ||||
-rw-r--r-- | gdk/win32/gdkim-win32.c | 322 | ||||
-rw-r--r-- | gdk/win32/gdkmain-win32.c | 2 | ||||
-rw-r--r-- | gdk/win32/gdkprivate-win32.h | 15 | ||||
-rw-r--r-- | gdk/win32/gdkproperty-win32.c | 67 | ||||
-rw-r--r-- | gdk/win32/gdkselection-win32.c | 454 |
12 files changed, 524 insertions, 590 deletions
@@ -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, diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index c88ee3f26b..e95a313117 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -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, diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index c88ee3f26b..e95a313117 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -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, diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index c88ee3f26b..e95a313117 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -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, diff --git a/gdk/win32/gdkdrawable-win32.c b/gdk/win32/gdkdrawable-win32.c index cd3c874184..c542eb9fe0 100644 --- a/gdk/win32/gdkdrawable-win32.c +++ b/gdk/win32/gdkdrawable-win32.c @@ -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); } diff --git a/gdk/win32/gdkfont-win32.c b/gdk/win32/gdkfont-win32.c index e52d63749b..2086fe7c8e 100644 --- a/gdk/win32/gdkfont-win32.c +++ b/gdk/win32/gdkfont-win32.c @@ -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; diff --git a/gdk/win32/gdkglobals-win32.c b/gdk/win32/gdkglobals-win32.c index 831c05acc6..523d5791e7 100644 --- a/gdk/win32/gdkglobals-win32.c +++ b/gdk/win32/gdkglobals-win32.c @@ -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; diff --git a/gdk/win32/gdkim-win32.c b/gdk/win32/gdkim-win32.c index b31b1b5dd3..aeb29bf7dd 100644 --- a/gdk/win32/gdkim-win32.c +++ b/gdk/win32/gdkim-win32.c @@ -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; - - 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; -} - -/* 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; + gchar *utf8; + gchar *retval; + const gchar *charset; - 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; + g_get_charset (&charset); + return g_convert (src, -1, charset, "UCS-4LE", NULL, NULL, NULL); } -/* - * 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; + gint retval; + gsize nwritten; + gint n_ucs4; + gunichar *ucs4; + const gchar *charset; - *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; + g_get_charset (&charset); + ucs4 = g_convert (src, -1, "UCS-4LE", charset, NULL, &nwritten, NULL); + n_ucs4 = nwritten * sizeof (GdkWChar); - cp += len; - wcp++; - n++; - } - if (cp != end) - return -1; + retval = MIN (dest_max, n_ucs4); + memmove (dest, ucs4, retval * sizeof (GdkWChar)); + g_free (ucs4); - return n; + return retval; } diff --git a/gdk/win32/gdkmain-win32.c b/gdk/win32/gdkmain-win32.c index df42789e23..b34973d3dd 100644 --- a/gdk/win32/gdkmain-win32.c +++ b/gdk/win32/gdkmain-win32.c @@ -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); diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h index 84cf832a04..a950c58ec0 100644 --- a/gdk/win32/gdkprivate-win32.h +++ b/gdk/win32/gdkprivate-win32.h @@ -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; diff --git a/gdk/win32/gdkproperty-win32.c b/gdk/win32/gdkproperty-win32.c index d372d9f876..5131b62d40 100644 --- a/gdk/win32/gdkproperty-win32.c +++ b/gdk/win32/gdkproperty-win32.c @@ -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 (i == nelements) - nchars = nelements; - else - 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); - 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: diff --git a/gdk/win32/gdkselection-win32.c b/gdk/win32/gdkselection-win32.c index e0b0ca6d4a..5c9e81ca23 100644 --- a/gdk/win32/gdkselection-win32.c +++ b/gdk/win32/gdkselection-win32.c @@ -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); + g_warning ("gdk_text_property_to_utf8_list_for_display: encoding %s not handled\n", gdk_atom_name (encoding)); + 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; + *list = NULL; - return count; + 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); } |