]> Pileus Git - ~andy/gtk/commitdiff
Check for broken glibc 2.0 mb functions, and avoid them.
authorOwen Taylor <otaylor@redhat.com>
Thu, 17 Dec 1998 04:20:29 +0000 (04:20 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Thu, 17 Dec 1998 04:20:29 +0000 (04:20 +0000)
Wed Dec 16 22:50:52 1998  Owen Taylor  <otaylor@redhat.com>

* gdk/gdk.c gdk/gdkim.c: Check for broken glibc 2.0
mb functions, and avoid them.

ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/gdk.c
gdk/gdkim.c
gdk/x11/gdkim-x11.c
gdk/x11/gdkmain-x11.c

index 3870762c6e4fa8519522783fa2e327415a85fefb..cbce163c107b3dbbde08aa42dd613f7c9f29fa2e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Dec 16 22:50:52 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c: Check for broken glibc 2.0 
+       mb functions, and avoid them.
+
 Wed Dec 16 16:57:55 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkevents.c (gdk_events_queue): Don't
index 3870762c6e4fa8519522783fa2e327415a85fefb..cbce163c107b3dbbde08aa42dd613f7c9f29fa2e 100644 (file)
@@ -1,3 +1,8 @@
+Wed Dec 16 22:50:52 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c: Check for broken glibc 2.0 
+       mb functions, and avoid them.
+
 Wed Dec 16 16:57:55 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkevents.c (gdk_events_queue): Don't
index 3870762c6e4fa8519522783fa2e327415a85fefb..cbce163c107b3dbbde08aa42dd613f7c9f29fa2e 100644 (file)
@@ -1,3 +1,8 @@
+Wed Dec 16 22:50:52 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c: Check for broken glibc 2.0 
+       mb functions, and avoid them.
+
 Wed Dec 16 16:57:55 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkevents.c (gdk_events_queue): Don't
index 3870762c6e4fa8519522783fa2e327415a85fefb..cbce163c107b3dbbde08aa42dd613f7c9f29fa2e 100644 (file)
@@ -1,3 +1,8 @@
+Wed Dec 16 22:50:52 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c: Check for broken glibc 2.0 
+       mb functions, and avoid them.
+
 Wed Dec 16 16:57:55 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkevents.c (gdk_events_queue): Don't
index 3870762c6e4fa8519522783fa2e327415a85fefb..cbce163c107b3dbbde08aa42dd613f7c9f29fa2e 100644 (file)
@@ -1,3 +1,8 @@
+Wed Dec 16 22:50:52 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c: Check for broken glibc 2.0 
+       mb functions, and avoid them.
+
 Wed Dec 16 16:57:55 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkevents.c (gdk_events_queue): Don't
index 3870762c6e4fa8519522783fa2e327415a85fefb..cbce163c107b3dbbde08aa42dd613f7c9f29fa2e 100644 (file)
@@ -1,3 +1,8 @@
+Wed Dec 16 22:50:52 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c: Check for broken glibc 2.0 
+       mb functions, and avoid them.
+
 Wed Dec 16 16:57:55 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkevents.c (gdk_events_queue): Don't
index 3870762c6e4fa8519522783fa2e327415a85fefb..cbce163c107b3dbbde08aa42dd613f7c9f29fa2e 100644 (file)
@@ -1,3 +1,8 @@
+Wed Dec 16 22:50:52 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c: Check for broken glibc 2.0 
+       mb functions, and avoid them.
+
 Wed Dec 16 16:57:55 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkevents.c (gdk_events_queue): Don't
index e0954808397444f6644a2801a5a2e6da4d167b49..1e3e04954476db5007ee5b88b1ee232137e07985 100644 (file)
--- a/gdk/gdk.c
+++ b/gdk/gdk.c
@@ -18,7 +18,6 @@
  */
 #include "config.h"
 
-#include <X11/Xlocale.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -448,39 +447,6 @@ gdk_exit (int errorcode)
   exit (errorcode);
 }
 
-/*
- *--------------------------------------------------------------
- * gdk_set_locale
- *
- * Arguments:
- *
- * Results:
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
-gchar*
-gdk_set_locale (void)
-{
-  if (!setlocale (LC_ALL,""))
-    g_message ("locale not supported by C library");
-  
-  if (!XSupportsLocale ())
-    {
-      g_message ("locale not supported by Xlib, locale set to C");
-      setlocale (LC_ALL, "C");
-    }
-  
-  if (!XSetLocaleModifiers (""))
-    {
-      g_message ("can not set locale modifiers");
-    }
-  
-  return setlocale (LC_ALL,NULL);
-}
-
 void
 gdk_set_use_xshm (gint use_xshm)
 {
index 5b2ded3fd3390c2889ff052558c65d73275e2d05..417430d0f0fd22b07f4efe25b0951aef313a28b6 100644 (file)
@@ -17,6 +17,7 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include <X11/Xlocale.h>
 #include "gdk.h"
 #include "gdkprivate.h"
 #include "gdki18n.h"
@@ -39,6 +40,12 @@ typedef struct {
   gpointer value;
 } GdkImArg;
 
+/* If this variable is FALSE, it indicates that we should
+ * avoid trying to use multibyte conversion functions and
+ * assume everything is 1-byte per character
+ */
+gboolean gdk_use_mb;
+
 #ifdef USE_XIM
 
 static void   gdk_im_instantiate_cb      (Display *display,
@@ -61,6 +68,69 @@ static GList* xim_ic_list;
 
 #endif /* USE_XIM */
 
+/*
+ *--------------------------------------------------------------
+ * gdk_set_locale
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gchar*
+gdk_set_locale (void)
+{
+  wchar_t result;
+  gchar *current_locale;
+
+  gdk_use_mb = FALSE;
+
+  if (!setlocale (LC_ALL,""))
+    g_message ("locale not supported by C library");
+  
+  if (!XSupportsLocale ())
+    {
+      g_message ("locale not supported by Xlib, locale set to C");
+      setlocale (LC_ALL, "C");
+    }
+  
+  if (!XSetLocaleModifiers (""))
+    g_message ("can not set locale modifiers");
+
+  current_locale = setlocale (LC_ALL, "");
+
+  if ((strcmp (current_locale, "C")) && (strcmp (current_locale, "POSIX")))
+    {
+      gdk_use_mb = TRUE;
+
+#ifndef X_LOCALE
+      /* Detect GNU libc, where mb == UTF8. Not useful unless it's
+       * really a UTF8 locale. The below still probably will
+       * screw up on Greek, Cyrillic, etc, encoded as UTF8.
+       */
+      
+      if ((MB_CUR_MAX == 2) &&
+         (mbstowcs (&result, "\xdd\xa5", 1) > 0) &&
+         result == 0x765)
+       {
+         if ((strlen (current_locale) < 4) ||
+             g_strcasecmp (current_locale + strlen(current_locale) - 4, "utf8"))
+           gdk_use_mb = FALSE;
+       }
+#endif /* X_LOCALE */
+    }
+
+  GDK_NOTE (XIM,
+           g_message ("%s multi-byte string functions.", 
+                      gdk_use_mb ? "Using" : "Not using"));
+  
+  return setlocale (LC_ALL,NULL);
+}
+
 /*
  *--------------------------------------------------------------
  * gdk_im_begin
@@ -1374,37 +1444,56 @@ gchar *
 gdk_wcstombs (const GdkWChar *src)
 {
   gchar *mbstr;
-  XTextProperty tpr;
-  if (sizeof(wchar_t) != sizeof(GdkWChar))
+
+  if (gdk_use_mb)
     {
-      gint i;
-      wchar_t *src_alt;
-      for (i=0; src[i]; i++);
-      src_alt = g_new (wchar_t, i+1);
-      for (; i>=0; i--)
-      src_alt[i] = src[i];
-      if (XwcTextListToTextProperty (gdk_display, &src_alt, 1, XTextStyle, &tpr)
-         != Success)
+      XTextProperty tpr;
+
+      if (sizeof(wchar_t) != sizeof(GdkWChar))
        {
+         gint i;
+         wchar_t *src_alt;
+         for (i=0; src[i]; i++);
+         src_alt = g_new (wchar_t, i+1);
+         for (; i>=0; i--)
+           src_alt[i] = src[i];
+         if (XwcTextListToTextProperty (gdk_display, &src_alt, 1, XTextStyle, &tpr)
+             != Success)
+           {
+             g_free (src_alt);
+             return NULL;
+           }
          g_free (src_alt);
-         return NULL;
        }
-      g_free (src_alt);
+      else
+       {
+         if (XwcTextListToTextProperty (gdk_display, (wchar_t**)&src, 1,
+                                        XTextStyle, &tpr) != Success)
+           {
+             return NULL;
+           }
+       }
+      /*
+       * We must copy the string into an area allocated by glib, because
+       * the string 'tpr.value' must be freed by XFree().
+       */
+      mbstr = g_strdup(tpr.value);
+      XFree (tpr.value);
     }
   else
     {
-      if (XwcTextListToTextProperty (gdk_display, (wchar_t**)&src, 1,
-                                    XTextStyle, &tpr) != Success)
-       {
-         return NULL;
-       }
+      gint length = 0;
+      gint i;
+
+      while (src[length++] != 0)
+       ;
+      
+      mbstr = g_new (gchar, length + 1);
+
+      for (i=0; i<length+1; i++)
+       mbstr[i] = src[i];
     }
-  /*
-   * We must copy the string into an area allocated by glib, because
-   * the string 'tpr.value' must be freed by XFree().
-   */
-  mbstr = g_strdup(tpr.value);
-  XFree (tpr.value);
+
   return mbstr;
 }
   
@@ -1418,28 +1507,40 @@ gdk_wcstombs (const GdkWChar *src)
 gint
 gdk_mbstowcs (GdkWChar *dest, const gchar *src, gint dest_max)
 {
-  XTextProperty tpr;
-  wchar_t **wstrs, *wstr_src;
-  gint num_wstrs;
-  gint len_cpy;
-  if (XmbTextListToTextProperty (gdk_display, (char **)&src, 1, XTextStyle,
-                                &tpr)
-      != Success)
-    {
-      /* NoMem or LocaleNotSupp */
-      return -1;
-    }
-  if (XwcTextPropertyToTextList (gdk_display, &tpr, &wstrs, &num_wstrs)
-      != Success)
-    {
-      /* InvalidChar */
-      return -1;
-    }
-  if (num_wstrs == 0)
-    return 0;
-  wstr_src = wstrs[0];
-  for (len_cpy=0; len_cpy<dest_max && wstr_src[len_cpy]; len_cpy++)
-    dest[len_cpy] = wstr_src[len_cpy];
-  XwcFreeStringList (wstrs);
-  return len_cpy;
+  if (gdk_use_mb)
+    {
+      XTextProperty tpr;
+      wchar_t **wstrs, *wstr_src;
+      gint num_wstrs;
+      gint len_cpy;
+      if (XmbTextListToTextProperty (gdk_display, (char **)&src, 1, XTextStyle,
+                                    &tpr)
+         != Success)
+       {
+         /* NoMem or LocaleNotSupp */
+         return -1;
+       }
+      if (XwcTextPropertyToTextList (gdk_display, &tpr, &wstrs, &num_wstrs)
+         != Success)
+       {
+         /* InvalidChar */
+         return -1;
+       }
+      if (num_wstrs == 0)
+       return 0;
+      wstr_src = wstrs[0];
+      for (len_cpy=0; len_cpy<dest_max && wstr_src[len_cpy]; len_cpy++)
+       dest[len_cpy] = wstr_src[len_cpy];
+      XwcFreeStringList (wstrs);
+      return len_cpy;
+    }
+  else
+    {
+      gint i;
+
+      for (i=0; i<dest_max && src[i]; i++)
+       dest[i] = src[i];
+
+      return i;
+    }
 }
index 5b2ded3fd3390c2889ff052558c65d73275e2d05..417430d0f0fd22b07f4efe25b0951aef313a28b6 100644 (file)
@@ -17,6 +17,7 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include <X11/Xlocale.h>
 #include "gdk.h"
 #include "gdkprivate.h"
 #include "gdki18n.h"
@@ -39,6 +40,12 @@ typedef struct {
   gpointer value;
 } GdkImArg;
 
+/* If this variable is FALSE, it indicates that we should
+ * avoid trying to use multibyte conversion functions and
+ * assume everything is 1-byte per character
+ */
+gboolean gdk_use_mb;
+
 #ifdef USE_XIM
 
 static void   gdk_im_instantiate_cb      (Display *display,
@@ -61,6 +68,69 @@ static GList* xim_ic_list;
 
 #endif /* USE_XIM */
 
+/*
+ *--------------------------------------------------------------
+ * gdk_set_locale
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gchar*
+gdk_set_locale (void)
+{
+  wchar_t result;
+  gchar *current_locale;
+
+  gdk_use_mb = FALSE;
+
+  if (!setlocale (LC_ALL,""))
+    g_message ("locale not supported by C library");
+  
+  if (!XSupportsLocale ())
+    {
+      g_message ("locale not supported by Xlib, locale set to C");
+      setlocale (LC_ALL, "C");
+    }
+  
+  if (!XSetLocaleModifiers (""))
+    g_message ("can not set locale modifiers");
+
+  current_locale = setlocale (LC_ALL, "");
+
+  if ((strcmp (current_locale, "C")) && (strcmp (current_locale, "POSIX")))
+    {
+      gdk_use_mb = TRUE;
+
+#ifndef X_LOCALE
+      /* Detect GNU libc, where mb == UTF8. Not useful unless it's
+       * really a UTF8 locale. The below still probably will
+       * screw up on Greek, Cyrillic, etc, encoded as UTF8.
+       */
+      
+      if ((MB_CUR_MAX == 2) &&
+         (mbstowcs (&result, "\xdd\xa5", 1) > 0) &&
+         result == 0x765)
+       {
+         if ((strlen (current_locale) < 4) ||
+             g_strcasecmp (current_locale + strlen(current_locale) - 4, "utf8"))
+           gdk_use_mb = FALSE;
+       }
+#endif /* X_LOCALE */
+    }
+
+  GDK_NOTE (XIM,
+           g_message ("%s multi-byte string functions.", 
+                      gdk_use_mb ? "Using" : "Not using"));
+  
+  return setlocale (LC_ALL,NULL);
+}
+
 /*
  *--------------------------------------------------------------
  * gdk_im_begin
@@ -1374,37 +1444,56 @@ gchar *
 gdk_wcstombs (const GdkWChar *src)
 {
   gchar *mbstr;
-  XTextProperty tpr;
-  if (sizeof(wchar_t) != sizeof(GdkWChar))
+
+  if (gdk_use_mb)
     {
-      gint i;
-      wchar_t *src_alt;
-      for (i=0; src[i]; i++);
-      src_alt = g_new (wchar_t, i+1);
-      for (; i>=0; i--)
-      src_alt[i] = src[i];
-      if (XwcTextListToTextProperty (gdk_display, &src_alt, 1, XTextStyle, &tpr)
-         != Success)
+      XTextProperty tpr;
+
+      if (sizeof(wchar_t) != sizeof(GdkWChar))
        {
+         gint i;
+         wchar_t *src_alt;
+         for (i=0; src[i]; i++);
+         src_alt = g_new (wchar_t, i+1);
+         for (; i>=0; i--)
+           src_alt[i] = src[i];
+         if (XwcTextListToTextProperty (gdk_display, &src_alt, 1, XTextStyle, &tpr)
+             != Success)
+           {
+             g_free (src_alt);
+             return NULL;
+           }
          g_free (src_alt);
-         return NULL;
        }
-      g_free (src_alt);
+      else
+       {
+         if (XwcTextListToTextProperty (gdk_display, (wchar_t**)&src, 1,
+                                        XTextStyle, &tpr) != Success)
+           {
+             return NULL;
+           }
+       }
+      /*
+       * We must copy the string into an area allocated by glib, because
+       * the string 'tpr.value' must be freed by XFree().
+       */
+      mbstr = g_strdup(tpr.value);
+      XFree (tpr.value);
     }
   else
     {
-      if (XwcTextListToTextProperty (gdk_display, (wchar_t**)&src, 1,
-                                    XTextStyle, &tpr) != Success)
-       {
-         return NULL;
-       }
+      gint length = 0;
+      gint i;
+
+      while (src[length++] != 0)
+       ;
+      
+      mbstr = g_new (gchar, length + 1);
+
+      for (i=0; i<length+1; i++)
+       mbstr[i] = src[i];
     }
-  /*
-   * We must copy the string into an area allocated by glib, because
-   * the string 'tpr.value' must be freed by XFree().
-   */
-  mbstr = g_strdup(tpr.value);
-  XFree (tpr.value);
+
   return mbstr;
 }
   
@@ -1418,28 +1507,40 @@ gdk_wcstombs (const GdkWChar *src)
 gint
 gdk_mbstowcs (GdkWChar *dest, const gchar *src, gint dest_max)
 {
-  XTextProperty tpr;
-  wchar_t **wstrs, *wstr_src;
-  gint num_wstrs;
-  gint len_cpy;
-  if (XmbTextListToTextProperty (gdk_display, (char **)&src, 1, XTextStyle,
-                                &tpr)
-      != Success)
-    {
-      /* NoMem or LocaleNotSupp */
-      return -1;
-    }
-  if (XwcTextPropertyToTextList (gdk_display, &tpr, &wstrs, &num_wstrs)
-      != Success)
-    {
-      /* InvalidChar */
-      return -1;
-    }
-  if (num_wstrs == 0)
-    return 0;
-  wstr_src = wstrs[0];
-  for (len_cpy=0; len_cpy<dest_max && wstr_src[len_cpy]; len_cpy++)
-    dest[len_cpy] = wstr_src[len_cpy];
-  XwcFreeStringList (wstrs);
-  return len_cpy;
+  if (gdk_use_mb)
+    {
+      XTextProperty tpr;
+      wchar_t **wstrs, *wstr_src;
+      gint num_wstrs;
+      gint len_cpy;
+      if (XmbTextListToTextProperty (gdk_display, (char **)&src, 1, XTextStyle,
+                                    &tpr)
+         != Success)
+       {
+         /* NoMem or LocaleNotSupp */
+         return -1;
+       }
+      if (XwcTextPropertyToTextList (gdk_display, &tpr, &wstrs, &num_wstrs)
+         != Success)
+       {
+         /* InvalidChar */
+         return -1;
+       }
+      if (num_wstrs == 0)
+       return 0;
+      wstr_src = wstrs[0];
+      for (len_cpy=0; len_cpy<dest_max && wstr_src[len_cpy]; len_cpy++)
+       dest[len_cpy] = wstr_src[len_cpy];
+      XwcFreeStringList (wstrs);
+      return len_cpy;
+    }
+  else
+    {
+      gint i;
+
+      for (i=0; i<dest_max && src[i]; i++)
+       dest[i] = src[i];
+
+      return i;
+    }
 }
index e0954808397444f6644a2801a5a2e6da4d167b49..1e3e04954476db5007ee5b88b1ee232137e07985 100644 (file)
@@ -18,7 +18,6 @@
  */
 #include "config.h"
 
-#include <X11/Xlocale.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -448,39 +447,6 @@ gdk_exit (int errorcode)
   exit (errorcode);
 }
 
-/*
- *--------------------------------------------------------------
- * gdk_set_locale
- *
- * Arguments:
- *
- * Results:
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
-gchar*
-gdk_set_locale (void)
-{
-  if (!setlocale (LC_ALL,""))
-    g_message ("locale not supported by C library");
-  
-  if (!XSupportsLocale ())
-    {
-      g_message ("locale not supported by Xlib, locale set to C");
-      setlocale (LC_ALL, "C");
-    }
-  
-  if (!XSetLocaleModifiers (""))
-    {
-      g_message ("can not set locale modifiers");
-    }
-  
-  return setlocale (LC_ALL,NULL);
-}
-
 void
 gdk_set_use_xshm (gint use_xshm)
 {