# ------------------------------------------------------------------------------
 #  button.c           |  118 +++++++++++++++++++++++++++------------------------
 #  charproc.c         |   10 +++-
 #  fontutils.c        |    3 -
 #  input.c            |    4 +
 #  keysym2ucs.c       |   16 ++++++
 #  ptyx.h             |    1 
 #  unicode/convmap.pl |   15 +++++-
 #  version.h          |    4 -
 #  xterm.log.html     |   22 +++++++++
 #  xterm.man          |    7 +++
 #  10 files changed, 135 insertions, 65 deletions
 # ------------------------------------------------------------------------------
 Index: button.c
--- xterm-107+/button.c Sun Jun 13 17:55:49 1999
 +++ xterm-108/button.c  Sat Jun 19 21:50:56 1999
 @@ -360,12 +360,12 @@
  }
 
 #if OPT_WIDE_CHARS
-static Atom XA_UTF_8(Display *dpy)
+static Atom XA_UTF8_STRING(Display *dpy)
  {
     static AtomPtr p = NULL;
 
     if(p == NULL)
-       p = XmuMakeAtom("UTF-8");
 +       p = XmuMakeAtom("UTF8_STRING");
      return XmuInternAtom(dpy, p);
 }
 #endif
@@ -391,25 +391,28 @@
     Char *q;
 
     if (used == 0) {
-       buffer = XtMalloc(used = len);
 +       buffer = (Char*)XtMalloc(used = len);
      } else if (len > (int) used) {
-       buffer = XtRealloc(buffer, used = len);
 +       buffer = (Char*)XtRealloc((char*)buffer, used = len);
      }
     q = buffer;
 
+     /* We're assuming that the xterm widget never contains Unicode
 +       control characters. */
 +
     while (p < s + len) {
        if ((*p & 0x80) == 0) {
            *q++ = *p++;
-       } else if ((*p & 0x3C) == 0 && p < s + len - 1) {
 +       } else if ((*p & 0x7C) == 0x40 && p < s + len - 1) {
             *q++ = (*p & 0x03) << 6 | (p[1] & 0x3F);
            p += 2;
-       } else if ((*p & 0x20) == 0) {
 +       } else if ((*p & 0x60) == 0x40) {
             *q++ = '#';
            p += 2;
-       } else if ((*p & 0x10) == 0) {
 +       } else if ((*p & 0x50) == 0x40) {
             *q++ = '#';
            p += 3;
-       } else {                /* this cannot currently happen */
 +       } else {                /* this cannot happen */
             *q++ = '#';
            p++;
        }
@@ -452,24 +455,24 @@
        if ((*p & 0x80) == 0) {
            codepoint = *p & 0x7F;
            size = 1;
-       } else if ((*p & 0x20) == 0x20 && p < s + len - 1) {
 +       } else if ((*p & 0x60) == 0x40 && p < s + len - 1) {
             codepoint = (p[0] & 0x1F) << 6 | (p[1] & 0x3F);
            size = 2;
-       } else if ((*p & 0x10) == 0 && p < s + len - 2) {
 +       } else if ((*p & 0x70) == 0x60 && p < s + len - 2) {
             codepoint = (s[0] & 0x0F) << 12
-                     | (s[1] & 0x3F) << 6
 +                     | (s[1] & 0x3F) << 6
                       | (s[2] & 0x3F);
            size = 3;
-       } else if ((*p & 0x08) == 0 && p < s + len - 3) {
 -           p += 4;                     /* eliminate surrogates */
 +       } else if ((*p & 0x78) == 0x70 && p < s + len - 3) {
 +           p += 4;             /* eliminate surrogates */
             continue;
-       } else if ((*p & 0x04) == 0 && p < s + len - 3) {
 +       } else if ((*p & 0x7C) == 0x78 && p < s + len - 4) {
             p += 5;
            continue;
-       } else if ((*p & 0x02) == 0 && p < s + len - 3) {
 +       } else if ((*p & 0x7E) == 0x7C && p < s + len - 5) {
             p += 6;
            continue;
-       } else {                    /* wrong UTF-8? */
 +       } else {                /* wrong UTF-8?  Silently discard. */
             p++;
            continue;
        }
@@ -486,16 +489,12 @@
                *q++ = 0x0A;
        } else if (codepoint >= 0x202A && codepoint <= 0x202E) {
            /* ignore Unicode control characters; surrogates have already
-           been eliminated */
 +              been eliminated */
             p += size;
        } else {
            /* just copy the UTF-8 */
-           if (size--)
 -               *q++ = *p++;
 -           if (size--)
 -               *q++ = *p++;
 -           if (size--)
 -               *q++ = *p++;
 +         while (size--)
 +           *q++ = *p++;
         }
     }
     return q - t;
@@ -547,16 +546,16 @@
     } else {
        struct _SelectionList* list;
 #if OPT_WIDE_CHARS
-        if (!screen->wide_chars || utf8_failed) {
 +       if (!screen->wide_chars || utf8_failed) {
             params++;
            num_params--;
            utf8_failed = False;
-        } else {
 +       } else {
             utf8_failed = True;
-        }
+       }
  #else
-        params++;
 -        num_params--;
 +       params++;
+       num_params--;
  #endif
 
        if (num_params) {
@@ -571,7 +570,7 @@
            XtGetSelectionValue(w, selection,
 #if OPT_WIDE_CHARS
                                (screen->wide_chars && utf8_failed) ?
-                               XA_UTF_8(XtDisplay(w)) :
 +                               XA_UTF8_STRING(XtDisplay(w)) :
  #endif
                                XA_STRING,
                                SelectionReceived,
@@ -579,7 +578,7 @@
     }
 }
 
-#if OPT_TRACE
+#if OPT_TRACE && OPT_WIDE_CHARS
  static void GettingSelection(char *tag, char *line, int len)
 {
     char *cp;
@@ -631,12 +630,12 @@
     len = *length;
 
     if_OPT_WIDE_CHARS(screen,{
-       if (*type == XA_UTF_8(XtDisplay(w))) {
 +       if (*type == XA_UTF8_STRING(XtDisplay(w))) {
             buf = (Char*)XtMalloc(*length);
-           GettingSelection("UTF-8", line, *length);
 +           GettingSelection("UTF8_STRING", line, *length);
             len = filterUTF8(buf, line, *length);
        } else {
-           buf = XtMalloc(2* *length);
 +           buf = (Char *)XtMalloc(2* *length);
             GettingSelection("Latin-1", line, *length);
            len = Latin1toUTF8(buf, line, *length);
        }
@@ -660,7 +659,7 @@
        v_write(pty, lag, end - lag);
 
     if_OPT_WIDE_CHARS(screen,{
-       XtFree(buf);
 +       XtFree((char*)buf);
      })
     XtFree((char *)client_data);
     XtFree((char *)value);
@@ -1103,16 +1102,20 @@
        register int i;
        register Char *ch;
 
-       for ( i = screen->max_col,
 -               ch = SCRN_BUF_ATTRS(screen, (row + screen->topline)) + i ;
 -             i >= 0 && !(*ch & CHARDRAWN) ;
 -             ch--, i--)
 -           ;
 +       if ((row += screen->topline) >= 0) {
 +               for ( i = screen->max_col,
 +                       ch = SCRN_BUF_ATTRS(screen, (row)) + i ;
 +                     i >= 0 && !(*ch & CHARDRAWN) ;
 +                     ch--, i--)
 +                   ;
  #if OPT_DEC_CHRSET
-       if (CSET_DOUBLE(SCRN_BUF_CSETS(screen, row + screen->topline)[0])) {
 -               i *= 2;
 -       }
+               if (CSET_DOUBLE(SCRN_BUF_CSETS(screen, row)[0])) {
 +                       i *= 2;
 +               }
  #endif
+       } else {
 +               i = 0;
 +       }
        return(i);
 }
 
@@ -1527,7 +1530,7 @@
     screen = &((XtermWidget)w)->screen;
 
     if (screen->selection_data == NULL)
-       return False;           /* can this happen? */
 +       return False;           /* can this happen? */
  
     if (*target == XA_TARGETS(d)) {
        Atom* targetP;
@@ -1541,11 +1544,11 @@
        *value = (XtPointer) targetP;
        *targetP++ = XA_STRING;
        *targetP++ = XA_TEXT(d);
-        *targetP = XA_COMPOUND_TEXT(d);
 -        if_OPT_WIDE_CHARS(screen, {
 -          *targetP = XA_UTF_8(d);
 -        })
-        targetP++;
 +       *targetP = XA_COMPOUND_TEXT(d);
 +       if_OPT_WIDE_CHARS(screen, {
 +         *targetP = XA_UTF8_STRING(d);
 +       })
+       targetP++;
         *targetP++ = XA_LENGTH(d);
        *targetP++ = XA_LIST_LENGTH(d);
        memcpy ( (char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
@@ -1557,7 +1560,8 @@
 
     if_OPT_WIDE_CHARS(screen,{
        if (*target == XA_STRING) {
-           *value = UTF8toLatin1(screen->selection_data, screen->selection_length, length);
 +           *value = UTF8toLatin1((Char*)screen->selection_data,
 +                                 screen->selection_length, length);
             *type = XA_STRING;
            *format = 8;
            return True;
@@ -1574,20 +1578,21 @@
            }
            if (p < screen->selection_data + screen->selection_length) {
                /* non ISO 8859-1 character found -- return UTF-8 */
-               *type = XA_UTF_8(d);
 +               *type = XA_UTF8_STRING(d);
                 *value = screen->selection_data;
                *length = screen->selection_length;
                *format = 8;
            } else {
                /* none found -- return STRING */
-               *value = UTF8toLatin1(screen->selection_data, screen->selection_length, length);
 +               *value = UTF8toLatin1((Char*)screen->selection_data,
 +                                     screen->selection_length, length);
                 *type = XA_STRING;
                *format = 8;
            }
            return True;
        }
-       if (*target == XA_UTF_8(d)) {
 -           *type = XA_UTF_8(d);
 +       if (*target == XA_UTF8_STRING(d)) {
 +           *type = XA_UTF8_STRING(d);
             *value = screen->selection_data;
            *length = screen->selection_length;
            *format = 8;
@@ -1608,7 +1613,7 @@
 #if OPT_WIDE_CHARS
     && !screen->wide_chars
 #endif
-        ) {
 +       ) {
        XTextProperty textprop;
 
        *value = (XtPointer) screen->selection_data;
@@ -1638,7 +1643,7 @@
     }
 
     if (*target == XA_LENGTH(d)) {
-        /* This value is wrong if we have UTF-8 text */
 +       /* This value is wrong if we have UTF-8 text */
         *value = XtMalloc(4);
        if (sizeof(long) == 4)
            *(long*)*value = screen->selection_length;
@@ -1756,6 +1761,9 @@
                        "%s: selection too big (%d bytes), not storing in CUT_BUFFER%d\n",
                        xterm_name, termw->screen.selection_length, cutbuffer);
            else
+             /* Cutbuffers are untyped, so in the wide chars case, we
 +                just store the raw UTF-8 data.  It is unlikely it
 +                will be useful to anyone. */
                 XStoreBuffer( XtDisplay((Widget)termw),
                              termw->screen.selection_data,
                              termw->screen.selection_length, cutbuffer );
Index: charproc.c
--- xterm-107+/charproc.c       Sun Jun 13 17:55:49 1999
 +++ xterm-108/charproc.c        Sat Jun 19 21:21:23 1999
 @@ -169,6 +169,7 @@
  #define XtNbellSuppressTime    "bellSuppressTime"
 #define XtNboldColors          "boldColors"
 #define XtNboldFont            "boldFont"
+#define XtNboldMode            "boldMode"
  #define XtNc132                        "c132"
 #define XtNcharClass           "charClass"
 #define XtNcolor0              "color0"
@@ -197,9 +198,9 @@
 #define XtNcolorULMode         "colorULMode"
 #define XtNcurses              "curses"
 #define XtNcursorBlink         "cursorBlink"
-#define XtNcursorOnTime                "cursorOnTime"
 -#define XtNcursorOffTime       "cursorOffTime"
  #define XtNcursorColor         "cursorColor"
+#define XtNcursorOffTime       "cursorOffTime"
 +#define XtNcursorOnTime                "cursorOnTime"
  #define XtNcutNewline          "cutNewline"
 #define XtNcutToBeginningOfLine        "cutToBeginningOfLine"
 #define XtNdecTerminalID       "decTerminalID"
@@ -269,6 +270,7 @@
 #define XtCBackarrowKey                "BackarrowKey"
 #define XtCBellSuppressTime    "BellSuppressTime"
 #define XtCBoldFont            "BoldFont"
+#define XtCBoldMode            "BoldMode"
  #define XtCC132                        "C132"
 #define XtCCharClass           "CharClass"
 #define XtCColorMode           "ColorMode"
@@ -867,6 +869,9 @@
        XtOffsetOf(XtermWidgetRec, screen.highlightcolor),
        XtRString, "XtDefaultForeground"},
 #endif /* OPT_HIGHLIGHT_COLOR */
+{XtNboldMode, XtCBoldMode, XtRBoolean, sizeof(Boolean),
 +       XtOffsetOf(XtermWidgetRec, screen.bold_mode),
 +       XtRBoolean, (XtPointer) &defaultTRUE},
  {XtNunderLine, XtCUnderLine, XtRBoolean, sizeof(Boolean),
        XtOffsetOf(XtermWidgetRec, screen.underline),
        XtRBoolean, (XtPointer) &defaultTRUE},
@@ -4114,6 +4119,7 @@
       wnew->num_ptrs = (OFF_WIDEC+1);
 #endif
 
+   wnew->screen.bold_mode = request->screen.bold_mode;
     wnew->screen.underline = request->screen.underline;
 
    wnew->cur_foreground = 0;
Index: fontutils.c
--- xterm-107+/fontutils.c      Sun May 16 15:55:44 1999
 +++ xterm-108/fontutils.c       Sat Jun 19 21:21:35 1999
 @@ -570,7 +570,8 @@
         }
 #endif
 
-       screen->enbolden = (nfs == bfs) || same_font_name(normal, bfontname);
 +       screen->enbolden = screen->bold_mode
 +               && ((nfs == bfs) || same_font_name(normal, bfontname));
         TRACE(("Will %suse 1-pixel offset/overstrike to simulate bold\n", screen->enbolden ? "" : "not "))
 
        set_menu_font (False);
Index: input.c
--- xterm-107+/input.c  Sun Jun 13 17:55:49 1999
 +++ xterm-108/input.c   Sat Jun 19 22:05:05 1999
 @@ -322,7 +322,9 @@
                 if (nbytes == 1) {
                /* Take ISO 8859-1 character delivered by XLookupString() */
                        ucs = (unsigned char) strbuf[0];
-               } else if (!nbytes && keysym >= 0x100 && keysym <= 0xf000)
 +               } else if (!nbytes && 
 +                          ((keysym >= 0x100 && keysym <= 0xf000) ||
 +                           (keysym & 0xff000000) == 0x01000000))
                         ucs = keysym2ucs(keysym);
                else
                        ucs = -2;
Index: keysym2ucs.c
--- xterm-107+/keysym2ucs.c     Sun Jun 13 17:55:49 1999
 +++ xterm-108/keysym2ucs.c      Sat Jun 19 22:05:05 1999
 @@ -12,6 +12,14 @@
   * by Xlib via XmbLookupString() and should ideally not have to be
  * done in X applications. But we are not there yet.
  *
+ * We allow to represent any UCS character in the range U+00000000 to
 + * U+00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
 + * This admittedly does not cover the entire 31-bit space of UCS, but
 + * it does cover all of the characters up to U+10FFFF, which can be
 + * represented by UTF-16, and more, and it is very unlikely that higher
 + * UCS codes will ever be assigned by ISO. So to get Unicode character
 + * U+ABCD you can directly use keysym 0x1000abcd.
 + *
  * NOTE: The comments in the table below contain the actual character
  * encoded in UTF-8, so for viewing and editing best use an editor in
  * UTF-8 mode.
@@ -586,7 +594,7 @@
   { 0x0bc4, 0x230a }, /*                   downstile âŒŠ LEFT FLOOR */
   { 0x0bc6, 0x005f }, /*                    underbar _ LOW LINE */
   { 0x0bca, 0x2218 }, /*                         jot âˆ˜ RING OPERATOR */
-  { 0x0bcc, 0x2395 }, /*                        quad âŽ• ??? */
 +  { 0x0bcc, 0x2395 }, /*                        quad âŽ• APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */
    { 0x0bce, 0x22a5 }, /*                      uptack âŠ¥ UP TACK */
   { 0x0bcf, 0x25cb }, /*                      circle â—‹ WHITE CIRCLE */
   { 0x0bd3, 0x2308 }, /*                     upstile âŒˆ LEFT CEILING */
@@ -827,8 +835,12 @@
         (keysym >= 0x00a0 && keysym <= 0x00ff))
         return keysym;
 
+    /* also check for directly encoded 24-bit UCS characters */
 +    if ((keysym & 0xff000000) == 0x01000000)
 +       return keysym & 0x00ffffff;
 +
     /* binary search in table */
-    while (max > min) {
 +    while (max >= min) {
         mid = (min + max) / 2;
        if (keysymtab[mid].keysym < keysym)
            min = mid + 1;
Index: ptyx.h
--- xterm-107+/ptyx.h   Sun Jun 13 17:55:49 1999
 +++ xterm-108/ptyx.h    Sat Jun 19 21:16:17 1999
 @@ -866,6 +866,7 @@
         Boolean         jumpscroll;     /* whether we should jumpscroll */
        Boolean         always_highlight; /* whether to highlight cursor */
        Boolean         underline;      /* whether to underline text    */
+       Boolean         bold_mode;      /* whether to use bold font     */
  
 #if OPT_MAXIMIZE
        Boolean         restore_data;
Index: unicode/convmap.pl
--- xterm-107+/unicode/convmap.pl       Sun Jun 13 17:55:49 1999
 +++ xterm-108/unicode/convmap.pl        Sat Jun 19 22:00:23 1999
 @@ -87,7 +87,6 @@
  
 print <<EOT;
 /* \$XFree86\$
-/*
  * This module converts keysym values into the corresponding ISO 10646-1
  * (UCS, Unicode) values.
  *
@@ -100,6 +99,14 @@
  * by Xlib via XmbLookupString() and should ideally not have to be
  * done in X applications. But we are not there yet.
  *
+ * We allow to represent any UCS character in the range U+00000000 to
 + * U+00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
 + * This admittedly does not cover the entire 31-bit space of UCS, but
 + * it does cover all of the characters up to U+10FFFF, which can be
 + * represented by UTF-16, and more, and it is very unlikely that higher
 + * UCS codes will ever be assigned by ISO. So to get Unicode character
 + * U+ABCD you can directly use keysym 0x1000abcd.
 + *
  * NOTE: The comments in the table below contain the actual character
  * encoded in UTF-8, so for viewing and editing best use an editor in
  * UTF-8 mode.
@@ -147,8 +154,12 @@
         (keysym >= 0x00a0 && keysym <= 0x00ff))
         return keysym;
 
+    /* also check for directly encoded 24-bit UCS characters */
 +    if ((keysym & 0xff000000) == 0x01000000)
 +       return keysym & 0x00ffffff;
 +
     /* binary search in table */
-    while (max > min) {
 +    while (max >= min) {
         mid = (min + max) / 2;
        if (keysymtab[mid].keysym < keysym)
            min = mid + 1;
Index: version.h
--- xterm-107+/version.h        Sun Jun 13 17:55:49 1999
 +++ xterm-108/version.h Sat Jun 19 20:36:14 1999
 @@ -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   107
-#define XFREE86_VERSION "XFree86 3.9Pq"
 +#define XTERM_PATCH   108
+#define XFREE86_VERSION "XFree86 3.9Ps"
 Index: xterm.log.html
--- xterm-107+/xterm.log.html   Sun Jun 13 17:55:49 1999
 +++ xterm-108/xterm.log.html    Sat Jun 19 22:46:20 1999
 @@ -41,6 +41,7 @@
  xc/programs/Xserver/hw/xfree86).
 
 <UL>
+<LI><A HREF="#xterm_108">Patch #108 - 1999/6/19 - XFree86 3.9Ps</A>
  <LI><A HREF="#xterm_107">Patch #107 - 1999/6/12 - XFree86 3.9Pq</A>
 <LI><A HREF="#xterm_106">Patch #106 - 1999/6/9 - XFree86 3.9Pq</A>
 <LI><A HREF="#xterm_105">Patch #105 - 1999/6/5 - XFree86 3.9Pp</A>
@@ -150,6 +151,27 @@
 <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_108">Patch #108 - 1999/6/19 - XFree86 3.9Ps</A></H1>
 +<ul>
+       <li>add a range-check to LastTextCol(), to guard against indexing
 +         before the beginning of the scrollback buffer.  This appears to
 +         happen with certain fonts under X11R5 (reported by Stephane Chazelas
 +         <Stephane_Chazelas@Raytheon.com>).
 +
+       <li>implement resource <em>boldMode</em>, to allow disabling the
 +         simulation of bold fonts when the bold and normal fonts are not
 +         different (requested by Will Day <willday@rom.oit.gatech.edu>).
 +
+       <li>change the atom "UTF-8" to "UTF8_STRING", and fixes a few bugs in
 +         the UTF-8 selection (patch by Juliusz Chroboczek).
 +
+       <li>correct logic of binary-search in keysym2ucs.c (patch by Markus
 +         Kuhn).
 +
+       <li>add special interpretation of keysym codes above 0x1000000 as
 +         the corresponding UCS value plus 0x1000000 (patch by Markus Kuhn).
 +</ul>
 
 <H1><A NAME="xterm_107">Patch #107 - 1999/6/12 - XFree86 3.9Pq</A></H1>
 <ul>
Index: xterm.man
--- xterm-107+/xterm.man        Sun Jun 13 17:55:49 1999
 +++ xterm-108/xterm.man Sat Jun 19 21:27:57 1999
 @@ -882,6 +882,13 @@
  .B "boldFont (\fPclass\fB BoldFont)"
 Specifies the name of the bold font to use instead of overstriking.
 .TP 8
+.B "boldMode (\fPclass\fB BoldMode)"
+This specifies whether or not text with the bold attribute should be
 +overstruck to simulate bold fonts if the resolved bold font is the
 +same as the normal font.
+It may be desirable to disable bold fonts when color is being
 +used for the bold attribute.
+.TP 8
  .B "c132 (\fPclass\fB C132)"
 Specifies whether or not the VT102 DECCOLM escape sequence should be honored.
 The default is ``false.''