changeset 3571:f6cd5fe9bf4c

[xemacs-hg @ 2006-08-24 21:21:34 by aidan] Vary support for multiple-width characters on a per-console basis.
author aidan
date Thu, 24 Aug 2006 21:21:36 +0000
parents 1ebada1a4643
children 907439dd5c47
files src/ChangeLog src/console-tty-impl.h src/console-tty.c src/redisplay-tty.c src/text.c
diffstat 5 files changed, 120 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Aug 23 21:51:03 2006 +0000
+++ b/src/ChangeLog	Thu Aug 24 21:21:36 2006 +0000
@@ -1,3 +1,31 @@
+2006-08-24  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* console-tty-impl.h (struct tty_console):
+	New flag; multiple_width, specifying whether East Asian characters
+	take up two columns on this terminal. The macro to access it
+	expands to a constant under non-Mule, so anything conditionalising
+	on it will be optimised away. 
+
+	* console-tty.c:
+	* console-tty.c (tty_init_console):
+	Initialise tty_con->multiple_width; zero on non-Mule, one on Mule.
+
+	* console-tty.c (Fconsole_tty_multiple_width): New.
+	* console-tty.c (Fset_console_tty_multiple_width): New. 
+	* console-tty.c (syms_of_console_tty): Make them available outside
+	console-tty.c.
+
+	* redisplay-tty.c (tty_text_width):
+	* redisplay-tty.c (tty_output_ibyte_string):
+	Check that the relevant console has multiple-width characters
+	before using something other than the number of characters in a
+	string for the text width of that string. 
+
+	* text.c:
+	* text.c (ibyte_string_displayed_columns):
+	* text.c (ichar_string_displayed_columns):
+	Remove some Mule conditionals; add some sanity-checking. 
+	
 2006-08-23  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* syntax.c (complex_vars_of_syntax):
--- a/src/console-tty-impl.h	Wed Aug 23 21:51:03 2006 +0000
+++ b/src/console-tty-impl.h	Thu Aug 24 21:21:36 2006 +0000
@@ -200,6 +200,8 @@
   /* Is this TTY our controlling terminal? */
   unsigned int controlling_terminal :1;
   unsigned int is_stdio :1;
+  /* Do East Asian chars take up two columns? */
+  unsigned int multiple_width :1; 
 };
 
 #ifdef NEW_GC
@@ -221,6 +223,17 @@
 #define CONSOLE_TTY_FINAL_CURSOR_X(c) (CONSOLE_TTY_DATA (c)->final_cursor_x)
 #define CONSOLE_TTY_FINAL_CURSOR_Y(c) (CONSOLE_TTY_DATA (c)->final_cursor_y)
 
+/* In a more ideal world where available terminfo files actually included
+   information on whether a given TTY supports double-width characters or
+   not, oh, and where Mule was not conditional, SUPPORTS_MULTIPLE_WIDTH
+   would be as console-specific as its syntax implies.
+
+   In this world, this is overengineering more than it is anything. */
+#define CONSOLE_TTY_SUPPORTS_MULTIPLE_WIDTH(c) (1 != MAX_ICHAR_LEN)
+#define CONSOLE_TTY_MULTIPLE_WIDTH(c)			\
+	(CONSOLE_TTY_SUPPORTS_MULTIPLE_WIDTH(c) ?	\
+	 CONSOLE_TTY_DATA (c)->multiple_width : (0))
+
 #define TTY_CM(c) (CONSOLE_TTY_DATA (c)->cm)
 #define TTY_SE(c) (CONSOLE_TTY_DATA (c)->se)
 #define TTY_SD(c) (CONSOLE_TTY_DATA (c)->sd)
--- a/src/console-tty.c	Wed Aug 23 21:51:03 2006 +0000
+++ b/src/console-tty.c	Thu Aug 24 21:21:36 2006 +0000
@@ -158,6 +158,10 @@
   tty_con->terminal_type = terminal_type;
   tty_con->controlling_process = controlling_process;
 
+  /* Defaults to 1 with Mule, 0 without. In the latter case the attribute is
+     read-only from Lisp. */
+  tty_con->multiple_width = CONSOLE_TTY_SUPPORTS_MULTIPLE_WIDTH(c); 
+
   if (NILP (CONSOLE_NAME (con)))
     CONSOLE_NAME (con) = Ffile_name_nondirectory (tty);
   {
@@ -319,6 +323,51 @@
   return Qnil;
 }
 
+DEFUN ("console-tty-multiple-width", Fconsole_tty_multiple_width,
+       0, 1, 0, /*
+Return whether CONSOLE treats East Asian double-width chars as such. 
+
+CONSOLE defaults to the selected console.  Without XEmacs support for
+double-width characters, this always gives nil.
+*/
+       (console))
+{
+  return CONSOLE_TTY_MULTIPLE_WIDTH (decode_tty_console(console)) 
+    ? Qt : Qnil;
+}
+
+DEFUN ("set-console-tty-multiple-width", Fset_console_tty_multiple_width,
+       0, 2, 0, /*
+Set whether CONSOLE treats East Asian double-width characters as such.
+
+CONSOLE defaults to the selected console, and VALUE defaults to nil.
+Without XEmacs support for double-width characters, this throws an error if
+VALUE is non-nil.
+*/
+       (console, value))
+{
+  struct console *c = decode_tty_console (console);
+
+  /* So people outside of East Asia can put (set-console-tty-multiple-width
+     (selected-console) nil) in their init files, independent of whether
+     Mule is enabled. */
+  if (!CONSOLE_TTY_MULTIPLE_WIDTH (c) && NILP(value))
+    {
+      return Qnil;
+    }
+
+  if (!CONSOLE_TTY_SUPPORTS_MULTIPLE_WIDTH (c))
+    {
+      invalid_change 
+	("No console support for double-width chars",
+	 Fmake_symbol(CONSOLE_NAME(c)));
+    }
+
+  CONSOLE_TTY_DATA(c)->multiple_width = NILP(value) ? 0 : 1;
+
+  return Qnil;
+}
+
 /* #### Move this function to lisp */
 DEFUN ("set-console-tty-coding-system", Fset_console_tty_coding_system,
        0, 2, 0, /*
@@ -431,6 +480,8 @@
   DEFSUBR (Fconsole_tty_input_coding_system);
   DEFSUBR (Fset_console_tty_input_coding_system);
   DEFSUBR (Fset_console_tty_coding_system);
+  DEFSUBR (Fconsole_tty_multiple_width);
+  DEFSUBR (Fset_console_tty_multiple_width);
 }
 
 void
--- a/src/redisplay-tty.c	Wed Aug 23 21:51:03 2006 +0000
+++ b/src/redisplay-tty.c	Thu Aug 24 21:21:36 2006 +0000
@@ -100,16 +100,23 @@
 /*****************************************************************************
  tty_text_width
 
- Non-Mule tty's don't have fonts (that we use at least), so everything
+ Non-Mule TTYs don't have fonts (that we use at least), so everything
  is considered to be fixed width -- in other words, we return LEN.
  Under Mule, however, a character can still cover more than one
  column, so we use ichar_string_displayed_columns().
  ****************************************************************************/
 static int
-tty_text_width (struct frame *UNUSED (f), struct face_cachel *UNUSED (cachel),
+tty_text_width (struct frame *f, struct face_cachel *UNUSED (cachel),
 		const Ichar *str, Charcount len)
 {
-  return ichar_string_displayed_columns (str, len);
+  struct console *c = XCONSOLE(FRAME_CONSOLE (f));
+
+  if (CONSOLE_TTY_MULTIPLE_WIDTH (c))
+    {
+      return ichar_string_displayed_columns (str, len);
+    }
+
+  return len;
 }
 
 /*****************************************************************************
@@ -533,6 +540,9 @@
 {
   struct frame *f = XFRAME (w->frame);
   struct console *c = XCONSOLE (FRAME_CONSOLE (f));
+  int incing = CONSOLE_TTY_MULTIPLE_WIDTH (c) ? 
+    ibyte_string_displayed_columns (str, len) : 
+    bytecount_to_charcount(str, len);
 
   /* First position the cursor. */
   cmgoto (f, dl->ypos - 1, xpos);
@@ -541,7 +551,7 @@
   tty_turn_on_face (w, findex);
 
   send_string_to_tty_console (c, str, len);
-  TTY_INC_CURSOR_X (c, ibyte_string_displayed_columns (str, len));
+  TTY_INC_CURSOR_X (c, incing);
 
   /* Turn the face properties back off. */
   tty_turn_off_face (w, findex);
--- a/src/text.c	Wed Aug 23 21:51:03 2006 +0000
+++ b/src/text.c	Thu Aug 24 21:21:36 2006 +0000
@@ -1998,20 +1998,26 @@
 #endif
 }
 
+/* A couple of these functions should only be called on a non-Mule build. */
+#ifdef MULE
+#define ASSERT_BUILT_WITH_MULE() assert(1)
+#else /* MULE */
+#define ASSERT_BUILT_WITH_MULE() assert(0)
+#endif /* MULE */
+
 int
 ibyte_string_displayed_columns (const Ibyte *str, Bytecount len)
 {
   int cols = 0;
   const Ibyte *end = str + len;
+  Ichar ch;
+
+  ASSERT_BUILT_WITH_MULE();
 
   while (str < end)
     {
-#ifdef MULE
-      Ichar ch = itext_ichar (str);
+      ch = itext_ichar (str);
       cols += XCHARSET_COLUMNS (ichar_charset (ch));
-#else
-      cols++;
-#endif
       INC_IBYTEPTR (str);
     }
 
@@ -2019,19 +2025,17 @@
 }
 
 int
-ichar_string_displayed_columns (const Ichar *USED_IF_MULE (str), Charcount len)
+ichar_string_displayed_columns (const Ichar * USED_IF_MULE(str), Charcount len)
 {
-#ifdef MULE
   int cols = 0;
   int i;
 
+  ASSERT_BUILT_WITH_MULE();
+
   for (i = 0; i < len; i++)
     cols += XCHARSET_COLUMNS (ichar_charset (str[i]));
 
   return cols;
-#else  /* not MULE */
-  return len;
-#endif
 }
 
 Charcount