# ------------------------------------------------------------------------------
# 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