Subject: Titles in 2.4.x

From: Olivier Chapuis <[email-masked]>
Date: Sun, 3 Feb 2002 10:55:01 +0100

Hello,

I recall the problem:

If the locale gives a charset != ISO-8859-1 (or a subset of this
charset) and if the title of an application with i18n support
has non ASCII characters then the application gives a COMPOUND_TEXT
WM_NAME hints (same for the icon title).
So if fvwm is compiled without multibyte support the window title
contains string(s) of the form ?*ISO8859-15?* as the WM_NAME is
taken as a STRING.
Notes: - ISO-8859-1 is now obsolete in the all Europe
       - It seems that it is not easy to filter a COMPOUND_TEXT string
         by hands

Possible fix:
1) compile fvwm with --enable-multibyte.
2) apply the attached patch

I do not think that 1) is acceptable in the view of the state
of the I18N_MB patch (e.g., it gives memory divergence). This
patch should be used only when it is really needed (for multibyte
charset).
So, I think that I/we should apply the attached patch (+ appropriate
NEWS and ChangeLog) to 2.4.6. The patch add a new config.h variable
WEAK_I18N_SUPPORT hard coded to 1 (see below). If WEAK_I18N_SUPPORT
is defined then, fvwm2 call setlocale at initialization and non STRING
WM_[ICON_]NAME are converted using the XmbTextPropertyToTextList
function. This fix the problem (on well configured machine) and
allows fvwm to be usable with any 8bits charset without
--enable-multibyte.
One objection (from Dan) is that the use of XmbTextPropertyToTextList
causes some system to load an additional library for nothing. With the
patch you should edit config.h and comment out the WEAK_I18N_SUPPORT
line to prevent this.

So, here what I propose:
If there are no objection I will apply the patch.
Dan if you think a --disable-foo option is needed for disabling the
patch I can add it.
If there are objection(s) I will apply the patch with WEAK_I18N_SUPPORT
off by default and add a config option --enable-foo to enable the patch.

My problem with the configure option is (i) find the good name for
"foo" and (ii) document this option in INSTALL.fvwm.

Of course any comments on the patch is welcome. It is not
pretty but it is "minimal".

Olivier
Index: acconfig.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/acconfig.h,v
retrieving revision 1.39
diff -u -r1.39 acconfig.h
--- acconfig.h	2001/10/30 19:16:52	1.39
+++ acconfig.h	2002/02/03 09:52:54
@@ -80,6 +80,14 @@
 /* Enables session management functionality. */
 #undef SESSION
 
+/* Enables filtering of the wm icons and windows names by using the
+ * XmbTextPropertyToTextList functions when needed.
+ * This is used only if I18N_MB is undef. This fix problems with
+ * windows/icons names which contain non ASCII characters if the
+ * locale charset is not ISO-8859-1 */
+/* NOTE: hard coded to 1 */
+#define WEAK_I18N_SUPPORT 1
+
 /* Enables X11 multibyte character support */
 #undef I18N_MB
 
Index: fvwm/add_window.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/add_window.c,v
retrieving revision 1.236.2.3
diff -u -r1.236.2.3 add_window.c
--- fvwm/add_window.c	2002/01/17 01:18:13	1.236.2.3
+++ fvwm/add_window.c	2002/02/03 09:53:03
@@ -207,21 +207,84 @@
 
   return;
 }
-#else
+#else /* I18N_MB */
 #define GET_NAME_PROPERTY(a, b, c, d) get_name_property(a, b, c)
+#ifdef WEAK_I18N_SUPPORT
 static void get_name_property(
   Status (func)(Display *, Window, XTextProperty *), Window w, char **ret_name)
 {
   XTextProperty text_prop;
+  int num;
+  char **list;
 
+  /* Note: we dump the name because we cannot keep the list in memory
+   * without a lot of changes */
   if (func(dpy, w, &text_prop) != 0)
+  {
+    if (text_prop.value)
+    {
+      if (text_prop.encoding == XA_STRING)
+      {
+        /* STRING encoding, use this as it is */
+	CopyString(&*ret_name, (char *)text_prop.value);
+	XFree(text_prop.value);
+      }
+      else
+      {
+        /* not STRING encoding, try to convert */
+        if (XmbTextPropertyToTextList(dpy, &text_prop, &list, &num) == Success
+            && num > 0 && *list)
+	{
+          /* XXX: does not consider the conversion is REALLY succeeded */
+          XFree(text_prop.value); /* return of XGetWM(Icon)Name() */
+	  CopyString(&*ret_name, *list);
+	  if (list)
+	    XFreeStringList(list);
+        }
+	else
+	{
+          if (list)
+            XFreeStringList(list);
+          XFree(text_prop.value); /* return of XGet(Icon)WMName() */
+	  if (func(dpy, w, &text_prop))
+	  {
+	    CopyString(&*ret_name, (char *)text_prop.value);
+	    XFree(text_prop.value);
+	  }
+	  else
+	  {
+	    *ret_name = NoName;
+	  }
+        }
+      }
+    }
+    else
+    {
+      *ret_name = NoName;
+    }
+  }
+  else
+  {
+    *ret_name = NoName;
+  }
+
+  return;
+}
+#else /* WEAK_I18N_SUPPORT */
+static void get_name_property(
+  Status (func)(Display *, Window, XTextProperty *), Window w, char **ret_name)
+{
+  XTextProperty text_prop;
+
+  if (func(dpy, w, &text_prop) != 0)
     *ret_name = (char *)text_prop.value;
   else
     *ret_name = NoName;
 
   return;
 }
-#endif
+#endif /* WEAK_I18N_SUPPORT */
+#endif /* I18N_MB */
 
 void setup_window_name(FvwmWindow *tmp_win)
 {
@@ -1940,7 +2003,11 @@
 #define FREE_TEXT_PROPERTY(a, b) free_text_property(a)
 static void free_text_property(char **ptext)
 {
+#ifdef WEAK_I18N_SUPPORT
+  free(*ptext);
+#else
   XFree(*ptext);
+#endif
   *ptext = NULL;
 }
 #endif
Index: fvwm/events.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/events.c,v
retrieving revision 1.309.2.4
diff -u -r1.309.2.4 events.c
--- fvwm/events.c	2002/01/10 11:31:35	1.309.2.4
+++ fvwm/events.c	2002/02/03 09:53:16
@@ -428,7 +428,60 @@
 #if 0
 fprintf(stderr, " '%s'\n", Tmp_win->name);
 #endif
-#else
+#else /* I18N_MB */
+#ifdef WEAK_I18N_SUPPORT
+    if (!XGetWMName (dpy, Tmp_win->w, &text_prop))
+      return;
+    if (text_prop.value)
+    {
+      if (text_prop.encoding == XA_STRING)
+      {
+        /* STRING encoding, use this as it is */
+	free_window_names (Tmp_win, True, False);
+	CopyString(&Tmp_win->name, (char *)text_prop.value);
+	XFree(text_prop.value);
+      }
+      else
+      {
+	int num;
+	char **list;
+
+	fprintf(stderr,"Not a String\n");
+        /* not STRING encoding, try to convert */
+        if (XmbTextPropertyToTextList(dpy, &text_prop, &list, &num) >= Success
+            && num > 0 && *list)
+	{
+	  free_window_names (Tmp_win, True, False);
+	  fprintf(stderr,"\tSuccess\n");
+          /* XXX: does not consider the conversion is REALLY succeeded */
+          XFree(text_prop.value); /* return of XGetWMName() */
+	  CopyString(&Tmp_win->name, (char *)list[0]);
+	  if (list)
+	    XFreeStringList(list);
+        }
+	else
+	{
+          if (list)
+            XFreeStringList(list);
+          XFree(text_prop.value); /* return of XGet(Icon)WMName() */
+	  if (XGetWMName(dpy, Tmp_win->w, &text_prop))
+	  {
+	    free_window_names (Tmp_win, True, False);
+	    CopyString(&Tmp_win->name, (char *)text_prop.value);
+	    XFree(text_prop.value);
+	  }
+	  else
+	  {
+	    return;
+	  }
+        }
+      }
+    }
+    else
+    {
+      return;
+    }
+#else /* WEAK_I18N_SUPPORT */
     if (!XGetWMName(dpy, Tmp_win->w, &text_prop))
       return;
     free_window_names (Tmp_win, True, False);
@@ -436,7 +489,8 @@
     if (Tmp_win->name && strlen(Tmp_win->name) > MAX_WINDOW_NAME_LEN)
       /* limit to prevent hanging X server */
       Tmp_win->name[MAX_WINDOW_NAME_LEN] = 0;
-#endif
+#endif /* WEAK_I18N_SUPPORT */
+#endif /* I18N_MB */
 
     SET_NAME_CHANGED(Tmp_win, 1);
 
@@ -508,8 +562,59 @@
       free_window_names (Tmp_win, False, True);
       Tmp_win->icon_name = (char *)text_prop.value;
       Tmp_win->icon_name_list = NULL;
+    }
+#else /* I18N_MB */
+#ifdef WEAK_I18N_SUPPORT
+    if (!XGetWMIconName (dpy, Tmp_win->w, &text_prop))
+      return;
+    if (text_prop.value)
+    {
+      if (text_prop.encoding == XA_STRING)
+      {
+        /* STRING encoding, use this as it is */
+	free_window_names (Tmp_win, False, True);
+	CopyString(&Tmp_win->icon_name, (char *)text_prop.value);
+	XFree(text_prop.value);
+      }
+      else
+      {
+	int num;
+	char **list;
+
+        /* not STRING encoding, try to convert */
+        if (XmbTextPropertyToTextList(dpy, &text_prop, &list, &num) >= Success
+            && num > 0 && *list)
+	{
+	  free_window_names (Tmp_win, False, True);
+          /* XXX: does not consider the conversion is REALLY succeeded */
+          XFree(text_prop.value); /* return of XGetWM(Icon)Name() */
+	  CopyString(&Tmp_win->icon_name, (char *)list[0]);
+	  if (list)
+	    XFreeStringList(list);
+        }
+	else
+	{
+          if (list)
+            XFreeStringList(list);
+          XFree(text_prop.value); /* return of XGet(Icon)WMName() */
+	  if (XGetWMIconName(dpy, Tmp_win->w, &text_prop))
+	  {
+	    free_window_names (Tmp_win, False, True);
+	    CopyString(&Tmp_win->icon_name, (char *)text_prop.value);
+	    XFree(text_prop.value);
+	  }
+	  else
+	  {
+	    return;
+	  }
+        }
+      }
+    }
+    else
+    {
+      return;
     }
-#else
+#else /* WEAK_I18N_SUPPORT */
     if (!XGetWMIconName (dpy, Tmp_win->w, &text_prop))
       return;
     free_window_names (Tmp_win, False, True);
@@ -518,7 +623,8 @@
 	MAX_ICON_NAME_LEN)
       /* limit to prevent hanging X server */
       Tmp_win->icon_name[MAX_ICON_NAME_LEN] = 0;
-#endif
+#endif /* WEAK_I18N_SUPPORT */
+#endif /* I18N_MB */
     SET_WAS_ICON_NAME_PROVIDED(Tmp_win, 1);
     if (Tmp_win->icon_name == NULL)
     {
Index: fvwm/fvwm.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/fvwm.c,v
retrieving revision 1.273
diff -u -r1.273 fvwm.c
--- fvwm/fvwm.c	2001/09/16 15:51:16	1.273
+++ fvwm/fvwm.c	2002/02/03 09:53:19
@@ -75,7 +75,7 @@
 /* need to get prototype for XrmUniqueQuark for XUniqueContext call */
 #include <X11/Xresource.h>
 
-#ifdef I18N_MB
+#if defined(I18N_MB) || defined(WEAK_I18N_SUPPORT)
 #include <X11/Xlocale.h>
 #endif
 
@@ -202,9 +202,17 @@
 
   setVersionInfo();
 
-#ifdef I18N_MB
-  if (setlocale(LC_CTYPE, "") == NULL)
-    fvwm_msg(ERR, "main", "Can't set locale. Check your $LC_CTYPE or $LANG.\n");
+#if defined(I18N_MB) || defined(WEAK_I18N_SUPPORT)
+  {
+    char *s;
+
+    if ((s = setlocale(LC_CTYPE, "")) == NULL)
+      fvwm_msg(ERR, "main","Can't set locale. Check your $LC_CTYPE or $LANG.\n");
+    else if (!XSupportsLocale())
+    {
+      fvwm_msg(WARN, "main", "X does not support current locale: %s\n", s);
+    }
+  }
 #endif
 
   /* Put the default module directory into the environment so it can be used

---

From: Dan Espen <[email-masked]>
Date: Sun, 03 Feb 2002 10:54:38 -0500

>        - It seems that it is not easy to filter a COMPOUND_TEXT string
...
> "foo" and (ii) document this option in INSTALL.fvwm.

--enable-compound-text

-- 
Dan Espen
444 Hoes Lane  Room RRC 1C-214           E-mail: [email-masked]
Piscataway, NJ 08854                     Phone: (732) 699-5570
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]