xterm-141.patch.txt

# ------------------------------------------------------------------------------
# MANIFEST                             |   15 
# Makefile.in                          |    4 
# button.c                             |   97 ++-
# charproc.c                           |  267 +++++++-
# configure                            |    6 
# configure.in                         |    6 
# fontutils.c                          |  128 +++-
# fontutils.h                          |   12 
# input.c                              |  122 ++-
# main.c                               |   49 +
# main.h                               |    2 
# menu.c                               |    2 
# misc.c                               |    9 
# os2main.c                            |   29 
# ptyx.h                               |   14 
# screen.c                             |  240 +++++++
# unicode/README                       |    5 
# util.c                               |  110 +++
# version.h                            |    4 
# xterm-141/UXTerm.ad                  |   16 
# xterm-141/charclass.c                |  139 ++++
# xterm-141/charclass.h                |   11 
# xterm-141/precompose.c               | 1025 +++++++++++++++++++++++++++++++++
# xterm-141/precompose.h               |    9 
# xterm-141/unicode/make-precompose.sh |    6 
# xterm-141/unicode/precompose.c.head  |   14 
# xterm-141/unicode/precompose.c.tail  |   23 
# xterm-141/wcwidth.c                  |  129 ++++
# xterm-141/wcwidth.h                  |    9 
# xterm.h                              |   27 
# xterm.log.html                       |   18 
# xterm.man                            |   22 
# 32 files changed, 2380 insertions(+), 189 deletions(-)
# ------------------------------------------------------------------------------
Index: MANIFEST
--- xterm-140+/MANIFEST Wed May 24 11:39:17 2000
+++ xterm-141/MANIFEST  Mon Aug 14 21:43:51 2000
@@ -1,4 +1,4 @@
-MANIFEST for xterm-133, version xterm-133
+MANIFEST for xterm-141, version xterm-141
 --------------------------------------------------------------------------------
 MANIFEST                        this file
 256colres.h                     resource-definitions for 256-color mode
@@ -16,6 +16,7 @@
 Tekparse.h                      Tek4014 parser-state definitions
 Tekproc.c                       Tek4014 parser-state functions
 Tests                           Useful tests for xterm-developers
+UXTerm.ad                       alternate resources for UTF-8
 VTPrsTbl.c                      VT100 parser state tables
 VTparse.def                     template for generating VTparse.h
 VTparse.h                       VT100 parser-state definitions
@@ -23,6 +24,8 @@
 XTerm.ad                        resource definitions for XTerm class
 aclocal.m4                      configure script: custom macros
 button.c                        mouse button and selection processing
+charclass.c                     compact character-class module
+charclass.h                     interface of charclass.c
 charproc.c                      VT100 parser functions
 charsets.c                      module to translate character-sets
 config.guess                    configure script: guess the system type
@@ -50,6 +53,8 @@
 misc.c                          miscellaneous utility functions for 'xterm'
 mkdirs.sh                       configure script: make directories for install process
 os2main.c                       main program for OS/2 EMX port of 'xterm'
+precompose.c                    table of precompose sequences
+precompose.h                    interface of precompose.c
 print.c                         VT100+ print support functions
 proto.h                         macros to simplify function prototypes
 ptydata.c                       functions to manipulate data read from pty
@@ -70,6 +75,8 @@
 version.h                       version of xterm
 vms.c                           VMS version of xterm's spawn(), etc.
 vms.h                           system headers and definitions for vms.c
+wcwidth.c                       wide-character utility functions
+wcwidth.h                       interface of wcwidth.c
 xcharmouse.h                    Jason Bacon's mouse-defs, cleaned up a little
 xterm.dat                       application defaults for VMS port of 'xterm'
 xterm.h                         common includes, definitions and prototypes for 'xterm'
@@ -88,6 +95,9 @@
 unicode/README                  description of files in ./unicode
 unicode/convmap.pl              perl script for generating the lookup table for UTF-8 to keysym
 unicode/keysym.map              keysym mapping from UTF-8
+unicode/make-precompose.sh      make precompose.c
+unicode/precompose.c.head       header of precompose.c
+unicode/precompose.c.tail       tail of precompose.c
 vttests                         subdirectory
 vttests/16colors.sh             test-script to show 16-colors
 vttests/256colors.pl            script to illustrate 256-colors
@@ -100,6 +110,3 @@
 vttests/fonts.sh                script to demonstrate font-switching sequences
 vttests/resize.sh               script to demonstrate resizing
 vttests/title.sh                test-script to show title of xterm in action
-
-
-$XFree86: xc/programs/xterm/MANIFEST,v 1.6 2000/05/18 16:30:03 dawes Exp $
Index: Makefile.in
--- xterm-140+/Makefile.in      Sun Jul 23 20:18:40 2000
+++ xterm-141/Makefile.in       Mon Aug 14 18:37:50 2000
@@ -87,7 +87,7 @@
 .def.hin:
        grep '^CASE_' $< | $(AWK) '{printf "#define %s %d\n", $$1, n++}' >$@
 
-main.o: version.h
+main.o: main.h version.h
 
 $(OBJS1) : ptyx.h xtermcfg.h
 
@@ -105,7 +105,7 @@
        -rm -f $@
        perl $(srcdir)/88colres.pl > $@
 
-charproc.o : @CHARPROC_DEPS@
+charproc.o : main.h @CHARPROC_DEPS@
 
 install \
 install-bin \
Index: UXTerm.ad
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-141/UXTerm.ad Mon Aug 14 21:05:20 2000
@@ -0,0 +1,16 @@
+! $XFree86$
+
+! Use
+!      xterm -class UXTerm
+! to set resources for UTF-8 mode with corresponding fonts.
+
+#include "XTerm"
+
+*fontMenu.Label:  Unicode Fonts
+*VT100*utf8:   1
+*VT100*font2:  -misc-fixed-medium-r-normal--8-80-75-75-c-50-iso10646-1
+*VT100*font:   -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1
+*VT100*font3:  -misc-fixed-medium-r-normal--14-130-75-75-c-70-iso10646-1
+*VT100*font4:  -misc-fixed-medium-r-normal--13-120-75-75-c-80-iso10646-1
+*VT100*font5:  -misc-fixed-medium-r-normal--15-140-75-75-c-90-iso10646-1
+*VT100*font6:  -misc-fixed-medium-r-normal--20-200-75-75-c-100-iso10646-1
Index: button.c
--- xterm-140+/button.c Wed Jun 14 15:50:37 2000
+++ xterm-141/button.c  Sun Aug 13 21:31:06 2000
@@ -77,7 +77,17 @@
 #include <menu.h>
 #include <xcharmouse.h>
 
+#if OPT_WIDE_CHARS
+#include <charclass.h>
+#include <wcwidth.h>
+#else
+#define CharacterClass(value) \
+       charClass[value & ((sizeof(charClass)/sizeof(charClass[0]))-1)]
+#endif
+
 #define XTERM_CELL(row,col) getXtermCell(screen, row + screen->topline, col)
+#define XTERM_CELL_C1(row,col) getXtermCellComb1(screen, row + screen->topline, col)
+#define XTERM_CELL_C2(row,col) getXtermCellComb2(screen, row + screen->topline, col)
 
       /*
        * We reserve shift modifier for cut/paste operations.  In principle we
@@ -1487,6 +1497,13 @@
     if (rawCol > cols) rawCol = cols;
 }
 
+#if OPT_WIDE_CHARS
+int iswide(int i)
+{
+    return my_wcwidth(i) == 2;
+}
+#endif
+
 static void
 PointToRowCol(
     register int y,
@@ -1512,6 +1529,17 @@
        else if(col > screen->max_col+1) {
                col = screen->max_col+1;
        }
+#if OPT_WIDE_CHARS
+       /*
+        * If we got a click on the right half of a doublewidth character,
+        * pretend it happened on the left half.
+        */
+       if (col > 0
+        && iswide(getXtermCell(screen, row, col-1))
+        && (getXtermCell(screen, row, col) == HIDDEN_CHAR)) {
+               col -= 1;
+       }
+#endif
        *r = row;
        *c = col;
 }
@@ -1540,6 +1568,7 @@
        return(i);
 }
 
+#if !OPT_WIDE_CHARS
 /*
 ** double click table for cut and paste in 8 bits
 **
@@ -1628,6 +1657,7 @@
 
     return (0);
 }
+#endif
 
 #if OPT_WIDE_CHARS
 static int class_of(TScreen *screen, int row, int col)
@@ -1639,13 +1669,18 @@
     }
 #endif
     value = XTERM_CELL(row, col);
-    if_OPT_WIDE_CHARS(screen,{
-       /*FIXME: extend the character-class table */
+    if_OPT_WIDE_CHARS(screen, {
+       return CharacterClass(value);
     })
-    return charClass[value & ((sizeof(charClass)/sizeof(charClass[0]))-1)];
+    return CharacterClass(value);
 }
+#define ClassSelects(screen, row, col, cclass) \
+        (class_of(screen,startSRow,startSCol) == cclass \
+        || getXtermCell(screen, startSRow, startSCol) == HIDDEN_CHAR)
 #else
 #define class_of(screen,row,col) charClass[XTERM_CELL(row, col)]
+#define ClassSelects(screen, row, col, cclass) \
+        (class_of(screen,startSRow,startSCol) == cclass)
 #endif
 
 /*
@@ -1665,6 +1700,21 @@
        register int length;
        register int cclass;
 
+#if OPT_WIDE_CHARS
+       if (startCol > 1
+        && iswide(getXtermCell(screen, startRow, startCol-1))
+        && getXtermCell(screen, startRow, startCol-0) == HIDDEN_CHAR) {
+               fprintf(stderr, "Adjusting start. Changing downwards from %i.\n", startCol);
+               startCol -= 1;
+               if (endCol == (startCol+1)) endCol--;
+       }
+
+       if (iswide(getXtermCell(screen, endRow, endCol-1))
+        && getXtermCell(screen, endRow, endCol) == HIDDEN_CHAR) {
+               endCol += 1;
+       }
+#endif
+
        if (Coordinate(startRow, startCol) <= Coordinate(endRow, endCol)) {
                startSRow = startRRow = startRow;
                startSCol = startRCol = startCol;
@@ -1702,9 +1752,15 @@
                                        startSCol = LastTextCol(startSRow);
                                    }
                                } while (startSCol >= 0
-                                && class_of(screen,startSRow,startSCol) == cclass);
+                                && ClassSelects(screen, startSRow, startSCol, cclass));
                                ++startSCol;
                        }
+
+#if OPT_WIDE_CHARS
+                       if (startSCol && getXtermCell(screen, startSRow, startSCol) == HIDDEN_CHAR)
+                               startSCol++;
+#endif
+
                        if (endSCol > (LastTextCol(endSRow) + 1)) {
                                endSCol = 0;
                                endSRow++;
@@ -1720,7 +1776,7 @@
                                        length = LastTextCol(endSRow);
                                    }
                                } while (endSCol <= length
-                                && class_of(screen,endSRow,endSCol) == cclass);
+                                && ClassSelects(screen,endSRow,endSCol, cclass));
                                /* Word select selects if pointing to any char
                                   in "word", especially in that it includes
                                   the last character in a word.  So no --endSCol
@@ -1730,6 +1786,12 @@
                                        ++endSRow;
                                }
                        }
+
+#if OPT_WIDE_CHARS
+                       if (endSCol && getXtermCell(screen, endSRow, endSCol) == HIDDEN_CHAR)
+                               endSCol++;
+#endif
+
                        saveStartWRow = startSRow;
                        saveStartWCol = startSCol;
                        break;
@@ -2261,6 +2323,10 @@
     int i = 0;
     unsigned c;
     Char *result = lp;
+#if OPT_WIDE_CHARS
+    int previous = 0;
+    unsigned c_1 = 0, c_2 = 0;
+#endif
 
     i = Length(screen, row, scol, ecol);
     ecol = scol + i;
@@ -2274,8 +2340,27 @@
     for (i = scol; i < ecol; i++) {
        c = E2A(XTERM_CELL(row, i));
 #if OPT_WIDE_CHARS
-       if (screen->utf8_mode)
+       if (screen->utf8_mode) {
+           c_1 = E2A(XTERM_CELL_C1(row, i));
+           c_2 = E2A(XTERM_CELL_C2(row, i));
+       }
+
+       /* We want to strip out every occurrence of HIDDEN_CHAR AFTER a
+        * wide character.
+        */
+       if (c == HIDDEN_CHAR && iswide(previous)) {
+           previous = c;
+           continue;
+       }
+       previous = c;
+       if (screen->utf8_mode) {
            lp = convertToUTF8(lp, c);
+           if (c_1) {
+               lp = convertToUTF8(lp, c_1);
+               if (c_2)
+                   lp = convertToUTF8(lp, c_2);
+           }
+       }
        else
 #endif
        {
Index: charclass.c
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-141/charclass.c       Sun Aug 13 21:53:55 2000
@@ -0,0 +1,139 @@
+/*
+ * Compact and efficient reimplementation of the
+ * xterm character class mechanism for large character sets
+ *
+ * Markus Kuhn -- mkuhn@acm.org -- 2000-07-03
+ *
+ * Xterm allows users to select entire words with a double-click on
+ * the left mouse button. Opinions might differ on what type of
+ * characters are part of separate words, therefore xterm allows users
+ * to configure a class code for each 8-bit character. Words are
+ * maximum length sequences of neighboring characters with identical
+ * class code. Extending this mechanism to Unicode naively would
+ * create an at least 2^16 entries (128 kB) long class code table.
+ * Instead, we transform the character class table into a list
+ * of intervals, that will be accessed via a linear search.
+ * Changes made to the table by the user will be appended. A special
+ * class code -1 (default) marks characters who have their code number
+ * as the class code. We could alternatively use a sorted table of
+ * non-overlapping intervals that can be accessed via binary search,
+ * but merging in new intervals is significantly more hassle and
+ * not worth the effort here.
+ */
+
+#include <xterm.h>
+#include <charclass.h>
+
+#if OPT_WIDE_CHARS
+
+#include <stdlib.h>
+
+struct classentry {
+  int class;
+  int first;
+  int last;
+} *classtab;
+
+/*
+ * Special convention for classtab[0]:
+ * - classtab[0].class is the allocated number of entries in classtab
+ * - classtab[0].first = 1 (first used entry in classtab)
+ * - classtab[0].last is the last used entry in classtab
+ */
+
+int SetCharacterClassRange(int low, int high, int value)
+{
+  if (high < low)
+    return -1; /* nothing to do */
+
+  /* make sure we have at least one free entry left at table end */
+  if (classtab[0].last > classtab[0].class - 2) {
+    classtab[0].class += 5 + classtab[0].class/4;
+    classtab = realloc(classtab,
+                       classtab[0].class * sizeof(struct classentry));
+    if (!classtab)
+      abort();
+  }
+
+  /* simply append new interval to end of interval array */
+  classtab[0].last++;
+  classtab[classtab[0].last].first = low;
+  classtab[classtab[0].last].last  = high;
+  classtab[classtab[0].last].class = value;
+
+  return 0;
+}
+
+void init_classtab(void)
+{
+  const int size = 50;
+
+  classtab = (struct classentry *) malloc(size * sizeof(struct classentry));
+  if (!classtab)
+    abort();
+  classtab[0].class = size;
+  classtab[0].first = 1;
+  classtab[0].last = 0;
+  
+  /* old xterm default classes */
+  SetCharacterClassRange(0, 0, 32);
+  SetCharacterClassRange(1, 31, 1);
+  SetCharacterClassRange('\t', '\t', 32);
+  SetCharacterClassRange('0', '9', 48);
+  SetCharacterClassRange('A', 'Z', 48);
+  SetCharacterClassRange('_', '_', 48);
+  SetCharacterClassRange('a', 'z', 48);
+  SetCharacterClassRange(127, 159, 1);
+  SetCharacterClassRange(160, 191, -1);
+  SetCharacterClassRange(192, 255, 48);
+  SetCharacterClassRange(215, 215, 216);
+  SetCharacterClassRange(247, 247, 248);
+
+  /* added Unicode classes */
+  SetCharacterClassRange(0x0100, 0xffdf, 48); /* mostly characters */
+  SetCharacterClassRange(0x037e, 0x037e, -1); /* Greek question mark */
+  SetCharacterClassRange(0x0387, 0x0387, -1); /* Greek ano teleia */
+  SetCharacterClassRange(0x055a, 0x055f, -1); /* Armenian punctuation */
+  SetCharacterClassRange(0x0589, 0x0589, -1); /* Armenian full stop */
+  SetCharacterClassRange(0x0700, 0x070d, -1); /* Syriac punctuation */
+  SetCharacterClassRange(0x104a, 0x104f, -1); /* Myanmar punctuation */
+  SetCharacterClassRange(0x10fb, 0x10fb, -1); /* Georgian punctuation */
+  SetCharacterClassRange(0x1361, 0x1368, -1); /* Ethiopic punctuation */
+  SetCharacterClassRange(0x166d, 0x166e, -1); /* Canadian Syl. punctuation */
+  SetCharacterClassRange(0x17d4, 0x17dc, -1); /* Khmer punctuation */
+  SetCharacterClassRange(0x1800, 0x180a, -1); /* Mongolian punctuation */
+  SetCharacterClassRange(0x2000, 0x200a, 32); /* spaces */
+  SetCharacterClassRange(0x200b, 0x27ff, -1); /* punctuation and symbols */
+  SetCharacterClassRange(0x2070, 0x207f, 0x2070); /* superscript */
+  SetCharacterClassRange(0x2080, 0x208f, 0x2080); /* subscript */
+  SetCharacterClassRange(0x3000, 0x3000, 32); /* ideographic space */
+  SetCharacterClassRange(0x3001, 0x3020, -1); /* ideographic punctuation */
+  SetCharacterClassRange(0x3040, 0x309f, 0x3040); /* Hiragana */
+  SetCharacterClassRange(0x30a0, 0x30ff, 0x30a0); /* Katakana */
+  SetCharacterClassRange(0x3300, 0x9fff, 0x4e00); /* CJK Ideographs */
+  SetCharacterClassRange(0xac00, 0xd7a3, 0xac00); /* Hangul Syllables */
+  SetCharacterClassRange(0xf900, 0xfaff, 0x4e00); /* CJK Ideographs */
+  SetCharacterClassRange(0xfe30, 0xfe6b, -1); /* punctuation forms */
+  SetCharacterClassRange(0xff00, 0xff0f, -1); /* half/fullwidth ASCII */
+  SetCharacterClassRange(0xff1a, 0xff20, -1); /* half/fullwidth ASCII */
+  SetCharacterClassRange(0xff3b, 0xff40, -1); /* half/fullwidth ASCII */
+  SetCharacterClassRange(0xff5b, 0xff64, -1); /* half/fullwidth ASCII */
+
+  return;
+}
+
+int CharacterClass(int c)
+{
+  int i, class = -1;
+
+  for (i = classtab[0].first; i <= classtab[0].last; i++)
+    if (classtab[i].first <= c && classtab[i].last >= c)
+      class = classtab[i].class;
+
+  if (class < 0)
+    class = c;
+  
+  return class;
+}
+
+#endif
Index: charclass.h
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-141/charclass.h       Sun Aug 13 17:08:22 2000
@@ -0,0 +1,11 @@
+#ifndef CHARCLASS_H
+#define CHARCLASS_H
+
+extern void init_classtab(void);
+/* intialise the table. needs calling before either of the 
+   others. */
+
+extern int SetCharacterClassRange(int low, int high, int value);
+extern int CharacterClass(int c);
+
+#endif
Index: charproc.c
--- xterm-140+/charproc.c       Sun Jul 23 16:08:11 2000
+++ xterm-141/charproc.c        Sun Aug 13 19:57:19 2000
@@ -99,6 +99,11 @@
 #include <X11/Xaw/XawImP.h>
 #endif
 
+#if OPT_WIDE_CHARS
+#include <wcwidth.h>
+#include <precompose.h>
+#endif
+
 #include <stdio.h>
 #include <ctype.h>
 
@@ -529,7 +534,8 @@
 {XtNutf8, XtCUtf8, XtRInt, sizeof(int),
        XtOffsetOf(XtermWidgetRec, screen.utf8_mode),
        XtRString, defaultUTF8},
-Bres(XtNwideChars, XtCWideChars, screen.wide_chars, FALSE),
+Bres(XtNwideChars,     XtCWideChars,   screen.wide_chars,      FALSE),
+Sres(XtNwideFont,      XtCWideFont,    misc.f_w,               DEFWIDEFONT),
 #endif
 };
 
@@ -763,6 +769,8 @@
            XSelectInput(XtDisplay((t)), XtWindow((t)), (s)->event_mask);       \
        }
 
+extern int last_written_col, last_written_row;
+
 static void VTparse(void)
 {
        /* Buffer for processing printable text */
@@ -788,6 +796,7 @@
        int lastchar;           /* positive iff we had a graphic character */
        int nextstate;
        int laststate;
+       int last_was_wide;
 
        /* We longjmp back to this point in VTReset() */
        (void)setjmp(vtjmpbuf);
@@ -802,11 +811,48 @@
        string_mode = 0;
        lastchar = -1;          /* not a legal IChar */
        nextstate = -1;         /* not a legal state */
+       last_was_wide = 0;
 
        for( ; ; ) {
            int thischar = -1;
            c = doinput();
 
+#if OPT_WIDE_CHARS
+           if (my_wcwidth(c) == 0) {
+               unsigned single = 0;
+               int prev, precomposed;
+
+               if (screen->curss) {
+                   dotext(screen, screen->gsets[(int)(screen->curss)],
+                          print_area, 1);
+                   screen->curss = 0;
+                   single++;
+               }
+               if (print_used > single) {
+                   dotext(screen,
+                           screen->gsets[(int)(screen->curgl)],
+                           print_area + single,
+                           print_used - single);
+               }
+               print_used = 0;
+
+               prev = getXtermCell(screen, last_written_row, last_written_col);
+               precomposed = do_precomposition(prev, c);
+
+               if (precomposed != -1) {
+                   putXtermCell(screen, last_written_row, last_written_col, precomposed);
+                   ScrnRefresh(screen, last_written_row, last_written_col, 1, 1, 1);
+                   continue;
+               } else {
+                   addXtermCombining(screen, last_written_row, last_written_col, c);
+                   if (!screen->scroll_amt)
+                       ScrnRefresh(screen, last_written_row, last_written_col, 1, 1, 1);
+                       /* does this suffice? */
+                   continue;
+               }
+           }
+#endif
+
            /* Intercept characters for printer controller mode */
            if (screen->printer_controlmode == 2) {
                if ((c = xtermPrinterControl(c)) == 0)
@@ -859,6 +905,31 @@
 #endif
              nextstate = parsestate[E2A(c)];
 
+#if OPT_WIDE_CHARS
+           /* if this character is a different width than
+              the last one, put the previous text into
+              the buffer and draw it now */
+
+           if (iswide(c) != last_was_wide) {
+               unsigned single = 0;
+
+               if (screen->curss) {
+                   dotext(screen,
+                           screen->gsets[(int)(screen->curss)],
+                           print_area, 1);
+                   screen->curss = 0;
+                   single++;
+               }
+               if (print_used > single) {
+                   dotext(screen,
+                           screen->gsets[(int)(screen->curgl)],
+                           print_area + single,
+                           print_used - single);
+               }
+               print_used = 0;
+           }
+#endif
+
            /*
             * Accumulate string for printable text.  This may be 8/16-bit
             * characters.
@@ -884,6 +955,9 @@
                print_area = new_string;
                print_size = new_length;
                print_area[print_used++] = lastchar = thischar = c;
+#if OPT_WIDE_CHARS
+               last_was_wide = iswide(c);
+#endif
                if (morePtyData(&VTbuffer)) {
                    continue;
                }
@@ -2598,12 +2672,17 @@
        IChar   *buf,           /* start of characters to process */
        Cardinal len)           /* end */
 {
-       int this_col;           /* must be signed */
-       Cardinal n, next_col, offset, last_col;
+#if OPT_WIDE_CHARS
+       Cardinal chars_chomped;
+#else
+       int next_col, last_col, this_col;       /* must be signed */
+#endif
+       Cardinal n, offset;
 
 #if OPT_WIDE_CHARS
        if (!screen->utf8_mode || charset == '0') /* don't translate if we use UTF-8 */
 #endif
+
        if (!xtermCharSetOut(buf, buf+len, charset))
                return;
 
@@ -2616,27 +2695,43 @@
                }
        })
 
-       for (offset = 0; offset < len; offset += this_col) {
-               last_col = CurMaxCol(screen, screen->cur_row);
-               this_col = last_col - screen->cur_col +1;
-               if (this_col <= 1) {
-                       if (screen->do_wrap && (term->flags & WRAPAROUND)) {
-                           /* mark that we had to wrap this line */
-                           ScrnSetWrapped(screen, screen->cur_row);
-                           xtermAutoPrint('\n');
-                           xtermIndex(screen, 1);
-                           screen->cur_col = 0;
-                           screen->do_wrap = 0;
-                           this_col = last_col + 1;
-                       } else
-                           this_col = 1;
+
+#if OPT_WIDE_CHARS
+       for (offset = 0; offset < len; offset += chars_chomped) {
+               int width_available = screen->max_col - screen->cur_col + 1;
+               int width_here = 0, need_wrap = 0;
+               chars_chomped = 0;
+
+               if (screen->do_wrap && (term->flags & WRAPAROUND)) {
+                       /* mark that we had to wrap this line */
+                       ScrnSetWrapped(screen, screen->cur_row);
+                       xtermAutoPrint('\n');
+                       xtermIndex(screen, 1);
+                       screen->cur_col = 0;
+                       screen->do_wrap = 0;
+                       width_available = screen->max_col - screen->cur_col + 1;
                }
-               if (offset + this_col > len) {
-                       this_col = len - offset;
+
+               while (width_here <= width_available && chars_chomped < (len - offset)) {
+                       width_here += my_wcwidth(buf[chars_chomped + offset]);
+                       chars_chomped ++;
+               }
+
+               if (width_here > width_available) {
+                       chars_chomped --;
+                       width_here -= my_wcwidth(buf[chars_chomped + offset]);
+                       need_wrap = 1;
+               }
+
+               if (width_here = 0) {
+                       screen->do_wrap = 0;
+                       continue;
+               }
+
+               if (chars_chomped != (len - offset)) {
+                       need_wrap = 1;
                }
-               next_col = screen->cur_col + this_col;
 
-#if OPT_WIDE_CHARS
                /*
                 * Split the wide characters back into separate arrays of 8-bit
                 * characters so we can use the existing interface.
@@ -2651,12 +2746,12 @@
                        Boolean both = False;
                        unsigned j, k;
 
-                       if (this_col >= (int) limit) {
-                               limit = (this_col + 1) * 2;
+                       if (chars_chomped >= limit) {
+                               limit = (chars_chomped + 1) * 2;
                                lobyte = (Char *)XtRealloc((char *)lobyte, limit);
                                hibyte = (Char *)XtRealloc((char *)hibyte, limit);
                        }
-                       for (j = offset; j < offset+this_col; j++) {
+                       for (j = offset; j < offset+chars_chomped; j++) {
                                k = j-offset;
                                lobyte[k] = buf[j];
                                if (buf[j] > 255) {
@@ -2669,13 +2764,35 @@
 
                        WriteText(screen, PAIRED_CHARS(
                                lobyte,
-                               both ? hibyte : 0), this_col);
+                               both ? hibyte : 0), chars_chomped);
                }
+               screen->do_wrap = need_wrap;
+       }
 #else
+
+       for (offset = 0; offset < len; offset += this_col) {
+               last_col = CurMaxCol(screen, screen->cur_row);
+               this_col = last_col - screen->cur_col +1;
+               if (this_col <= 1) {
+                       if (screen->do_wrap && (term->flags & WRAPAROUND)) {
+                           /* mark that we had to wrap this line */
+                           ScrnSetWrapped(screen, screen->cur_row);
+                           xtermAutoPrint('\n');
+                           xtermIndex(screen, 1);
+                           screen->cur_col = 0;
+                           screen->do_wrap = 0;
+                           this_col = last_col + 1;
+                       } else
+                           this_col = 1;
+               }
+               if (offset + this_col > len) {
+                       this_col = len - offset;
+               }
+               next_col = screen->cur_col + this_col;
+
                WriteText(screen, PAIRED_CHARS(
                        buf+offset,
                        buf2 ? buf2+offset : 0), this_col);
-#endif
 
                /*
                 * the call to WriteText updates screen->cur_col.
@@ -2684,6 +2801,8 @@
                 */
                screen->do_wrap = (screen->cur_col < (int)next_col);
        }
+
+#endif
 }
 
 #if HANDLE_STRUCT_NOTIFY
@@ -2699,6 +2818,24 @@
 static int mapstate = -1;
 #endif /* HANDLE_STRUCT_NOTIFY */
 
+#if OPT_WIDE_CHARS
+int visual_width(PAIRED_CHARS(Char *str, Char *str2), Cardinal len) {
+       /* returns the visual width of a string (doublewide characters count
+          as 2, normalwide characters count as 1) */
+       int my_len = 0;
+       while (len) {
+               int ch = *str;
+               if (str2) ch |= *str2 << 8;
+               if (str) str++;
+               if (str2) str2++;
+               if (iswide(ch)) my_len += 2;
+               else my_len++;
+               len--;
+       }
+       return my_len;
+}
+#endif
+
 /*
  * write a string str of length len onto the screen at
  * the current cursor position.  update cursor position.
@@ -2720,8 +2857,9 @@
                if(screen->cursor_state)
                        HideCursor();
 
-               if (flags & INSERT)
-                       InsertChar(screen, len);
+               if (flags & INSERT) {
+                       InsertChar(screen, visual_width(PAIRED_CHARS(str, str2), len));
+               }
                if (!AddToRefresh(screen)) {
                        /* make sure that the correct GC is current */
                        currentGC = updatedXtermGC(screen, flags, fg_bg, False);
@@ -2762,7 +2900,7 @@
                }
        }
        ScreenWrite(screen, PAIRED_CHARS(str, str2), flags, fg_bg, len);
-       CursorForward(screen, len);
+       CursorForward(screen, visual_width(PAIRED_CHARS(str, str2), len));
 #if OPT_ZICONBEEP
        /* Flag icon name with "***"  on window output when iconified.
         */
@@ -4242,7 +4380,7 @@
       TRACE(("initialized UTF-8 mode\n"));
    }
    if (wnew->screen.wide_chars != False)
-      wnew->num_ptrs = (OFF_WIDEC+1);
+      wnew->num_ptrs = (OFF_COM2H+1);
 #endif
 
    wnew->screen.bold_mode = request->screen.bold_mode;
@@ -4353,13 +4491,19 @@
        TabReset (term->tabs);
 
        screen->menu_font_names[fontMenu_fontdefault] = term->misc.f_n;
-       screen->fnt_norm = screen->fnt_bold = NULL;
-       if (!xtermLoadFont(screen, term->misc.f_n, term->misc.f_b, False, 0)) {
+       screen->fnt_norm = screen->fnt_bold = screen->fnt_dwd = NULL;
+       if (!xtermLoadFont(screen,
+                          VT_FONTSET(term->misc.f_n,
+                                     term->misc.f_b,
+                                     term->misc.f_w),
+                          False, 0)) {
            if (XmuCompareISOLatin1(term->misc.f_n, "fixed") != 0) {
                fprintf (stderr,
                     "%s:  unable to open font \"%s\", trying \"fixed\"....\n",
                     xterm_name, term->misc.f_n);
-               (void) xtermLoadFont (screen, "fixed", NULL, False, 0);
+               (void) xtermLoadFont (screen,
+                                     VT_FONTSET("fixed", NULL, NULL),
+                                     False, 0);
                screen->menu_font_names[fontMenu_fontdefault] = "fixed";
            }
        }
@@ -4720,8 +4864,9 @@
        if(curvt->misc.f_n != newvt->misc.f_n)
            newvt->screen.menu_font_names[fontMenu_fontdefault] = newvt->misc.f_n;
        if (xtermLoadFont(&newvt->screen,
-                       newvt->screen.menu_font_names[curvt->screen.menu_font_number],
-                       newvt->screen.menu_font_names[curvt->screen.menu_font_number],
+                       VT_FONTSET(newvt->screen.menu_font_names[curvt->screen.menu_font_number],
+                                  newvt->screen.menu_font_names[curvt->screen.menu_font_number],
+                                  NULL),
                        TRUE, newvt->screen.menu_font_number)) {
            /* resizing does the redisplay, so don't ask for it here */
            refresh_needed = TRUE;
@@ -4776,6 +4921,10 @@
 #endif
 #if OPT_WIDE_CHARS
        Char    chi = 0;
+       Char    c1h = 0;
+       Char    c1l = 0;
+       Char    c2h = 0;
+       Char    c2l = 0;
 #endif
 
        if (screen->cursor_state == BLINKED_OFF)
@@ -4801,6 +4950,10 @@
 
        if_OPT_WIDE_CHARS(screen,{
            chi = SCRN_BUF_WIDEC(screen, screen->cursor_row)[screen->cursor_col];
+           c1l = SCRN_BUF_COM1L(screen, screen->cursor_row)[screen->cursor_col];
+           c1h = SCRN_BUF_COM1H(screen, screen->cursor_row)[screen->cursor_col];
+           c2l = SCRN_BUF_COM2L(screen, screen->cursor_row)[screen->cursor_col];
+           c2h = SCRN_BUF_COM2H(screen, screen->cursor_row)[screen->cursor_col];
        })
 
        if (clo == 0
@@ -4907,6 +5060,21 @@
                curXtermChrSet(screen->cur_row),
                PAIRED_CHARS(&clo, &chi), 1);
 
+#if OPT_WIDE_CHARS
+       if (c1l || c1h) {
+               drawXtermText(screen, flags, currentGC,
+                             x, y,
+                             curXtermChrSet(screen->cur_row),
+                             PAIRED_CHARS(&c1l, &c1h), 1);
+
+               if (c2l || c2h)
+                       drawXtermText(screen, flags, currentGC,
+                                     x, y,
+                                     curXtermChrSet(screen->cur_row),
+                                     PAIRED_CHARS(&c2l, &c2h), 1);
+       }
+#endif
+
        if (!screen->select && !screen->always_highlight) {
                screen->box->x = x;
                screen->box->y = y;
@@ -4928,10 +5096,15 @@
        GC      currentGC;
        register int flags;
        register int fg_bg = 0;
+       int x, y;
        Char    clo;
        Boolean in_selection;
 #if OPT_WIDE_CHARS
        Char    chi = 0;
+       Char    c1h = 0;
+       Char    c1l = 0;
+       Char    c2h = 0;
+       Char    c2l = 0;
 #endif
 
        if (screen->cursor_state == OFF)        /* FIXME */
@@ -4959,6 +5132,10 @@
 
        if_OPT_WIDE_CHARS(screen,{
            chi = SCRN_BUF_WIDEC(screen, screen->cursor_row)[screen->cursor_col];
+           c1l = SCRN_BUF_COM1L(screen, screen->cursor_row)[screen->cursor_col];
+           c1h = SCRN_BUF_COM1H(screen, screen->cursor_row)[screen->cursor_col];
+           c2l = SCRN_BUF_COM2L(screen, screen->cursor_row)[screen->cursor_col];
+           c2h = SCRN_BUF_COM2H(screen, screen->cursor_row)[screen->cursor_col];
        })
 
        if (screen->cursor_row > screen->endHRow ||
@@ -4984,11 +5161,25 @@
        TRACE(("%s @%d, HideCursor calling drawXtermText cur(%d,%d)\n", __FILE__, __LINE__,
                screen->cursor_row, screen->cursor_col));
        drawXtermText(screen, flags, currentGC,
-               CurCursorX(screen, screen->cursor_row, screen->cursor_col),
-               CursorY(screen, screen->cursor_row),
+               x = CurCursorX(screen, screen->cursor_row, screen->cursor_col),
+               y = CursorY(screen, screen->cursor_row),
                curXtermChrSet(screen->cursor_row),
                PAIRED_CHARS(&clo, &chi), 1);
 
+#if OPT_WIDE_CHARS
+       if (c1l || c1h) {
+               drawXtermText (screen, flags, currentGC,
+                               x, y,
+                               curXtermChrSet(screen->cur_row),
+                               PAIRED_CHARS(&c1l, &c1h), 1);
+
+               if (c2l || c2h)
+                       drawXtermText (screen, flags, currentGC,
+                                       x, y,
+                                       curXtermChrSet(screen->cur_row),
+                                       PAIRED_CHARS(&c2l, &c2h), 1);
+       }
+#endif
        screen->cursor_state = OFF;
        resetXtermGC(screen, flags, in_selection);
 }
@@ -5362,7 +5553,7 @@
           we are a little more liberal here. */
        if (len > 1000  ||  strchr(val, '\n'))
            return;
-       if (!xtermLoadFont (&term->screen, val, NULL, True, fontMenu_fontsel))
+       if (!xtermLoadFont (&term->screen, VT_FONTSET(val, NULL, NULL), True, fontMenu_fontsel))
            Bell(XkbBI_MinorError,0);
     }
 }
Index: configure
--- xterm-140+/configure        Thu Jul 20 22:06:02 2000
+++ xterm-141/configure Sun Aug 13 17:45:21 2000
@@ -5687,9 +5687,9 @@
 #define OPT_WIDE_CHARS 1
 EOF
 
-       EXTRAHDRS="$EXTRAHDRS keysym2ucs.h"
-       EXTRASRCS="$EXTRASRCS keysym2ucs.c"
-       EXTRAOBJS="$EXTRAOBJS keysym2ucs.o"
+       EXTRAHDRS="$EXTRAHDRS charclass.h keysym2ucs.h precompose.h wcwidth.h"
+       EXTRASRCS="$EXTRASRCS charclass.c keysym2ucs.c precompose.c wcwidth.c"
+       EXTRAOBJS="$EXTRAOBJS charclass.o keysym2ucs.o precompose.o wcwidth.o"
 fi
 
 echo $ac_n "checking if you want DECterm Locator support""... $ac_c" 1>&6
Index: configure.in
--- xterm-140+/configure.in     Wed Jun 14 15:50:37 2000
+++ xterm-141/configure.in      Sun Aug 13 17:44:00 2000
@@ -440,9 +440,9 @@
 AC_MSG_RESULT($enable_wchar)
 if test $enable_wchar = yes ; then
        AC_DEFINE(OPT_WIDE_CHARS,1)
-       EXTRAHDRS="$EXTRAHDRS keysym2ucs.h"
-       EXTRASRCS="$EXTRASRCS keysym2ucs.c"
-       EXTRAOBJS="$EXTRAOBJS keysym2ucs.o"
+       EXTRAHDRS="$EXTRAHDRS charclass.h keysym2ucs.h precompose.h wcwidth.h"
+       EXTRASRCS="$EXTRASRCS charclass.c keysym2ucs.c precompose.c wcwidth.c"
+       EXTRAOBJS="$EXTRAOBJS charclass.o keysym2ucs.o precompose.o wcwidth.o"
 fi
 
 AC_MSG_CHECKING(if you want DECterm Locator support)
Index: fontutils.c
--- xterm-140+/fontutils.c      Sat Jun 17 14:42:47 2000
+++ xterm-141/fontutils.c       Mon Aug 14 20:53:05 2000
@@ -92,14 +92,20 @@
 typedef struct {
      /* registry, foundry, family */
      char *beginning;
-     char *width;
-     /* slant, width, add_style */
-     char *middle;
+     /* weight */
+     char *weight;
+     /* slant */
+     char *slant;
+     /* wideness */
+     char *wideness;
+     /* add style */
+     char *add_style;
      int pixel_size;
      char *point_size;
      int res_x;
      int res_y;
      char *spacing;
+     int average_width;
      /* charset registry, charset encoding */
      char *end;
 } FontNameProperties;
@@ -196,11 +202,19 @@
                return 0;
 
        /* weight is the next */
-       if ((props.width = n_fields(&name, 1, 1)) == 0)
+       if ((props.weight = n_fields(&name, 1, 1)) == 0)
                return 0;
 
-       /* slant, width, add style */
-       if ((props.middle = n_fields(&name, 1, 3)) == 0)
+       /* slant */
+       if ((props.slant = n_fields(&name, 1, 1)) == 0)
+               return 0;
+
+       /* width */
+       if ((props.wideness = n_fields(&name, 1, 1)) == 0)
+               return 0;
+
+       /* add style */
+       if ((props.add_style = n_fields(&name, 1, 1)) == 0)
                return 0;
 
        /* pixel size */
@@ -229,9 +243,11 @@
        if ((props.spacing = n_fields(&name, 1, 1)) == 0)
                return 0;
 
-       /* skip the average width */
+       /* average width */
        if ((str = n_fields(&name, 1, 1)) == 0)
                return 0;
+       if ((props.average_width = atoi(str)) == 0)
+               return 0;
 
        /* the rest: charset registry and charset encoding */
        props.end = name;
@@ -254,18 +270,47 @@
       * "<beginning>-bold-<middle>-<pixel_size>-<point_size>-<res_x>-<res_y>"\
       * "-<spacing>-*-<end>"
       */
-     sprintf(ret, "%s-bold-%s-%d-%s-%d-%d-%s-*-%s",
+     sprintf(ret, "%s-bold-%s-%s-%s-%d-%s-%d-%d-%s-*-%s",
+            props->beginning,
+            props->slant,
+            props->wideness,
+            props->add_style,
+            props->pixel_size,
+            props->point_size,
+            props->res_x,
+            props->res_y,
+            props->spacing,
+            props->end);
+     return ret;
+}
+
+#if OPT_WIDE_CHARS
+/* like bold_font_name, but doubles AVERAGE_WIDTH */
+static char *
+wide_font_name(FontNameProperties *props)
+{
+     static char ret[MAX_FONTNAME];
+
+     /*
+      * Put together something in the form
+      * "<beginning>-bold-<middle>-<pixel_size>-<point_size>-<res_x>-<res_y>"\
+      * "-<spacing>-*-<end>"
+      */
+     sprintf(ret, "%s-%s-%s-*-*-%d-%s-%d-%d-%s-%i-%s",
             props->beginning,
-            props->middle,
+            props->weight,
+            props->slant,
             props->pixel_size,
             props->point_size,
             props->res_x,
             props->res_y,
             props->spacing,
+            props->average_width * 2,
             props->end);
 
      return ret;
 }
+#endif /* OPT_WIDE_CHARS */
 
 #if OPT_DEC_CHRSET
 /*
@@ -301,7 +346,7 @@
        if (atts & BOLD)
                width = "bold";
        else
-               width = props->width;
+               width = props->weight;
 
        if (CSET_DOUBLE(chrset))
                res_x *= 2;
@@ -330,10 +375,12 @@
        }
 #endif
 
-       sprintf(tmp, "%s-%s-%s-%d-%s-%d-%d-%s-*-%s",
+       sprintf(tmp, "%s-%s-%s-%s-%s-%d-%s-%d-%d-%s-*-%s",
                props->beginning,
                width,
-               props->middle,
+               props->slant,
+               props->wideness,
+               props->add_style,
                pixel_size,
                props->point_size,
                res_x,
@@ -430,8 +477,7 @@
 int
 xtermLoadFont (
        TScreen *screen,
-       char *nfontname,
-       char *bfontname,
+       VT_FONTSET(char *nfontname, char *bfontname, char *wfontname),
        Bool doresize,
        int fontnum)
 {
@@ -439,6 +485,7 @@
        FontNameProperties *fp;
        XFontStruct *nfs = NULL;
        XFontStruct *bfs = NULL;
+       XFontStruct *wfs = NULL;
        XGCValues xgcv;
        unsigned long mask;
        GC new_normalGC      = NULL;
@@ -468,6 +515,7 @@
        if (EmptyFont(nfs))
                goto bad;               /* can't use a 0-sized font */
 
+
        strcpy(normal, nfontname);
        if (bfontname == 0) {
                fp = get_font_name_props(screen->display, nfs, normal);
@@ -490,6 +538,30 @@
                TRACE(("...cannot load bold font %s\n", bfontname));
        }
 
+       /* if there is no widefont specified, fake it by doubling
+        * AVERAGE_WIDTH of normal fonts XLFD, and asking for it.
+        * This plucks out 18x18ja and 12x13ja as the corresponding
+        * fonts for 9x18 and 6x13.
+        */
+       if_OPT_WIDE_CHARS(screen, {
+               if (wfontname == 0) {
+                       fp = get_font_name_props(screen->display, nfs, normal);
+                       if (fp != 0) {
+                               wfontname = wide_font_name(fp);
+                               TRACE(("...derived wide %s\n", wfontname));
+                       }
+               }
+               if (wfontname
+                && (wfs = XLoadQueryFont( screen->display, wfontname)) == 0) {
+               }
+       })
+
+       /* Most of the time this call to load the font will succeed, even if there is
+        * no wide font : the X server doubles the width of the normal font, or similar.
+        *
+        * But if it did fail for some reason, then nevermind.
+        */
+
        if (EmptyFont(bfs))
                goto bad;               /* can't use a 0-sized font */
 
@@ -507,8 +579,9 @@
                 */
                if (bfontname != 0) {
                        return xtermLoadFont (screen,
-                                             nfontname,
+                                             VT_FONTSET(nfontname,
                                              NULL,     /* throw it away! */
+                                             wfontname),
                                              doresize,
                                              fontnum);
                }
@@ -529,6 +602,9 @@
                proportional = True;
        }
 
+       /* TODO : enforce that the width of the wide font is 2* the width
+          of the narrow font */
+
        mask = (GCFont | GCForeground | GCBackground | GCGraphicsExposures |
        GCFunction);
 
@@ -592,6 +668,7 @@
 
        screen->fnt_norm = nfs;
        screen->fnt_bold = bfs;
+       screen->fnt_dwd = wfs;
        screen->fnt_prop = proportional;
        screen->fnt_boxes = True;
 
@@ -762,6 +839,9 @@
                else {
                        CI_GET_CHAR_INFO_2D (font, (ch >> 8), (ch & 0xff), tmp, pc);
                }
+#else
+
+               if (!pc) return False; /* Urgh! */
 #endif
 
                if (CI_NONEXISTCHAR(pc)) {
@@ -1082,7 +1162,7 @@
                        m = n;
        }
        if (m >= 0) {
-               SetVTFont (m, TRUE, NULL, NULL);
+               SetVTFont (m, TRUE, VT_FONTSET(NULL, NULL, NULL));
        } else {
                Bell(XkbBI_MinorError,0);
        }
@@ -1108,7 +1188,7 @@
                        m = n;
        }
        if (m >= 0) {
-               SetVTFont (m, TRUE, NULL, NULL);
+               SetVTFont (m, TRUE, VT_FONTSET(NULL, NULL, NULL));
        } else {
                Bell(XkbBI_MinorError,0);
        }
@@ -1124,7 +1204,7 @@
        Cardinal *param_count)
 {
     int fontnum;
-    char *name1 = NULL, *name2 = NULL;
+    char *name1 = NULL, *name2 = NULL, *name3 = NULL;
 
     if (*param_count == 0) {
        fontnum = fontMenu_fontdefault;
@@ -1147,7 +1227,7 @@
          case '6':
            fontnum = fontMenu_font6; break;
          case 'e': case 'E':
-           fontnum = fontMenu_fontescape; maxparams = 3; break;
+           fontnum = fontMenu_fontescape; maxparams = 4; break;
          case 's': case 'S':
            fontnum = fontMenu_fontsel; maxparams = 2; break;
          default:
@@ -1159,6 +1239,9 @@
            return;
        }
        switch (*param_count) {         /* assign 'em */
+         case 4:
+           name3 = params[3];
+           /* FALLTHRU */
          case 3:
            name2 = params[2];
            /* FALLTHRU */
@@ -1168,14 +1251,13 @@
        }
     }
 
-    SetVTFont (fontnum, True, name1, name2);
+    SetVTFont (fontnum, True, VT_FONTSET(name1, name2, name3));
 }
 
 void SetVTFont (
        int i,
        Bool doresize,
-       char *name1,
-       char *name2)
+       VT_FONTSET(char *name1, char *name2, char *name3))
 {
     TScreen *screen = &term->screen;
 
@@ -1190,7 +1272,7 @@
        } else {
            if (name1 == 0)
                name1 = screen->menu_font_names[i];
-           if (xtermLoadFont(screen, name1, name2, doresize, i)) {
+           if (xtermLoadFont(screen, VT_FONTSET(name1, name2, name3), doresize, i)) {
                return;
            }
        }
Index: fontutils.h
--- xterm-140+/fontutils.h      Wed Jun 14 15:50:37 2000
+++ xterm-141/fontutils.h       Sun Aug 13 18:46:46 2000
@@ -40,9 +40,17 @@
 #include <ptyx.h>
 #include <proto.h>
 
-extern int xtermLoadFont (TScreen *screen, char *nfontname, char *bfontname, Bool doresize, int fontnum);
+#if OPT_WIDE_CHARS
+#define VT_FONTSET(n,b,w) n, b, w
+#else
+#define VT_FONTSET(n,b,w) n, b
+#endif
+
+extern int xtermLoadFont (TScreen *screen,
+                         VT_FONTSET(char *nfontname, char *bfontname, char *wfontname),
+                         Bool doresize, int fontnum);
 extern void HandleSetFont PROTO_XT_ACTIONS_ARGS;
-extern void SetVTFont (int i, Bool doresize, char *name1, char *name2);
+extern void SetVTFont (int i, Bool doresize, VT_FONTSET(char *name1, char *name2, char *name3));
 extern void xtermComputeFontInfo (TScreen *screen, struct _vtwin *win, XFontStruct *font, int sbwidth);
 extern void xtermSaveFontInfo (TScreen *screen, XFontStruct *font);
 extern void xtermSetCursorBox (TScreen *screen);
Index: input.c
--- xterm-140+/input.c  Sun Jul 23 16:19:48 2000
+++ xterm-141/input.c   Mon Aug 14 21:32:31 2000
@@ -345,6 +345,7 @@
 #if OPT_TCAP_QUERY
        if (screen->tc_query >= 0) {
                keysym = screen->tc_query;
+               nbytes = 0;
                strbuf[0] = 0;
        }
        else
@@ -1097,69 +1098,79 @@
 /*
  * Parse the termcap/terminfo name from the string, returning a positive number
  * (the keysym) if found, otherwise -1.  Update the string pointer.
+ * Returns the (shift, control) state in *state.
  */
 int
-xtermcapKeycode(char **params)
+xtermcapKeycode(char **params, unsigned *state)
 {
-#define DATA(tc,ti,x) { tc, ti, x }
+#define DATA(tc,ti,x,y) { tc, ti, x, y }
        static struct {
                char *tc;
                char *ti;
                int code;
+               unsigned state;
        } table[] = {
-               DATA(   "%1",   "khlp",         XK_Help),
-               DATA(   "*6",   "kslt",         XK_Select),
-               DATA(   "@0",   "kfnd",         XK_Find),
-               DATA(   "@7",   "kend",         XK_End),
-               DATA(   "F1",   "kf11",         XK_F11),
-               DATA(   "F2",   "kf12",         XK_F12),
-               DATA(   "F3",   "kf13",         XK_F13),
-               DATA(   "F4",   "kf14",         XK_F14),
-               DATA(   "F5",   "kf15",         XK_F15),
-               DATA(   "F6",   "kf16",         XK_F16),
-               DATA(   "F7",   "kf17",         XK_F17),
-               DATA(   "F8",   "kf18",         XK_F18),
-               DATA(   "F9",   "kf19",         XK_F19),
-               DATA(   "FA",   "kf20",         XK_F20),
-               DATA(   "FB",   "kf21",         XK_F21),
-               DATA(   "FC",   "kf22",         XK_F22),
-               DATA(   "FD",   "kf23",         XK_F23),
-               DATA(   "FE",   "kf24",         XK_F24),
-               DATA(   "FF",   "kf25",         XK_F25),
-               DATA(   "FG",   "kf26",         XK_F26),
-               DATA(   "FH",   "kf27",         XK_F27),
-               DATA(   "FI",   "kf28",         XK_F28),
-               DATA(   "FJ",   "kf29",         XK_F29),
-               DATA(   "FK",   "kf30",         XK_F30),
-               DATA(   "FL",   "kf31",         XK_F31),
-               DATA(   "FM",   "kf32",         XK_F32),
-               DATA(   "FN",   "kf33",         XK_F33),
-               DATA(   "FO",   "kf34",         XK_F34),
-               DATA(   "FP",   "kf35",         XK_F35),
-               DATA(   "FQ",   "kf36",         SunXK_F36),
-               DATA(   "FR",   "kf37",         SunXK_F37),
-               DATA(   "k1",   "kf1",          XK_F1),
-               DATA(   "k2",   "kf2",          XK_F2),
-               DATA(   "k3",   "kf3",          XK_F3),
-               DATA(   "k4",   "kf4",          XK_F4),
-               DATA(   "k5",   "kf5",          XK_F5),
-               DATA(   "k6",   "kf6",          XK_F6),
-               DATA(   "k7",   "kf7",          XK_F7),
-               DATA(   "k8",   "kf8",          XK_F8),
-               DATA(   "k9",   "kf9",          XK_F9),
-               DATA(   "k;",   "kf10",         XK_F10), /* cannot termcap */
-               DATA(   "kB",   "kcbt",         XK_ISO_Left_Tab),
-               DATA(   "kC",   "kclr",         XK_Clear),
-               DATA(   "kD",   "kdch1",        XK_Delete),
-               DATA(   "kI",   "kich1",        XK_Insert),
-               DATA(   "kN",   "knp",          XK_Next),
-               DATA(   "kP",   "kpp",          XK_Prior),
-               DATA(   "kb",   "kbs",          XK_BackSpace),
-               DATA(   "kd",   "kcud1",        XK_Down),
-               DATA(   "kh",   "khome",        XK_Home),
-               DATA(   "kl",   "kcub1",        XK_Left),
-               DATA(   "kr",   "kcuf1",        XK_Right),
-               DATA(   "ku",   "kcuu1",        XK_Up),
+               DATA(   "#2",   "kHOM",         XK_Home,        ShiftMask),
+               DATA(   "#4",   "kLFT",         XK_Left,        ShiftMask),
+               DATA(   "%1",   "khlp",         XK_Help,        0),
+               DATA(   "%i",   "kRIT",         XK_Right,       ShiftMask),
+               DATA(   "*6",   "kslt",         XK_Select,      0),
+               DATA(   "*7",   "kEND",         XK_End,         ShiftMask),
+               DATA(   "@0",   "kfnd",         XK_Find,        0),
+               DATA(   "@7",   "kend",         XK_End,         0),
+               DATA(   "F1",   "kf11",         XK_F11,         0),
+               DATA(   "F2",   "kf12",         XK_F12,         0),
+               DATA(   "F3",   "kf13",         XK_F13,         0),
+               DATA(   "F4",   "kf14",         XK_F14,         0),
+               DATA(   "F5",   "kf15",         XK_F15,         0),
+               DATA(   "F6",   "kf16",         XK_F16,         0),
+               DATA(   "F7",   "kf17",         XK_F17,         0),
+               DATA(   "F8",   "kf18",         XK_F18,         0),
+               DATA(   "F9",   "kf19",         XK_F19,         0),
+               DATA(   "FA",   "kf20",         XK_F20,         0),
+               DATA(   "FB",   "kf21",         XK_F21,         0),
+               DATA(   "FC",   "kf22",         XK_F22,         0),
+               DATA(   "FD",   "kf23",         XK_F23,         0),
+               DATA(   "FE",   "kf24",         XK_F24,         0),
+               DATA(   "FF",   "kf25",         XK_F25,         0),
+               DATA(   "FG",   "kf26",         XK_F26,         0),
+               DATA(   "FH",   "kf27",         XK_F27,         0),
+               DATA(   "FI",   "kf28",         XK_F28,         0),
+               DATA(   "FJ",   "kf29",         XK_F29,         0),
+               DATA(   "FK",   "kf30",         XK_F30,         0),
+               DATA(   "FL",   "kf31",         XK_F31,         0),
+               DATA(   "FM",   "kf32",         XK_F32,         0),
+               DATA(   "FN",   "kf33",         XK_F33,         0),
+               DATA(   "FO",   "kf34",         XK_F34,         0),
+               DATA(   "FP",   "kf35",         XK_F35,         0),
+               DATA(   "FQ",   "kf36",         SunXK_F36,      0),
+               DATA(   "FR",   "kf37",         SunXK_F37,      0),
+               DATA(   "K1",   "ka1",          XK_KP_Home,     0),
+               DATA(   "K4",   "kc1",          XK_KP_End,      0),
+               DATA(   "k1",   "kf1",          XK_F1,          0),
+               DATA(   "k2",   "kf2",          XK_F2,          0),
+               DATA(   "k3",   "kf3",          XK_F3,          0),
+               DATA(   "k4",   "kf4",          XK_F4,          0),
+               DATA(   "k5",   "kf5",          XK_F5,          0),
+               DATA(   "k6",   "kf6",          XK_F6,          0),
+               DATA(   "k7",   "kf7",          XK_F7,          0),
+               DATA(   "k8",   "kf8",          XK_F8,          0),
+               DATA(   "k9",   "kf9",          XK_F9,          0),
+               DATA(   "k;",   "kf10",         XK_F10,         0), /* cannot termcap */
+#ifdef XK_ISO_Left_Tab
+               DATA(   "kB",   "kcbt",         XK_ISO_Left_Tab,0),
+#endif
+               DATA(   "kC",   "kclr",         XK_Clear,       0),
+               DATA(   "kD",   "kdch1",        XK_Delete,      0),
+               DATA(   "kI",   "kich1",        XK_Insert,      0),
+               DATA(   "kN",   "knp",          XK_Next,        0),
+               DATA(   "kP",   "kpp",          XK_Prior,       0),
+               DATA(   "kb",   "kbs",          XK_BackSpace,   0),
+               DATA(   "kd",   "kcud1",        XK_Down,        0),
+               DATA(   "kh",   "khome",        XK_Home,        0),
+               DATA(   "kl",   "kcub1",        XK_Left,        0),
+               DATA(   "kr",   "kcuf1",        XK_Right,       0),
+               DATA(   "ku",   "kcuu1",        XK_Up,          0),
        };
        Cardinal n;
        unsigned len = 0;
@@ -1175,6 +1186,7 @@
                if (!strcmp(table[n].ti, *params)
                 || !strcmp(table[n].tc, *params)) {
                        code = table[n].code;
+                       *state = table[n].state;
                        break;
                }
        }
Index: main.c
--- xterm-140+/main.c   Sun Jul 23 15:57:52 2000
+++ xterm-141/main.c    Mon Aug 14 19:41:25 2000
@@ -89,6 +89,11 @@
 #include <data.h>
 #include <error.h>
 #include <menu.h>
+#include <main.h>
+
+#if OPT_WIDE_CHARS
+#include <charclass.h>
+#endif
 
 #ifdef AMOEBA
 #include <amoeba.h>
@@ -866,15 +871,15 @@
 #undef offset
 
 static char *fallback_resources[] = {
-    "XTerm*SimpleMenu*menuLabel.vertSpace: 100",
-    "XTerm*SimpleMenu*HorizontalMargins: 16",
-    "XTerm*SimpleMenu*Sme.height: 16",
-    "XTerm*SimpleMenu*Cursor: left_ptr",
-    "XTerm*mainMenu.Label:  Main Options (no app-defaults)",
-    "XTerm*vtMenu.Label:  VT Options (no app-defaults)",
-    "XTerm*fontMenu.Label:  VT Fonts (no app-defaults)",
+    "*SimpleMenu*menuLabel.vertSpace: 100",
+    "*SimpleMenu*HorizontalMargins: 16",
+    "*SimpleMenu*Sme.height: 16",
+    "*SimpleMenu*Cursor: left_ptr",
+    "*mainMenu.Label:  Main Options (no app-defaults)",
+    "*vtMenu.Label:  VT Options (no app-defaults)",
+    "*fontMenu.Label:  VT Fonts (no app-defaults)",
 #if OPT_TEK4014
-    "XTerm*tekMenu.Label:  Tek Options (no app-defaults)",
+    "*tekMenu.Label:  Tek Options (no app-defaults)",
 #endif
     NULL
 };
@@ -904,6 +909,7 @@
 {"-cb",                "*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "off"},
 {"+cb",                "*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "on"},
 {"-cc",                "*charClass",   XrmoptionSepArg,        (caddr_t) NULL},
+{"-class",     NULL,           XrmoptionSkipArg,       (caddr_t) NULL},
 {"-cm",                "*colorMode",   XrmoptionNoArg,         (caddr_t) "off"},
 {"+cm",                "*colorMode",   XrmoptionNoArg,         (caddr_t) "on"},
 {"-cn",                "*cutNewline",  XrmoptionNoArg,         (caddr_t) "off"},
@@ -918,6 +924,9 @@
 #ifndef NO_ACTIVE_ICON
 {"-fi",                "*iconFont",    XrmoptionSepArg,        (caddr_t) NULL},
 #endif /* NO_ACTIVE_ICON */
+#if OPT_WIDE_CHARS
+{"-fw",                "*wideFont",    XrmoptionSepArg,        (caddr_t) NULL},
+#endif
 #if OPT_HIGHLIGHT_COLOR
 {"-hc",                "*highlightColor", XrmoptionSepArg,     (caddr_t) NULL},
 #endif
@@ -1030,8 +1039,13 @@
 { "-bd color",             "border color" },
 { "-bw number",            "border width in pixels" },
 { "-fn fontname",          "normal text font" },
+{ "-fb fontname",          "bold text font" },
+#if OPT_WIDE_CHARS
+{ "-fw fontname",          "doublewidth text font" },
+#endif
 { "-iconic",               "start iconic" },
 { "-name string",          "client instance, icon, and title strings" },
+{ "-class string",         "class string (XTerm)" },
 { "-title string",         "title string" },
 { "-xrm resourcestring",   "additional resource specifications" },
 { "-/+132",                "turn on/off column switch inhibiting" },
@@ -1052,7 +1066,6 @@
 { "-cr color",             "text cursor color" },
 { "-/+cu",                 "turn on/off curses emulation" },
 { "-/+dc",                "turn off/on dynamic color selection" },
-{ "-fb fontname",          "bold text font" },
 #if OPT_HIGHLIGHT_COLOR
 { "-hc",                  "selection background color" },
 #endif
@@ -1133,7 +1146,7 @@
 { "-ziconbeep percent",    "beep and flag icon of window having hidden output" },
 #endif
 #if OPT_SAME_NAME
-{"-/+sameName",           "Turn on/off the no flicker option for title and icon name" },
+{"-/+sameName",           "turn on/off the no-flicker option for title and icon name" },
 #endif
 { NULL, NULL }};
 
@@ -1302,14 +1315,21 @@
        Widget form_top, menu_top;
        register TScreen *screen;
        int mode;
+       char *my_class = DEFCLASS;
 
        /* Do these first, since we may not be able to open the display */
        ProgramName = argv[0];
        if (argc > 1) {
+               int n;
                if (abbrev(argv[1], "-version"))
                        Version();
                if (abbrev(argv[1], "-help"))
                        Help();
+               for (n = 1; n < argc; n++) {
+                       if (abbrev(argv[n], "-class"))
+                               if ((my_class = argv[++n]) == 0)
+                                       Help();
+               }
        }
 
        /* This dumps core on HP-UX 9.05 with X11R5 */
@@ -1618,7 +1638,7 @@
 #endif
 
            XtSetErrorHandler(xt_error);
-           toplevel = XtAppInitialize (&app_con, "XTerm",
+           toplevel = XtAppInitialize (&app_con, my_class,
                                        optionDescList,
                                        XtNumber(optionDescList),
                                        &argc, argv, fallback_resources,
@@ -1701,6 +1721,11 @@
        XtSetValues (toplevel, ourTopLevelShellArgs,
                     number_ourTopLevelShellArgs);
 
+#if OPT_WIDE_CHARS
+       /* seems as good a place as any */
+       init_classtab();
+#endif
+
        /* Parse the rest of the command line */
        for (argc--, argv++ ; argc > 0 ; argc--, argv++) {
            if(**argv != '-') Syntax (*argv);
@@ -1740,6 +1765,8 @@
                debug = TRUE;
                continue;
 #endif /* DEBUG */
+            case 'c':  /* -class */
+               break;
             case 'e':
                if (argc <= 1) Syntax (*argv);
                command_to_exec = ++argv;
Index: main.h
--- xterm-140+/main.h   Wed Jan 10 12:27:01 1996
+++ xterm-141/main.h    Mon Aug 14 18:38:23 2000
@@ -26,6 +26,8 @@
  * SOFTWARE.
  */
 
+#define        DEFCLASS                "XTerm"
 #define        DEFFONT                 "fixed"
+#define DEFWIDEFONT            NULL    /* grab one which is 2x as wide */
 #define        DEFBOLDFONT             NULL    /* no bold font uses overstriking */
 #define        DEFBORDER               2
Index: menu.c
--- xterm-140+/menu.c   Wed Jun 14 15:50:37 2000
+++ xterm-141/menu.c    Sun Aug 13 18:29:43 2000
@@ -1193,7 +1193,7 @@
 
     for (i = 0; i < NMENUFONTS; i++) {
        if (strcmp (entryname, fontMenuEntries[i].name) == 0) {
-           SetVTFont (i, True, (char *)0, (char *)0);
+           SetVTFont (i, True, VT_FONTSET(NULL, NULL, NULL));
            return;
        }
     }
Index: misc.c
--- xterm-140+/misc.c   Sun Jul 23 16:33:36 2000
+++ xterm-141/misc.c    Mon Aug 14 21:22:13 2000
@@ -1336,7 +1336,7 @@
                            break;
                        }
                    }
-                   SetVTFont (fontMenu_fontescape, True, buf, NULL);
+                   SetVTFont (fontMenu_fontescape, True, VT_FONTSET(buf, NULL, NULL));
                }
                break;
        case 51:
@@ -1499,9 +1499,10 @@
        case '+':
                cp++;
                if (*cp == 'q') {
+                       unsigned state;
                        okay = True;
                        for (tmp = ++cp; *tmp;) {
-                               if (xtermcapKeycode(&tmp) < 0) {
+                               if (xtermcapKeycode(&tmp, &state) < 0) {
                                        okay = False;
                                        break;
                                }
@@ -1515,9 +1516,9 @@
                                int count = 0;
                                for (tmp = cp; *tmp;) {
                                        screen->tc_query = -1;
-                                       if ((code = xtermcapKeycode(&tmp)) >= 0) {
+                                       if ((code = xtermcapKeycode(&tmp, &state)) >= 0) {
                                                XKeyEvent event;
-                                               event.state = 0;
+                                               event.state = state;
                                                if (count++)
                                                        unparseputc(';', screen->respond);
                                                screen->tc_query = code;
Index: os2main.c
--- xterm-140+/os2main.c        Sat Jun 17 23:04:29 2000
+++ xterm-141/os2main.c Mon Aug 14 19:43:26 2000
@@ -88,6 +88,7 @@
 #include <data.h>
 #include <error.h>
 #include <menu.h>
+#include <main.h>
 
 #include <sys/termio.h>
 
@@ -304,15 +305,15 @@
 #undef offset
 
 static char *fallback_resources[] = {
-    "XTerm*SimpleMenu*menuLabel.vertSpace: 100",
-    "XTerm*SimpleMenu*HorizontalMargins: 16",
-    "XTerm*SimpleMenu*Sme.height: 16",
-    "XTerm*SimpleMenu*Cursor: left_ptr",
-    "XTerm*mainMenu.Label:  Main Options (no app-defaults)",
-    "XTerm*vtMenu.Label:  VT Options (no app-defaults)",
-    "XTerm*fontMenu.Label:  VT Fonts (no app-defaults)",
+    "*SimpleMenu*menuLabel.vertSpace: 100",
+    "*SimpleMenu*HorizontalMargins: 16",
+    "*SimpleMenu*Sme.height: 16",
+    "*SimpleMenu*Cursor: left_ptr",
+    "*mainMenu.Label:  Main Options (no app-defaults)",
+    "*vtMenu.Label:  VT Options (no app-defaults)",
+    "*fontMenu.Label:  VT Fonts (no app-defaults)",
 #if OPT_TEK4014
-    "XTerm*tekMenu.Label:  Tek Options (no app-defaults)",
+    "*tekMenu.Label:  Tek Options (no app-defaults)",
 #endif
     NULL
 };
@@ -342,6 +343,7 @@
 {"-cb",                "*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "off"},
 {"+cb",                "*cutToBeginningOfLine", XrmoptionNoArg, (caddr_t) "on"},
 {"-cc",                "*charClass",   XrmoptionSepArg,        (caddr_t) NULL},
+{"-class",     NULL,           XrmoptionSkipArg,       (caddr_t) NULL},
 {"-cm",                "*colorMode",   XrmoptionNoArg,         (caddr_t) "off"},
 {"+cm",                "*colorMode",   XrmoptionNoArg,         (caddr_t) "on"},
 {"-cn",                "*cutNewline",  XrmoptionNoArg,         (caddr_t) "off"},
@@ -464,6 +466,7 @@
 { "-fn fontname",          "normal text font" },
 { "-iconic",               "start iconic" },
 { "-name string",          "client instance, icon, and title strings" },
+{ "-class string",         "class string (XTerm)" },
 { "-title string",         "title string" },
 { "-xrm resourcestring",   "additional resource specifications" },
 { "-/+132",                "turn on/off column switch inhibiting" },
@@ -833,6 +836,7 @@
        Widget form_top, menu_top;
        register TScreen *screen;
        int mode;
+       char *my_class = DEFCLASS;
 
        /* Do these first, since we may not be able to open the display */
        ProgramName = argv[0];
@@ -842,6 +846,11 @@
                        Version();
                if (abbrev(argv[1], "-help"))
                        Help();
+               for (n = 1; n < argc; n++) {
+                       if (abbrev(argv[n], "-class"))
+                               if ((my_class = argv[++n]) == 0)
+                                       Help();
+               }
        }
 
        /* XXX: for some obscure reason EMX seems to lose the value of
@@ -887,7 +896,7 @@
        /* Init the Toolkit. */
        {
            XtSetErrorHandler(xt_error);
-           toplevel = XtAppInitialize (&app_con, "XTerm",
+           toplevel = XtAppInitialize (&app_con, my_class,
                                        optionDescList,
                                        XtNumber(optionDescList),
                                        &argc, argv, fallback_resources,
@@ -986,6 +995,8 @@
                debug = TRUE;
                continue;
 #endif /* DEBUG */
+            case 'c':  /* -class */
+               break;
             case 'e':
                if (argc <= 1) Syntax (*argv);
                command_to_exec = ++argv;
Index: precompose.c
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-141/precompose.c      Fri Aug 11 06:09:25 2000
@@ -0,0 +1,1025 @@
+/*
+ * Canonical Compositions
+ *
+ * DO NOT EDIT BY HAND! This is generated by the script
+ * unicode/make-precompose.sh
+ */
+
+#include "precompose.h"
+
+struct {
+  int base;
+  int comb; 
+  int replacement;
+} precompositions[] = {
+{ 0x00C0, 0x0041, 0x0300},
+{ 0x00C1, 0x0041, 0x0301},
+{ 0x00C2, 0x0041, 0x0302},
+{ 0x00C3, 0x0041, 0x0303},
+{ 0x00C4, 0x0041, 0x0308},
+{ 0x00C5, 0x0041, 0x030A},
+{ 0x00C7, 0x0043, 0x0327},
+{ 0x00C8, 0x0045, 0x0300},
+{ 0x00C9, 0x0045, 0x0301},
+{ 0x00CA, 0x0045, 0x0302},
+{ 0x00CB, 0x0045, 0x0308},
+{ 0x00CC, 0x0049, 0x0300},
+{ 0x00CD, 0x0049, 0x0301},
+{ 0x00CE, 0x0049, 0x0302},
+{ 0x00CF, 0x0049, 0x0308},
+{ 0x00D1, 0x004E, 0x0303},
+{ 0x00D2, 0x004F, 0x0300},
+{ 0x00D3, 0x004F, 0x0301},
+{ 0x00D4, 0x004F, 0x0302},
+{ 0x00D5, 0x004F, 0x0303},
+{ 0x00D6, 0x004F, 0x0308},
+{ 0x00D9, 0x0055, 0x0300},
+{ 0x00DA, 0x0055, 0x0301},
+{ 0x00DB, 0x0055, 0x0302},
+{ 0x00DC, 0x0055, 0x0308},
+{ 0x00DD, 0x0059, 0x0301},
+{ 0x00E0, 0x0061, 0x0300},
+{ 0x00E1, 0x0061, 0x0301},
+{ 0x00E2, 0x0061, 0x0302},
+{ 0x00E3, 0x0061, 0x0303},
+{ 0x00E4, 0x0061, 0x0308},
+{ 0x00E5, 0x0061, 0x030A},
+{ 0x00E7, 0x0063, 0x0327},
+{ 0x00E8, 0x0065, 0x0300},
+{ 0x00E9, 0x0065, 0x0301},
+{ 0x00EA, 0x0065, 0x0302},
+{ 0x00EB, 0x0065, 0x0308},
+{ 0x00EC, 0x0069, 0x0300},
+{ 0x00ED, 0x0069, 0x0301},
+{ 0x00EE, 0x0069, 0x0302},
+{ 0x00EF, 0x0069, 0x0308},
+{ 0x00F1, 0x006E, 0x0303},
+{ 0x00F2, 0x006F, 0x0300},
+{ 0x00F3, 0x006F, 0x0301},
+{ 0x00F4, 0x006F, 0x0302},
+{ 0x00F5, 0x006F, 0x0303},
+{ 0x00F6, 0x006F, 0x0308},
+{ 0x00F9, 0x0075, 0x0300},
+{ 0x00FA, 0x0075, 0x0301},
+{ 0x00FB, 0x0075, 0x0302},
+{ 0x00FC, 0x0075, 0x0308},
+{ 0x00FD, 0x0079, 0x0301},
+{ 0x00FF, 0x0079, 0x0308},
+{ 0x0100, 0x0041, 0x0304},
+{ 0x0101, 0x0061, 0x0304},
+{ 0x0102, 0x0041, 0x0306},
+{ 0x0103, 0x0061, 0x0306},
+{ 0x0104, 0x0041, 0x0328},
+{ 0x0105, 0x0061, 0x0328},
+{ 0x0106, 0x0043, 0x0301},
+{ 0x0107, 0x0063, 0x0301},
+{ 0x0108, 0x0043, 0x0302},
+{ 0x0109, 0x0063, 0x0302},
+{ 0x010A, 0x0043, 0x0307},
+{ 0x010B, 0x0063, 0x0307},
+{ 0x010C, 0x0043, 0x030C},
+{ 0x010D, 0x0063, 0x030C},
+{ 0x010E, 0x0044, 0x030C},
+{ 0x010F, 0x0064, 0x030C},
+{ 0x0112, 0x0045, 0x0304},
+{ 0x0113, 0x0065, 0x0304},
+{ 0x0114, 0x0045, 0x0306},
+{ 0x0115, 0x0065, 0x0306},
+{ 0x0116, 0x0045, 0x0307},
+{ 0x0117, 0x0065, 0x0307},
+{ 0x0118, 0x0045, 0x0328},
+{ 0x0119, 0x0065, 0x0328},
+{ 0x011A, 0x0045, 0x030C},
+{ 0x011B, 0x0065, 0x030C},
+{ 0x011C, 0x0047, 0x0302},
+{ 0x011D, 0x0067, 0x0302},
+{ 0x011E, 0x0047, 0x0306},
+{ 0x011F, 0x0067, 0x0306},
+{ 0x0120, 0x0047, 0x0307},
+{ 0x0121, 0x0067, 0x0307},
+{ 0x0122, 0x0047, 0x0327},
+{ 0x0123, 0x0067, 0x0327},
+{ 0x0124, 0x0048, 0x0302},
+{ 0x0125, 0x0068, 0x0302},
+{ 0x0128, 0x0049, 0x0303},
+{ 0x0129, 0x0069, 0x0303},
+{ 0x012A, 0x0049, 0x0304},
+{ 0x012B, 0x0069, 0x0304},
+{ 0x012C, 0x0049, 0x0306},
+{ 0x012D, 0x0069, 0x0306},
+{ 0x012E, 0x0049, 0x0328},
+{ 0x012F, 0x0069, 0x0328},
+{ 0x0130, 0x0049, 0x0307},
+{ 0x0134, 0x004A, 0x0302},
+{ 0x0135, 0x006A, 0x0302},
+{ 0x0136, 0x004B, 0x0327},
+{ 0x0137, 0x006B, 0x0327},
+{ 0x0139, 0x004C, 0x0301},
+{ 0x013A, 0x006C, 0x0301},
+{ 0x013B, 0x004C, 0x0327},
+{ 0x013C, 0x006C, 0x0327},
+{ 0x013D, 0x004C, 0x030C},
+{ 0x013E, 0x006C, 0x030C},
+{ 0x0143, 0x004E, 0x0301},
+{ 0x0144, 0x006E, 0x0301},
+{ 0x0145, 0x004E, 0x0327},
+{ 0x0146, 0x006E, 0x0327},
+{ 0x0147, 0x004E, 0x030C},
+{ 0x0148, 0x006E, 0x030C},
+{ 0x014C, 0x004F, 0x0304},
+{ 0x014D, 0x006F, 0x0304},
+{ 0x014E, 0x004F, 0x0306},
+{ 0x014F, 0x006F, 0x0306},
+{ 0x0150, 0x004F, 0x030B},
+{ 0x0151, 0x006F, 0x030B},
+{ 0x0154, 0x0052, 0x0301},
+{ 0x0155, 0x0072, 0x0301},
+{ 0x0156, 0x0052, 0x0327},
+{ 0x0157, 0x0072, 0x0327},
+{ 0x0158, 0x0052, 0x030C},
+{ 0x0159, 0x0072, 0x030C},
+{ 0x015A, 0x0053, 0x0301},
+{ 0x015B, 0x0073, 0x0301},
+{ 0x015C, 0x0053, 0x0302},
+{ 0x015D, 0x0073, 0x0302},
+{ 0x015E, 0x0053, 0x0327},
+{ 0x015F, 0x0073, 0x0327},
+{ 0x0160, 0x0053, 0x030C},
+{ 0x0161, 0x0073, 0x030C},
+{ 0x0162, 0x0054, 0x0327},
+{ 0x0163, 0x0074, 0x0327},
+{ 0x0164, 0x0054, 0x030C},
+{ 0x0165, 0x0074, 0x030C},
+{ 0x0168, 0x0055, 0x0303},
+{ 0x0169, 0x0075, 0x0303},
+{ 0x016A, 0x0055, 0x0304},
+{ 0x016B, 0x0075, 0x0304},
+{ 0x016C, 0x0055, 0x0306},
+{ 0x016D, 0x0075, 0x0306},
+{ 0x016E, 0x0055, 0x030A},
+{ 0x016F, 0x0075, 0x030A},
+{ 0x0170, 0x0055, 0x030B},
+{ 0x0171, 0x0075, 0x030B},
+{ 0x0172, 0x0055, 0x0328},
+{ 0x0173, 0x0075, 0x0328},
+{ 0x0174, 0x0057, 0x0302},
+{ 0x0175, 0x0077, 0x0302},
+{ 0x0176, 0x0059, 0x0302},
+{ 0x0177, 0x0079, 0x0302},
+{ 0x0178, 0x0059, 0x0308},
+{ 0x0179, 0x005A, 0x0301},
+{ 0x017A, 0x007A, 0x0301},
+{ 0x017B, 0x005A, 0x0307},
+{ 0x017C, 0x007A, 0x0307},
+{ 0x017D, 0x005A, 0x030C},
+{ 0x017E, 0x007A, 0x030C},
+{ 0x01A0, 0x004F, 0x031B},
+{ 0x01A1, 0x006F, 0x031B},
+{ 0x01AF, 0x0055, 0x031B},
+{ 0x01B0, 0x0075, 0x031B},
+{ 0x01CD, 0x0041, 0x030C},
+{ 0x01CE, 0x0061, 0x030C},
+{ 0x01CF, 0x0049, 0x030C},
+{ 0x01D0, 0x0069, 0x030C},
+{ 0x01D1, 0x004F, 0x030C},
+{ 0x01D2, 0x006F, 0x030C},
+{ 0x01D3, 0x0055, 0x030C},
+{ 0x01D4, 0x0075, 0x030C},
+{ 0x01D5, 0x00DC, 0x0304},
+{ 0x01D6, 0x00FC, 0x0304},
+{ 0x01D7, 0x00DC, 0x0301},
+{ 0x01D8, 0x00FC, 0x0301},
+{ 0x01D9, 0x00DC, 0x030C},
+{ 0x01DA, 0x00FC, 0x030C},
+{ 0x01DB, 0x00DC, 0x0300},
+{ 0x01DC, 0x00FC, 0x0300},
+{ 0x01DE, 0x00C4, 0x0304},
+{ 0x01DF, 0x00E4, 0x0304},
+{ 0x01E0, 0x0226, 0x0304},
+{ 0x01E1, 0x0227, 0x0304},
+{ 0x01E2, 0x00C6, 0x0304},
+{ 0x01E3, 0x00E6, 0x0304},
+{ 0x01E6, 0x0047, 0x030C},
+{ 0x01E7, 0x0067, 0x030C},
+{ 0x01E8, 0x004B, 0x030C},
+{ 0x01E9, 0x006B, 0x030C},
+{ 0x01EA, 0x004F, 0x0328},
+{ 0x01EB, 0x006F, 0x0328},
+{ 0x01EC, 0x01EA, 0x0304},
+{ 0x01ED, 0x01EB, 0x0304},
+{ 0x01EE, 0x01B7, 0x030C},
+{ 0x01EF, 0x0292, 0x030C},
+{ 0x01F0, 0x006A, 0x030C},
+{ 0x01F4, 0x0047, 0x0301},
+{ 0x01F5, 0x0067, 0x0301},
+{ 0x01F8, 0x004E, 0x0300},
+{ 0x01F9, 0x006E, 0x0300},
+{ 0x01FA, 0x00C5, 0x0301},
+{ 0x01FB, 0x00E5, 0x0301},
+{ 0x01FC, 0x00C6, 0x0301},
+{ 0x01FD, 0x00E6, 0x0301},
+{ 0x01FE, 0x00D8, 0x0301},
+{ 0x01FF, 0x00F8, 0x0301},
+{ 0x0200, 0x0041, 0x030F},
+{ 0x0201, 0x0061, 0x030F},
+{ 0x0202, 0x0041, 0x0311},
+{ 0x0203, 0x0061, 0x0311},
+{ 0x0204, 0x0045, 0x030F},
+{ 0x0205, 0x0065, 0x030F},
+{ 0x0206, 0x0045, 0x0311},
+{ 0x0207, 0x0065, 0x0311},
+{ 0x0208, 0x0049, 0x030F},
+{ 0x0209, 0x0069, 0x030F},
+{ 0x020A, 0x0049, 0x0311},
+{ 0x020B, 0x0069, 0x0311},
+{ 0x020C, 0x004F, 0x030F},
+{ 0x020D, 0x006F, 0x030F},
+{ 0x020E, 0x004F, 0x0311},
+{ 0x020F, 0x006F, 0x0311},
+{ 0x0210, 0x0052, 0x030F},
+{ 0x0211, 0x0072, 0x030F},
+{ 0x0212, 0x0052, 0x0311},
+{ 0x0213, 0x0072, 0x0311},
+{ 0x0214, 0x0055, 0x030F},
+{ 0x0215, 0x0075, 0x030F},
+{ 0x0216, 0x0055, 0x0311},
+{ 0x0217, 0x0075, 0x0311},
+{ 0x0218, 0x0053, 0x0326},
+{ 0x0219, 0x0073, 0x0326},
+{ 0x021A, 0x0054, 0x0326},
+{ 0x021B, 0x0074, 0x0326},
+{ 0x021E, 0x0048, 0x030C},
+{ 0x021F, 0x0068, 0x030C},
+{ 0x0226, 0x0041, 0x0307},
+{ 0x0227, 0x0061, 0x0307},
+{ 0x0228, 0x0045, 0x0327},
+{ 0x0229, 0x0065, 0x0327},
+{ 0x022A, 0x00D6, 0x0304},
+{ 0x022B, 0x00F6, 0x0304},
+{ 0x022C, 0x00D5, 0x0304},
+{ 0x022D, 0x00F5, 0x0304},
+{ 0x022E, 0x004F, 0x0307},
+{ 0x022F, 0x006F, 0x0307},
+{ 0x0230, 0x022E, 0x0304},
+{ 0x0231, 0x022F, 0x0304},
+{ 0x0232, 0x0059, 0x0304},
+{ 0x0233, 0x0079, 0x0304},
+{ 0x0344, 0x0308, 0x0301},
+{ 0x0385, 0x00A8, 0x0301},
+{ 0x0386, 0x0391, 0x0301},
+{ 0x0388, 0x0395, 0x0301},
+{ 0x0389, 0x0397, 0x0301},
+{ 0x038A, 0x0399, 0x0301},
+{ 0x038C, 0x039F, 0x0301},
+{ 0x038E, 0x03A5, 0x0301},
+{ 0x038F, 0x03A9, 0x0301},
+{ 0x0390, 0x03CA, 0x0301},
+{ 0x03AA, 0x0399, 0x0308},
+{ 0x03AB, 0x03A5, 0x0308},
+{ 0x03AC, 0x03B1, 0x0301},
+{ 0x03AD, 0x03B5, 0x0301},
+{ 0x03AE, 0x03B7, 0x0301},
+{ 0x03AF, 0x03B9, 0x0301},
+{ 0x03B0, 0x03CB, 0x0301},
+{ 0x03CA, 0x03B9, 0x0308},
+{ 0x03CB, 0x03C5, 0x0308},
+{ 0x03CC, 0x03BF, 0x0301},
+{ 0x03CD, 0x03C5, 0x0301},
+{ 0x03CE, 0x03C9, 0x0301},
+{ 0x03D3, 0x03D2, 0x0301},
+{ 0x03D4, 0x03D2, 0x0308},
+{ 0x0400, 0x0415, 0x0300},
+{ 0x0401, 0x0415, 0x0308},
+{ 0x0403, 0x0413, 0x0301},
+{ 0x0407, 0x0406, 0x0308},
+{ 0x040C, 0x041A, 0x0301},
+{ 0x040D, 0x0418, 0x0300},
+{ 0x040E, 0x0423, 0x0306},
+{ 0x0419, 0x0418, 0x0306},
+{ 0x0439, 0x0438, 0x0306},
+{ 0x0450, 0x0435, 0x0300},
+{ 0x0451, 0x0435, 0x0308},
+{ 0x0453, 0x0433, 0x0301},
+{ 0x0457, 0x0456, 0x0308},
+{ 0x045C, 0x043A, 0x0301},
+{ 0x045D, 0x0438, 0x0300},
+{ 0x045E, 0x0443, 0x0306},
+{ 0x0476, 0x0474, 0x030F},
+{ 0x0477, 0x0475, 0x030F},
+{ 0x04C1, 0x0416, 0x0306},
+{ 0x04C2, 0x0436, 0x0306},
+{ 0x04D0, 0x0410, 0x0306},
+{ 0x04D1, 0x0430, 0x0306},
+{ 0x04D2, 0x0410, 0x0308},
+{ 0x04D3, 0x0430, 0x0308},
+{ 0x04D6, 0x0415, 0x0306},
+{ 0x04D7, 0x0435, 0x0306},
+{ 0x04DA, 0x04D8, 0x0308},
+{ 0x04DB, 0x04D9, 0x0308},
+{ 0x04DC, 0x0416, 0x0308},
+{ 0x04DD, 0x0436, 0x0308},
+{ 0x04DE, 0x0417, 0x0308},
+{ 0x04DF, 0x0437, 0x0308},
+{ 0x04E2, 0x0418, 0x0304},
+{ 0x04E3, 0x0438, 0x0304},
+{ 0x04E4, 0x0418, 0x0308},
+{ 0x04E5, 0x0438, 0x0308},
+{ 0x04E6, 0x041E, 0x0308},
+{ 0x04E7, 0x043E, 0x0308},
+{ 0x04EA, 0x04E8, 0x0308},
+{ 0x04EB, 0x04E9, 0x0308},
+{ 0x04EC, 0x042D, 0x0308},
+{ 0x04ED, 0x044D, 0x0308},
+{ 0x04EE, 0x0423, 0x0304},
+{ 0x04EF, 0x0443, 0x0304},
+{ 0x04F0, 0x0423, 0x0308},
+{ 0x04F1, 0x0443, 0x0308},
+{ 0x04F2, 0x0423, 0x030B},
+{ 0x04F3, 0x0443, 0x030B},
+{ 0x04F4, 0x0427, 0x0308},
+{ 0x04F5, 0x0447, 0x0308},
+{ 0x04F8, 0x042B, 0x0308},
+{ 0x04F9, 0x044B, 0x0308},
+{ 0x0622, 0x0627, 0x0653},
+{ 0x0623, 0x0627, 0x0654},
+{ 0x0624, 0x0648, 0x0654},
+{ 0x0625, 0x0627, 0x0655},
+{ 0x0626, 0x064A, 0x0654},
+{ 0x06C0, 0x06D5, 0x0654},
+{ 0x06C2, 0x06C1, 0x0654},
+{ 0x06D3, 0x06D2, 0x0654},
+{ 0x0929, 0x0928, 0x093C},
+{ 0x0931, 0x0930, 0x093C},
+{ 0x0934, 0x0933, 0x093C},
+{ 0x0958, 0x0915, 0x093C},
+{ 0x0959, 0x0916, 0x093C},
+{ 0x095A, 0x0917, 0x093C},
+{ 0x095B, 0x091C, 0x093C},
+{ 0x095C, 0x0921, 0x093C},
+{ 0x095D, 0x0922, 0x093C},
+{ 0x095E, 0x092B, 0x093C},
+{ 0x095F, 0x092F, 0x093C},
+{ 0x09CB, 0x09C7, 0x09BE},
+{ 0x09CC, 0x09C7, 0x09D7},
+{ 0x09DC, 0x09A1, 0x09BC},
+{ 0x09DD, 0x09A2, 0x09BC},
+{ 0x09DF, 0x09AF, 0x09BC},
+{ 0x0A33, 0x0A32, 0x0A3C},
+{ 0x0A36, 0x0A38, 0x0A3C},
+{ 0x0A59, 0x0A16, 0x0A3C},
+{ 0x0A5A, 0x0A17, 0x0A3C},
+{ 0x0A5B, 0x0A1C, 0x0A3C},
+{ 0x0A5E, 0x0A2B, 0x0A3C},
+{ 0x0B48, 0x0B47, 0x0B56},
+{ 0x0B4B, 0x0B47, 0x0B3E},
+{ 0x0B4C, 0x0B47, 0x0B57},
+{ 0x0B5C, 0x0B21, 0x0B3C},
+{ 0x0B5D, 0x0B22, 0x0B3C},
+{ 0x0B94, 0x0B92, 0x0BD7},
+{ 0x0BCA, 0x0BC6, 0x0BBE},
+{ 0x0BCB, 0x0BC7, 0x0BBE},
+{ 0x0BCC, 0x0BC6, 0x0BD7},
+{ 0x0C48, 0x0C46, 0x0C56},
+{ 0x0CC0, 0x0CBF, 0x0CD5},
+{ 0x0CC7, 0x0CC6, 0x0CD5},
+{ 0x0CC8, 0x0CC6, 0x0CD6},
+{ 0x0CCA, 0x0CC6, 0x0CC2},
+{ 0x0CCB, 0x0CCA, 0x0CD5},
+{ 0x0D4A, 0x0D46, 0x0D3E},
+{ 0x0D4B, 0x0D47, 0x0D3E},
+{ 0x0D4C, 0x0D46, 0x0D57},
+{ 0x0DDA, 0x0DD9, 0x0DCA},
+{ 0x0DDC, 0x0DD9, 0x0DCF},
+{ 0x0DDD, 0x0DDC, 0x0DCA},
+{ 0x0DDE, 0x0DD9, 0x0DDF},
+{ 0x0F43, 0x0F42, 0x0FB7},
+{ 0x0F4D, 0x0F4C, 0x0FB7},
+{ 0x0F52, 0x0F51, 0x0FB7},
+{ 0x0F57, 0x0F56, 0x0FB7},
+{ 0x0F5C, 0x0F5B, 0x0FB7},
+{ 0x0F69, 0x0F40, 0x0FB5},
+{ 0x0F73, 0x0F71, 0x0F72},
+{ 0x0F75, 0x0F71, 0x0F74},
+{ 0x0F76, 0x0FB2, 0x0F80},
+{ 0x0F78, 0x0FB3, 0x0F80},
+{ 0x0F81, 0x0F71, 0x0F80},
+{ 0x0F93, 0x0F92, 0x0FB7},
+{ 0x0F9D, 0x0F9C, 0x0FB7},
+{ 0x0FA2, 0x0FA1, 0x0FB7},
+{ 0x0FA7, 0x0FA6, 0x0FB7},
+{ 0x0FAC, 0x0FAB, 0x0FB7},
+{ 0x0FB9, 0x0F90, 0x0FB5},
+{ 0x1026, 0x1025, 0x102E},
+{ 0x1E00, 0x0041, 0x0325},
+{ 0x1E01, 0x0061, 0x0325},
+{ 0x1E02, 0x0042, 0x0307},
+{ 0x1E03, 0x0062, 0x0307},
+{ 0x1E04, 0x0042, 0x0323},
+{ 0x1E05, 0x0062, 0x0323},
+{ 0x1E06, 0x0042, 0x0331},
+{ 0x1E07, 0x0062, 0x0331},
+{ 0x1E08, 0x00C7, 0x0301},
+{ 0x1E09, 0x00E7, 0x0301},
+{ 0x1E0A, 0x0044, 0x0307},
+{ 0x1E0B, 0x0064, 0x0307},
+{ 0x1E0C, 0x0044, 0x0323},
+{ 0x1E0D, 0x0064, 0x0323},
+{ 0x1E0E, 0x0044, 0x0331},
+{ 0x1E0F, 0x0064, 0x0331},
+{ 0x1E10, 0x0044, 0x0327},
+{ 0x1E11, 0x0064, 0x0327},
+{ 0x1E12, 0x0044, 0x032D},
+{ 0x1E13, 0x0064, 0x032D},
+{ 0x1E14, 0x0112, 0x0300},
+{ 0x1E15, 0x0113, 0x0300},
+{ 0x1E16, 0x0112, 0x0301},
+{ 0x1E17, 0x0113, 0x0301},
+{ 0x1E18, 0x0045, 0x032D},
+{ 0x1E19, 0x0065, 0x032D},
+{ 0x1E1A, 0x0045, 0x0330},
+{ 0x1E1B, 0x0065, 0x0330},
+{ 0x1E1C, 0x0228, 0x0306},
+{ 0x1E1D, 0x0229, 0x0306},
+{ 0x1E1E, 0x0046, 0x0307},
+{ 0x1E1F, 0x0066, 0x0307},
+{ 0x1E20, 0x0047, 0x0304},
+{ 0x1E21, 0x0067, 0x0304},
+{ 0x1E22, 0x0048, 0x0307},
+{ 0x1E23, 0x0068, 0x0307},
+{ 0x1E24, 0x0048, 0x0323},
+{ 0x1E25, 0x0068, 0x0323},
+{ 0x1E26, 0x0048, 0x0308},
+{ 0x1E27, 0x0068, 0x0308},
+{ 0x1E28, 0x0048, 0x0327},
+{ 0x1E29, 0x0068, 0x0327},
+{ 0x1E2A, 0x0048, 0x032E},
+{ 0x1E2B, 0x0068, 0x032E},
+{ 0x1E2C, 0x0049, 0x0330},
+{ 0x1E2D, 0x0069, 0x0330},
+{ 0x1E2E, 0x00CF, 0x0301},
+{ 0x1E2F, 0x00EF, 0x0301},
+{ 0x1E30, 0x004B, 0x0301},
+{ 0x1E31, 0x006B, 0x0301},
+{ 0x1E32, 0x004B, 0x0323},
+{ 0x1E33, 0x006B, 0x0323},
+{ 0x1E34, 0x004B, 0x0331},
+{ 0x1E35, 0x006B, 0x0331},
+{ 0x1E36, 0x004C, 0x0323},
+{ 0x1E37, 0x006C, 0x0323},
+{ 0x1E38, 0x1E36, 0x0304},
+{ 0x1E39, 0x1E37, 0x0304},
+{ 0x1E3A, 0x004C, 0x0331},
+{ 0x1E3B, 0x006C, 0x0331},
+{ 0x1E3C, 0x004C, 0x032D},
+{ 0x1E3D, 0x006C, 0x032D},
+{ 0x1E3E, 0x004D, 0x0301},
+{ 0x1E3F, 0x006D, 0x0301},
+{ 0x1E40, 0x004D, 0x0307},
+{ 0x1E41, 0x006D, 0x0307},
+{ 0x1E42, 0x004D, 0x0323},
+{ 0x1E43, 0x006D, 0x0323},
+{ 0x1E44, 0x004E, 0x0307},
+{ 0x1E45, 0x006E, 0x0307},
+{ 0x1E46, 0x004E, 0x0323},
+{ 0x1E47, 0x006E, 0x0323},
+{ 0x1E48, 0x004E, 0x0331},
+{ 0x1E49, 0x006E, 0x0331},
+{ 0x1E4A, 0x004E, 0x032D},
+{ 0x1E4B, 0x006E, 0x032D},
+{ 0x1E4C, 0x00D5, 0x0301},
+{ 0x1E4D, 0x00F5, 0x0301},
+{ 0x1E4E, 0x00D5, 0x0308},
+{ 0x1E4F, 0x00F5, 0x0308},
+{ 0x1E50, 0x014C, 0x0300},
+{ 0x1E51, 0x014D, 0x0300},
+{ 0x1E52, 0x014C, 0x0301},
+{ 0x1E53, 0x014D, 0x0301},
+{ 0x1E54, 0x0050, 0x0301},
+{ 0x1E55, 0x0070, 0x0301},
+{ 0x1E56, 0x0050, 0x0307},
+{ 0x1E57, 0x0070, 0x0307},
+{ 0x1E58, 0x0052, 0x0307},
+{ 0x1E59, 0x0072, 0x0307},
+{ 0x1E5A, 0x0052, 0x0323},
+{ 0x1E5B, 0x0072, 0x0323},
+{ 0x1E5C, 0x1E5A, 0x0304},
+{ 0x1E5D, 0x1E5B, 0x0304},
+{ 0x1E5E, 0x0052, 0x0331},
+{ 0x1E5F, 0x0072, 0x0331},
+{ 0x1E60, 0x0053, 0x0307},
+{ 0x1E61, 0x0073, 0x0307},
+{ 0x1E62, 0x0053, 0x0323},
+{ 0x1E63, 0x0073, 0x0323},
+{ 0x1E64, 0x015A, 0x0307},
+{ 0x1E65, 0x015B, 0x0307},
+{ 0x1E66, 0x0160, 0x0307},
+{ 0x1E67, 0x0161, 0x0307},
+{ 0x1E68, 0x1E62, 0x0307},
+{ 0x1E69, 0x1E63, 0x0307},
+{ 0x1E6A, 0x0054, 0x0307},
+{ 0x1E6B, 0x0074, 0x0307},
+{ 0x1E6C, 0x0054, 0x0323},
+{ 0x1E6D, 0x0074, 0x0323},
+{ 0x1E6E, 0x0054, 0x0331},
+{ 0x1E6F, 0x0074, 0x0331},
+{ 0x1E70, 0x0054, 0x032D},
+{ 0x1E71, 0x0074, 0x032D},
+{ 0x1E72, 0x0055, 0x0324},
+{ 0x1E73, 0x0075, 0x0324},
+{ 0x1E74, 0x0055, 0x0330},
+{ 0x1E75, 0x0075, 0x0330},
+{ 0x1E76, 0x0055, 0x032D},
+{ 0x1E77, 0x0075, 0x032D},
+{ 0x1E78, 0x0168, 0x0301},
+{ 0x1E79, 0x0169, 0x0301},
+{ 0x1E7A, 0x016A, 0x0308},
+{ 0x1E7B, 0x016B, 0x0308},
+{ 0x1E7C, 0x0056, 0x0303},
+{ 0x1E7D, 0x0076, 0x0303},
+{ 0x1E7E, 0x0056, 0x0323},
+{ 0x1E7F, 0x0076, 0x0323},
+{ 0x1E80, 0x0057, 0x0300},
+{ 0x1E81, 0x0077, 0x0300},
+{ 0x1E82, 0x0057, 0x0301},
+{ 0x1E83, 0x0077, 0x0301},
+{ 0x1E84, 0x0057, 0x0308},
+{ 0x1E85, 0x0077, 0x0308},
+{ 0x1E86, 0x0057, 0x0307},
+{ 0x1E87, 0x0077, 0x0307},
+{ 0x1E88, 0x0057, 0x0323},
+{ 0x1E89, 0x0077, 0x0323},
+{ 0x1E8A, 0x0058, 0x0307},
+{ 0x1E8B, 0x0078, 0x0307},
+{ 0x1E8C, 0x0058, 0x0308},
+{ 0x1E8D, 0x0078, 0x0308},
+{ 0x1E8E, 0x0059, 0x0307},
+{ 0x1E8F, 0x0079, 0x0307},
+{ 0x1E90, 0x005A, 0x0302},
+{ 0x1E91, 0x007A, 0x0302},
+{ 0x1E92, 0x005A, 0x0323},
+{ 0x1E93, 0x007A, 0x0323},
+{ 0x1E94, 0x005A, 0x0331},
+{ 0x1E95, 0x007A, 0x0331},
+{ 0x1E96, 0x0068, 0x0331},
+{ 0x1E97, 0x0074, 0x0308},
+{ 0x1E98, 0x0077, 0x030A},
+{ 0x1E99, 0x0079, 0x030A},
+{ 0x1E9B, 0x017F, 0x0307},
+{ 0x1EA0, 0x0041, 0x0323},
+{ 0x1EA1, 0x0061, 0x0323},
+{ 0x1EA2, 0x0041, 0x0309},
+{ 0x1EA3, 0x0061, 0x0309},
+{ 0x1EA4, 0x00C2, 0x0301},
+{ 0x1EA5, 0x00E2, 0x0301},
+{ 0x1EA6, 0x00C2, 0x0300},
+{ 0x1EA7, 0x00E2, 0x0300},
+{ 0x1EA8, 0x00C2, 0x0309},
+{ 0x1EA9, 0x00E2, 0x0309},
+{ 0x1EAA, 0x00C2, 0x0303},
+{ 0x1EAB, 0x00E2, 0x0303},
+{ 0x1EAC, 0x1EA0, 0x0302},
+{ 0x1EAD, 0x1EA1, 0x0302},
+{ 0x1EAE, 0x0102, 0x0301},
+{ 0x1EAF, 0x0103, 0x0301},
+{ 0x1EB0, 0x0102, 0x0300},
+{ 0x1EB1, 0x0103, 0x0300},
+{ 0x1EB2, 0x0102, 0x0309},
+{ 0x1EB3, 0x0103, 0x0309},
+{ 0x1EB4, 0x0102, 0x0303},
+{ 0x1EB5, 0x0103, 0x0303},
+{ 0x1EB6, 0x1EA0, 0x0306},
+{ 0x1EB7, 0x1EA1, 0x0306},
+{ 0x1EB8, 0x0045, 0x0323},
+{ 0x1EB9, 0x0065, 0x0323},
+{ 0x1EBA, 0x0045, 0x0309},
+{ 0x1EBB, 0x0065, 0x0309},
+{ 0x1EBC, 0x0045, 0x0303},
+{ 0x1EBD, 0x0065, 0x0303},
+{ 0x1EBE, 0x00CA, 0x0301},
+{ 0x1EBF, 0x00EA, 0x0301},
+{ 0x1EC0, 0x00CA, 0x0300},
+{ 0x1EC1, 0x00EA, 0x0300},
+{ 0x1EC2, 0x00CA, 0x0309},
+{ 0x1EC3, 0x00EA, 0x0309},
+{ 0x1EC4, 0x00CA, 0x0303},
+{ 0x1EC5, 0x00EA, 0x0303},
+{ 0x1EC6, 0x1EB8, 0x0302},
+{ 0x1EC7, 0x1EB9, 0x0302},
+{ 0x1EC8, 0x0049, 0x0309},
+{ 0x1EC9, 0x0069, 0x0309},
+{ 0x1ECA, 0x0049, 0x0323},
+{ 0x1ECB, 0x0069, 0x0323},
+{ 0x1ECC, 0x004F, 0x0323},
+{ 0x1ECD, 0x006F, 0x0323},
+{ 0x1ECE, 0x004F, 0x0309},
+{ 0x1ECF, 0x006F, 0x0309},
+{ 0x1ED0, 0x00D4, 0x0301},
+{ 0x1ED1, 0x00F4, 0x0301},
+{ 0x1ED2, 0x00D4, 0x0300},
+{ 0x1ED3, 0x00F4, 0x0300},
+{ 0x1ED4, 0x00D4, 0x0309},
+{ 0x1ED5, 0x00F4, 0x0309},
+{ 0x1ED6, 0x00D4, 0x0303},
+{ 0x1ED7, 0x00F4, 0x0303},
+{ 0x1ED8, 0x1ECC, 0x0302},
+{ 0x1ED9, 0x1ECD, 0x0302},
+{ 0x1EDA, 0x01A0, 0x0301},
+{ 0x1EDB, 0x01A1, 0x0301},
+{ 0x1EDC, 0x01A0, 0x0300},
+{ 0x1EDD, 0x01A1, 0x0300},
+{ 0x1EDE, 0x01A0, 0x0309},
+{ 0x1EDF, 0x01A1, 0x0309},
+{ 0x1EE0, 0x01A0, 0x0303},
+{ 0x1EE1, 0x01A1, 0x0303},
+{ 0x1EE2, 0x01A0, 0x0323},
+{ 0x1EE3, 0x01A1, 0x0323},
+{ 0x1EE4, 0x0055, 0x0323},
+{ 0x1EE5, 0x0075, 0x0323},
+{ 0x1EE6, 0x0055, 0x0309},
+{ 0x1EE7, 0x0075, 0x0309},
+{ 0x1EE8, 0x01AF, 0x0301},
+{ 0x1EE9, 0x01B0, 0x0301},
+{ 0x1EEA, 0x01AF, 0x0300},
+{ 0x1EEB, 0x01B0, 0x0300},
+{ 0x1EEC, 0x01AF, 0x0309},
+{ 0x1EED, 0x01B0, 0x0309},
+{ 0x1EEE, 0x01AF, 0x0303},
+{ 0x1EEF, 0x01B0, 0x0303},
+{ 0x1EF0, 0x01AF, 0x0323},
+{ 0x1EF1, 0x01B0, 0x0323},
+{ 0x1EF2, 0x0059, 0x0300},
+{ 0x1EF3, 0x0079, 0x0300},
+{ 0x1EF4, 0x0059, 0x0323},
+{ 0x1EF5, 0x0079, 0x0323},
+{ 0x1EF6, 0x0059, 0x0309},
+{ 0x1EF7, 0x0079, 0x0309},
+{ 0x1EF8, 0x0059, 0x0303},
+{ 0x1EF9, 0x0079, 0x0303},
+{ 0x1F00, 0x03B1, 0x0313},
+{ 0x1F01, 0x03B1, 0x0314},
+{ 0x1F02, 0x1F00, 0x0300},
+{ 0x1F03, 0x1F01, 0x0300},
+{ 0x1F04, 0x1F00, 0x0301},
+{ 0x1F05, 0x1F01, 0x0301},
+{ 0x1F06, 0x1F00, 0x0342},
+{ 0x1F07, 0x1F01, 0x0342},
+{ 0x1F08, 0x0391, 0x0313},
+{ 0x1F09, 0x0391, 0x0314},
+{ 0x1F0A, 0x1F08, 0x0300},
+{ 0x1F0B, 0x1F09, 0x0300},
+{ 0x1F0C, 0x1F08, 0x0301},
+{ 0x1F0D, 0x1F09, 0x0301},
+{ 0x1F0E, 0x1F08, 0x0342},
+{ 0x1F0F, 0x1F09, 0x0342},
+{ 0x1F10, 0x03B5, 0x0313},
+{ 0x1F11, 0x03B5, 0x0314},
+{ 0x1F12, 0x1F10, 0x0300},
+{ 0x1F13, 0x1F11, 0x0300},
+{ 0x1F14, 0x1F10, 0x0301},
+{ 0x1F15, 0x1F11, 0x0301},
+{ 0x1F18, 0x0395, 0x0313},
+{ 0x1F19, 0x0395, 0x0314},
+{ 0x1F1A, 0x1F18, 0x0300},
+{ 0x1F1B, 0x1F19, 0x0300},
+{ 0x1F1C, 0x1F18, 0x0301},
+{ 0x1F1D, 0x1F19, 0x0301},
+{ 0x1F20, 0x03B7, 0x0313},
+{ 0x1F21, 0x03B7, 0x0314},
+{ 0x1F22, 0x1F20, 0x0300},
+{ 0x1F23, 0x1F21, 0x0300},
+{ 0x1F24, 0x1F20, 0x0301},
+{ 0x1F25, 0x1F21, 0x0301},
+{ 0x1F26, 0x1F20, 0x0342},
+{ 0x1F27, 0x1F21, 0x0342},
+{ 0x1F28, 0x0397, 0x0313},
+{ 0x1F29, 0x0397, 0x0314},
+{ 0x1F2A, 0x1F28, 0x0300},
+{ 0x1F2B, 0x1F29, 0x0300},
+{ 0x1F2C, 0x1F28, 0x0301},
+{ 0x1F2D, 0x1F29, 0x0301},
+{ 0x1F2E, 0x1F28, 0x0342},
+{ 0x1F2F, 0x1F29, 0x0342},
+{ 0x1F30, 0x03B9, 0x0313},
+{ 0x1F31, 0x03B9, 0x0314},
+{ 0x1F32, 0x1F30, 0x0300},
+{ 0x1F33, 0x1F31, 0x0300},
+{ 0x1F34, 0x1F30, 0x0301},
+{ 0x1F35, 0x1F31, 0x0301},
+{ 0x1F36, 0x1F30, 0x0342},
+{ 0x1F37, 0x1F31, 0x0342},
+{ 0x1F38, 0x0399, 0x0313},
+{ 0x1F39, 0x0399, 0x0314},
+{ 0x1F3A, 0x1F38, 0x0300},
+{ 0x1F3B, 0x1F39, 0x0300},
+{ 0x1F3C, 0x1F38, 0x0301},
+{ 0x1F3D, 0x1F39, 0x0301},
+{ 0x1F3E, 0x1F38, 0x0342},
+{ 0x1F3F, 0x1F39, 0x0342},
+{ 0x1F40, 0x03BF, 0x0313},
+{ 0x1F41, 0x03BF, 0x0314},
+{ 0x1F42, 0x1F40, 0x0300},
+{ 0x1F43, 0x1F41, 0x0300},
+{ 0x1F44, 0x1F40, 0x0301},
+{ 0x1F45, 0x1F41, 0x0301},
+{ 0x1F48, 0x039F, 0x0313},
+{ 0x1F49, 0x039F, 0x0314},
+{ 0x1F4A, 0x1F48, 0x0300},
+{ 0x1F4B, 0x1F49, 0x0300},
+{ 0x1F4C, 0x1F48, 0x0301},
+{ 0x1F4D, 0x1F49, 0x0301},
+{ 0x1F50, 0x03C5, 0x0313},
+{ 0x1F51, 0x03C5, 0x0314},
+{ 0x1F52, 0x1F50, 0x0300},
+{ 0x1F53, 0x1F51, 0x0300},
+{ 0x1F54, 0x1F50, 0x0301},
+{ 0x1F55, 0x1F51, 0x0301},
+{ 0x1F56, 0x1F50, 0x0342},
+{ 0x1F57, 0x1F51, 0x0342},
+{ 0x1F59, 0x03A5, 0x0314},
+{ 0x1F5B, 0x1F59, 0x0300},
+{ 0x1F5D, 0x1F59, 0x0301},
+{ 0x1F5F, 0x1F59, 0x0342},
+{ 0x1F60, 0x03C9, 0x0313},
+{ 0x1F61, 0x03C9, 0x0314},
+{ 0x1F62, 0x1F60, 0x0300},
+{ 0x1F63, 0x1F61, 0x0300},
+{ 0x1F64, 0x1F60, 0x0301},
+{ 0x1F65, 0x1F61, 0x0301},
+{ 0x1F66, 0x1F60, 0x0342},
+{ 0x1F67, 0x1F61, 0x0342},
+{ 0x1F68, 0x03A9, 0x0313},
+{ 0x1F69, 0x03A9, 0x0314},
+{ 0x1F6A, 0x1F68, 0x0300},
+{ 0x1F6B, 0x1F69, 0x0300},
+{ 0x1F6C, 0x1F68, 0x0301},
+{ 0x1F6D, 0x1F69, 0x0301},
+{ 0x1F6E, 0x1F68, 0x0342},
+{ 0x1F6F, 0x1F69, 0x0342},
+{ 0x1F70, 0x03B1, 0x0300},
+{ 0x1F72, 0x03B5, 0x0300},
+{ 0x1F74, 0x03B7, 0x0300},
+{ 0x1F76, 0x03B9, 0x0300},
+{ 0x1F78, 0x03BF, 0x0300},
+{ 0x1F7A, 0x03C5, 0x0300},
+{ 0x1F7C, 0x03C9, 0x0300},
+{ 0x1F80, 0x1F00, 0x0345},
+{ 0x1F81, 0x1F01, 0x0345},
+{ 0x1F82, 0x1F02, 0x0345},
+{ 0x1F83, 0x1F03, 0x0345},
+{ 0x1F84, 0x1F04, 0x0345},
+{ 0x1F85, 0x1F05, 0x0345},
+{ 0x1F86, 0x1F06, 0x0345},
+{ 0x1F87, 0x1F07, 0x0345},
+{ 0x1F88, 0x1F08, 0x0345},
+{ 0x1F89, 0x1F09, 0x0345},
+{ 0x1F8A, 0x1F0A, 0x0345},
+{ 0x1F8B, 0x1F0B, 0x0345},
+{ 0x1F8C, 0x1F0C, 0x0345},
+{ 0x1F8D, 0x1F0D, 0x0345},
+{ 0x1F8E, 0x1F0E, 0x0345},
+{ 0x1F8F, 0x1F0F, 0x0345},
+{ 0x1F90, 0x1F20, 0x0345},
+{ 0x1F91, 0x1F21, 0x0345},
+{ 0x1F92, 0x1F22, 0x0345},
+{ 0x1F93, 0x1F23, 0x0345},
+{ 0x1F94, 0x1F24, 0x0345},
+{ 0x1F95, 0x1F25, 0x0345},
+{ 0x1F96, 0x1F26, 0x0345},
+{ 0x1F97, 0x1F27, 0x0345},
+{ 0x1F98, 0x1F28, 0x0345},
+{ 0x1F99, 0x1F29, 0x0345},
+{ 0x1F9A, 0x1F2A, 0x0345},
+{ 0x1F9B, 0x1F2B, 0x0345},
+{ 0x1F9C, 0x1F2C, 0x0345},
+{ 0x1F9D, 0x1F2D, 0x0345},
+{ 0x1F9E, 0x1F2E, 0x0345},
+{ 0x1F9F, 0x1F2F, 0x0345},
+{ 0x1FA0, 0x1F60, 0x0345},
+{ 0x1FA1, 0x1F61, 0x0345},
+{ 0x1FA2, 0x1F62, 0x0345},
+{ 0x1FA3, 0x1F63, 0x0345},
+{ 0x1FA4, 0x1F64, 0x0345},
+{ 0x1FA5, 0x1F65, 0x0345},
+{ 0x1FA6, 0x1F66, 0x0345},
+{ 0x1FA7, 0x1F67, 0x0345},
+{ 0x1FA8, 0x1F68, 0x0345},
+{ 0x1FA9, 0x1F69, 0x0345},
+{ 0x1FAA, 0x1F6A, 0x0345},
+{ 0x1FAB, 0x1F6B, 0x0345},
+{ 0x1FAC, 0x1F6C, 0x0345},
+{ 0x1FAD, 0x1F6D, 0x0345},
+{ 0x1FAE, 0x1F6E, 0x0345},
+{ 0x1FAF, 0x1F6F, 0x0345},
+{ 0x1FB0, 0x03B1, 0x0306},
+{ 0x1FB1, 0x03B1, 0x0304},
+{ 0x1FB2, 0x1F70, 0x0345},
+{ 0x1FB3, 0x03B1, 0x0345},
+{ 0x1FB4, 0x03AC, 0x0345},
+{ 0x1FB6, 0x03B1, 0x0342},
+{ 0x1FB7, 0x1FB6, 0x0345},
+{ 0x1FB8, 0x0391, 0x0306},
+{ 0x1FB9, 0x0391, 0x0304},
+{ 0x1FBA, 0x0391, 0x0300},
+{ 0x1FBC, 0x0391, 0x0345},
+{ 0x1FC1, 0x00A8, 0x0342},
+{ 0x1FC2, 0x1F74, 0x0345},
+{ 0x1FC3, 0x03B7, 0x0345},
+{ 0x1FC4, 0x03AE, 0x0345},
+{ 0x1FC6, 0x03B7, 0x0342},
+{ 0x1FC7, 0x1FC6, 0x0345},
+{ 0x1FC8, 0x0395, 0x0300},
+{ 0x1FCA, 0x0397, 0x0300},
+{ 0x1FCC, 0x0397, 0x0345},
+{ 0x1FCD, 0x1FBF, 0x0300},
+{ 0x1FCE, 0x1FBF, 0x0301},
+{ 0x1FCF, 0x1FBF, 0x0342},
+{ 0x1FD0, 0x03B9, 0x0306},
+{ 0x1FD1, 0x03B9, 0x0304},
+{ 0x1FD2, 0x03CA, 0x0300},
+{ 0x1FD6, 0x03B9, 0x0342},
+{ 0x1FD7, 0x03CA, 0x0342},
+{ 0x1FD8, 0x0399, 0x0306},
+{ 0x1FD9, 0x0399, 0x0304},
+{ 0x1FDA, 0x0399, 0x0300},
+{ 0x1FDD, 0x1FFE, 0x0300},
+{ 0x1FDE, 0x1FFE, 0x0301},
+{ 0x1FDF, 0x1FFE, 0x0342},
+{ 0x1FE0, 0x03C5, 0x0306},
+{ 0x1FE1, 0x03C5, 0x0304},
+{ 0x1FE2, 0x03CB, 0x0300},
+{ 0x1FE4, 0x03C1, 0x0313},
+{ 0x1FE5, 0x03C1, 0x0314},
+{ 0x1FE6, 0x03C5, 0x0342},
+{ 0x1FE7, 0x03CB, 0x0342},
+{ 0x1FE8, 0x03A5, 0x0306},
+{ 0x1FE9, 0x03A5, 0x0304},
+{ 0x1FEA, 0x03A5, 0x0300},
+{ 0x1FEC, 0x03A1, 0x0314},
+{ 0x1FED, 0x00A8, 0x0300},
+{ 0x1FF2, 0x1F7C, 0x0345},
+{ 0x1FF3, 0x03C9, 0x0345},
+{ 0x1FF4, 0x03CE, 0x0345},
+{ 0x1FF6, 0x03C9, 0x0342},
+{ 0x1FF7, 0x1FF6, 0x0345},
+{ 0x1FF8, 0x039F, 0x0300},
+{ 0x1FFA, 0x03A9, 0x0300},
+{ 0x1FFC, 0x03A9, 0x0345},
+{ 0x219A, 0x2190, 0x0338},
+{ 0x219B, 0x2192, 0x0338},
+{ 0x21AE, 0x2194, 0x0338},
+{ 0x21CD, 0x21D0, 0x0338},
+{ 0x21CE, 0x21D4, 0x0338},
+{ 0x21CF, 0x21D2, 0x0338},
+{ 0x2204, 0x2203, 0x0338},
+{ 0x2209, 0x2208, 0x0338},
+{ 0x220C, 0x220B, 0x0338},
+{ 0x2224, 0x2223, 0x0338},
+{ 0x2226, 0x2225, 0x0338},
+{ 0x2241, 0x223C, 0x0338},
+{ 0x2244, 0x2243, 0x0338},
+{ 0x2247, 0x2245, 0x0338},
+{ 0x2249, 0x2248, 0x0338},
+{ 0x2260, 0x003D, 0x0338},
+{ 0x2262, 0x2261, 0x0338},
+{ 0x226D, 0x224D, 0x0338},
+{ 0x226E, 0x003C, 0x0338},
+{ 0x226F, 0x003E, 0x0338},
+{ 0x2270, 0x2264, 0x0338},
+{ 0x2271, 0x2265, 0x0338},
+{ 0x2274, 0x2272, 0x0338},
+{ 0x2275, 0x2273, 0x0338},
+{ 0x2278, 0x2276, 0x0338},
+{ 0x2279, 0x2277, 0x0338},
+{ 0x2280, 0x227A, 0x0338},
+{ 0x2281, 0x227B, 0x0338},
+{ 0x2284, 0x2282, 0x0338},
+{ 0x2285, 0x2283, 0x0338},
+{ 0x2288, 0x2286, 0x0338},
+{ 0x2289, 0x2287, 0x0338},
+{ 0x22AC, 0x22A2, 0x0338},
+{ 0x22AD, 0x22A8, 0x0338},
+{ 0x22AE, 0x22A9, 0x0338},
+{ 0x22AF, 0x22AB, 0x0338},
+{ 0x22E0, 0x227C, 0x0338},
+{ 0x22E1, 0x227D, 0x0338},
+{ 0x22E2, 0x2291, 0x0338},
+{ 0x22E3, 0x2292, 0x0338},
+{ 0x22EA, 0x22B2, 0x0338},
+{ 0x22EB, 0x22B3, 0x0338},
+{ 0x22EC, 0x22B4, 0x0338},
+{ 0x22ED, 0x22B5, 0x0338},
+{ 0x304C, 0x304B, 0x3099},
+{ 0x304E, 0x304D, 0x3099},
+{ 0x3050, 0x304F, 0x3099},
+{ 0x3052, 0x3051, 0x3099},
+{ 0x3054, 0x3053, 0x3099},
+{ 0x3056, 0x3055, 0x3099},
+{ 0x3058, 0x3057, 0x3099},
+{ 0x305A, 0x3059, 0x3099},
+{ 0x305C, 0x305B, 0x3099},
+{ 0x305E, 0x305D, 0x3099},
+{ 0x3060, 0x305F, 0x3099},
+{ 0x3062, 0x3061, 0x3099},
+{ 0x3065, 0x3064, 0x3099},
+{ 0x3067, 0x3066, 0x3099},
+{ 0x3069, 0x3068, 0x3099},
+{ 0x3070, 0x306F, 0x3099},
+{ 0x3071, 0x306F, 0x309A},
+{ 0x3073, 0x3072, 0x3099},
+{ 0x3074, 0x3072, 0x309A},
+{ 0x3076, 0x3075, 0x3099},
+{ 0x3077, 0x3075, 0x309A},
+{ 0x3079, 0x3078, 0x3099},
+{ 0x307A, 0x3078, 0x309A},
+{ 0x307C, 0x307B, 0x3099},
+{ 0x307D, 0x307B, 0x309A},
+{ 0x3094, 0x3046, 0x3099},
+{ 0x309E, 0x309D, 0x3099},
+{ 0x30AC, 0x30AB, 0x3099},
+{ 0x30AE, 0x30AD, 0x3099},
+{ 0x30B0, 0x30AF, 0x3099},
+{ 0x30B2, 0x30B1, 0x3099},
+{ 0x30B4, 0x30B3, 0x3099},
+{ 0x30B6, 0x30B5, 0x3099},
+{ 0x30B8, 0x30B7, 0x3099},
+{ 0x30BA, 0x30B9, 0x3099},
+{ 0x30BC, 0x30BB, 0x3099},
+{ 0x30BE, 0x30BD, 0x3099},
+{ 0x30C0, 0x30BF, 0x3099},
+{ 0x30C2, 0x30C1, 0x3099},
+{ 0x30C5, 0x30C4, 0x3099},
+{ 0x30C7, 0x30C6, 0x3099},
+{ 0x30C9, 0x30C8, 0x3099},
+{ 0x30D0, 0x30CF, 0x3099},
+{ 0x30D1, 0x30CF, 0x309A},
+{ 0x30D3, 0x30D2, 0x3099},
+{ 0x30D4, 0x30D2, 0x309A},
+{ 0x30D6, 0x30D5, 0x3099},
+{ 0x30D7, 0x30D5, 0x309A},
+{ 0x30D9, 0x30D8, 0x3099},
+{ 0x30DA, 0x30D8, 0x309A},
+{ 0x30DC, 0x30DB, 0x3099},
+{ 0x30DD, 0x30DB, 0x309A},
+{ 0x30F4, 0x30A6, 0x3099},
+{ 0x30F7, 0x30EF, 0x3099},
+{ 0x30F8, 0x30F0, 0x3099},
+{ 0x30F9, 0x30F1, 0x3099},
+{ 0x30FA, 0x30F2, 0x3099},
+{ 0x30FE, 0x30FD, 0x3099},
+{ 0xFB1D, 0x05D9, 0x05B4},
+{ 0xFB1F, 0x05F2, 0x05B7},
+{ 0xFB2A, 0x05E9, 0x05C1},
+{ 0xFB2B, 0x05E9, 0x05C2},
+{ 0xFB2C, 0xFB49, 0x05C1},
+{ 0xFB2D, 0xFB49, 0x05C2},
+{ 0xFB2E, 0x05D0, 0x05B7},
+{ 0xFB2F, 0x05D0, 0x05B8},
+{ 0xFB30, 0x05D0, 0x05BC},
+{ 0xFB31, 0x05D1, 0x05BC},
+{ 0xFB32, 0x05D2, 0x05BC},
+{ 0xFB33, 0x05D3, 0x05BC},
+{ 0xFB34, 0x05D4, 0x05BC},
+{ 0xFB35, 0x05D5, 0x05BC},
+{ 0xFB36, 0x05D6, 0x05BC},
+{ 0xFB38, 0x05D8, 0x05BC},
+{ 0xFB39, 0x05D9, 0x05BC},
+{ 0xFB3A, 0x05DA, 0x05BC},
+{ 0xFB3B, 0x05DB, 0x05BC},
+{ 0xFB3C, 0x05DC, 0x05BC},
+{ 0xFB3E, 0x05DE, 0x05BC},
+{ 0xFB40, 0x05E0, 0x05BC},
+{ 0xFB41, 0x05E1, 0x05BC},
+{ 0xFB43, 0x05E3, 0x05BC},
+{ 0xFB44, 0x05E4, 0x05BC},
+{ 0xFB46, 0x05E6, 0x05BC},
+{ 0xFB47, 0x05E7, 0x05BC},
+{ 0xFB48, 0x05E8, 0x05BC},
+{ 0xFB49, 0x05E9, 0x05BC},
+{ 0xFB4A, 0x05EA, 0x05BC},
+{ 0xFB4B, 0x05D5, 0x05B9},
+{ 0xFB4C, 0x05D1, 0x05BF},
+{ 0xFB4D, 0x05DB, 0x05BF},
+{ 0xFB4E, 0x05E4, 0x05BF},
+};
+
+int do_precomposition(int base, int comb) {
+  int min = 0;
+  int max = sizeof(precompositions) / sizeof(precompositions[0]) - 1;
+  int mid;
+  int sought = (base << 16) | comb, that;
+
+  /* binary search */
+  while (max >= min) {
+    mid = (min + max) / 2;
+    that = (precompositions[mid].base << 16) | (precompositions[mid].comb);
+    if (that < sought) {
+      min = mid + 1;
+    } else if (that > sought) {
+      max = mid - 1;
+    } else {
+      return precompositions[mid].replacement;
+    }
+  }
+  /* no match */
+  return -1;
+}
Index: precompose.h
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-141/precompose.h      Fri Aug 11 06:09:25 2000
@@ -0,0 +1,9 @@
+#ifndef PRECOMPOSE_H
+#define PRECOMPOSE_H
+
+int do_precomposition(int base, int comb);
+
+/* returns unicode value if a canonical composition exists,
+   otherwise -1 */
+
+#endif
Index: ptyx.h
--- xterm-140+/ptyx.h   Sun Jul 23 16:35:57 2000
+++ xterm-141/ptyx.h    Fri Aug 11 06:09:25 2000
@@ -758,6 +758,10 @@
 #endif
 #if OPT_WIDE_CHARS
        , OFF_WIDEC
+       , OFF_COM1L
+       , OFF_COM1H
+       , OFF_COM2L
+       , OFF_COM2H
 #endif
 } BufOffsets;
 
@@ -770,6 +774,10 @@
 #define BUF_BGRND(buf, row) (buf[MAX_PTRS * (row) + OFF_BGRND])
 #define BUF_CSETS(buf, row) (buf[MAX_PTRS * (row) + OFF_CSETS])
 #define BUF_WIDEC(buf, row) (buf[MAX_PTRS * (row) + OFF_WIDEC])
+#define BUF_COM1L(buf, row) (buf[MAX_PTRS * (row) + OFF_COM1L])
+#define BUF_COM1H(buf, row) (buf[MAX_PTRS * (row) + OFF_COM1H])
+#define BUF_COM2L(buf, row) (buf[MAX_PTRS * (row) + OFF_COM2L])
+#define BUF_COM2H(buf, row) (buf[MAX_PTRS * (row) + OFF_COM2H])
 
        /* TScreen-level macros */
 #define SCRN_BUF_FLAGS(screen, row) BUF_FLAGS(screen->visbuf, row)
@@ -780,6 +788,10 @@
 #define SCRN_BUF_BGRND(screen, row) BUF_BGRND(screen->visbuf, row)
 #define SCRN_BUF_CSETS(screen, row) BUF_CSETS(screen->visbuf, row)
 #define SCRN_BUF_WIDEC(screen, row) BUF_WIDEC(screen->visbuf, row)
+#define SCRN_BUF_COM1L(screen, row) BUF_COM1L(screen->visbuf, row)
+#define SCRN_BUF_COM2L(screen, row) BUF_COM2L(screen->visbuf, row)
+#define SCRN_BUF_COM1H(screen, row) BUF_COM1H(screen->visbuf, row)
+#define SCRN_BUF_COM2H(screen, row) BUF_COM2H(screen->visbuf, row)
 
 typedef struct {
        unsigned        chrset;
@@ -999,6 +1011,7 @@
        Dimension       fnt_high;
        XFontStruct     *fnt_norm;      /* normal font of terminal      */
        XFontStruct     *fnt_bold;      /* bold font of terminal        */
+       XFontStruct     *fnt_dwd;       /* wide font of terminal        */
 #ifndef NO_ACTIVE_ICON
        XFontStruct     *fnt_icon;      /* icon font */
 #endif /* NO_ACTIVE_ICON */
@@ -1194,6 +1207,7 @@
     char *T_geometry;
     char *f_n;
     char *f_b;
+    char *f_w;
     int limit_resize;
 #ifdef ALLOWLOGGING
     Boolean log_on;
Index: screen.c
--- xterm-140+/screen.c Wed Jun 14 15:50:37 2000
+++ xterm-141/screen.c  Fri Aug 11 06:09:25 2000
@@ -58,6 +58,7 @@
 
 /* screen.c */
 
+#include <stdio.h>
 #include <xterm.h>
 #include <error.h>
 #include <data.h>
@@ -274,6 +275,9 @@
        return move_down ? move_down : -move_up; /* convert to rows */
 }
 
+int last_written_row = -1;
+int last_written_col = -1;
+
 /*
  * Writes str into buf at screen's current row and column.  Characters are set
  * to match flags.
@@ -302,6 +306,17 @@
        int avail  = screen->max_col - screen->cur_col + 1;
        Char *col;
        int wrappedbit;
+       Char starcol, starcol2; 
+ #if OPT_WIDE_CHARS
+       Char *comb1l, *comb1h, *comb2l, *comb2h;
+ #endif
+ 
+ #if OPT_WIDE_CHARS
+       int real_width = visual_width(PAIRED_CHARS(str, str2), length);
+ #else
+       int real_width = length;
+ #endif
+       str[len] = 0;
 
        if (length > avail)
            length = avail;
@@ -311,6 +326,14 @@
        col   = SCRN_BUF_CHARS(screen, screen->cur_row) + screen->cur_col;
        attrs = SCRN_BUF_ATTRS(screen, screen->cur_row) + screen->cur_col;
 
+#if OPT_WIDE_CHARS
+       comb1l   = SCRN_BUF_COM1L(screen, screen->cur_row) + screen->cur_col;
+       comb1h   = SCRN_BUF_COM1H(screen, screen->cur_row) + screen->cur_col;
+
+       comb2l   = SCRN_BUF_COM2L(screen, screen->cur_row) + screen->cur_col;
+       comb2h   = SCRN_BUF_COM2H(screen, screen->cur_row) + screen->cur_col;
+#endif
+
        if_OPT_EXT_COLORS(screen,{
                fbf = SCRN_BUF_FGRND(screen, screen->cur_row) + screen->cur_col;
                fbb = SCRN_BUF_BGRND(screen, screen->cur_row) + screen->cur_col;
@@ -324,36 +347,108 @@
 
        wrappedbit = ScrnTstWrapped(screen, screen->cur_row);
 
+       starcol = *col;
+       starcol2 = col[length-1];
+
        /* write blanks if we're writing invisible text */
        if (flags & INVISIBLE) {
+#if OPT_WIDE_CHARS
+               memset(col, ' ', real_width);
+#else
                memset(col, ' ', length);
+#endif
        } else {
-               memcpy(col, str, length);
+               memcpy(col, str, length); /* This can stand for the present. If it
+                                             is wrong, we will scribble over it */
        }
+#define ERROR_1 0x20
+#define ERROR_2 0x00
        if_OPT_WIDE_CHARS(screen,{
+
                Char *wc;
+
+               if (real_width != length) {
+                       Char *c = col;
+                       wc = SCRN_BUF_WIDEC(screen, screen->cur_row);
+                       wc += screen->cur_col;
+                       if (screen->cur_col && starcol == HIDDEN_LO && *wc == HIDDEN_HI
+                           && iswide(c[-1] | (wc[-1] << 8))) {
+                               c[-1] = ERROR_1;
+                               wc[-1] = ERROR_2;
+                       }
+                       /* if we are overwriting the right hand half of a
+                           wide character, make the other half vanish */
+                       while (length) {
+                               int ch = *str;
+                               if (str2) ch |= *str2 << 8;
+
+                               *c = *str;
+                               c++; str++;
+                               
+                               if (str2) { *wc = *str2; str2++; } else *wc = 0;
+                               wc++;
+                               length--;
+
+                               if (iswide(ch)) {
+                                       *c = HIDDEN_LO; *wc = HIDDEN_HI;
+                                       c++; wc++;
+                               }
+                       }
+
+                       if (*c == HIDDEN_LO && *wc == HIDDEN_HI && c[-1] == HIDDEN_LO && wc[-1] == HIDDEN_HI) {
+                               *c = ERROR_1;
+                               *wc = ERROR_2;
+                       }
+                       /* if we are overwriting the left hand half of a
+                           wide character, make the other half vanish */
+               }
+
+               else {
+
                if ((wc = SCRN_BUF_WIDEC(screen, screen->cur_row)) != 0) {
                        wc += screen->cur_col;
+                       if (screen->cur_col && starcol == HIDDEN_LO && *wc == HIDDEN_HI
+                           && iswide(col[-1] | (wc[-1] << 8))) {
+                               col[-1] = ERROR_1;
+                               wc[-1] = ERROR_2;
+                       }
+                       /* if we are overwriting the right hand half of a
+                           wide character, make the other half vanish */
+                       if (col[length] == HIDDEN_LO && wc[length] == HIDDEN_HI &&
+                            iswide(starcol2 | (wc[length-1]<<8))) {
+                               col[length] = ERROR_1;
+                               wc[length] = ERROR_2;
+                       }
+                       /* if we are overwriting the left hand half of a
+                           wide character, make the other half vanish */
                        if ((flags & INVISIBLE) || (str2 == 0))
                                memset(wc, 0, length);
                        else
                                memcpy(wc, str2, length);
                }
+        }
        })
 
        flags &= ATTRIBUTES;
        flags |= CHARDRAWN;
-       memset( attrs, flags,  length);
+       memset( attrs, flags,  real_width);
+
+if_OPT_WIDE_CHARS(screen, {
+       memset( comb1l,   0, real_width);
+       memset( comb2l,   0, real_width);
+       memset( comb1h,   0, real_width);
+       memset( comb2h,   0, real_width);
+       })
 
        if_OPT_EXT_COLORS(screen,{
-               memset( fbf,  cur_fg_bg >> 8, length);
-               memset( fbb,  cur_fg_bg & 0xff, length);
+               memset( fbf,  cur_fg_bg >> 8, real_width);
+               memset( fbb,  cur_fg_bg & 0xff, real_width);
        })
        if_OPT_ISO_TRADITIONAL_COLORS(screen,{
-               memset( fb,   cur_fg_bg, length);
+               memset( fb,   cur_fg_bg, real_width);
        })
        if_OPT_DEC_CHRSET({
-               memset( cb,   curXtermChrSet(screen->cur_row), length);
+               memset( cb,   curXtermChrSet(screen->cur_row), real_width);
        })
 
        if (wrappedbit)
@@ -361,6 +456,9 @@
        else
            ScrnClrWrapped(screen, screen->cur_row);
 
+       last_written_col = screen->cur_col + real_width - 1;
+       last_written_row = screen->cur_row;
+
        if_OPT_XMC_GLITCH(screen,{
                Resolve_XMC(screen);
        })
@@ -542,6 +640,22 @@
            ptr = BUF_WIDEC(sb, row);
            memmove(ptr + col + n, ptr + col, nbytes);
            memset(ptr + col, 0, n);
+
+           ptr = BUF_COM1L(sb, row);
+           memmove(ptr + col + n, ptr + col, nbytes);
+           memset(ptr + col, 0, n);
+           
+           ptr = BUF_COM1H(sb, row);
+           memmove(ptr + col + n, ptr + col, nbytes);
+           memset(ptr + col, 0, n);
+           
+           ptr = BUF_COM2L(sb, row);
+           memmove(ptr + col + n, ptr + col, nbytes);
+           memset(ptr + col, 0, n);
+           
+           ptr = BUF_COM2H(sb, row);
+           memmove(ptr + col + n, ptr + col, nbytes);
+           memset(ptr + col, 0, n);
        })
 
        if (wrappedbit)
@@ -598,6 +712,22 @@
            ptr = BUF_WIDEC(sb, row);
            memmove(ptr + col, ptr + col + n, nbytes);
            memset(ptr + size - n, 0, n);
+
+           ptr = BUF_COM1L(sb, row);
+           memmove(ptr + col, ptr + col + n, nbytes);
+           memset(ptr + size - n, 0, n);
+             
+           ptr = BUF_COM1H(sb, row);
+           memmove(ptr + col, ptr + col + n, nbytes);
+           memset(ptr + size - n, 0, n);
+             
+           ptr = BUF_COM2L(sb, row);
+           memmove(ptr + col, ptr + col + n, nbytes);
+           memset(ptr + size - n, 0, n);
+             
+           ptr = BUF_COM2H(sb, row);
+           memmove(ptr + col, ptr + col + n, nbytes);
+           memset(ptr + size - n, 0, n);
        })
        ScrnClrWrapped(screen, row);
 }
@@ -616,7 +746,8 @@
        int leftcol,
        int nrows,
        int ncols,
-       Bool force)                     /* ... leading/trailing spaces */
+       Bool force
+)                      /* ... leading/trailing spaces */
 {
        int y = toprow * FontHeight(screen) + screen->border;
        int row;
@@ -628,6 +759,7 @@
 #ifdef __CYGWIN__
        static char first_time = 1;
 #endif
+        static int recurse = 0;
 
        TRACE(("ScrnRefresh (%d,%d) - (%d,%d)%s\n",
                toprow, leftcol,
@@ -653,6 +785,7 @@
           Char *cb = 0;
 #endif
 #if OPT_WIDE_CHARS
+          int wideness = 0;
           Char *widec = 0;
 #define WIDEC_PTR(cell) widec ? &widec[cell] : 0
 #endif
@@ -688,6 +821,26 @@
                widec = SCRN_BUF_WIDEC(screen, lastind + topline);
           })
 
+          if_OPT_WIDE_CHARS(screen,{
+          /* This fixes an infinite recursion bug, that leads
+              to display anomalies. It seems to be related to 
+              problems with the selection. */
+           if (recurse < 3) {
+                   /* adjust to redraw all of a widechar if we just wanted 
+                      to draw the right hand half */
+                  if (iswide(chars[leftcol - 1] | (widec[leftcol -1]<<8)) &&
+                       (chars[leftcol] | (widec[leftcol]<<8))==HIDDEN_CHAR)
+                  {
+                       leftcol--;
+                       ncols++;
+                       col = leftcol;
+                  }
+           } else {
+               fprintf(stderr, "This should not happen. Why is it so?\n");
+          }
+          }
+           )
+
           if (row < screen->startHRow || row > screen->endHRow ||
               (row == screen->startHRow && maxcol < screen->startHCol) ||
               (row == screen->endHRow && col >= screen->endHCol))
@@ -723,11 +876,13 @@
           else {
               /* row intersects selection; split into pieces of single type */
               if (row == screen->startHRow && col < screen->startHCol) {
+                  recurse++;
                   ScrnRefresh(screen, row, col, 1, screen->startHCol - col,
                               force);
                   col = screen->startHCol;
               }
               if (row == screen->endHRow && maxcol >= screen->endHCol) {
+                  recurse++;
                   ScrnRefresh(screen, row, screen->endHCol, 1,
                               maxcol - screen->endHCol + 1, force);
                   maxcol = screen->endHCol - 1;
@@ -775,6 +930,12 @@
           })
 
           flags = attrs[col];
+#if OPT_WIDE_CHARS
+          if (widec)
+            wideness = iswide(chars[col] | (widec[col]<<8));
+          else
+            wideness = 0;
+#endif
           if_OPT_EXT_COLORS(screen,{
                fbf = SCRN_BUF_FGRND(screen, lastind + topline);
                fbb = SCRN_BUF_BGRND(screen, lastind + topline);
@@ -808,6 +969,11 @@
                 || ((flags & BG_COLOR) && (extract_bg(fb[col],attrs[col]) != bg))
 #endif
 #endif
+#if OPT_WIDE_CHARS
+                 || (widec 
+                     && ((iswide(chars[col] | (widec[col]<<8))) != wideness)
+                     && !((chars[col] | (widec[col]<<8))==HIDDEN_CHAR))
+#endif
 #if OPT_DEC_CHRSET
                 || (cb[col] != cs)
 #endif
@@ -819,9 +985,34 @@
                                PAIRED_CHARS(&chars[lastind], WIDEC_PTR(lastind)),
                                col - lastind)));
                   x = drawXtermText(screen, flags, gc, x, y,
-                       cs,
+                       cs,
                        PAIRED_CHARS(&chars[lastind], WIDEC_PTR(lastind)),
                        col - lastind);
+ 
+ if_OPT_WIDE_CHARS(screen, 
+                  {
+                       int i;
+                       Char *comb1l = BUF_COM1L(screen->visbuf, row + topline);
+                       Char *comb2l = BUF_COM2L(screen->visbuf, row + topline);
+                       Char *comb1h = BUF_COM1H(screen->visbuf, row + topline);
+                       Char *comb2h = BUF_COM2H(screen->visbuf, row + topline);
+                       for (i = lastind ; i < col; i++) {
+                               int my_x = CurCursorX(screen, row + topline, i);
+                               int comb1 = comb1l[i] | (comb1h[i] << 8);
+                               int comb2 = comb2l[i] | (comb2h[i] << 8);
+ 
+                               if (comb1 != 0) {
+                                       drawXtermText(screen, flags, gc, my_x, y, cs,
+                                                     PAIRED_CHARS(comb1l+i, comb1h+i), 1);
+                               }
+ 
+                               if (comb2 != 0) {
+                                       drawXtermText(screen, flags, gc, my_x, y, cs,
+                                                     PAIRED_CHARS(comb2l+i, comb2h+i), 1);
+                               }
+                       }
+                  })
+ 
                   resetXtermGC(screen, flags, hilite);
 
                   lastind = col;
@@ -843,6 +1034,10 @@
                   if_OPT_DEC_CHRSET({
                        cs = cb[col];
                   })
+#if OPT_WIDE_CHARS
+                  if (widec)
+                     wideness = iswide(chars[col] | (widec[col]<<8));
+#endif
                   gc = updatedXtermGC(screen, flags, fg_bg, hilite);
                   gc_changes |= (flags & (FG_COLOR|BG_COLOR));
                }
@@ -863,6 +1058,30 @@
                cs,
                PAIRED_CHARS(&chars[lastind], WIDEC_PTR(lastind)),
                col - lastind);
+
+if_OPT_WIDE_CHARS(screen,         {
+                       int i;
+                       Char *comb1l = BUF_COM1L(screen->visbuf, row + topline);
+                       Char *comb2l = BUF_COM2L(screen->visbuf, row + topline);
+                       Char *comb1h = BUF_COM1H(screen->visbuf, row + topline);
+                       Char *comb2h = BUF_COM2H(screen->visbuf, row + topline);
+                       for (i = lastind ; i < col; i++) {
+                               int my_x = CurCursorX(screen, row + topline, i);
+                               int comb1 = comb1l[i] | (comb1h[i] << 8);
+                               int comb2 = comb2l[i] | (comb2h[i] << 8);
+
+                               if (comb1 != 0) {
+                                       drawXtermText(screen, flags, gc, my_x, y, cs,
+                                                     PAIRED_CHARS(comb1l+i, comb1h+i), 1);
+                               }
+
+                               if (comb2 != 0) {
+                                       drawXtermText(screen, flags, gc, my_x, y, cs,
+                                                     PAIRED_CHARS(comb2l+i, comb2h+i), 1);
+                               }
+                       }
+          })
+
           resetXtermGC(screen, flags, hilite);
        }
 
@@ -890,6 +1109,7 @@
                ioctl (screen->respond, TIOCSWINSZ, (char *)&ws);
        }
 #endif
+       recurse--;
 }
 
 /*
@@ -924,6 +1144,10 @@
            })
            if_OPT_WIDE_CHARS(screen,{
                memset(BUF_WIDEC(buf, row), 0, len);
+               memset(BUF_COM1L(buf, row), 0, len);
+               memset(BUF_COM1H(buf, row), 0, len);
+               memset(BUF_COM2L(buf, row), 0, len);
+               memset(BUF_COM2H(buf, row), 0, len);
            })
        }
 }
Index: unicode/README
--- xterm-140+/unicode/README   Wed Jun 14 15:50:37 2000
+++ xterm-141/unicode/README    Fri Aug 11 06:09:25 2000
@@ -16,3 +16,8 @@
        ./convmap.plp >../keysym2ucs.c
 
 keysym.map is input data for convmap.pl
+
+
+The make-precompose.sh script makes the precompose.c file, which is used to
+handle canonical composition. This also needs UnicodeData-Latest.txt. It uses
+precompose.c.head and precompose.c.tail as templates.
Index: unicode/make-precompose.sh
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-141/unicode/make-precompose.sh        Fri Aug 11 06:09:25 2000
@@ -0,0 +1,6 @@
+#!/bin/sh
+cat precompose.c.head
+cut UnicodeData-Latest.txt -d ";" -f 1,6 | \
+ grep ";[0-9,A-F]" | grep " " | \
+ sed -e "s/ /, 0x/;s/^/{ 0x/;s/;/, 0x/;s/$/},/"
+cat precompose.c.tail
Index: unicode/precompose.c.head
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-141/unicode/precompose.c.head Sun Aug 13 21:55:15 2000
@@ -0,0 +1,14 @@
+/*
+ * Canonical Compositions
+ *
+ * DO NOT EDIT BY HAND! This is generated by the script
+ * unicode/make-precompose.sh
+ */
+
+#include <precompose.h>
+
+struct {
+  int base;
+  int comb; 
+  int replacement;
+} precompositions[] = {
Index: unicode/precompose.c.tail
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-141/unicode/precompose.c.tail Fri Aug 11 06:09:25 2000
@@ -0,0 +1,23 @@
+};
+
+int do_precomposition(int base, int comb) {
+  int min = 0;
+  int max = sizeof(precompositions) / sizeof(precompositions[0]) - 1;
+  int mid;
+  int sought = (base << 16) | comb, that;
+
+  /* binary search */
+  while (max >= min) {
+    mid = (min + max) / 2;
+    that = (precompositions[mid].base << 16) | (precompositions[mid].comb);
+    if (that < sought) {
+      min = mid + 1;
+    } else if (that > sought) {
+      max = mid - 1;
+    } else {
+      return precompositions[mid].replacement;
+    }
+  }
+  /* no match */
+  return -1;
+}
Index: util.c
--- xterm-140+/util.c   Wed Jun 14 15:50:37 2000
+++ xterm-141/util.c    Sun Aug 13 20:27:41 2000
@@ -64,6 +64,10 @@
 #include <menu.h>
 #include <fontutils.h>
 
+#if OPT_WIDE_CHARS
+#include <wcwidth.h>
+#endif
+
 #include <stdio.h>
 #include <ctype.h>
 
@@ -544,7 +548,7 @@
                HideCursor();
        screen->do_wrap = 0;
        if (n > (width = screen->max_col + 1 - screen->cur_col))
-               n = width;
+               n = width;
 
        if(screen->cur_row - screen->topline <= screen->max_row) {
            if(!AddToRefresh(screen)) {
@@ -732,6 +736,10 @@
        })
        if_OPT_WIDE_CHARS(screen,{
                memset(SCRN_BUF_WIDEC(screen, row) + col, 0, len);
+               memset(SCRN_BUF_COM1L(screen, row) + col, 0, len);
+               memset(SCRN_BUF_COM1H(screen, row) + col, 0, len);
+               memset(SCRN_BUF_COM2L(screen, row) + col, 0, len);
+               memset(SCRN_BUF_COM2H(screen, row) + col, 0, len);
        })
 
        return rc;
@@ -813,7 +821,7 @@
 
        if (saved_mode == DEC_PROTECT
         && saved_mode != mode)
-               screen->protected_mode = OFF_PROTECT;
+               screen->protected_mode = OFF_PROTECT;
 
        switch (param) {
        case -1:        /* DEFAULT */
@@ -846,7 +854,7 @@
 
        if (saved_mode == DEC_PROTECT
         && saved_mode != mode)
-               screen->protected_mode = OFF_PROTECT;
+               screen->protected_mode = OFF_PROTECT;
 
        switch (param) {
        case -1:        /* DEFAULT */
@@ -1377,6 +1385,7 @@
        PAIRED_CHARS(Char *text, Char *text2),
        Cardinal len)
 {
+       int real_length = len;
 #if OPT_WIDE_CHARS
        /*
         * It's simpler to pass in a null pointer for text2 in places where
@@ -1566,25 +1575,63 @@
 
 #if OPT_WIDE_CHARS
                if (screen->wide_chars) {
+                       int ascent_adjust = 0;
                        static XChar2b *sbuf;
                        static Cardinal slen;
                        Cardinal n;
+                       int ch = text[0] | (text2[0] << 8);
+                       int wideness = (iswide(ch)!=0) && (screen->fnt_dwd!=NULL);
+                       unsigned char *endtext = text + len;
                        if (slen < len) {
                                slen = (len + 1) * 2;
                                sbuf = (XChar2b *)XtRealloc((char *)sbuf, slen * sizeof(*sbuf));
                        }
                        for (n = 0; n < len; n++) {
-                               sbuf[n].byte2 = text[n];
-                               sbuf[n].byte1 = text2[n];
+                               sbuf[n].byte2 = *text;
+                               sbuf[n].byte1 = *text2;
+                               text++; text2++;
+                               if (wideness) {
+                                       /* filter out those pesky fake characters. */
+                                       while (text < endtext
+                                        && *text == HIDDEN_HI
+                                        && *text2 == HIDDEN_LO) {
+                                               text++; text2++;
+                                               len--;
+                                       }
+                               }
                        }
-                       XDrawImageString16(screen->display, VWindow(screen), gc,
-                               x, y, sbuf, len);
+                       /* This is probably wrong. But it works. */
+                       if (wideness && screen->fnt_dwd->fid) {
+                               real_length = len * 2;
+                               XSetFont(screen->display, gc, screen->fnt_dwd->fid);
+                               ascent_adjust = screen->fnt_dwd->ascent - screen->fnt_norm->ascent;
+                               /* fix ascent */
+                       }
+                       else if (flags & (BOLD|BLINK) && screen->fnt_bold->fid)
+                               XSetFont(screen->display, gc, screen->fnt_bold->fid);
+                       else
+                               XSetFont(screen->display, gc, screen->fnt_norm->fid);
+
+                       if (my_wcwidth(ch) == 0)
+                               XDrawString16(screen->display,
+                                             VWindow(screen), gc,
+                                             x, y + ascent_adjust,
+                                             sbuf, n);
+                       else
+                               XDrawImageString16(screen->display,
+                                                  VWindow(screen), gc,
+                                                  x, y + ascent_adjust,
+                                                  sbuf, n);
+
                } else
 #endif
                {
                XDrawImageString(screen->display, VWindow(screen), gc,
                        x, y,  (char *)text, len);
-
+#ifndef OPT_WIDE_CHARS
+               /* FIXME: This is rather broken with wide chars. It should
+                * use XDrawString16 where appropriate.
+                */
                if ((flags & (BOLD|BLINK)) && screen->enbolden) {
 #if OPT_CLIP_BOLD
                        /*
@@ -1611,6 +1658,7 @@
                        XSetClipMask(screen->display, gc, None);
 #endif
                }
+#endif /* !OPT_WIDE_CHARS */
                }
 
                if ((flags & UNDERLINE) && screen->underline) {
@@ -1628,15 +1676,21 @@
                                  : screen->fnt_norm;
                Cardinal last, first = 0;
                Boolean save_force = screen->force_box_chars;
-
                screen->fnt_boxes = True;
                for (last = 0; last < len; last++) {
                        unsigned ch = text[last];
+                       Boolean isMissing;
 #if OPT_WIDE_CHARS
                        if (text2 != 0)
                                ch |= (text2[last] << 8);
+                       isMissing = xtermMissingChar(ch,
+                                       (iswide(ch) && screen->fnt_dwd)
+                                       ? screen->fnt_dwd
+                                       : font);
+#else
+                       isMissing = xtermMissingChar(ch, font);
 #endif
-                       if (xtermMissingChar(ch, font)) {
+                       if (isMissing) {
                                if (last > first) {
                                        screen->force_box_chars = False;
                                        DrawSegment(first,last);
@@ -1655,7 +1709,7 @@
 #endif
        }
 
-       return x + len * FontWidth(screen);
+       return x + real_length * FontWidth(screen);
 }
 
 /*
@@ -1843,6 +1897,22 @@
     return ch;
 }
 
+unsigned getXtermCellComb1 (TScreen *screen, int row, int col)
+{
+    unsigned ch = SCRN_BUF_COM1L(screen, row)[col];
+    ch |= (SCRN_BUF_COM1H(screen, row)[col] << 8);
+    return ch;
+}
+
+
+unsigned getXtermCellComb2 (TScreen *screen, int row, int col)
+{
+    unsigned ch = SCRN_BUF_COM2L(screen, row)[col];
+    ch |= (SCRN_BUF_COM2H(screen, row)[col] << 8);
+    return ch;
+}
+
+
 /*
  * Sets a single 8/16-bit number for the given cell
  */
@@ -1851,7 +1921,25 @@
     SCRN_BUF_CHARS(screen, row)[col] = ch;
     if_OPT_WIDE_CHARS(screen,{
        SCRN_BUF_WIDEC(screen, row)[col] = (ch >> 8);
+       SCRN_BUF_COM1L(screen, row)[col] = 0;
+       SCRN_BUF_COM1H(screen, row)[col] = 0;
+       SCRN_BUF_COM2L(screen, row)[col] = 0;
+       SCRN_BUF_COM2H(screen, row)[col] = 0;
     })
+}
+
+/*
+ * Add a the combining character for the given cell
+ */
+void addXtermCombining (TScreen *screen, int row, int col, int ch)
+{
+    if (!SCRN_BUF_COM1L(screen, row)[col]) {
+           SCRN_BUF_COM1L(screen, row)[col] = ch & 0xff;
+           SCRN_BUF_COM1H(screen, row)[col] = ch >> 8;
+    } else if (!SCRN_BUF_COM2H(screen, row)[col]) {
+           SCRN_BUF_COM2L(screen, row)[col] = ch & 0xff;
+           SCRN_BUF_COM2H(screen, row)[col] = ch >> 8;
+    }
 }
 #endif
 
Index: version.h
--- xterm-140+/version.h        Sun Jul 23 18:30:28 2000
+++ xterm-141/version.h Mon Aug 14 21:30:27 2000
@@ -6,5 +6,5 @@
  * XFree86 to which this version of xterm has been built.  The number in
  * parentheses is my patch number (T.Dickey).
  */
-#define XTERM_PATCH   140
-#define XFREE86_VERSION "XFree86 4.0.1"
+#define XTERM_PATCH   141
+#define XFREE86_VERSION "XFree86 4.0.1b"
Index: wcwidth.c
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-141/wcwidth.c Fri Aug 11 06:55:13 2000
@@ -0,0 +1,129 @@
+/*
+ * This is an implementation of wcwidth() and wcswidth() as defined in
+ * "The Single UNIX Specification, Version 2, The Open Group, 1997"
+ * <http://www.UNIX-systems.org/online.html>
+ *
+ * Markus Kuhn -- 2000-02-08 -- public domain
+ */
+
+#include <wcwidth.h>
+
+/* These functions define the column width of an ISO 10646 character
+ * as follows:
+ *
+ *    - The null character (U+0000) has a column width of 0.
+ *
+ *    - Other C0/C1 control characters and DEL will lead to a return
+ *      value of -1.
+ *
+ *    - Non-spacing and enclosing combining characters (general
+ *      category code Mn or Me in the Unicode database) have a
+ *      column width of 0.
+ *
+ *    - Spacing characters in the East Asian Wide (W) or East Asian
+ *      FullWidth (F) category as defined in Unicode Technical
+ *      Report #11 have a column width of 2.
+ *
+ *    - All remaining characters (including all printable
+ *      ISO 8859-1 and WGL4 characters, Unicode control characters,
+ *      etc.) have a column width of 1.
+ *
+ * This implementation assumes that wchar_t characters are encoded
+ * in ISO 10646.
+ */
+
+int my_wcwidth(wchar_t ucs)
+{
+  /* sorted list of non-overlapping intervals of non-spacing characters */
+  static const struct interval {
+    unsigned short first;
+    unsigned short last;
+  } combining[] = {
+    { 0x0300, 0x034E }, { 0x0360, 0x0362 }, { 0x0483, 0x0486 },
+    { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 },
+    { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
+    { 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 },
+    { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
+    { 0x0711, 0x0711 }, { 0x0730, 0x074A }, { 0x07A6, 0x07B0 },
+    { 0x0901, 0x0902 }, { 0x093C, 0x093C }, { 0x0941, 0x0948 },
+    { 0x094D, 0x094D }, { 0x0951, 0x0954 }, { 0x0962, 0x0963 },
+    { 0x0981, 0x0981 }, { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 },
+    { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 }, { 0x0A02, 0x0A02 },
+    { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 },
+    { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 },
+    { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 },
+    { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
+    { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
+    { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
+    { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
+    { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBF, 0x0CBF },
+    { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, { 0x0D41, 0x0D43 },
+    { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 },
+    { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A },
+    { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 },
+    { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 },
+    { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 },
+    { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 },
+    { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 },
+    { 0x102D, 0x1030 }, { 0x1032, 0x1032 }, { 0x1036, 0x1037 },
+    { 0x1039, 0x1039 }, { 0x1058, 0x1059 }, { 0x17B7, 0x17BD },
+    { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x18A9, 0x18A9 },
+    { 0x20D0, 0x20E3 }, { 0x302A, 0x302F }, { 0x3099, 0x309A },
+    { 0xFB1E, 0xFB1E }, { 0xFE20, 0xFE23 }
+  };
+  int min = 0;
+  int max = sizeof(combining) / sizeof(struct interval) - 1;
+  int mid;
+
+  /* test for 8-bit control characters */
+  if (ucs == 0)
+    return 0;
+  if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) {
+    return -1;
+  }
+
+  /* first quick check for Latin-1 etc. characters */
+  if (ucs < combining[0].first)
+    return 1;
+
+  /* binary search in table of non-spacing characters */
+  while (max >= min) {
+    mid = (min + max) / 2;
+    if (combining[mid].last < ucs)
+      min = mid + 1;
+    else if (combining[mid].first > ucs)
+      max = mid - 1;
+    else if (combining[mid].first <= ucs && combining[mid].last >= ucs)
+      return 0;
+  }
+
+  /* if we arrive here, ucs is not a combining or C0/C1 control character */
+
+  /* fast test for majority of non-wide scripts */
+  if (ucs < 0x1100)
+    return 1;
+
+  return 1 +
+    ((ucs >= 0x1100 && ucs <= 0x115f) || /* Hangul Jamo */
+     (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a &&
+      ucs != 0x303f) ||                  /* CJK ... Yi */
+     (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
+     (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
+     (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
+     (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */
+     (ucs >= 0xffe0 && ucs <= 0xffe6));
+}
+
+
+int wcswidth(const wchar_t *pwcs, size_t n)
+{
+  int w, width = 0;
+
+  for (;*pwcs && n-- > 0; pwcs++)
+    if ((w = my_wcwidth(*pwcs)) < 0)
+      return -1;
+    else
+      width += w;
+
+  return width;
+}
Index: wcwidth.h
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-141/wcwidth.h Sun Aug 13 17:44:08 2000
@@ -0,0 +1,9 @@
+#ifndef        included_wcwidth_h
+#define        included_wcwidth_h 1
+
+#include <wchar.h>
+
+extern int my_wcwidth(wchar_t ucs);
+extern int wcswidth(const wchar_t *pwcs, size_t n);
+
+#endif /* included_wcwidth_h */
Index: xterm.h
--- xterm-140+/xterm.h  Sun Jul 23 14:11:35 2000
+++ xterm-141/xterm.h   Mon Aug 14 21:27:00 2000
@@ -182,6 +182,12 @@
 #undef HAVE_WAITPID
 #endif
 
+#if OPT_WIDE_CHARS
+#define HIDDEN_HI 0xff
+#define HIDDEN_LO 0xff
+#define HIDDEN_CHAR 0xffff
+#endif
+
 /***====================================================================***/
 
 #include <proto.h>
@@ -271,6 +277,7 @@
 #define XtNeightBitInput       "eightBitInput"
 #define XtNeightBitOutput      "eightBitOutput"
 #define XtNfontDoublesize      "fontDoublesize"
+#define XtNfontStyle           "fontStyle"
 #define XtNhighlightColor      "highlightColor"
 #define XtNhighlightSelection  "highlightSelection"
 #define XtNhpLowerleftBugCompat        "hpLowerleftBugCompat"
@@ -321,6 +328,7 @@
 #define XtNutf8                        "utf8"
 #define XtNvisualBell          "visualBell"
 #define XtNwideChars           "wideChars"
+#define XtNwideFont            "wideFont"
 #define XtNxmcAttributes       "xmcAttributes"
 #define XtNxmcGlitch           "xmcGlitch"
 #define XtNxmcInline           "xmcInline"
@@ -357,6 +365,7 @@
 #define XtCEightBitInput       "EightBitInput"
 #define XtCEightBitOutput      "EightBitOutput"
 #define XtCFontDoublesize      "FontDoublesize"
+#define XtCFontStyle           "FontStyle"
 #define XtCHighlightSelection  "HighlightSelection"
 #define XtCHpLowerleftBugCompat        "HpLowerleftBugCompat"
 #define XtCJumpScroll          "JumpScroll"
@@ -399,6 +408,7 @@
 #define XtCUtf8                        "Utf8"
 #define XtCVisualBell          "VisualBell"
 #define XtCWideChars           "WideChars"
+#define XtCWideFont            "WideFont"
 #define XtCXmcAttributes       "XmcAttributes"
 #define XtCXmcGlitch           "XmcGlitch"
 #define XtCXmcInline           "XmcInline"
@@ -468,6 +478,10 @@
 extern void InitLocatorFilter (XtermWidget w);
 #endif /* OPT_DEC_LOCATOR */
 
+#if OPT_WIDE_CHARS
+extern int iswide(int i);
+#endif
+
 /* charproc.c */
 extern int VTInit (void);
 extern int v_write (int f, Char *d, int len);
@@ -532,7 +546,7 @@
 #endif
 
 #if OPT_TCAP_QUERY
-extern int xtermcapKeycode(char **params);
+extern int xtermcapKeycode(char **params, unsigned *state);
 #endif
 
 #if OPT_WIDE_CHARS
@@ -653,7 +667,7 @@
 extern void ScrnDeleteLine (TScreen *screen, ScrnBuf sb, int n, int last, int size, int where);
 extern void ScrnInsertChar (TScreen *screen, int n);
 extern void ScrnInsertLine (TScreen *screen, ScrnBuf sb, int last, int where, int n, int size);
-extern void ScrnRefresh (TScreen *screen, int toprow, int leftcol, int nrows, int ncols, int force);
+extern void ScrnRefresh (TScreen *screen, int toprow, int leftcol, int nrows, int ncols, Bool force);
 
 #define ScrnClrWrapped(screen, row) \
        SCRN_BUF_FLAGS(screen, row + screen->topline) = \
@@ -783,6 +797,9 @@
 
 #if OPT_WIDE_CHARS
 extern unsigned getXtermCell (TScreen *screen, int row, int col);
+extern unsigned getXtermCellComb1 (TScreen *screen, int row, int col);
+extern unsigned getXtermCellComb2 (TScreen *screen, int row, int col);
+extern void addXtermCombining (TScreen *screen, int row, int col, int ch);
 extern void putXtermCell (TScreen *screen, int row, int col, int ch);
 #else
 #define getXtermCell(screen,row,col) SCRN_BUF_CHARS(screen, row)[col]
@@ -793,6 +810,12 @@
 extern void Mark_XMC (TScreen *screen, int param);
 extern void Jump_XMC (TScreen *screen);
 extern void Resolve_XMC (TScreen *screen);
+#endif
+
+#if OPT_WIDE_CHARS
+int visual_width(PAIRED_CHARS(Char *str, Char *str2), Cardinal len);
+#else
+#define visual_width(a, b) (b)
 #endif
 
 #ifdef __cplusplus
Index: xterm.log.html
--- xterm-140+/xterm.log.html   Sun Jul 23 22:03:00 2000
+++ xterm-141/xterm.log.html    Mon Aug 14 21:36:11 2000
@@ -42,6 +42,7 @@
 xc/programs/Xserver/hw/xfree86).
 
 <UL>
+<LI><A HREF="#xterm_141">Patch #141 - 2000/7/14 - XFree86 4.0.1b</A>
 <LI><A HREF="#xterm_140">Patch #140 - 2000/7/23 - XFree86 4.0.1</A>
 <LI><A HREF="#xterm_139">Patch #139 - 2000/6/17 - XFree86 4.0d</A>
 <LI><A HREF="#xterm_138">Patch #138 - 2000/6/15 - XFree86 4.0c</A>
@@ -184,6 +185,23 @@
 <LI><A HREF="#xterm_02">Patch #2 - 1996/1/7</A>
 <LI><A HREF="#xterm_01">Patch #1 - 1996/1/6</A>
 </UL>
+
+<H1><A NAME="xterm_141">Patch #141 - 2000/8/14 - XFree86 4.0.1b</A></H1>
+<ul>
+       <li>Most of this patch is an integration of Robert Brady's patch #11
+         for doublewidth and combining characters, from
+         http://www.ecs.soton.ac.uk/~rwb197/xterm/.  In this context,
+         doublewidth refers to 16-bit character sets which may have glyphs
+         occupying two cells.
+
+       <li>add command-line option <code>-class</code>, which allows one
+         to override xterm's resource class.  Also add resource file
+         <code>UXTerm.ad</code>, which simplifies using xterm for both
+         8-bit character sets and UTF-8.
+
+       <li>fixes/improvements to OPT_TCAP_QUERY logic (patches by Bram
+         Moolenaar, Steve Wall).
+</ul>
 
 <H1><A NAME="xterm_140">Patch #140 - 2000/7/23 - XFree86 4.0.1</A></H1>
 <ul>
Index: xterm.man
--- xterm-140+/xterm.man        Thu Jul 20 19:18:30 2000
+++ xterm-141/xterm.man Mon Aug 14 20:08:17 2000
@@ -279,6 +279,11 @@
 This sets classes indicated by the given ranges for using in selecting by
 words.  See the section specifying character classes.
 .TP 8
+.BI \-class " string"
+This option allows you to override \fIxterm\fP's resource class.
+Normally it is ``XTerm'', but
+can be set to another class such as ``UXTerm'' to override selected resources.
+.TP 8
 .B "\-cm"
 This option disables recognition of ANSI color-change escape sequences.
 .TP 8
@@ -339,6 +344,12 @@
 normal font and the bold font will be produced by overstriking this font.
 The default is to do overstriking of the normal font.
 .TP 8
+.B \-fw \fIfont\fP
+This option specifies the font to be used for displaying wide text.  By default,
+it will attempt to use a font twice as wide as the font that will be used to
+draw normal text.  If no doublewidth font is found, it will improvise, by stretching 
+the normal font.
+.TP 8
 .B \-fi
 This option sets the font for active icons if that feature was compiled
 into xterm.
@@ -1951,11 +1962,12 @@
 series of comma-separated
 of \fIrange\fP:\fIvalue\fP pairs.  The
 \fIrange\fP is either a single number or \fIlow\fP-\fIhigh\fP in the range of 0
-to 255, corresponding to the 8-bit code for the character or characters to be
+to 65535, corresponding to the code for the character or characters to be
 set.  The \fIvalue\fP is arbitrary, although the default table uses the
-character number of the first character occurring in the set.
+character number of the first character occurring in the set. When not in 
+UTF-8 mode, only the first 256 bytes of this table will be used.
 .PP
-The default table is
+The default table starts as follows -
 .sp
 .in +8
 .ft C                  \" Courier
@@ -2341,8 +2353,8 @@
 used when
 \fIxterm\fP was started), \fI1\fP through \fI6\fP indicate the fonts
 specified by the \fIfont1\fP through \fIfont6\fP resources, \fIe\fP or \fIE\fP
-indicate the normal and bold fonts that have been set through escape codes
-(or specified as the second and third action arguments, respectively), and
+indicate the normal, bold and wide fonts that have been set through escape codes
+(or specified as the second, third and fourth action arguments, respectively), and
 \fIs\fP or \fIS\fP indicate the font selection (as made by programs such as
 \fIxfontsel(1)\fP) indicated by the second action argument.
 .TP 8