Suggested patch for improved locale handling on Win32



Basically this just splits out the ifdefified code snipped already
present in gtk_get_default_language() into a new internal GTK
function, _gtk_get_lc_ctype(). That function is then also called from
gtk_im_multicontext_get_slave() instead of setlocale().

(On Unix, the code snippet calls setlocale(LC_CTYPE, NULL), and on
Windows it checks for LC_ALL, LC_CTYPE and LANG environment variables
(for Unix compatibilty; those envvars aren't used by the C library on
Windows), and if not found, then calls g_win32_getlocale() which uses
the Win32 API to get the thread's locale and translates it into an
en_US -style locale string.)

Without this, the locale-specific "slave" input methods (is that the
correct terminology?), mainly the imcedilla module, won't work. (A
small fix to gdk/win32/gdkkeys-win32.c is also needed for it to work,
otherwise the single/double quote key on the US-International keyboard
won't be correctly translated into the correct dead GDK keysyms.)

g_win32_getlocale() currently looks for LC_MESSAGES (After LC_ALL and
before LANG). it probably should be changed to look for LC_CTYPE
instead. Then _gtk_get_lc_ctype() could just call it, and not look
itself for the envvars.

OK to commit?

--tml

Index: gtkimmulticontext.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkimmulticontext.c,v
retrieving revision 1.25.2.3
diff -u -4 -r1.25.2.3 gtkimmulticontext.c
--- gtkimmulticontext.c	19 Aug 2003 19:24:50 -0000	1.25.2.3
+++ gtkimmulticontext.c	18 Sep 2003 22:20:54 -0000
@@ -23,8 +23,9 @@
 #include <locale.h>
 
 #include "gtkimmulticontext.h"
 #include "gtkimmodule.h"
+#include "gtkmain.h"
 #include "gtkradiomenuitem.h"
 #include "gtkintl.h"
 
 struct _GtkIMMulticontextPrivate
@@ -254,9 +255,9 @@
       if (!global_context_id)
 	{
 	  const char *locale;
 	  
-	  locale = setlocale (LC_CTYPE, NULL);
+	  locale = _gtk_get_lc_ctype ();
 
 	  global_context_id = _gtk_im_module_get_default_context_id (locale);
 	}
 	
Index: gtkmain.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.c,v
retrieving revision 1.222.2.2
diff -u -4 -r1.222.2.2 gtkmain.c
--- gtkmain.c	24 Feb 2003 20:29:39 -0000	1.222.2.2
+++ gtkmain.c	18 Sep 2003 22:20:56 -0000
@@ -988,67 +988,105 @@
  * program environment. This is the same as calling the C library function
  * <literal>setlocale (LC_ALL, "")</literal> but also takes care of the 
  * locale specific setup of the windowing system used by GDK.
  * 
- * Return value: a string corresponding to the locale set, as with the
- * C library function <function>setlocale()</function>.
+ * Return value: a string corresponding to the locale set. On Unix,
+ * this is as with the C library function
+ * <function>setlocale()</function>, typically consisting of an
+ * ISO3166 language code and optionally an ISO639 country code. Also
+ * on Windows the return value is a Unix style string with language
+ * and country codes, even if the C library uses a different
+ * convention, with language and country names spelled out in English.
+ *
+ * Return value: a string private to GTK, must not be tampered with.
  **/
 gchar *
 gtk_set_locale (void)
 {
   return gdk_set_locale ();
 }
 
 /**
- * gtk_get_default_language:
+ * _gtk_get_lc_ctype:
  *
- * Returns the #PangoLanguage for the default language currently in
- * effect. (Note that this can change over the life of an
- * application.)  The default language is derived from the current
- * locale. It determines, for example, whether GTK+ uses the
- * right-to-left or left-to-right text direction.
+ * Return the Unix-style locale string for the language currently in
+ * effect. On Unixish systems, this is the return value from
+ * <literal>setlocale(LC_CTYPE, NULL)</literal>, and the user can
+ * affect this through the environment variables LC_ALL, LC_CTYPE or
+ * LANG (checked in that order). The locale strings typically use
+ * ISO3166 country codes and ISO639 language codes, for instance sv_FI
+ * for Swedish as written in Finland or pt_BR for Portuguese as
+ * written in Brazil.
  * 
- * Return value: the default language as a #PangoLanguage, must not be
- * freed
- **/
-PangoLanguage *
-gtk_get_default_language (void)
+ * On Windows, the C library doesn't use any such environment
+ * variables, and setting them won't affect the behaviour of functions
+ * like <function>ctime()</function>. The user sets the locale through
+ * the Regional Options in the Control Panel. The C library (for
+ * instance in the return value from the
+ * <function>setlocale()</function> function) does not use country and
+ * language codes, but country and language names spelled out in
+ * English. However, this function does check the above environment
+ * variables, and does return a Unix-style locale string based on
+ * either said environment variables or the thread's current locale.
+ *
+ * Return value: a dynamically allocated string, free with g_free().
+ */
+
+gchar *
+_gtk_get_lc_ctype (void)
 {
-  gchar *lang;
-  PangoLanguage *result;
   gchar *p;
-  
+
 #ifdef G_OS_WIN32
   /* Somebody might try to set the locale for this process using the
    * LANG or LC_ environment variables. The Microsoft C library
    * doesn't know anything about them. You set the locale in the
    * Control Panel. Setting these env vars won't have any affect on
-   * locale-dependent C library functions like ctime. But just for
-   * kicks, do obey LC_ALL, LANG and LC_CTYPE in GTK. (This also makes
+   * locale-dependent C library functions like ctime(). But just for
+   * kicks, do obey LC_ALL, LC_CTYPE and LANG in GTK. (This also makes
    * it easier to test GTK and Pango in various default languages, you
    * don't have to clickety-click in the Control Panel, you can simply
    * start the program with LC_ALL=something on the command line.)
    */
   p = getenv ("LC_ALL");
   if (p != NULL)
-    lang = g_strdup (p);
-  else
-    {
-      p = getenv ("LANG");
-      if (p != NULL)
-	lang = g_strdup (p);
-      else
-	{
-	  p = getenv ("LC_CTYPE");
-	  if (p != NULL)
-	    lang = g_strdup (p);
-	  else
-	    lang = g_win32_getlocale ();
-	}
-    }
+    return g_strdup (p);
+
+  p = getenv ("LC_CTYPE");
+  if (p != NULL)
+    return g_strdup (p);
+
+  p = getenv ("LANG");
+  if (p != NULL)
+    return g_strdup (p);
+
+  return g_win32_getlocale ();
 #else
-  lang = g_strdup (setlocale (LC_CTYPE, NULL));
+  return g_strdup (setlocale (LC_CTYPE, NULL));
 #endif
+}
+
+/**
+ * gtk_get_default_language:
+ *
+ * Returns the #PangoLanguage for the default language currently in
+ * effect. (Note that this can change over the life of an
+ * application.)  The default language is derived from the current
+ * locale. It determines, for example, whether GTK+ uses the
+ * right-to-left or left-to-right text direction. See
+ * _gtk_get_lc_ctype for notes on behaviour on Windows.
+ * 
+ * Return value: the default language as a #PangoLanguage, must not be
+ * freed
+ **/
+PangoLanguage *
+gtk_get_default_language (void)
+{
+  gchar *lang;
+  PangoLanguage *result;
+  gchar *p;
+  
+  lang = _gtk_get_lc_ctype ();
   p = strchr (lang, '.');
   if (p)
     *p = '\0';
   p = strchr (lang, '@');
Index: gtkmain.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.h,v
retrieving revision 1.48
diff -u -4 -r1.48 gtkmain.h
--- gtkmain.h	24 Aug 2002 23:06:16 -0000	1.48
+++ gtkmain.h	18 Sep 2003 22:20:56 -0000
@@ -213,8 +213,10 @@
 gchar * _gtk_find_module     (const gchar *name,
 			      const gchar *type);
 gchar **_gtk_get_module_path (const gchar *type);
 
+gchar *_gtk_get_lc_ctype (void);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
Index: gtkrc.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkrc.c,v
retrieving revision 1.134.2.5
diff -u -4 -r1.134.2.5 gtkrc.c
--- gtkrc.c	24 Aug 2003 21:01:54 -0000	1.134.2.5
+++ gtkrc.c	18 Sep 2003 22:20:59 -0000
@@ -843,13 +843,9 @@
   const gchar *locale;
   gint length, j;
   gboolean found = FALSE;
 
-#ifdef G_OS_WIN32      
-  locale = g_win32_getlocale ();
-#else      
-  locale = setlocale (LC_CTYPE, NULL);
-#endif
+  locale = _gtk_get_lc_ctype ();
 
   if (strcmp (locale, "C") && strcmp (locale, "POSIX"))
     {
       /* Determine locale-specific suffixes for RC files.





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]