]> Pileus Git - ~andy/gtk/commitdiff
gdk/win32/gdkdrawable-win32.c (gdk_win32_draw_text)
authorTor Lillqvist <tml@iki.fi>
Wed, 7 Jul 2004 00:10:03 +0000 (00:10 +0000)
committerTor Lillqvist <tml@src.gnome.org>
Wed, 7 Jul 2004 00:10:03 +0000 (00:10 +0000)
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.

12 files changed:
ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/win32/gdkdrawable-win32.c
gdk/win32/gdkfont-win32.c
gdk/win32/gdkglobals-win32.c
gdk/win32/gdkim-win32.c
gdk/win32/gdkmain-win32.c
gdk/win32/gdkprivate-win32.h
gdk/win32/gdkproperty-win32.c
gdk/win32/gdkselection-win32.c

index c88ee3f26b72b4cef022f925f4385058a8a62013..e95a3131178c702cb6c89a05309e891749ec21cc 100644 (file)
--- a/ChangeLog
+++ b/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, 
index c88ee3f26b72b4cef022f925f4385058a8a62013..e95a3131178c702cb6c89a05309e891749ec21cc 100644 (file)
@@ -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, 
index c88ee3f26b72b4cef022f925f4385058a8a62013..e95a3131178c702cb6c89a05309e891749ec21cc 100644 (file)
@@ -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, 
index c88ee3f26b72b4cef022f925f4385058a8a62013..e95a3131178c702cb6c89a05309e891749ec21cc 100644 (file)
@@ -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, 
index cd3c8741849291589d31209402dd85e903e562c7..c542eb9fe0ca2f3a737290f09707c3d54fe35338 100644 (file)
@@ -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);
 }
 
index e52d63749b68eed996f264ca23f68fc6a1e2712c..2086fe7c8ec3050835da5978cdb038510f9f7c4d 100644 (file)
@@ -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;
index 831c05acc6bb0208ec421cef34246d806d5ff160..523d5791e7b4751ec266404007e936fb8a8ea36e 100644 (file)
@@ -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;
index b31b1b5dd336b1c36f1e0b61add36139a5ee03a1..aeb29bf7ddd419ff6651a72c2f5a6292632a9d12 100644 (file)
@@ -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;
 }
index df42789e23f042cfd3d86b070af87012161dc185..b34973d3dd27ca6eafb0444cb756629242e1c071 100644 (file)
@@ -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);
index 84cf832a04aa972e49579940b634ad4b10b1ea2d..a950c58ec0f0b75dabd870ab86cee93084a4e1db 100644 (file)
@@ -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;
index d372d9f8768c978dbe071329a5a10a405b75796a..5131b62d409b5e87921a9cffa4c0d6560a3f6068 100644 (file)
@@ -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:
index e0b0ca6d4a07cddbdf9c798f3d346f9f193f3a3d..5c9e81ca238b705b7cfa598b8dc18afe7fbc3ada 100644 (file)
@@ -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);
 }