xterm-97.patch.txt

# ------------------------------------------------------------------------------
#  Imakefile          |    9 -
#  Makefile.in        |    6 
#  Tekproc.c          |  254 +++++++++++++++------------------
#  charproc.c         |  391 +++++++++++++++++++++++++++++----------------------
#  charsets.c         |   10 -
#  configure          |  133 +++++++++++------
#  configure.in       |    3 
#  data.c             |   10 -
#  data.h             |   12 -
#  main.c             |   28 ++-
#  misc.c             |   58 ++++---
#  os2main.c          |    9 -
#  ptyx.h             |   45 ++++-
#  screen.c           |   24 ++-
#  termcap            |    4 
#  terminfo           |    4 
#  testxmc.c          |   10 -
#  trace.c            |   66 ++++++++
#  trace.h            |    5 
#  util.c             |   12 -
#  version.h          |    4 
#  xterm-97/ptydata.c |  187 ++++++++++++++++++++++++
#  xterm.h            |   16 +-
#  xterm.log.html     |   86 +++++++++--
#  xterm.man          |   20 ++
#  25 files changed, 948 insertions, 458 deletions
# ------------------------------------------------------------------------------
Index: Imakefile
--- xterm-96+/Imakefile Sun Apr 25 17:28:21 1999
+++ xterm-97/Imakefile  Sun Apr 25 22:06:47 1999
@@ -13,6 +13,9 @@
 /* Uncomment SCROLLBAR_RIGHT if you want the scroll bar to be on the right */
 SCROLLBAR_RIGHT = -DSCROLLBAR_RIGHT
 
+/* Uncomment UTF8_OPTION to compile-in support for UTF-8 */
+UTF8_OPTION    = -DOPT_WIDE_CHARS
+
 /*
  * Fixes to allow compile with X11R5
  */
@@ -77,7 +80,7 @@
                  -DOSMINORVERSION=$(OSMINORVERSION)
    MISC_DEFINES = /* -DALLOWLOGGING -DALLOWLOGFILEEXEC */ 
     XKB_DEFINES = XkbClientDefines
-        DEFINES = -I. $(XKB_DEFINES) $(TERMCAPDEFINES) $(FEATURE_DEFINES) $(SCROLLBAR_RIGHT)
+        DEFINES = -I. $(XKB_DEFINES) $(TERMCAPDEFINES) $(FEATURE_DEFINES) $(SCROLLBAR_RIGHT) $(UTF8_OPTION)
 
 #ifdef OS2Architecture
           MAINSRC = os2main.c
@@ -88,12 +91,12 @@
 #endif
           SRCS1 = button.c charproc.c charsets.c cursor.c \
                  data.c doublechr.c fontutils.c input.c \
-                 $(MAINSRC) menu.c misc.c print.c \
+                 $(MAINSRC) menu.c misc.c print.c ptydata.c \
                  screen.c scrollbar.c tabs.c util.c \
                  TekPrsTbl.c Tekproc.c VTPrsTbl.c $(EXTRASRC)
           OBJS1 = button.o charproc.o charsets.o cursor.o \
                  data.o doublechr.o fontutils.o input.o \
-                 $(MAINOBJ) menu.o misc.o print.o \
+                 $(MAINOBJ) menu.o misc.o print.o ptydata.o \
                  screen.o scrollbar.o tabs.o util.o \
                  TekPrsTbl.o Tekproc.o VTPrsTbl.o $(EXTRAOBJ)
           SRCS2 = resize.c
Index: Makefile.in
--- xterm-96+/Makefile.in       Sun Apr 25 17:28:21 1999
+++ xterm-97/Makefile.in        Sun Apr 25 21:22:24 1999
@@ -50,12 +50,12 @@
 
           SRCS1 = button.c charproc.c charsets.c cursor.c \
                  data.c doublechr.c fontutils.c input.c \
-                 $(MAINSRC) menu.c misc.c print.c \
+                 $(MAINSRC) menu.c misc.c print.c ptydata.c \
                  screen.c scrollbar.c tabs.c util.c \
                  VTPrsTbl.c $(EXTRASRC)
           OBJS1 = button.o charproc.o charsets.o cursor.o \
                  data.o doublechr.o fontutils.o input.o \
-                 main.o menu.o misc.o print.o \
+                 main.o menu.o misc.o print.o ptydata.o \
                  screen.o scrollbar.o tabs.o util.o \
                  VTPrsTbl.o $(EXTRAOBJ)
           SRCS2 = resize.c
@@ -115,7 +115,7 @@
        -$(RM) $(appsdir)/XTerm-color
 
 mostlyclean:
-       -$(RM) *.[ois] XtermLog.* .pure core *~ *.BAK *.out
+       -$(RM) *.[ois] XtermLog.* .pure core *~ *.bak *.BAK *.out
 
 clean: mostlyclean
        -$(RM) $(PROGRAMS)
Index: Tekproc.c
--- xterm-96+/Tekproc.c Mon Mar 29 13:36:18 1999
+++ xterm-97/Tekproc.c  Sun Apr 25 08:08:17 1999
@@ -7,7 +7,7 @@
 
 
 /*
- 
+
 Copyright (c) 1988  X Consortium
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -68,7 +68,6 @@
 
 #include <stdio.h>
 #include <ctype.h>
-#include <setjmp.h>
 #include <signal.h>
 
 #include <Tekparse.h>
@@ -90,21 +89,6 @@
 #define write(f,b,s) nbio_write(f,b,s)
 #endif
 
-/*
- * Check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
- * systems are broken and return EWOULDBLOCK when they should return EAGAIN.
- * Note that this macro may evaluate its argument more than once.
- */
-#if defined(EAGAIN) && defined(EWOULDBLOCK)
-#define E_TEST(err) ((err) == EAGAIN || (err) == EWOULDBLOCK)
-#else
-#ifdef EAGAIN
-#define E_TEST(err) ((err) == EAGAIN)
-#else
-#define E_TEST(err) ((err) == EWOULDBLOCK)
-#endif
-#endif
-
 extern jmp_buf Tekend;
 
 #define DefaultGCID XGContextFromGC(DefaultGC(screen->display, DefaultScreen(screen->display)))
@@ -136,7 +120,6 @@
 #define        TEKMINWIDTH     600
 #define        TEKTOPPAD       34
 #define        TEKWIDTH        4096
-#define        TEXT_BUF_SIZE   256
 #define        WEST            02
 
 #define        TekMove(x,y)    screen->cur_X = x; screen->cur_Y = y
@@ -190,7 +173,7 @@
                 ~Meta<Btn3Down>: gin-press(r)";
 
 
-static XtActionsRec actionsList[] = { 
+static XtActionsRec actionsList[] = {
     { "string",        HandleStringEvent },
     { "insert",        HandleKeyPressed },     /* alias for insert-seven-bit */
     { "insert-seven-bit",      HandleKeyPressed },
@@ -284,7 +267,7 @@
 
 static WidgetClassRec tekClassRec = {
   {
-/* core_class fields */        
+/* core_class fields */
     /* superclass        */    (WidgetClass) &widgetClassRec,
     /* class_name        */    "Tek4014",
     /* widget_size       */    sizeof(TekWidgetRec),
@@ -292,7 +275,7 @@
     /* class_part_initialize */ NULL,
     /* class_inited       */   FALSE,
     /* initialize        */    TekInitialize,
-    /* initialize_hook    */    NULL,                          
+    /* initialize_hook    */    NULL,
     /* realize           */    TekRealize,
     /* actions           */    actionsList,
     /* num_actions       */    XtNumber(actionsList),
@@ -311,12 +294,12 @@
     /* set_values_almost  */    NULL,
     /* get_values_hook    */    NULL,
     /* accept_focus      */    NULL,
-    /* version            */    XtVersion,
+    /* version           */    XtVersion,
     /* callback_offsets   */    NULL,
-    /* tm_table           */    defaultTranslations,
+    /* tm_table                  */    defaultTranslations,
     /* query_geometry     */    XtInheritQueryGeometry,
     /* display_accelerator*/    XtInheritDisplayAccelerator,
-    /* extension          */    NULL
+    /* extension         */    NULL
   }
 };
 #define tekWidgetClass ((WidgetClass)&tekClassRec)
@@ -329,7 +312,7 @@
 {
     /* this causes the Initialize method to be called */
     tekshellwidget = XtCreatePopupShell ("tektronix", topLevelShellWidgetClass,
-                                        toplevel, ourTopLevelShellArgs, 
+                                        toplevel, ourTopLevelShellArgs,
                                         number_ourTopLevelShellArgs);
 
     /* this causes the Realize method to be called */
@@ -350,15 +333,51 @@
     return (0);
 }
 
+/*
+ * If we haven't allocated the PtyData struct, do so.
+ */
+int
+TekPtyData(void)
+{
+    if (Tbuffer == 0) {
+       if ((Tbuffer = (PtyData *)malloc(sizeof(PtyData))) == NULL
+        || (Tpushb = (Char *)malloc(10)) == NULL
+        || (Tline = (XSegment *)malloc(MAX_VTX * sizeof(XSegment))) == NULL) {
+           fprintf (stderr, "%s: Not enough core for Tek mode\n", xterm_name);
+           if(Tpushb) free((char *)Tpushb);
+           if(Tbuffer) free((char *)Tbuffer);
+           Tfailed = TRUE;
+           return 0;
+       }
+    }
+    return 1;
+}
+
 static void Tekparse(void)
 {
        register TScreen *screen = &term->screen;
        register int c, x, y;
-       char ch;
+       Char ch;
+       int nextstate;
 
        for( ; ; ) {
            c = input();
-           switch(Tparsestate[c]) {
+           /*
+            * The parsing tables all have 256 entries.  If we're supporting
+            * wide characters, we handle them by treating them the same as
+            * printing characters.
+            */
+#if OPT_WIDE_CHARS
+           if (c > 255) {
+               nextstate = (Tparsestate == Talptable)
+                       ? CASE_PRINT
+                       : CASE_IGNORE;
+           } else
+#endif
+             nextstate = Tparsestate[c];
+           TRACE(("parse %d -> %d\n", c, nextstate))
+
+           switch(nextstate) {
                 case CASE_REPORT:
                        /* report address */
                        if(screen->TekGIN) {
@@ -381,7 +400,7 @@
 #ifdef ALLOWLOGGING
                        if(screen->logging) {
                                FlushLog(screen);
-                               screen->logstart = VTbuffer;
+                               screen->logstart = VTbuffer.buf;
                        }
 #endif
                        return;
@@ -397,7 +416,7 @@
                        /* Do Tek GIN mode */
                        screen->TekGIN = &TekRecord->ptr[-1];
                                /* Set cross-hair cursor raster array */
-                       if ((GINcursor = 
+                       if ((GINcursor =
                            make_colored_cursor (XC_tcross, screen->mousecolor,
                                                 screen->mousecolorback)) != 0)
                                XDefineCursor (screen->display, TShellWindow,
@@ -517,9 +536,9 @@
                        Tparsestate = curstate;
                        break;
 
-                case CASE_CHAR_SIZE: 
+                case CASE_CHAR_SIZE:
                        /* character size selector */
-                       TekSetFontSize (c & 03);
+                       TekSetFontSize (c & 03);
                        Tparsestate = curstate;
                        break;
 
@@ -631,13 +650,31 @@
                        /* printable character */
                        ch = c;
                        c = screen->cur.fontsize;
+                       x = (int)(screen->cur_X * TekScale(screen)) + screen->border;
+                       y = (int)((TEKHEIGHT + TEKTOPPAD - screen->cur_Y) * TekScale(screen)) + screen->border;
 
+#if OPT_WIDE_CHARS
+                       if (screen->wide_chars
+                        && (ch > 255)) {
+                               XChar2b sbuf;
+                               sbuf.byte2 = (ch & 0xff);
+                               sbuf.byte1 = ((ch >>8) & 0xff);
+                               XDrawImageString16(
+                                   screen->display,
+                                   TWindow(screen),
+                                   screen->TnormalGC,
+                                   x,
+                                   y,
+                                   &sbuf,
+                                   1);
+                       } else
+#endif
                        XDrawString(
                            screen->display,
-                           TWindow(screen), 
+                           TWindow(screen),
                            screen->TnormalGC,
-                           (int)(screen->cur_X * TekScale(screen)) + screen->border,
-                           (int)((TEKHEIGHT + TEKTOPPAD - screen->cur_Y) * TekScale(screen)) + screen->border,
+                           x,
+                           y,
                            &ch,
                            1);
                        TCursorForward();
@@ -663,7 +700,7 @@
                        break;
                }
        }
-}                      
+}
 
 static int rcnt;
 static char *rptr;
@@ -691,7 +728,7 @@
                longjmp(Tekjump, 1);
        }
 again:
-       if(Tbcnt-- <= 0) {
+       if(Tbuffer->cnt-- <= 0) {
                if(nplot > 0)   /* flush line Tbuffer */
                        TekFlush();
                XFD_COPYSET (&pty_mask, &Tselect_mask);
@@ -700,54 +737,12 @@
                        struct timeval crocktimeout;
                        crocktimeout.tv_sec = 0;
                        crocktimeout.tv_usec = 0;
-                       (void) Select (max_plus1, 
-                                      &Tselect_mask, NULL, NULL, 
+                       (void) Select (max_plus1,
+                                      &Tselect_mask, NULL, NULL,
                                       &crocktimeout);
 #endif
-#ifndef AMOEBA
-                       if(FD_ISSET (screen->respond, &Tselect_mask))
-#else
-                       /* XXX resolve polling since it wastes CPU cycles */
-                       if ((Tbcnt = cb_full(screen->tty_outq)) > 0)
-#endif /* AMOEBA */
-                       {
-#ifdef ALLOWLOGGING
-                               if(screen->logging)
-                                       FlushLog(screen);
-#endif
-#ifndef AMOEBA
-                               Tbcnt = read(screen->respond, (char *)(Tbptr = Tbuffer), BUF_SIZE);
-#else
-                               Tbptr = Tbuffer;
-                               if ((Tbcnt = cb_gets(screen->tty_outq, Tbptr, Tbcnt, BUF_SIZE)) == 0) {
-                                       errno = EIO;
-                                       Tbcnt = -1;
-                               }
-#endif /* AMOEBA */
-                               if(Tbcnt < 0) {
-                                       if(errno == EIO)
-                                               Cleanup (0);
-                                       else if(!E_TEST(errno))
-                                               Panic(
-                                "Tinput:read returned unexpected error (%d)\n",
-                                                errno);
-                               } else if(Tbcnt == 0)
-#ifdef MINIX
-                                       Cleanup (0);
-#else
-                                       Panic("input: read returned zero\n", 0);
-#endif
-                               else {
-                                   if (!screen->output_eight_bits) {
-                                       register int bc = Tbcnt;
-                                       register Char *b = Tbptr;
-
-                                       for (; bc > 0; bc--, b++) {
-                                           *b &= (Char) 0x7f;
-                                       }
-                                   }
-                                       break;
-                               }
+                       if (getPtyData(screen, &Tselect_mask, Tbuffer)) {
+                           break;
                        }
                        if (Ttoggled && curstate == Talptable) {
                                TCursorToggle(TOGGLE);
@@ -759,8 +754,8 @@
                        } else {
                                XFlush(screen->display);
                                XFD_COPYSET (&Select_mask, &Tselect_mask);
-                               if((i = Select(max_plus1, 
-                                              &Tselect_mask, NULL, NULL, 
+                               if((i = Select(max_plus1,
+                                              &Tselect_mask, NULL, NULL,
                                               NULL)) < 0){
                                        if (errno != EINTR)
                                                SysError(ERROR_TSELECT);
@@ -772,7 +767,7 @@
                        i = _X11TransAmSelect(ConnectionNumber(screen->display),
                                              1);
                        /* if there are X events already in our queue,
-                           it counts as being readable */
+                          it counts as being readable */
                        if (XtAppPending(app_con) || i > 0) {
                                xevents();
                                continue;
@@ -781,18 +776,18 @@
                                if (errno != EINTR && !exiting)
                                        SysError(ERROR_SELECT);
                        }
-                       if (Tbcnt > 0)
+                       if (Tbuffer->cnt > 0)
                                goto again;
                        if (cb_full(screen->tty_outq) <= 0)
                                SleepMainThread();
 #endif /* AMOEBA */
                        if(FD_ISSET (ConnectionNumber (screen->display), &Tselect_mask)) {
                                xevents();
-                               if(Tbcnt > 0)
+                               if(Tbuffer->cnt > 0)
                                        goto again;
                        }
                }
-               Tbcnt--;
+               Tbuffer->cnt--;
                if (!Ttoggled && curstate == Talptable) {
                        TCursorToggle(TOGGLE);
                        Ttoggled = TRUE;
@@ -811,7 +806,7 @@
                tek->ptr = tek->data;
        }
        tek->count++;
-       return(*tek->ptr++ = *Tbptr++);
+       return(*tek->ptr++ = *(Tbuffer->ptr)++);
 }
 
 /* this should become the Tek Widget's Resize proc */
@@ -874,9 +869,9 @@
        static Cursor wait_cursor = None;
 
        if (wait_cursor == None)
-            wait_cursor = make_colored_cursor (XC_watch, screen->mousecolor,
+           wait_cursor = make_colored_cursor (XC_watch, screen->mousecolor,
                                               screen->mousecolorback);
-        XDefineCursor(screen->display, TShellWindow, wait_cursor);
+       XDefineCursor(screen->display, TShellWindow, wait_cursor);
        XFlush(screen->display);
        if(!setjmp(Tekjump))
                Tekparse();
@@ -1094,7 +1089,7 @@
 {
        register TScreen *screen = &term->screen;
 
-       XDrawSegments(screen->display, TWindow(screen), 
+       XDrawSegments(screen->display, TWindow(screen),
                ((screen->cur.linetype == SOLIDLINE)?  screen->TnormalGC :
                 screen->linepat[screen->cur.linetype - 1]),
                 Tline, nplot);
@@ -1106,7 +1101,7 @@
 TekGINoff(void)
 {
        register TScreen *screen = &term->screen;
-       
+
        XDefineCursor(screen->display, TShellWindow, screen->arrow);
        if(GINcursor)
                XFreeCursor(screen->display, GINcursor);
@@ -1125,7 +1120,7 @@
        Window root, subw;
 
        XQueryPointer(
-           screen->display, TWindow(screen), 
+           screen->display, TWindow(screen),
            &root, &subw,
            &rootx, &rooty,
            &mousex, &mousey,
@@ -1175,7 +1170,7 @@
 {
        register TScreen *screen = &term->screen;
        register int i;
-       
+
        if(!TWindow(screen) && !TekInit()) {
                if(VWindow(screen)) {
                        screen->TekEmu = FALSE;
@@ -1185,17 +1180,17 @@
        }
        if(!screen->Tshow) {
            set_tek_visibility (TRUE);
-       } 
+       }
        update_vttekmode();
        update_vtshow();
        update_tekshow();
        set_tekhide_sensitivity();
 
        Tpushback = Tpushb;
-       Tbptr = Tbuffer;
-       for(i = Tbcnt = bcnt ; i > 0 ; i--)
-               *Tbptr++ = *bptr++;
-       Tbptr = Tbuffer;
+       Tbuffer->ptr = DecodedData(Tbuffer);
+       for(i = Tbuffer->cnt = VTbuffer.cnt ; i > 0 ; i--)
+               *(Tbuffer->ptr)++ = *(VTbuffer.ptr)++;
+       Tbuffer->ptr = DecodedData(Tbuffer);
        Ttoggled = TRUE;
        if(!setjmp(Tekend))
                Tekparse();
@@ -1280,20 +1275,13 @@
     tw->core.border_pixel = term->core.border_pixel;
 
     for (i = 0; i < TEKNUMFONTS; i++) {
-       if (!tw->tek.Tfont[i]) 
+       if (!tw->tek.Tfont[i])
          tw->tek.Tfont[i] = XQueryFont (screen->display, DefaultGCID);
        tw->tek.tobaseline[i] = tw->tek.Tfont[i]->ascent;
     }
 
-    if((Tbuffer = (Char *)malloc(BUF_SIZE)) == NULL ||
-       (Tpushb = (Char *)malloc(10)) == NULL ||
-       (Tline = (XSegment *)malloc(MAX_VTX * sizeof(XSegment))) == NULL) {
-       fprintf (stderr, "%s: Not enough core for Tek mode\n", xterm_name);
-       if(Tpushb) free((char *)Tpushb);
-       if(Tbuffer) free((char *)Tbuffer);
-       Tfailed = TRUE;
+    if (!TekPtyData())
        return;
-    }
 
     screen->xorplane = 1;
 
@@ -1323,11 +1311,11 @@
     pr = XParseGeometry(term->misc.T_geometry, &winX, &winY, (unsigned int *)&width, (unsigned int *)&height);
     if ((pr & XValue) && (pr & XNegative))
       winX += DisplayWidth(screen->display, DefaultScreen(screen->display))
-                        - width - (term->core.parent->core.border_width * 2);
+                       - width - (term->core.parent->core.border_width * 2);
     if ((pr & YValue) && (pr & YNegative))
       winY += DisplayHeight(screen->display, DefaultScreen(screen->display))
        - height - (term->core.parent->core.border_width * 2);
-  
+
     /* set up size hints */
     sizehints.min_width = TEKMINWIDTH + border;
     sizehints.min_height = TEKMINHEIGHT + border;
@@ -1380,7 +1368,7 @@
     values->win_gravity = NorthWestGravity;
     values->background_pixel = screen->Tbackground;
 
-    tw->core.window = TWindow(screen) = 
+    tw->core.window = TWindow(screen) =
        XCreateWindow (screen->display,
                       tw->core.parent->core.window,
                       tw->core.x, tw->core.y,
@@ -1398,7 +1386,7 @@
     if((d = (double)THeight(screen) / (TEKHEIGHT + TEKTOPPAD +
                                       TEKBOTTOMPAD)) < TekScale(screen))
       TekScale(screen) = d;
-    
+
 
     screen->cur.fontsize = TEK_FONT_LARGE;
     if (tw->tek.initial_font) {
@@ -1406,10 +1394,10 @@
 
        if (XmuCompareISOLatin1 (s, "large") == 0)
          screen->cur.fontsize = TEK_FONT_LARGE;
-       else if (XmuCompareISOLatin1 (s, "2") == 0 || 
+       else if (XmuCompareISOLatin1 (s, "2") == 0 ||
                 XmuCompareISOLatin1 (s, "two") == 0)
          screen->cur.fontsize = TEK_FONT_2;
-       else if (XmuCompareISOLatin1 (s, "3") == 0 || 
+       else if (XmuCompareISOLatin1 (s, "3") == 0 ||
                 XmuCompareISOLatin1 (s, "three") == 0)
          screen->cur.fontsize = TEK_FONT_3;
        else if (XmuCompareISOLatin1 (s, "small") == 0)
@@ -1430,12 +1418,12 @@
     gcv.font = tw->tek.Tfont[screen->cur.fontsize]->fid;
     gcv.foreground = screen->Tforeground;
     gcv.background = screen->Tbackground;
-    
+
     /* if font wasn't successfully opened, then gcv.font will contain
-       the Default GC's ID, meaning that we must use the server default font. 
+       the Default GC's ID, meaning that we must use the server default font.
      */
     TEKgcFontMask = (gcv.font == DefaultGCID) ? 0 : GCFont;
-    screen->TnormalGC = XCreateGC (screen->display, TWindow(screen), 
+    screen->TnormalGC = XCreateGC (screen->display, TWindow(screen),
                                   (TEKgcFontMask|GCGraphicsExposures|
                                    GCForeground|GCBackground), &gcv);
 
@@ -1444,7 +1432,7 @@
                                         screen->Tcursorcolor);
     gcv.join_style = JoinMiter;        /* default */
     gcv.line_width = 1;
-    screen->TcursorGC = XCreateGC (screen->display, TWindow(screen), 
+    screen->TcursorGC = XCreateGC (screen->display, TWindow(screen),
                                   (GCFunction|GCPlaneMask), &gcv);
 
     gcv.foreground = screen->Tforeground;
@@ -1452,7 +1440,7 @@
     gcv.line_width = 0;
     for(i = 0 ; i < TEKNUMLINES ; i++) {
        screen->linepat[i] = XCreateGC (screen->display, TWindow(screen),
-                                       (GCForeground|GCLineStyle), &gcv); 
+                                       (GCForeground|GCLineStyle), &gcv);
        XSetDashes (screen->display, screen->linepat[i], 0,
                    (char *) dashes[i], dash_length[i]);
     }
@@ -1494,7 +1482,7 @@
     tek->count = 0;
     tek->ptr = tek->data;
     Tpushback = Tpushb;
-    Tbptr = Tbuffer;
+    Tbuffer->ptr = DecodedData(Tbuffer);
     screen->cur_X = 0;
     screen->cur_Y = TEKHOME;
     line_pt = Tline;
@@ -1509,14 +1497,14 @@
     int oldsize = screen->cur.fontsize;
     int newsize = MI2FS(newitem);
     Font fid;
-    
+
     if (!tekWidget  ||  oldsize == newsize)
        return;
     if (!Ttoggled) TCursorToggle(TOGGLE);
     set_tekfont_menu_item (oldsize, FALSE);
 
     fid = tekWidget->tek.Tfont[newsize]->fid;
-    if (fid == DefaultGCID) 
+    if (fid == DefaultGCID)
        /* we didn't succeed in opening a real font
          for this size.  Instead, use server default. */
        XCopyGC (screen->display,
@@ -1580,15 +1568,15 @@
 {
        register int i;
        XGCValues gcv;
-        
+
 
        i = screen->Tbackground;
        screen->Tbackground = screen->Tforeground;
        screen->Tforeground = i;
-       
-       XSetForeground(screen->display, screen->TnormalGC, 
+
+       XSetForeground(screen->display, screen->TnormalGC,
         screen->Tforeground);
-       XSetBackground(screen->display, screen->TnormalGC, 
+       XSetBackground(screen->display, screen->TnormalGC,
         screen->Tbackground);
 
        if (tekWidget) {
@@ -1604,7 +1592,7 @@
        }
 
        for(i = 0 ; i < TEKNUMLINES ; i++) {
-               XSetForeground(screen->display, screen->linepat[i], 
+               XSetForeground(screen->display, screen->linepat[i],
                 screen->Tforeground);
        }
 
@@ -1620,7 +1608,7 @@
 TekBackground(register TScreen *screen)
 {
        if(TWindow(screen))
-               XSetWindowBackground(screen->display, TWindow(screen), 
+               XSetWindowBackground(screen->display, TWindow(screen),
                 screen->Tbackground);
 }
 
@@ -1638,7 +1626,7 @@
 
        c = screen->cur.fontsize;
        cellwidth = (unsigned) tekWidget->tek.Tfont[c]->max_bounds.width;
-       cellheight = (unsigned) (tekWidget->tek.Tfont[c]->ascent + 
+       cellheight = (unsigned) (tekWidget->tek.Tfont[c]->ascent +
                                 tekWidget->tek.Tfont[c]->descent);
 
        x = (int)((screen->cur_X * TekScale(screen)) + screen->border);
@@ -1646,7 +1634,7 @@
            + screen->border - tekWidget->tek.tobaseline[c]);
 
        if (toggle == TOGGLE) {
-          if (screen->select || screen->always_highlight) 
+          if (screen->select || screen->always_highlight)
               XFillRectangle(screen->display, TWindow(screen),
                              screen->TcursorGC, x, y,
                              cellwidth, cellheight);
@@ -1674,7 +1662,7 @@
     if (!tekWidget)
        return;
     if (reset) {
-/*      bzero ((char *)&curmodes, sizeof(Tmodes));             */
+/*     bzero ((char *)&curmodes, sizeof(Tmodes));             */
        bzero ((char *) &screen->cur, sizeof screen->cur);
     }
     TekRefresh = (TekLink *)0;
@@ -1734,7 +1722,7 @@
                ESC, screen->page.fontsize + '8',
                ESC, screen->page.linetype + '`');
            write(tekcopyfd, initbuf, 4);
-           Tp = &Tek0; 
+           Tp = &Tek0;
            do {
                write(tekcopyfd, (char *)Tp->data, Tp->count);
                Tp = Tp->next;
Index: charproc.c
--- xterm-96+/charproc.c        Sun Apr 11 16:38:14 1999
+++ xterm-97/charproc.c Sun Apr 25 21:51:51 1999
@@ -100,7 +100,6 @@
 #endif
 
 #include <stdio.h>
-#include <setjmp.h>
 #include <ctype.h>
 
 #ifdef MINIX
@@ -123,22 +122,6 @@
 #include <X11/Shell.h>
 #endif /* NO_ACTIVE_ICON */
 
-/*
- * Check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
- * systems are broken and return EWOULDBLOCK when they should return EAGAIN.
- * Note that this macro may evaluate its argument more than once.
- */
-#if defined(EAGAIN) && defined(EWOULDBLOCK)
-#define E_TEST(err) ((err) == EAGAIN || (err) == EWOULDBLOCK)
-#else
-#ifdef EAGAIN
-#define E_TEST(err) ((err) == EAGAIN)
-#else
-#define E_TEST(err) ((err) == EWOULDBLOCK)
-#endif
-#endif
-
-extern jmp_buf VTend;
 extern Widget toplevel;
 extern char *ProgramName;
 
@@ -265,6 +248,7 @@
 #define XtNtekStartup          "tekStartup"
 #define XtNtiteInhibit         "titeInhibit"
 #define XtNunderLine           "underLine"
+#define XtNutf8                        "utf8"
 #define XtNvisualBell          "visualBell"
 #define XtNwideChars           "wideChars"
 #define XtNxmcAttributes       "xmcAttributes"
@@ -330,6 +314,7 @@
 #define XtCTekStartup          "TekStartup"
 #define XtCTiteInhibit         "TiteInhibit"
 #define XtCUnderLine           "UnderLine"
+#define XtCUtf8                        "Utf8"
 #define XtCVisualBell          "VisualBell"
 #define XtCWideChars           "WideChars"
 #define XtCXmcAttributes       "XmcAttributes"
@@ -342,7 +327,7 @@
 #define XtCGeometry            "Geometry"
 #endif
 
-#define        doinput()               (bcnt-- > 0 ? *bptr++ : in_put())
+#define        doinput()               (morePtyData(&VTbuffer) ? nextPtyData(&VTbuffer) : in_put())
 
 static int nparam;
 static ANSI reply;
@@ -883,6 +868,9 @@
        XtRString, XtExtdefaultbackground},
 #endif /* NO_ACTIVE_ICON */
 #if OPT_WIDE_CHARS
+{XtNutf8, XtCUtf8, XtRInt, sizeof(int),
+       XtOffsetOf(XtermWidgetRec, screen.utf8_mode),
+       XtRString, "0"},
 {XtNwideChars, XtCWideChars, XtRBoolean, sizeof(Boolean),
        XtOffsetOf(XtermWidgetRec, screen.wide_chars),
        XtRBoolean, (XtPointer) &defaultFALSE},
@@ -1055,8 +1043,28 @@
        screen->curss = 0;                      /* No single shift.     */
 }
 
+       /* allocate larger buffer if needed/possible */
+#define SafeAlloc(type, area, used, size) \
+               type *new_string = area; \
+               unsigned new_length = size; \
+               if (new_length == 0) { \
+                   new_length = 256; \
+                   new_string = (type *)malloc(new_length * sizeof(type)); \
+               } else if (used+1 >= new_length) { \
+                   new_length = size * 2; \
+                   new_string = (type *)malloc(new_length * sizeof(type)); \
+                   if (new_string != 0 \
+                    && area != 0 \
+                    && used != 0) \
+                       memcpy(new_string, area, used * sizeof(type)); \
+               }
+
 static void VTparse(void)
 {
+       /* Buffer for processing printable text */
+       static IChar *print_area;
+       static size_t print_size, print_used;
+
        /* Buffer for processing strings (e.g., OSC ... ST) */
        static Char *string_area;
        static size_t string_size, string_used;
@@ -1066,14 +1074,16 @@
 #endif
 
        Const PARSE_T *groundtable = ansi_table;
-       register TScreen *screen = &term->screen;
-       register Const PARSE_T *parsestate;
-       register unsigned int c;
-       register unsigned char *cp;
-       register int row, col, top, bot, scstype, count;
+       TScreen *screen = &term->screen;
+       Const PARSE_T *parsestate;
+       unsigned int c;
+       Char *cp;
+       int row, col, top, bot, scstype, count;
        Bool private_function;  /* distinguish private-mode from standard */
        int string_mode;        /* nonzero iff we're processing a string */
        int lastchar;           /* positive iff we had a graphic character */
+       int nextstate;
+       int laststate;
 
        /* We longjmp back to this point in VTReset() */
        (void)setjmp(vtjmpbuf);
@@ -1086,7 +1096,8 @@
        scstype = 0;
        private_function = False;
        string_mode = 0;
-       lastchar = -1;
+       lastchar = -1;          /* not a legal IChar */
+       nextstate = -1;         /* not a legal state */
 
        for( ; ; ) {
             int thischar = -1;
@@ -1098,23 +1109,6 @@
                    continue;
            }
 
-           /* Accumulate string for APC, DCS, PM, OSC, SOS controls */
-           if (parsestate == sos_table) {
-               if (string_size == 0) {
-                       string_area = (Char *)malloc(string_size = 256);
-               } else if (string_used+1 >= string_size) {
-                       string_size += string_size;
-                       string_area = (Char *)realloc(string_area, string_size);
-                       if (string_area == NULL)
-                           SysError(ERROR_VTREALLOC);
-               }
-               string_area[string_used++] = c;
-           } else if (parsestate != esc_table) {
-               /* if we were accumulating, we're not any more */
-               string_mode = 0;
-               string_used = 0;
-           }
-
            /*
             * VT52 is a little ugly in the one place it has a parameterized
             * control sequence, since the parameter falls after the character
@@ -1138,44 +1132,98 @@
            }
 #endif
 
-           TRACE(("parse %d -> %d\n", c, parsestate[c]))
-           switch (parsestate[c]) {
-                case CASE_PRINT:
-                       /* printable characters */
-                       top = bcnt > TEXT_BUF_SIZE ? TEXT_BUF_SIZE : bcnt;
-                       cp = bptr;
-                       *--bptr = c;
-                       while(top > 0 && isprint(*cp & 0x7f)) {
+           /*
+            * The parsing tables all have 256 entries.  If we're supporting
+            * wide characters, we handle them by treating them the same as
+            * printing characters.
+            */
+           laststate = nextstate;
+#if OPT_WIDE_CHARS
+           if (c > 255) {
+               nextstate = (parsestate == groundtable)
+                       ? CASE_PRINT
+                       : CASE_GROUND_STATE;
+           } else
+#endif
+             nextstate = parsestate[c];
+
+           /* 
+            * Accumulate string for printable text.  This may be 8/16-bit
+            * characters.
+            */
+           if (nextstate == CASE_PRINT) {
+               SafeAlloc(IChar, print_area, print_used, print_size);
+               if (new_string == 0) {
+                   fprintf(stderr,
+                           "Cannot allocate %d bytes for printable text\n",
+                           new_length);
+                   continue;
+               }
+
 #if OPT_VT52_MODE
-                               /*
-                                * Strip output text to 7-bits for VT52.  We
-                                * should do this for VT100 also (which is a
-                                * 7-bit device), but since xterm has been
-                                * doing this for so long we shouldn't change
-                                * this behavior.
-                                */
-                               if (screen->ansi_level < 1)
-                                       *cp &= 0x7f;
+               /*
+                * Strip output text to 7-bits for VT52.  We should do this for
+                * VT100 also (which is a 7-bit device), but xterm has been
+                * doing this for so long we shouldn't change this behavior.
+                */
+               if (screen->ansi_level < 1)
+                   c &= 0x7f;
 #endif
-                               top--;
-                               bcnt--;
-                               cp++;
-                       }
-                       if(screen->curss) {
-                               thischar = *bptr;
-                               dotext(screen,
-                                       screen->gsets[(int)(screen->curss)],
-                                       PAIRED_CHARS(bptr, 0), 1);
-                               bptr += 1;
-                               screen->curss = 0;
-                       }
-                       if(bptr < cp) {
-                               thischar = cp[-1];
-                               dotext(screen,
-                                       screen->gsets[(int)(screen->curgl)],
-                                       PAIRED_CHARS(bptr, 0), cp - bptr);
-                       }
-                       bptr = cp;
+               print_area = new_string;
+               print_size = new_length;
+               print_area[print_used++] = lastchar = thischar = c;
+               if (morePtyData(&VTbuffer)) {
+                   continue;
+               }
+           }
+
+           if (nextstate == CASE_PRINT
+            || (laststate == CASE_PRINT && print_used)) {
+               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;
+           }
+
+           /*
+            * Accumulate string for APC, DCS, PM, OSC, SOS controls
+            * This should always be 8-bit characters.
+            */
+           if (parsestate == sos_table) {
+               SafeAlloc(Char, string_area, string_used, string_size);
+               if (new_string == 0) {
+                   fprintf(stderr,
+                           "Cannot allocate %d bytes for string mode %d\n",
+                           new_length, string_mode);
+                   continue;
+               }
+
+               string_area = new_string;
+               string_size = new_length;
+               string_area[string_used++] = c;
+           } else if (parsestate != esc_table) {
+               /* if we were accumulating, we're not any more */
+               string_mode = 0;
+               string_used = 0;
+           }
+
+           TRACE(("parse %d -> %d\n", c, nextstate))
+
+           switch (nextstate) {
+                case CASE_PRINT:
+                       /* printable characters (see above) */
                        break;
 
                 case CASE_GROUND_STATE:
@@ -1877,7 +1925,7 @@
                                bzero(SCRN_BUF_ATTRS(screen, row),
                                 col = screen->max_col + 1);
                                for(cp = SCRN_BUF_CHARS(screen, row) ; col > 0 ; col--)
-                                       *cp++ = (unsigned char) 'E';
+                                       *cp++ = (Char)'E';
                                if_OPT_WIDE_CHARS(screen,{
                                        bzero(SCRN_BUF_WIDEC(screen, row),
                                              screen->max_col+1);
@@ -2161,13 +2209,13 @@
                 case CASE_REP:
                        /* REP */
                        if (lastchar >= 0 && isprint(lastchar)) {
-                           Char repeated[2];
+                           IChar repeated[2];
                            count = (param[0] < 1) ? 1 : param[0];
                            repeated[0] = lastchar;
                            while (count-- > 0) {
                                dotext(screen,
                                        screen->gsets[(int)(screen->curgl)],
-                                       PAIRED_CHARS(repeated, 0), 1);
+                                       repeated, 1);
                            }
                        }
                        parsestate = groundtable;
@@ -2219,7 +2267,12 @@
                        break;
 #if OPT_WIDE_CHARS
                 case CASE_UTF8:
-                       screen->utf8_mode = (c == 'G');
+                       /* If we did not set UTF-8 mode from resource or
+                        * the command-line, allow it to be enabled/disabled
+                        * by control sequence.
+                        */
+                       if (screen->utf8_mode != 2)
+                               screen->utf8_mode = (c == 'G');
                        parsestate = groundtable;
                        break;
 #endif
@@ -2403,67 +2456,18 @@
     static struct timeval select_timeout;
 
     for( ; ; ) {
-#ifndef AMOEBA
-       if (FD_ISSET (screen->respond, &select_mask) && eventMode == NORMAL)
-#else
-       if ((bcnt = cb_full(screen->tty_outq)) > 0 && eventMode == NORMAL)
-#endif
-       {
-#ifdef ALLOWLOGGING
-           if (screen->logging)
-               FlushLog(screen);
-#endif
-#ifndef AMOEBA
-           bcnt = read(screen->respond, (char *)(bptr = VTbuffer), BUF_SIZE);
-#else
-           bptr = VTbuffer;
-           if ((bcnt = cb_gets(screen->tty_outq, bptr, bcnt, BUF_SIZE)) == 0) {
-               errno = EIO;
-               bcnt = -1;
-           }
-#endif
-           if (bcnt <= 0) {
-/*
- * Yes, I know this is a majorly f*ugly hack, however it seems to be
- * necessary for Solaris x86.   DWH 11/15/94
- * Dunno why though..
- */
-#if defined(i386) && defined(SVR4) && defined(sun)
-               if (errno == EIO || errno == 0 )
-#else
-               if (errno == EIO)
-#endif
-                   Cleanup (0);
-               else if (!E_TEST(errno))
-                   Panic(
-                         "input: read returned unexpected error (%d)\n",
-                         errno);
-           } else if (bcnt == 0) {
-#if defined(MINIX) || defined(__EMX__)
-               Cleanup(0);
-#else
-               Panic("input: read returned zero\n", 0);
-#endif
-           } else {
-               /* read from pty was successful */
-               if (!screen->output_eight_bits) {
-                   register int bc = bcnt;
-                   register Char *b = bptr;
-
-                   for (; bc > 0; bc--, b++) {
-                       *b &= (Char) 0x7f;
-                   }
-               }
-               if ( screen->scrollWidget && screen->scrollttyoutput &&
-                    screen->topline < 0)
-                   WindowScroll(screen, 0);  /* Scroll to bottom */
-               pty_read_bytes += bcnt;
-               /* stop speed reading at some point to look for X stuff */
-               /* (4096 is just a random large number.) */
-               if (pty_read_bytes > 4096)
-                   FD_CLR (screen->respond, &select_mask);
-               break;
-           }
+       if (eventMode == NORMAL
+        && getPtyData(screen, &select_mask, &VTbuffer)) {
+           if (screen->scrollWidget
+            && screen->scrollttyoutput
+            && screen->topline < 0)
+               WindowScroll(screen, 0);  /* Scroll to bottom */
+           pty_read_bytes += VTbuffer.cnt;
+           /* stop speed reading at some point to look for X stuff */
+           /* (4096 is just a random large number.) */
+           if (pty_read_bytes > 4096)
+               FD_CLR (screen->respond, &select_mask);
+           break;
        }
        pty_read_bytes = 0;
        /* update the screen */
@@ -2530,7 +2534,7 @@
        if (XtAppPending(app_con) ||
            FD_ISSET (ConnectionNumber(screen->display), &select_mask)) {
            xevents();
-           if (bcnt > 0)       /* HandleInterpret */
+           if (VTbuffer.cnt > 0)       /* HandleInterpret */
                break;
        }
 #else  /* AMOEBA */
@@ -2539,7 +2543,7 @@
           it counts as being readable */
        if (XtAppPending(app_con) || i > 0) {
            xevents();
-           if (bcnt > 0)       /* HandleInterpret */
+           if (VTbuffer.cnt > 0)       /* HandleInterpret */
                break;
            continue;
        } else if (i < 0) {
@@ -2552,8 +2556,7 @@
 #endif /* AMOENA */
 
     }
-    bcnt--;
-    return(*bptr++);
+    return nextPtyData(&VTbuffer);
 }
 
 /*
@@ -2562,13 +2565,16 @@
  */
 void
 dotext(
-       register TScreen *screen,
+       TScreen *screen,
        int     charset,
-       PAIRED_CHARS(Char *buf,Char *buf2), /* start of characters to process */
+       IChar   *buf,           /* start of characters to process */
        Cardinal len)           /* end */
 {
        Cardinal n, next_col, 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;
 
@@ -2599,9 +2605,46 @@
                        n = len - offset;
                next_col = screen->cur_col + n;
 
+#if OPT_WIDE_CHARS
+               /*
+                * Split the wide characters back into separate arrays of 8-bit
+                * characters so we can use the existing interface.
+                *
+                * FIXME:  If we rewrote this interface, it would involve
+                * rewriting all of the memory-management for the screen
+                * buffers (perhaps this is simpler).
+                */
+               {
+                       static unsigned limit;
+                       static Char *hibyte, *lobyte;
+                       Boolean both = False;
+                       unsigned j, k;
+
+                       if (n >= limit) {
+                               limit = (n + 1) * 2;
+                               lobyte = XtRealloc(lobyte, limit);
+                               hibyte = XtRealloc(hibyte, limit);
+                       }
+                       for (j = offset; j < offset+n; j++) {
+                               k = j-offset;
+                               lobyte[k] = buf[j];
+                               if (buf[j] > 255) {
+                                       hibyte[k] = (buf[j] >> 8);
+                                       both = True;
+                               } else {
+                                       hibyte[k] = 0;
+                               }
+                       }
+
+                       WriteText(screen, PAIRED_CHARS(
+                               lobyte,
+                               both ? hibyte : 0), n);
+               }
+#else
                WriteText(screen, PAIRED_CHARS(
                        buf+offset,
                        buf2 ? buf2+offset : 0), n);
+#endif
 
                /*
                 * the call to WriteText updates screen->cur_col.
@@ -2637,11 +2680,11 @@
        int     fg_bg = makeColorPair(term->cur_foreground, term->cur_background);
        GC      currentGC;
 
-       TRACE(("WriteText (%2d,%2d) (%d) %3d:%.*s\n",
+       TRACE(("WriteText (%2d,%2d) (%d) %3d:%s\n",
                screen->cur_row,
                screen->cur_col,
                curXtermChrSet(screen->cur_row),
-               len, (int)len, str))
+               len, visibleChars(PAIRED_CHARS(str, str2), len)))
 
        if(screen->cur_row - screen->topline <= screen->max_row) {
                if(screen->cursor_state)
@@ -2656,8 +2699,13 @@
                        if(screen->scroll_amt)
                                FlushScroll(screen);
 
-                       if (flags & INVISIBLE)
+                       if (flags & INVISIBLE) {
                                memset(str, ' ', len);
+                               if_OPT_WIDE_CHARS(screen,{
+                                       if (str2 != 0)
+                                               memset(str2, ' ', len);
+                               })
+                       }
 
                        TRACE(("%s @%d, calling drawXtermText (%d,%d)\n",
                                __FILE__, __LINE__,
@@ -2683,7 +2731,7 @@
 #endif
                }
        }
-       ScreenWrite(screen, str, flags, fg_bg, len);
+       ScreenWrite(screen, PAIRED_CHARS(str, str2), flags, fg_bg, len);
        CursorForward(screen, len);
 #if OPT_ZICONBEEP
        /* Flag icon name with "***"  on window output when iconified.
@@ -2884,9 +2932,9 @@
 #if OPT_TEK4014
                        if(func == bitset && !(screen->inhibit & I_TEK)) {
 #ifdef ALLOWLOGGING
-                               if(screen->logging) {
+                               if(screen->logging && TekPtyData()) {
                                        FlushLog(screen);
-                                       screen->logstart = Tbuffer;
+                                       screen->logstart = Tbuffer->buf;
                                }
 #endif
                                screen->TekEmu = TRUE;
@@ -3491,7 +3539,7 @@
 void
 unparseputc(int c, int fd)
 {
-       Char    buf[2];
+       IChar   buf[2];
        register int i = 1;
 
 #ifdef AMOEBA
@@ -3506,8 +3554,7 @@
        /* If send/receive mode is reset, we echo characters locally */
        if ((term->keyboard.flags & MODE_SRM) == 0) {
                register TScreen *screen = &term->screen;
-               dotext(screen, screen->gsets[(int)(screen->curgl)],
-                       PAIRED_CHARS(buf, 0), i);
+               dotext(screen, screen->gsets[(int)(screen->curgl)], buf, i);
        }
 }
 
@@ -3615,17 +3662,16 @@
        screen->cursor_set = ON;
        StartBlinking(screen);
 
-       bcnt = 0;
-       bptr = VTbuffer;
+       initPtyData(&VTbuffer);
 #if OPT_TEK4014
        while(Tpushb > Tpushback) {
-               *bptr++ = *--Tpushb;
-               bcnt++;
+               *(VTbuffer.ptr)++ = *--Tpushb;
+               VTbuffer.cnt++;
        }
-       bcnt += (i = Tbcnt);
+       VTbuffer.cnt += (i = (Tbuffer ? Tbuffer->cnt : 0));
        for( ; i > 0 ; i--)
-               *bptr++ = *Tbptr++;
-       bptr = VTbuffer;
+               *(VTbuffer.ptr)++ = *(Tbuffer->ptr)++;
+       VTbuffer.ptr = DecodedData(&VTbuffer);
 #endif
        if(!setjmp(VTend))
                VTparse();
@@ -4004,8 +4050,13 @@
 #endif
 
 #if OPT_WIDE_CHARS
-   wnew->screen.utf8_mode = False; /* will activate with control-sequence */
-   if ((wnew->screen.wide_chars = request->screen.wide_chars) != False)
+   wnew->screen.wide_chars = request->screen.wide_chars;
+   if (request->screen.utf8_mode) {
+      wnew->screen.wide_chars = True;
+      wnew->screen.utf8_mode = 2; /* disable further change */
+      TRACE(("initialized UTF-8 mode\n"));
+   }
+   if (wnew->screen.wide_chars != False)
       wnew->num_ptrs += 1;
 #endif
 
@@ -4539,8 +4590,10 @@
            chi = SCRN_BUF_WIDEC(screen, screen->cursor_row)[screen->cursor_col];
        })
 
-       if (clo == 0)
+       if (clo == 0) {
                clo = ' ';
+               if_OPT_WIDE_CHARS(screen,{chi = 0;})
+       }
 
        /*
         * Compare the current cell to the last set of colors used for the
@@ -4690,8 +4743,10 @@
 
        currentGC = updatedXtermGC(screen, flags, fg_bg, in_selection);
 
-       if (clo == 0)
+       if (clo == 0) {
                clo = ' ';
+               if_OPT_WIDE_CHARS(screen,{chi = 0;})
+       }
 
        TRACE(("%s @%d, HideCursor calling drawXtermText\n", __FILE__, __LINE__))
        drawXtermText(screen, flags, currentGC,
Index: charsets.c
--- xterm-96+/charsets.c        Sun Jan 24 14:44:33 1999
+++ xterm-97/charsets.c Sat Apr 24 18:14:07 1999
@@ -241,19 +241,19 @@
  * Translate a string to the display form.  This assumes the font has the
  * DEC graphic characters in cells 0-31, and otherwise is ISO-8859-1.
  */
-int xtermCharSetOut(Char *buf, Char *ptr, char leftset)
+int xtermCharSetOut(IChar *buf, IChar *ptr, char leftset)
 {
-       Char *s;
+       IChar *s;
        register TScreen *screen = &term->screen;
        int count = 0;
        int rightset = screen->gsets[(int)(screen->curgr)];
 
-       TRACE(("CHARSET GL=%c(G%d) GR=%c(G%d) %.*s\n",
+       TRACE(("CHARSET GL=%c(G%d) GR=%c(G%d) %s\n",
                leftset,  screen->curss ? screen->curss : screen->curgl,
                rightset, screen->curgr,
-               ptr-buf, buf))
+               visibleIChar(buf, ptr-buf)))
 
-       for (s=buf; s<ptr; ++s) {
+       for (s = buf; s < ptr; ++s) {
                int cs = (*s >= 128) ? rightset : leftset;
 
                count++;
Index: configure
--- xterm-96+/configure Sun Apr 11 16:38:14 1999
+++ xterm-97/configure  Fri Apr 23 18:20:24 1999
@@ -3785,11 +3785,60 @@
 
 LIBS="$LIBS $X_EXTRA_LIBS"
 
+# Unix98 pty's on Linux with glibc2 use openpty, which lives in libutil.a
+echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6
+echo "configure:3791: checking for openpty in -lutil" >&5
+ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lutil  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3799 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char openpty();
+
+int main() {
+openpty()
+; return 0; }
+EOF
+if { (eval echo configure:3810: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo util | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lutil $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
 
 # Extract the first word of "xterm", so it can be a program name with args.
 set dummy xterm; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3793: checking for $ac_word" >&5
+echo "configure:3842: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_XTERM_PATH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3823,7 +3872,7 @@
 
 XTERM_MODE=755
 echo $ac_n "checking for presumed installation-mode""... $ac_c" 1>&6
-echo "configure:3827: checking for presumed installation-mode" >&5
+echo "configure:3876: checking for presumed installation-mode" >&5
 if test -f "$XTERM_PATH" ; then
        ls -l $XTERM_PATH >conftest.out
        read cf_mode cf_rest <conftest.out
@@ -3842,12 +3891,12 @@
        
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3846: checking for $ac_func" >&5
+echo "configure:3895: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3851 "configure"
+#line 3900 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3870,7 +3919,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:3874: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3896,7 +3945,7 @@
 
 
 echo $ac_n "checking if we should use imake to help""... $ac_c" 1>&6
-echo "configure:3900: checking if we should use imake to help" >&5
+echo "configure:3949: checking if we should use imake to help" >&5
 
 # Check whether --enable-imake or --disable-imake was given.
 if test "${enable_imake+set}" = set; then
@@ -3921,7 +3970,7 @@
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3925: checking for $ac_word" >&5
+echo "configure:3974: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_IMAKE'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4060,7 +4109,7 @@
 
 
 echo $ac_n "checking for default terminal-id""... $ac_c" 1>&6
-echo "configure:4064: checking for default terminal-id" >&5
+echo "configure:4113: checking for default terminal-id" >&5
 
 # Check whether --with-terminal-id or --without-terminal-id was given.
 if test "${with_terminal_id+set}" = set; then
@@ -4081,7 +4130,7 @@
 
 
 echo $ac_n "checking for default terminal-type""... $ac_c" 1>&6
-echo "configure:4085: checking for default terminal-type" >&5
+echo "configure:4134: checking for default terminal-type" >&5
 
 # Check whether --with-terminal-type or --without-terminal-type was given.
 if test "${with_terminal_type+set}" = set; then
@@ -4098,7 +4147,7 @@
 
 
 echo $ac_n "checking for private terminfo-directory""... $ac_c" 1>&6
-echo "configure:4102: checking for private terminfo-directory" >&5
+echo "configure:4151: checking for private terminfo-directory" >&5
 
 # Check whether --with-own-terminfo or --without-own-terminfo was given.
 if test "${with_own_terminfo+set}" = set; then
@@ -4129,7 +4178,7 @@
 
 ###    checks for optional features
 echo $ac_n "checking if you want active-icons""... $ac_c" 1>&6
-echo "configure:4133: checking if you want active-icons" >&5
+echo "configure:4182: checking if you want active-icons" >&5
 
 # Check whether --enable-active-icon or --disable-active-icon was given.
 if test "${enable_active_icon+set}" = set; then
@@ -4155,7 +4204,7 @@
 fi
 
 echo $ac_n "checking if you want ANSI color""... $ac_c" 1>&6
-echo "configure:4159: checking if you want ANSI color" >&5
+echo "configure:4208: checking if you want ANSI color" >&5
 
 # Check whether --enable-ansi-color or --disable-ansi-color was given.
 if test "${enable_ansi_color+set}" = set; then
@@ -4179,7 +4228,7 @@
 
 
 echo $ac_n "checking if you want 16 colors like aixterm""... $ac_c" 1>&6
-echo "configure:4183: checking if you want 16 colors like aixterm" >&5
+echo "configure:4232: checking if you want 16 colors like aixterm" >&5
 
 # Check whether --enable-16-color or --disable-16-color was given.
 if test "${enable_16_color+set}" = set; then
@@ -4203,7 +4252,7 @@
 
 
 echo $ac_n "checking if you want bold colors mapped like IBM PC""... $ac_c" 1>&6
-echo "configure:4207: checking if you want bold colors mapped like IBM PC" >&5
+echo "configure:4256: checking if you want bold colors mapped like IBM PC" >&5
 
 # Check whether --enable-bold-color or --disable-bold-color was given.
 if test "${enable_bold_color+set}" = set; then
@@ -4227,7 +4276,7 @@
 
 
 echo $ac_n "checking if you want color-mode enabled by default""... $ac_c" 1>&6
-echo "configure:4231: checking if you want color-mode enabled by default" >&5
+echo "configure:4280: checking if you want color-mode enabled by default" >&5
 
 # Check whether --enable-color-mode or --disable-color-mode was given.
 if test "${enable_color_mode+set}" = set; then
@@ -4251,7 +4300,7 @@
 
 
 echo $ac_n "checking if you want support for color highlighting""... $ac_c" 1>&6
-echo "configure:4255: checking if you want support for color highlighting" >&5
+echo "configure:4304: checking if you want support for color highlighting" >&5
 
 # Check whether --enable-highlighting or --disable-highlighting was given.
 if test "${enable_highlighting+set}" = set; then
@@ -4275,7 +4324,7 @@
 
 
 echo $ac_n "checking if you want support for doublesize characters""... $ac_c" 1>&6
-echo "configure:4279: checking if you want support for doublesize characters" >&5
+echo "configure:4328: checking if you want support for doublesize characters" >&5
 
 # Check whether --enable-doublechars or --disable-doublechars was given.
 if test "${enable_doublechars+set}" = set; then
@@ -4299,7 +4348,7 @@
 
 
 echo $ac_n "checking if you want fallback-support for box characters""... $ac_c" 1>&6
-echo "configure:4303: checking if you want fallback-support for box characters" >&5
+echo "configure:4352: checking if you want fallback-support for box characters" >&5
 
 # Check whether --enable-boxchars or --disable-boxchars was given.
 if test "${enable_boxchars+set}" = set; then
@@ -4323,7 +4372,7 @@
 
 
 echo $ac_n "checking if you want support for HP-style function keys""... $ac_c" 1>&6
-echo "configure:4327: checking if you want support for HP-style function keys" >&5
+echo "configure:4376: checking if you want support for HP-style function keys" >&5
 
 # Check whether --enable-hp-fkeys or --disable-hp-fkeys was given.
 if test "${enable_hp_fkeys+set}" = set; then
@@ -4349,7 +4398,7 @@
 fi
 
 echo $ac_n "checking if you want support for internationalization""... $ac_c" 1>&6
-echo "configure:4353: checking if you want support for internationalization" >&5
+echo "configure:4402: checking if you want support for internationalization" >&5
 
 # Check whether --enable-i18n or --disable-i18n was given.
 if test "${enable_i18n+set}" = set; then
@@ -4375,7 +4424,7 @@
 fi
 
 echo $ac_n "checking if you want support for initial-erase setup""... $ac_c" 1>&6
-echo "configure:4379: checking if you want support for initial-erase setup" >&5
+echo "configure:4428: checking if you want support for initial-erase setup" >&5
 
 # Check whether --enable-initial-erase or --disable-initial-erase was given.
 if test "${enable_initial_erase+set}" = set; then
@@ -4401,7 +4450,7 @@
 fi
 
 echo $ac_n "checking if you want support for input-method""... $ac_c" 1>&6
-echo "configure:4405: checking if you want support for input-method" >&5
+echo "configure:4454: checking if you want support for input-method" >&5
 
 # Check whether --enable-input-method or --disable-input-method was given.
 if test "${enable_input_method+set}" = set; then
@@ -4427,7 +4476,7 @@
 fi
 
 echo $ac_n "checking if you want support for logging""... $ac_c" 1>&6
-echo "configure:4431: checking if you want support for logging" >&5
+echo "configure:4480: checking if you want support for logging" >&5
 
 # Check whether --enable-logging or --disable-logging was given.
 if test "${enable_logging+set}" = set; then
@@ -4451,7 +4500,7 @@
 EOF
 
        echo $ac_n "checking if you want to allow logging via a pipe""... $ac_c" 1>&6
-echo "configure:4455: checking if you want to allow logging via a pipe" >&5
+echo "configure:4504: checking if you want to allow logging via a pipe" >&5
        
 # Check whether --enable-logfile-exec or --disable-logfile-exec was given.
 if test "${enable_logfile_exec+set}" = set; then
@@ -4478,7 +4527,7 @@
 fi
 
 echo $ac_n "checking if you want support for iconify/maximize translations""... $ac_c" 1>&6
-echo "configure:4482: checking if you want support for iconify/maximize translations" >&5
+echo "configure:4531: checking if you want support for iconify/maximize translations" >&5
 
 # Check whether --enable-maximize or --disable-maximize was given.
 if test "${enable_maximize+set}" = set; then
@@ -4502,7 +4551,7 @@
 
 
 echo $ac_n "checking if you want NumLock to override keyboard tables""... $ac_c" 1>&6
-echo "configure:4506: checking if you want NumLock to override keyboard tables" >&5
+echo "configure:4555: checking if you want NumLock to override keyboard tables" >&5
 
 # Check whether --enable-num-lock or --disable-num-lock was given.
 if test "${enable_num_lock+set}" = set; then
@@ -4526,7 +4575,7 @@
 
 
 echo $ac_n "checking if you want support for right-scrollbar""... $ac_c" 1>&6
-echo "configure:4530: checking if you want support for right-scrollbar" >&5
+echo "configure:4579: checking if you want support for right-scrollbar" >&5
 
 # Check whether --enable-rightbar or --disable-rightbar was given.
 if test "${enable_rightbar+set}" = set; then
@@ -4552,7 +4601,7 @@
 fi
 
 echo $ac_n "checking if you want check for redundant name-change""... $ac_c" 1>&6
-echo "configure:4556: checking if you want check for redundant name-change" >&5
+echo "configure:4605: checking if you want check for redundant name-change" >&5
 
 # Check whether --enable-samename or --disable-samename was given.
 if test "${enable_samename+set}" = set; then
@@ -4576,7 +4625,7 @@
 
 
 echo $ac_n "checking if you want support for tek4014""... $ac_c" 1>&6
-echo "configure:4580: checking if you want support for tek4014" >&5
+echo "configure:4629: checking if you want support for tek4014" >&5
 
 # Check whether --enable-tek4014 or --disable-tek4014 was given.
 if test "${enable_tek4014+set}" = set; then
@@ -4606,7 +4655,7 @@
 fi
 
 echo $ac_n "checking if you want VT52 emulation""... $ac_c" 1>&6
-echo "configure:4610: checking if you want VT52 emulation" >&5
+echo "configure:4659: checking if you want VT52 emulation" >&5
 
 # Check whether --enable-vt52 or --disable-vt52 was given.
 if test "${enable_vt52+set}" = set; then
@@ -4630,7 +4679,7 @@
 
 
 echo $ac_n "checking if you want wide-character support""... $ac_c" 1>&6
-echo "configure:4634: checking if you want wide-character support" >&5
+echo "configure:4683: checking if you want wide-character support" >&5
 
 # Check whether --enable-wide-chars or --disable-wide-chars was given.
 if test "${enable_wide_chars+set}" = set; then
@@ -4654,7 +4703,7 @@
 
 
 echo $ac_n "checking if you want -ziconbeep option""... $ac_c" 1>&6
-echo "configure:4658: checking if you want -ziconbeep option" >&5
+echo "configure:4707: checking if you want -ziconbeep option" >&5
 
 # Check whether --enable-ziconbeep or --disable-ziconbeep was given.
 if test "${enable_ziconbeep+set}" = set; then
@@ -4679,7 +4728,7 @@
 
 # development/testing aids
 echo $ac_n "checking if you want debugging traces""... $ac_c" 1>&6
-echo "configure:4683: checking if you want debugging traces" >&5
+echo "configure:4732: checking if you want debugging traces" >&5
 
 # Check whether --enable-trace or --disable-trace was given.
 if test "${enable_trace+set}" = set; then
@@ -4708,7 +4757,7 @@
 
 
 echo $ac_n "checking if you want to see long compiling messages""... $ac_c" 1>&6
-echo "configure:4712: checking if you want to see long compiling messages" >&5
+echo "configure:4761: checking if you want to see long compiling messages" >&5
 
 # Check whether --enable-echo or --disable-echo was given.
 if test "${enable_echo+set}" = set; then
@@ -4748,7 +4797,7 @@
 
 
 echo $ac_n "checking if you want magic cookie emulation""... $ac_c" 1>&6
-echo "configure:4752: checking if you want magic cookie emulation" >&5
+echo "configure:4801: checking if you want magic cookie emulation" >&5
 
 # Check whether --enable-xmc-glitch or --disable-xmc-glitch was given.
 if test "${enable_xmc_glitch+set}" = set; then
@@ -4777,7 +4826,7 @@
 
 if test -n "$GCC" ; then
 echo $ac_n "checking if you want to turn on gcc warnings""... $ac_c" 1>&6
-echo "configure:4781: checking if you want to turn on gcc warnings" >&5
+echo "configure:4830: checking if you want to turn on gcc warnings" >&5
 
 # Check whether --enable-warnings or --disable-warnings was given.
 if test "${enable_warnings+set}" = set; then
@@ -4817,9 +4866,9 @@
 if test -n "$GCC"
 then
        echo "checking for gcc __attribute__ directives" 1>&6
-echo "configure:4821: checking for gcc __attribute__ directives" >&5
+echo "configure:4870: checking for gcc __attribute__ directives" >&5
        cat > conftest.$ac_ext <<EOF
-#line 4823 "configure"
+#line 4872 "configure"
 #include "confdefs.h"
 #include "conftest.h"
 #include "conftest.i"
@@ -4857,7 +4906,7 @@
 EOF
                        ;;
                esac
-               if { (eval echo configure:4861: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+               if { (eval echo configure:4910: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
                        test -n "$verbose" && echo "$ac_t""... $cf_attribute" 1>&6
                        cat conftest.h >>confdefs.h
 #              else
@@ -4874,11 +4923,11 @@
 if test -n "$GCC"
 then
                cat > conftest.$ac_ext <<EOF
-#line 4878 "configure"
+#line 4927 "configure"
 int main(int argc, char *argv[]) { return argv[argc-1] == 0; }
 EOF
                echo "checking for gcc warning options" 1>&6
-echo "configure:4882: checking for gcc warning options" >&5
+echo "configure:4931: checking for gcc warning options" >&5
        cf_save_CFLAGS="$CFLAGS"
        EXTRA_CFLAGS="-W -Wall"
        cf_warn_CONST=""
@@ -4896,7 +4945,7 @@
                Wstrict-prototypes $cf_warn_CONST
        do
                CFLAGS="$cf_save_CFLAGS $EXTRA_CFLAGS -$cf_opt"
-               if { (eval echo configure:4900: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+               if { (eval echo configure:4949: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
                        test -n "$verbose" && echo "$ac_t""... -$cf_opt" 1>&6
                        EXTRA_CFLAGS="$EXTRA_CFLAGS -$cf_opt"
                        test "$cf_opt" = Wcast-qual && EXTRA_CFLAGS="$EXTRA_CFLAGS -DXTSTRINGDEFINES"
Index: configure.in
--- xterm-96+/configure.in      Sun Apr 11 16:38:14 1999
+++ xterm-97/configure.in       Fri Apr 23 18:03:52 1999
@@ -101,6 +101,9 @@
 
 LIBS="$LIBS $X_EXTRA_LIBS"
 
+# Unix98 pty's on Linux with glibc2 use openpty, which lives in libutil.a
+AC_CHECK_LIB(util,openpty)
+
 CF_XTERM_MODE
 
 AC_CHECK_FUNCS( \
Index: data.c
--- xterm-96+/data.c    Sun Apr 11 16:38:14 1999
+++ xterm-97/data.c     Sat Apr 24 22:22:01 1999
@@ -33,11 +33,8 @@
 #include <ptyx.h>              /* gets Xt stuff, too */
 #include <data.h>
 
-#include <setjmp.h>
-
 #if OPT_TEK4014
-Char *Tbptr;
-Char *Tbuffer;
+PtyData *Tbuffer;
 Char *Tpushb;
 Char *Tpushback;
 TekLink *TekRefresh;
@@ -45,14 +42,11 @@
 int TEKgcFontMask = GCFont;
 int T_lastx = -1;
 int T_lasty = -1;
-int Tbcnt = 0;
 int Ttoggled = 0;
 jmp_buf Tekend;
 #endif
 
-int bcnt = 0;
-Char VTbuffer[BUF_SIZE];
-Char *bptr = VTbuffer;
+PtyData VTbuffer;
 
 jmp_buf VTend;
 
Index: data.h
--- xterm-96+/data.h    Sun Apr 11 16:38:14 1999
+++ xterm-97/data.h     Sat Apr 24 22:21:45 1999
@@ -42,23 +42,23 @@
 #include <sys/select.h>
 #endif
 
+#include <setjmp.h>
+
 extern XtAppContext app_con;
 
 #if OPT_TEK4014
-extern Char *Tbptr;
-extern Char *Tbuffer;
 extern Char *Tpushb;
 extern Char *Tpushback;
+extern PtyData *Tbuffer;
 extern TekLink *TekRefresh;
 extern TekWidget tekWidget;
 extern int TEKgcFontMask;
 extern int T_lastx;
 extern int T_lasty;
-extern int Tbcnt;
 extern int Ttoggled;
+extern jmp_buf Tekend;
 #endif
 
-extern Char *bptr;
 #ifdef ALLOWLOGGING
 extern char log_def_name[];
 #endif
@@ -84,10 +84,10 @@
 extern Boolean sunKeyboard;
 #endif
 
-extern Char VTbuffer[];
+extern PtyData VTbuffer;
 extern int am_slave;
-extern int bcnt;
 extern int max_plus1;
+extern jmp_buf VTend;
 
 #ifdef DEBUG
 extern int debug;
Index: main.c
--- xterm-96+/main.c    Sun Apr 25 17:28:21 1999
+++ xterm-97/main.c     Sun Apr 25 21:23:24 1999
@@ -177,8 +177,7 @@
 #define LASTLOG
 #define WTMP
 #undef  HAS_LTCHARS
-#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
-#define USE_USG_PTYS 1
+#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
 #include <pty.h>
 #endif
 #endif
@@ -388,7 +387,6 @@
 #endif
 
 #include <stdio.h>
-#include <setjmp.h>
 
 #ifdef X_NOT_STDC_ENV
 extern time_t time ();
@@ -927,6 +925,10 @@
 {"-ti",                "*decTerminalID",XrmoptionSepArg,       (caddr_t) NULL},
 {"-tm",                "*ttyModes",    XrmoptionSepArg,        (caddr_t) NULL},
 {"-tn",                "*termName",    XrmoptionSepArg,        (caddr_t) NULL},
+#if OPT_WIDE_CHARS
+{"-u8",                "*utf8",        XrmoptionNoArg,         (caddr_t) "2"},
+{"+u8",                "*utf8",        XrmoptionNoArg,         (caddr_t) "0"},
+#endif
 {"-ulc",       "*colorULMode", XrmoptionNoArg,         (caddr_t) "off"},
 {"+ulc",       "*colorULMode", XrmoptionNoArg,         (caddr_t) "on"},
 {"-ut",                "*utmpInhibit", XrmoptionNoArg,         (caddr_t) "on"},
@@ -1001,6 +1003,9 @@
 #if OPT_HP_FUNC_KEYS
 { "-/+hf",                 "turn on/off HP Function Key escape codes" },
 #endif
+#if OPT_INITIAL_ERASE
+{ "-/+ie",                "turn on/off initialization of 'erase' from pty" },
+#endif
 { "-/+im",                "use insert mode for TERMCAP" },
 { "-/+j",                  "turn on/off jump scroll" },
 #ifdef ALLOWLOGGING
@@ -1039,6 +1044,9 @@
 { "-tm string",            "terminal mode keywords and characters" },
 { "-tn name",              "TERM environment variable name" },
 { "-/+ulc",                "turn off/on display of underline as color" },
+#if OPT_WIDE_CHARS
+{ "-/+u8",                 "turn on/off UTF-8 mode (implies wide-characters)" },
+#endif
 #ifdef UTMP
 { "-/+ut",                 "turn on/off utmp inhibit" },
 #else
@@ -1885,7 +1893,7 @@
 static int
 get_pty (int *pty)
 {
-#if defined(__osf__) || (defined(linux) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1)
+#if defined(__osf__) || (defined(linux) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1))
     int tty;
     return (openpty(pty, &tty, ttydev, NULL, NULL));
 #elif defined(SYSV) && defined(i386) && !defined(SVR4)
@@ -2666,7 +2674,7 @@
 #endif
 #endif /* USE_SYSV_PGRP */
                while (1) {
-#if defined(TIOCNOTTY) && !(defined(linux) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1)
+#if defined(TIOCNOTTY) && !(defined(linux) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1))
                        if (!no_dev_tty && (tty = open ("/dev/tty", O_RDWR)) >= 0) {
                                ioctl (tty, TIOCNOTTY, (char *) NULL);
                                close (tty);
@@ -3231,7 +3239,7 @@
                               sizeof(utmp.ut_name));
 
                utmp.ut_pid = getpid();
-#if defined(SVR4) || defined(SCO325) || (defined(linux) && defined(__GLIBC__) && __GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0))
+#if defined(SVR4) || defined(SCO325) || (defined(linux) && defined(__GLIBC__) && (__GLIBC__ >= 2) && !(defined(__powerpc__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0)))
                utmp.ut_session = getsid(0);
                utmp.ut_xtime = time ((time_t *) 0);
                utmp.ut_tv.tv_usec = 0;
@@ -3246,7 +3254,7 @@
 #if defined(SVR4) || defined(SCO325)
                if (term->misc.login_shell)
                    updwtmpx(WTMPX_FILE, &utmp);
-#elif defined(linux) && defined(__GLIBC__) && __GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+#elif defined(linux) && defined(__GLIBC__) && (__GLIBC__ >= 2) && !(defined(__powerpc__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0))
                if (term->misc.login_shell)
                    updwtmp(etc_wtmp, &utmp);
 #else
@@ -4005,7 +4013,7 @@
 #endif
        char* ptyname;
        char* ptynameptr = 0;
-#if defined(WTMP) && !defined(SVR4) && !(defined(linux) && defined(__GLIBC__) && __GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0))
+#if defined(WTMP) && !defined(SVR4) && !(defined(linux) && defined(__GLIBC__) && (__GLIBC__ >= 2) && !(defined(__powerpc__) && __GLIBC__ == 2 && (__GLIBC_MINOR__ == 0)))
        int fd;                 /* for /etc/wtmp */
        int i;
 #endif
@@ -4037,7 +4045,7 @@
            /* write it out only if it exists, and the pid's match */
            if (utptr && (utptr->ut_pid == screen->pid)) {
                    utptr->ut_type = DEAD_PROCESS;
-#if defined(SVR4) || defined(SCO325) || (defined(linux) && defined(__GLIBC__) &&__GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0))
+#if defined(SVR4) || defined(SCO325) || (defined(linux) && defined(__GLIBC__) && (__GLIBC__ >= 2) && !(defined(__powerpc__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0)))
                    utptr->ut_session = getsid(0);
                    utptr->ut_xtime = time ((time_t *) 0);
                    utptr->ut_tv.tv_usec = 0;
@@ -4050,7 +4058,7 @@
 #if defined(SVR4) || defined(SCO325)
                    if (term->misc.login_shell)
                        updwtmpx(WTMPX_FILE, utptr);
-#elif defined(linux) && defined(__GLIBC__) && __GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+#elif defined(linux) && defined(__GLIBC__) && (__GLIBC__ >= 2) && !(defined(__powerpc__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0))
                    strncpy (utmp.ut_line, utptr->ut_line, sizeof (utmp.ut_line));
                    if (term->misc.login_shell)
                        updwtmp(etc_wtmp, utptr);
Index: misc.c
--- xterm-96+/misc.c    Sun Apr 11 16:38:14 1999
+++ xterm-97/misc.c     Sat Apr 24 22:22:37 1999
@@ -60,7 +60,6 @@
 
 #include <X11/Xos.h>
 #include <stdio.h>
-#include <setjmp.h>
 #include <signal.h>
 #include <ctype.h>
 #include <pwd.h>
@@ -95,10 +94,6 @@
 #endif
 
 extern char **environ;         /* used in 'Setenv()' */
-
-extern jmp_buf Tekend;
-extern jmp_buf VTend;
-
 extern Widget toplevel;                /* used in 'ChangeGroup()' */
 
 #if OPT_TEK4014
@@ -271,7 +266,7 @@
  * input queue.  That lets a user have access to any of the control sequences
  * for a key binding.  This is the equivalent of local function key support.
  *
- * NOTE:  This code does not support the hexidecimal kludge used in
+ * NOTE:  This code does not support the hexadecimal kludge used in
  * HandleStringEvent because it prevents us from sending an arbitrary string
  * (but it appears in a lot of examples - so we are stuck with it).  The
  * standard string converter does recognize "\" for newline ("\n") and for
@@ -285,18 +280,33 @@
        String *params,
        Cardinal *param_count)
 {
-    unsigned need;
-    if (*param_count != 1) return;
-    need = strlen(params[0]);
-    if (bcnt < 0)
-       bcnt = 0;
-    if ((unsigned)bcnt + need >= BUF_SIZE) return;
-    if (bcnt != 0
-     && (unsigned)(bptr - VTbuffer) < need)
-       memmove(bptr + need - (bptr - VTbuffer), bptr, bcnt);
-    bcnt += need;
-    bptr -= need;
-    memcpy(bptr, params[0], need);
+    if (*param_count == 1) {
+       char *value = params[0];
+       int need = strlen(value);
+       int used = usedPtyData(&VTbuffer);
+       int have = (VTbuffer.cnt >= 0) ? VTbuffer.cnt : 0;
+       int n;
+
+       if (have - used + need < BUF_SIZE) {
+
+           FlushLog(&term->screen);
+
+           if (have != 0
+            && used < have) {
+               memmove(VTbuffer.ptr + (need - used),
+                       VTbuffer.ptr,
+                       VTbuffer.cnt * sizeof(*VTbuffer.ptr));
+           } else {
+               initPtyData(&VTbuffer);
+               used = 0;
+           }
+
+           VTbuffer.cnt += (need - used);
+           VTbuffer.ptr -= used;
+           for (n = 0; n < need; n++)
+               VTbuffer.ptr[n] = (value[n] & 0xff);
+       }
+    }
 }
 
 static void DoSpecialEnterNotify (register XEnterWindowEvent *ev)
@@ -916,7 +926,7 @@
                                         0644)) < 0)
                        return;
        }
-       screen->logstart = CURRENT_EMU_VAL(screen, Tbptr, bptr);
+       screen->logstart = CURRENT_EMU_VAL(screen, Tbuffer->ptr, VTbuffer.ptr);
        screen->logging = TRUE;
        update_logging();
 }
@@ -938,10 +948,10 @@
        register Char *cp;
        register int i;
 
-       cp = CURRENT_EMU_VAL(screen, Tbptr, bptr);
+       cp = CURRENT_EMU_VAL(screen, Tbuffer->ptr, VTbuffer.ptr);
        if((i = cp - screen->logstart) > 0)
                write(screen->logfd, (char *)screen->logstart, i);
-       screen->logstart = CURRENT_EMU_VAL(screen, Tbuffer, VTbuffer);
+       screen->logstart = CURRENT_EMU_VAL(screen, Tbuffer->buf, VTbuffer.buf);
 }
 
 #endif /* ALLOWLOGGING */
@@ -1733,7 +1743,7 @@
 #ifdef ALLOWLOGGING
        if (screen->logging) {
            FlushLog (screen);
-           screen->logstart = VTbuffer;
+           screen->logstart = VTbuffer.buf;
        }
 #endif
        longjmp(Tekend, 1);
@@ -1747,9 +1757,9 @@
 
     if (!screen->TekEmu) {
 #ifdef ALLOWLOGGING
-       if(screen->logging) {
+       if(screen->logging && TekPtyData()) {
            FlushLog(screen);
-           screen->logstart = Tbuffer;
+           screen->logstart = Tbuffer->buf;
        }
 #endif
        screen->TekEmu = TRUE;
Index: os2main.c
--- xterm-96+/os2main.c Sun Apr 11 16:38:14 1999
+++ xterm-97/os2main.c  Sun Apr 25 16:14:54 1999
@@ -98,8 +98,6 @@
 #include <sys/param.h> /* for NOFILE */
 
 #include <stdio.h>
-#include <setjmp.h>
-
 #include <time.h>
 
 #include <signal.h>
@@ -405,6 +403,10 @@
 {"-ti",                "*decTerminalID",XrmoptionSepArg,       (caddr_t) NULL},
 {"-tm",                "*ttyModes",    XrmoptionSepArg,        (caddr_t) NULL},
 {"-tn",                "*termName",    XrmoptionSepArg,        (caddr_t) NULL},
+#if OPT_WIDE_CHARS
+{"-u8",                "*utf8",        XrmoptionNoArg,         (caddr_t) "2"},
+{"+u8",                "*utf8",        XrmoptionNoArg,         (caddr_t) "0"},
+#endif
 {"-ulc",       "*colorULMode", XrmoptionNoArg,         (caddr_t) "off"},
 {"+ulc",       "*colorULMode", XrmoptionNoArg,         (caddr_t) "on"},
 {"-ut",                "*utmpInhibit", XrmoptionNoArg,         (caddr_t) "on"},
@@ -516,6 +518,9 @@
 { "-ti termid",            "terminal identifier" },
 { "-tm string",            "terminal mode keywords and characters" },
 { "-tn name",              "TERM environment variable name" },
+#if OPT_WIDE_CHARS
+{ "-/+u8",                 "turn on/off UTF-8 mode (implies wide-characters)" },
+#endif
 { "-/+ulc",                "turn off/on display of underline as color" },
 { "-/+ut",                 "turn on/off utmp inhibit (not supported)" },
 { "-/+vb",                 "turn on/off visual bell" },
Index: ptydata.c
--- /dev/null   Sun Jul 17 19:46:18 1994
+++ xterm-97/ptydata.c  Sun Apr 25 19:24:39 1999
@@ -0,0 +1,187 @@
+/*
+ * $XFree86$
+ */
+
+/************************************************************
+
+Copyright 1999 by Thomas E. Dickey <dickey@clark.net>
+
+                        All Rights Reserved
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name(s) of the above copyright
+holders shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization.
+
+********************************************************/
+
+#include <xterm.h>
+#include <data.h>
+
+/*
+ * Check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+ * systems are broken and return EWOULDBLOCK when they should return EAGAIN.
+ * Note that this macro may evaluate its argument more than once.
+ */
+#if defined(EAGAIN) && defined(EWOULDBLOCK)
+#define E_TEST(err) ((err) == EAGAIN || (err) == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define E_TEST(err) ((err) == EAGAIN)
+#else
+#define E_TEST(err) ((err) == EWOULDBLOCK)
+#endif
+#endif
+
+int getPtyData(TScreen *screen, fd_set *select_mask, PtyData *data)
+{
+    int i;
+
+#ifndef AMOEBA
+    if (FD_ISSET (screen->respond, select_mask))
+#else
+    if ((data->cnt = cb_full(screen->tty_outq)) > 0)
+#endif
+    {
+#ifdef ALLOWLOGGING
+       if (screen->logging)
+           FlushLog(screen);
+#endif
+       /* set data->ptr here, in case we need it outside this chunk */
+       data->ptr = DecodedData(data);
+#ifndef AMOEBA
+       data->cnt = read(screen->respond, (char *) data->buf, BUF_SIZE);
+#else
+       if ((data->cnt = cb_gets(screen->tty_outq, data->buf, data->cnt, BUF_SIZE)) == 0) {
+           errno = EIO;
+           data->cnt = -1;
+       }
+#endif
+       if (data->cnt <= 0) {
+           /*
+            * Yes, I know this is a majorly f*ugly hack, however it seems to
+            * be necessary for Solaris x86.  DWH 11/15/94
+            * Dunno why though..
+            */
+#if defined(i386) && defined(SVR4) && defined(sun)
+           if (errno == EIO || errno == 0 )
+#else
+           if (errno == EIO)
+#endif
+               Cleanup (0);
+           else if (!E_TEST(errno))
+               Panic("input: read returned unexpected error (%d)\n", errno);
+       } else if (data->cnt == 0) {
+#if defined(MINIX) || defined(__EMX__)
+           Cleanup(0);
+#else
+           Panic("input: read returned zero\n", 0);
+#endif
+       } else {
+#if OPT_WIDE_CHARS
+           if (screen->utf8_mode) {
+               int j = 0;
+               for (i = 0; i < data->cnt; i++) {
+                   unsigned c = data->buf[i];
+                   /* Combine UTF-8 into Unicode */
+                   /* Incomplete characters silently ignored,
+                    * should probably be better represented by U+fffc
+                    * (replacement character).
+                    */
+                   if (c > 0x7f) {
+                       if (screen->utf_count > 0 && (c & 0xc0) == 0x80) {
+                               screen->utf_char <<= 6;
+                               screen->utf_char |= (c & 0x3f);
+                               screen->utf_count--;
+                               if (screen->utf_count == 0)
+                                   data->buf2[j++] = c = screen->utf_char;
+                       } else {
+                           if ((c & 0xe0) == 0xc0) {
+                               screen->utf_count = 1;
+                               screen->utf_char = (c & 0x1f);
+                           } else if ((c & 0xf0) == 0xe0) {
+                               screen->utf_count = 2;
+                               screen->utf_char = (c & 0x0f);
+                           } else if ((c & 0xf8) == 0xf0) {
+                               screen->utf_count = 3;
+                               screen->utf_char = (c & 0x07);
+                           } else if ((c & 0xfc) == 0xf8) {
+                               screen->utf_count = 4;
+                               screen->utf_char = (c & 0x03);
+                           } else if ((c & 0xfe) == 0xfc) {
+                               screen->utf_count = 5;
+                               screen->utf_char = (c & 0x01);
+                           } else {
+                               screen->utf_count = 0;
+                           }
+                       }
+                   } else {
+                       data->buf2[j++] = c;
+                       screen->utf_count = 0;
+                   }
+               }
+               TRACE(("UTF8 count %d, char %04X input %d/%d bytes\n",
+                       screen->utf_count,
+                       screen->utf_char,
+                       data->cnt, j))
+               data->cnt = j;
+           } else {
+               for (i = 0; i < data->cnt; i++)
+                   data->ptr[i] = data->buf[i];
+           }
+#endif
+           /* read from pty was successful */
+           if (!screen->output_eight_bits) {
+               for (i = 0; i < data->cnt; i++) {
+                   data->ptr[i] &= 0x7f;
+               }
+           }
+           return (data->cnt);
+       }
+    }
+    return 0;
+}
+
+int morePtyData(PtyData *data)
+{
+    return (data->cnt > 0);
+}
+
+int nextPtyData(PtyData *data)
+{
+    (data->cnt)--;
+    return(*(data->ptr)++);
+}
+
+void initPtyData(PtyData *data)
+{
+    data->cnt = 0;
+    data->ptr = DecodedData(data);
+}
+
+/*
+ * Tells how much we have used out of the current buffer
+ */
+unsigned usedPtyData(PtyData *data)
+{
+    return (data->ptr - DecodedData(data));
+}
Index: ptyx.h
--- xterm-96+/ptyx.h    Sun Apr 25 17:28:21 1999
+++ xterm-97/ptyx.h     Sun Apr 25 21:23:52 1999
@@ -132,7 +132,7 @@
 #ifdef __hpux
 #define TTYDEV         "/dev/pty/ttyxx"
 #else  /* !__hpux */
-#if defined(__osf__) || (defined(linux) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1)
+#if defined(__osf__) || (defined(linux) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1))
 #define TTYDEV         "/dev/ttydirs/xxx/xxxxxxxxxxxxxx"
 #else
 #define        TTYDEV          "/dev/ttyxx"
@@ -548,15 +548,6 @@
 
 /***====================================================================***/
 
-#if OPT_TRACE
-#include <trace.h>
-#else
-#define TRACE(p) /*nothing*/
-#define TRACE_CHILD /*nothing*/
-#endif
-
-/***====================================================================***/
-
 #if OPT_VT52_MODE
 #define if_OPT_VT52_MODE(screen, code) if(screen->ansi_level == 0) code
 #else
@@ -578,9 +569,37 @@
 #if OPT_WIDE_CHARS
 #define if_OPT_WIDE_CHARS(screen, code) if(screen->wide_chars) code
 #define PAIRED_CHARS(a,b) a,b
+typedef unsigned short IChar;  /* for 8 or 16-bit characters */
+#undef  ALLOWLOGGING           /* FIXME: not yet */
 #else
 #define if_OPT_WIDE_CHARS(screen, code) /* nothing */
 #define PAIRED_CHARS(a,b) a
+typedef unsigned char IChar;   /* for 8-bit characters */
+#endif
+
+/***====================================================================***/
+
+#define BUF_SIZE 4096
+
+typedef struct {
+       int     cnt;            /* number of chars left to process */
+       IChar * ptr;            /* pointer into decoded data */
+       Char    buf[BUF_SIZE];  /* we read directly into this */
+#if OPT_WIDE_CHARS
+       IChar   buf2[BUF_SIZE]; /* ...and may decode into this */
+#define DecodedData(data) (data)->buf2
+#else
+#define DecodedData(data) (data)->buf
+#endif
+       } PtyData;
+
+/***====================================================================***/
+
+#if OPT_TRACE
+#include <trace.h>
+#else
+#define TRACE(p) /*nothing*/
+#define TRACE_CHILD /*nothing*/
 #endif
 
 /***====================================================================***/
@@ -718,7 +737,9 @@
 #endif
 #if OPT_WIDE_CHARS
        Boolean         wide_chars;     /* true when 16-bit chars       */
-       Boolean         utf8_mode;      /* use UTF-8 decode/encode      */
+       int             utf8_mode;      /* use UTF-8 decode/encode: 0-2 */
+       int             utf_count;      /* state of utf_char */
+       IChar           utf_char;       /* in-progress character */
 #endif
        int             border;         /* inner border                 */
        Cursor          arrow;          /* arrow cursor                 */
@@ -1053,8 +1074,6 @@
     TekPart tek;
 } TekWidgetRec, *TekWidget;
 #endif /* OPT_TEK4014 */
-
-#define BUF_SIZE 4096
 
 /*
  * terminal flags
Index: screen.c
--- xterm-96+/screen.c  Sun Apr 11 16:38:14 1999
+++ xterm-97/screen.c   Sun Apr 25 20:55:06 1999
@@ -281,7 +281,7 @@
 void
 ScreenWrite (
        TScreen *screen,
-       Char *str,
+       PAIRED_CHARS(Char *str, Char *str2),
        register unsigned flags,
        register unsigned cur_fg_bg,
        register int length)            /* length of string */
@@ -320,6 +320,16 @@
        } else {
                memcpy(col, str, length);
        }
+       if_OPT_WIDE_CHARS(screen,{
+               Char *wc;
+               if (str2 != 0
+                && (wc = SCRN_BUF_WIDEC(screen, screen->cur_row) + screen->cur_col) != 0) {
+                       if (flags & INVISIBLE)
+                               memset(wc, ' ', length);
+                       else
+                               memcpy(wc, str2, length);
+               }
+       })
 
        flags &= ATTRIBUTES;
        flags |= CHARDRAWN;
@@ -366,8 +376,10 @@
                                        screen->save_ptr[i+j] = 0;
                                else if (j == OFF_ATTRS)
                                        memset(screen->save_ptr[i+j], flags, size);
+#if OPT_ISO_COLORS
                                else if (j == OFF_COLOR)
                                        memset(screen->save_ptr[i+j], xtermColorPair(), size);
+#endif
                                else
                                        bzero( screen->save_ptr[i+j], size);
                        }
@@ -745,10 +757,12 @@
                 || (cb[col] != cs)
 #endif
                 ) {
-                  TRACE(("%s @%d, calling drawXtermText %d..%d:%.*s\n",
+                  TRACE(("%s @%d, calling drawXtermText %d..%d:%s\n",
                        __FILE__, __LINE__,
                        lastind, col,
-                       col - lastind, &chars[lastind]))
+                       visibleChars(
+                               PAIRED_CHARS(&chars[lastind], &widec[lastind]),
+                               col - lastind)))
                   x = drawXtermText(screen, flags, gc, x, y,
                        cs,
                        PAIRED_CHARS(&chars[lastind], &widec[lastind]),
@@ -777,10 +791,10 @@
                        chars[col] = ' ';
           }
 
-          TRACE(("%s @%d, calling drawXtermText %d..%d:%.*s\n",
+          TRACE(("%s @%d, calling drawXtermText %d..%d:%s\n",
                __FILE__, __LINE__,
                lastind, col,
-               col - lastind, &chars[lastind]))
+               visibleChars(PAIRED_CHARS(&chars[lastind], &widec[lastind]), col - lastind)))
           drawXtermText(screen, flags, gc, x, y,
                cs,
                PAIRED_CHARS(&chars[lastind], &widec[lastind]),
Index: termcap
--- xterm-96+/termcap   Mon Mar 29 13:36:18 1999
+++ xterm-97/termcap    Sat Apr 24 09:57:03 1999
@@ -32,7 +32,7 @@
        :k;=\E[21~:F1=\E[23~:F2=\E[24~:\
        :kn#12:\
        :kH=\EOF::@7=\EOF:kh=\EOH:\
-       :@0=\EOH:kI=\E[2~:kD=\E[3~:\
+       :@0=\EOH:kI=\E[2~:kD=^?:\
        :*6=\EOF:kP=\E[5~:kN=\E[6~:\
        :km:\
        :kb=^H:ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:\
@@ -94,7 +94,7 @@
        :F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:F5=\E[28~:\
        :F6=\E[29~:F7=\E[31~:F8=\E[32~:F9=\E[33~:FA=\E[34~:\
        :kn#20:\
-       :@0=\E[1~:kI=\E[2~:kD=\E[3~:\
+       :@0=\E[1~:kI=\E[2~:kD=^?:\
        :*6=\E[4~:kP=\E[5~:kN=\E[6~:\
        :km:\
        :kb=^H:ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:\
Index: terminfo
--- xterm-96+/terminfo  Mon Mar 29 13:36:18 1999
+++ xterm-97/terminfo   Sat Apr 24 09:58:17 1999
@@ -603,7 +603,7 @@
        kcud1=\EOB,
        kcuf1=\EOC,
        kcuu1=\EOA,
-       kdch1=\E[3~,
+       kdch1=\177,
        kend=\E[4~,
        kf1=\EOP,
        kf10=\E[21~,
@@ -708,7 +708,7 @@
        kcud1=\EOB,
        kcuf1=\EOC,
        kcuu1=\EOA,
-       kdch1=\E[3~,
+       kdch1=\177,
        kdl1=\E[31~,
        kel=\E[8~,
        kend=\E[4~,
Index: testxmc.c
--- xterm-96+/testxmc.c Sun Apr 11 16:38:14 1999
+++ xterm-97/testxmc.c  Sat Apr 24 15:23:10 1999
@@ -93,14 +93,16 @@
 
 void Mark_XMC(register TScreen *screen, int param)
 {
-       static Char *glitch;
+       static IChar *glitch;
        Boolean found = FALSE;
        Char my_attrs = (screen->xmc_attributes & XMC_FLAGS);
        Char whichone = 0;
 
        if (glitch == 0) {
-               glitch = (Char *)malloc(screen->xmc_glitch);
-               memset(glitch, XMC_GLITCH, screen->xmc_glitch);
+               unsigned len = screen->xmc_glitch;
+               glitch = (IChar *)malloc(len * sizeof(IChar));
+               while (len--)
+                       glitch[len] = XMC_GLITCH;
        }
        switch (param) {
        case -1:/* DEFAULT */
@@ -135,7 +137,7 @@
                unsigned save = term->flags;
                term->flags ^= whichone;
                TRACE(("XMC Writing glitch (%d/%d) after SGR %d\n", my_attrs, whichone, param))
-               dotext(screen, '?', PAIRED_CHARS(glitch, 0), screen->xmc_glitch);
+               dotext(screen, '?', glitch, screen->xmc_glitch);
                term->flags = save;
        }
 }
Index: trace.c
--- xterm-96+/trace.c   Sun Oct 25 13:31:39 1998
+++ xterm-97/trace.c    Sun Apr 25 20:51:31 1999
@@ -30,10 +30,6 @@
 /*
  * debugging support via TRACE macro.
  */
-#ifdef HAVE_CONFIG_H
-#include <xtermcfg.h>
-#endif
-
 #include <stdio.h>
 #include <time.h>
 #include <unistd.h>
@@ -90,4 +86,66 @@
                (void)fflush(stderr);
        }
        va_end(ap);
+}
+
+char *
+visibleChars(PAIRED_CHARS(Char *buf, Char *buf2), unsigned len)
+{
+       static char *result;
+       static unsigned used;
+       unsigned limit = ((len + 1) * 8) + 1;
+       char *dst;
+
+       if (limit > used) {
+               used = limit;
+               result = XtRealloc(result, used);
+       }
+       dst = result;
+       while (len--) {
+               unsigned value = *buf++;
+#if OPT_WIDE_CHARS
+               if (buf2 != 0) {
+                       value |= (*buf2 << 8);
+                       buf2++;
+               }
+               if (value > 127)
+                       sprintf(dst, "\\u+%04X", value);
+               else
+#endif
+               if (value < 32 || (value > 127 && value < 160))
+                       sprintf(dst, "\\%03o", value);
+               else
+                       sprintf(dst, "%c", value);
+               dst += strlen(dst);
+       }
+       return result;
+}
+
+char *
+visibleIChar(IChar *buf, unsigned len)
+{
+       static char *result;
+       static unsigned used;
+       unsigned limit = ((len + 1) * 6) + 1;
+       char *dst;
+
+       if (limit > used) {
+               used = limit;
+               result = XtRealloc(result, used);
+       }
+       dst = result;
+       while (len--) {
+               unsigned value = *buf++;
+#if OPT_WIDE_CHARS
+               if (value > 127)
+                       sprintf(dst, "\\u+%04X", value);
+               else
+#endif
+               if (value < 32 || (value > 127 && value < 160))
+                       sprintf(dst, "\\%03o", value);
+               else
+                       sprintf(dst, "%c", value);
+               dst += strlen(dst);
+       }
+       return result;
 }
Index: trace.h
--- xterm-96+/trace.h   Sun Oct 25 13:31:39 1998
+++ xterm-97/trace.h    Sun Apr 25 16:59:59 1999
@@ -37,12 +37,17 @@
 #include <xtermcfg.h>
 #endif
 
+#include <ptyx.h>
+
 extern void    Trace ( char *, ... )
 #ifdef GCC_PRINTF
        __attribute__ ((format(printf,1,2)))
 #endif
        ;
 #define TRACE(p) Trace p;
+
+extern char *  visibleChars (PAIRED_CHARS(Char *buf, Char *buf2), unsigned len);
+extern char *  visibleIChar (IChar *, unsigned);
 
 extern char    *trace_who;
 #define TRACE_CHILD int tracing_child = (trace_who = "child") != 0;
Index: util.c
--- xterm-96+/util.c    Sun Apr 25 17:28:21 1999
+++ xterm-97/util.c     Sun Apr 25 21:24:19 1999
@@ -1360,7 +1360,7 @@
        if (text2 == 0) {
                static Char *dbuf;
                static unsigned dlen;
-               if (dlen < len) {
+               if (dlen <= len) {
                        dlen = (len + 1) * 2;
                        dbuf = XtRealloc(dbuf, dlen);
                        memset(dbuf, 0, dlen);
@@ -1455,11 +1455,12 @@
                        SAVE_FONT_INFO (screen);
 
                } else {        /* simulate double-sized characters */
-                       Char *temp = (Char *) malloc(2 * len);
+                       unsigned need = 2 * len;
+                       Char *temp = (Char *) malloc(need);
                        Char *wide = 0;
                        int n = 0;
                        if_OPT_WIDE_CHARS(screen,{
-                               wide = (Char *)malloc(2 * len);
+                               wide = (Char *)malloc(need);
                        })
                        while (len--) {
                                if_OPT_WIDE_CHARS(screen,{
@@ -1525,9 +1526,10 @@
 
        /* If the font is complete, draw it as-is */
        if (screen->fnt_boxes) {
-               TRACE(("drawtext%c[%4d,%4d] (%d) %d:%.*s\n",
+               TRACE(("drawtext%c[%4d,%4d] (%d) %d:%s\n",
                        screen->cursor_state == OFF ? ' ' : '*',
-                       y, x, chrset, len, (int)len, text))
+                       y, x, chrset, len,
+                       visibleChars(PAIRED_CHARS(text, text2), len)))
                y += FontAscent(screen);
 
 #if OPT_WIDE_CHARS
Index: version.h
--- xterm-96+/version.h Sun Apr 25 17:28:21 1999
+++ xterm-97/version.h  Sun Apr 25 21:24:36 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   96
-#define XFREE86_VERSION "XFree86 3.9Pj"
+#define XTERM_PATCH   97
+#define XFREE86_VERSION "XFree86 3.9Pk"
Index: xterm.h
--- xterm-96+/xterm.h   Sun Apr 11 16:38:14 1999
+++ xterm-97/xterm.h    Sun Apr 25 17:25:34 1999
@@ -131,6 +131,7 @@
 
 /* Tekproc.c */
 extern int TekInit (void);
+extern int TekPtyData (void);
 extern void ChangeTekColors (TScreen *screen, ScrnColors *pNew);
 extern void TCursorToggle (int toggle);
 extern void TekCopy (void);
@@ -175,7 +176,7 @@
 extern void ToggleAlternate (TScreen *screen);
 extern void VTReset (int full, int saved);
 extern void VTRun (void);
-extern void dotext (TScreen *screen, int charset, PAIRED_CHARS(Char *buf, Char *buf2), Cardinal len);
+extern void dotext (TScreen *screen, int charset, IChar *buf, Cardinal len);
 extern void resetCharsets (TScreen *screen);
 extern void set_cursor_gcs (TScreen *screen);
 extern void unparseputc (int c, int fd);
@@ -190,7 +191,7 @@
 
 /* charsets.c */
 extern unsigned xtermCharSetIn (unsigned code, int charset);
-extern int xtermCharSetOut (Char *buf, Char *ptr, char charset);
+extern int xtermCharSetOut (IChar *buf, IChar *ptr, char charset);
 
 /* cursor.c */
 extern void CarriageReturn (TScreen *screen);
@@ -296,6 +297,8 @@
 extern void StartLog (TScreen *screen);
 extern void CloseLog (TScreen *screen);
 extern void FlushLog (TScreen *screen);
+#else
+#define FlushLog(screen) /*nothing*/
 #endif
 
 /* print.c */
@@ -304,6 +307,13 @@
 extern void xtermMediaControl (int param, int private_seq);
 extern void xtermPrintScreen (void);
 
+/* ptydata.c */
+extern int getPtyData (TScreen *screen, fd_set *select_mask, PtyData *data);
+extern int morePtyData (PtyData *data);
+extern int nextPtyData (PtyData *data);
+extern unsigned usedPtyData(PtyData *data);
+extern void initPtyData (PtyData *data);
+
 /* screen.c */
 extern Bool non_blank_line (ScrnBuf sb, int row, int col, int len);
 extern ScrnBuf Allocate (int nrow, int ncol, Char **addr);
@@ -311,7 +321,7 @@
 extern int ScrnTstWrapped (TScreen *screen, int row);
 extern size_t ScrnPointers (TScreen *screen, size_t len);
 extern void ClearBufRows (TScreen *screen, int first, int last);
-extern void ScreenWrite (TScreen *screen, Char *str, unsigned flags, unsigned cur_fg_bg, int length);
+extern void ScreenWrite (TScreen *screen, PAIRED_CHARS(Char *str, Char *str2), unsigned flags, unsigned cur_fg_bg, int length);
 extern void ScrnClrWrapped (TScreen *screen, int row);
 extern void ScrnDeleteChar (TScreen *screen, int n, int size);
 extern void ScrnDeleteLine (TScreen *screen, ScrnBuf sb, int n, int last, int size, int where);
Index: xterm.log.html
--- xterm-96+/xterm.log.html    Sun Apr 25 17:28:21 1999
+++ xterm-97/xterm.log.html     Sun Apr 25 21:25:38 1999
@@ -41,6 +41,7 @@
 xc/programs/Xserver/hw/xfree86).
 
 <UL>
+<LI><A HREF="#xterm_97">Patch #97 - 1999/4/25 - XFree86 3.9Pk</A>
 <LI><A HREF="#xterm_96">Patch #96 - 1999/4/19 - XFree86 3.9Pj</A>
 <LI><A HREF="#xterm_95">Patch #95 - 1999/4/5 - XFree86 3.9Ph</A>
 <LI><A HREF="#xterm_94">Patch #94 - 1999/3/27 - XFree86 3.9Pf</A>
@@ -140,6 +141,63 @@
 <LI><A HREF="#xterm_01">Patch #1 - 1996/1/6</A>
 </UL>
 
+<H1><A NAME="xterm_97">Patch #97 - 1999/4/25 - XFree86 3.9Pk</A></H1>
+<ul>
+       <li>add configure script test for -lutil, needed for openpty call when
+         configuring xterm for Glibc-2.1 and Unix98 PTY's (first reported by
+         Martin Lorentz" &lt;m.lorentz@w12.link-goe.de&gt;).
+
+       <li>completely parenthesize ifdef expressions for Glibc (suggested by
+         Bob Maynard).
+
+       <li>add initial-erase options (-ie, +ie) to help message (reported by
+         Vikas Agnihotri).
+
+       <li>remove duplicate definition of USE_USG_PTYS (reported by Jeremy
+         Buhler).
+
+       <li>change termcap <em>kD</em> and terminfo <em>kdch1</em> to a DEL
+         (\177).
+         I overlooked this when separating the styles of keyboard with
+         the <em>sunKeyboard</em> resources in patch #94, so that it normally
+         matches the value of the stty erase character:
+         <ul>
+         <li>Reported by Jae Gangemi &lt;jgangemi@ccf.rutgers.edu&gt;,
+           this caused emacs to not process the DEL properly, combining it
+           with succeeding characters.
+         <li>This does not appear to be related to a problem which I have
+           found with <em>screen</em>, which translates the stty erase into
+           the termcap <em>kD</em> or terminfo <em>kdch1</em> value
+           (depending on how it is linked)
+           if the $TERMCAP variable is set when <em>screen</em> is invoked.
+         </ul>
+
+       <li>add command-line options for enabling UTF-8 mode: -u8 and +u8.
+         The more obvious -utf8 and +utf8 would conflict with xterm's
+         -ut and +ut (utmp) options.
+
+         The utf8 changes were requested by Markus Kuhn
+         &lt;Markus.Kuhn@cl.cam.ac.uk&gt;.  This patch does not complete utf8
+         implementation, but makes it usable, i.e., display and refresh work,
+         and I am able to display the test cases which Markus provides.
+         More work is needed to complete this feature:
+         <ul>
+         <li>the control sequences for switching in/out of UTF-8 mode are
+           partly implemented (don't use them).  Similarly, the switching
+           between vt100 and tek4014 emulations when UTF-8 mode is enabled
+           will not work properly.
+           <p>
+           You must use the -u8 command line option
+           to use this feature, as well as compile with the OPT_WIDE_CHARS
+           definition.
+         <li>cut/paste only copies 8-bit characters.
+         <li>logging is disabled in the wide-character configuration
+         <li>printing only writes 8-bit characters.
+         <li>input only does 8-bit characters.  This is the area that I know
+           least about.
+         </ul>
+</ul>
+
 <H1><A NAME="xterm_96">Patch #96 - 1999/4/19 - XFree86 3.9Pj</A></H1>
 <ul>
        <li>modify Makefile.in to work with configure script's --srcdir option.
@@ -154,7 +212,7 @@
          bold version of that using a one-pixel offset overstrike
          (reported by Henrik Harmsen &lt;harmsen@erv.ericsson.se&gt;).
 
-       <li>correct horizontal spacing of doublewidth line-drawing characters
+       <li>correct horizontal spacing of double width line-drawing characters
          that xterm simulates.
 
        <li>improve support for Unix98 PTY's, using patch in Debian bug report
@@ -170,7 +228,7 @@
 <ul>
        <li>modify primary DA response to allow a '1' parameter.
 
-       <li>add printer and national replacment character sets to VT220
+       <li>add printer and national replacement character sets to VT220
          primary DA response.
 
        <li>document primary and secondary DA responses in ctlseqs.ms
@@ -185,13 +243,13 @@
        <li>limit user-defined keys (DECUDK) to VT220-style keyboard
          when sunKeyBoard resource is true.
 
-       <li>modify ifdef's for Linux-2.2.x with GLibc-2.1 to work with
+       <li>modify ifdef's for Linux-2.2.x with Glibc-2.1 to work with
          Glibc-2.1 and no Unix98 PTY support (patch from From Andreas Jaeger
          &lt;aj@arthur.rhein-neckar.de&gt;)
 
        <li>add optional feature (resource and command-line options) to make
-         xterm use the pty's sense of erase character on startup, rather than
-         requiring it to be \177, or set the pty's erase character to match
+         xterm use the PTY's sense of erase character on startup, rather than
+         requiring it to be \177, or set the PTY's erase character to match
          xterm's configuration.  Note that while $TERMCAP is modified to
          reflect the actual configuration, the terminfo kdch1 string is not
          (request by Dirk H Hohndel &lt;hohndel@suse.de&gt;)
@@ -385,7 +443,7 @@
 
        <li>correct missing initialization of tekInhibit and tekSmall resources.
 
-       <li>correct ifdefs in charproc.c for XtNgeometry and XtCGeometry
+       <li>correct ifdef's in charproc.c for XtNgeometry and XtCGeometry
          (reported by Bram Moolenaar).
 </ul>
 
@@ -599,7 +657,7 @@
 <H1><A NAME="sync_83">Resync #83 - 1998/10/7 - XFree86 3.3.2e</A></H1>
 
 Merge changes through patch #83 with the 3.3.2e version.  This follows a
-patch by Matthieu Herrb &lt;matthieu@laas.fr&gt; to add checks for nonnull
+patch by Matthieu Herrb &lt;matthieu@laas.fr&gt; to add checks for non-null
 return from malloc.
 
 <H1><A NAME="xterm_83">Patch #83 - 1998/8/25 - XFree86 3.9Nb</A></H1>
@@ -659,7 +717,7 @@
 </ul>
 From resync with XFree86 3.9Aj:
 <ul>
-       <li>correcton to patch #73, supply missing #else for fallback definitions
+       <li>correction to patch #73, supply missing #else for fallback definitions
          of size_t, time_t (Robin Cutshaw &lt;robin@intercore.com&gt;).
 </ul>
 
@@ -702,7 +760,7 @@
          backarrow key from sending a 127 for the delete key (the 'remove'
          escape sequence was being sent instead).
 
-       <li>use return-value from getutid() rather than the parameter, to work on
+       <li>use return-value from getuid() rather than the parameter, to work on
          systems which do not update the latter (patch by Kevin Buhr
          &lt;buhr@mozart.stat.wisc.edu&gt;)
 
@@ -853,7 +911,7 @@
        <li>define USE_SYSV_ENVVARS for HP-UX, curses does not use $TERMCAP (patch
          by Tor Lillqvist).
 
-       <li>on HP-UX, use the /dev/ptym/clone device to allocate ptys.  Works
+       <li>on HP-UX, use the /dev/ptym/clone device to allocate PTY's.  Works
          both on HP-UX 9 and 10.  (patch by Tor Lillqvist).
 
        <li>modify configure script to obtain the $(EXTRA_LOADFLAGS) value from
@@ -1161,7 +1219,7 @@
          resource, text is highlighted by changing only the background color,
          rather than using reverse video.  I find this easier to read,
          especially when selecting multi-colored text, and it is similar to
-         the way netscape shows selections.
+         the way Netscape shows selections.
 
        <LI>Most of the code changes are under "#if OPT_HIGHLIGHT_COLOR".  The
          principal exception is in screen.c, where I added a couple calls to
@@ -1288,7 +1346,7 @@
          Hiebert &lt;darren@hmi.com&gt;.
 
        <LI>review diffs between main.c and os2main.c, to make them more alike.
-         (applies some minor bugfixes to OS/2's version).
+         (applies some minor bug-fixes to OS/2's version).
 
        <LI>add missing quotes in memmove/bcopy configure test
 </UL>
@@ -1583,7 +1641,7 @@
        <LI>the doublesize character support uses the normal font (using scaled
          fonts will be another patch) with blanks to simulate doublesize
          characters.  This patch does most of the global changes that'll be
-         required.  I've hidden most of the details in macros and ifdefs so
+         required.  I've hidden most of the details in macros and ifdef's so
          it's easy to configure out (part of the patch is a configure option
          for that purpose).
 
@@ -1653,7 +1711,7 @@
          2.4, possibly IRIX - sorry network was down today, but I did test
          an earlier version yesterday).
 
-       <LI>enables/disables the configuration ifdefs for ANSI color and VT52
+       <LI>enables/disables the configuration ifdef's for ANSI color and VT52
          emulation.
 </UL>
 It does not make tests for the things that imake does (that's another project),
Index: xterm.man
--- xterm-96+/xterm.man Sun Apr 25 17:28:21 1999
+++ xterm-97/xterm.man  Sun Apr 25 21:25:53 1999
@@ -518,6 +518,14 @@
 environment variable.  This terminal type must exist in the \fItermcap(5)\fP
 database and should have \fIli#\fP and \fIco#\fP entries.
 .TP 8
+.B \-u8
+This option sets the \fButf8\fP resource.
+When \fButf8\fP is set, xterm interprets incoming data as UTF-8.
+This sets \fBwideChars\fP as a side-effect.
+.TP 8
+.B \+u8
+This option resets the \fButf8\fP resource.
+.TP 8
 .B "\-ulc"
 This option disables the display of characters with underline attribute as
 color rather than with underlining.
@@ -544,6 +552,11 @@
 .TP 8
 .B \-wc
 This option sets the \fBwideChars\fP resource.
+When \fBwideChars\fP is set, xterm maintains internal structures for 16-bit
+characters.
+.TP 8
+.B \+wc
+This option resets the \fBwideChars\fP resource.
 .TP 8
 .B \-wf
 This option indicates that \fIxterm\fP should wait for the window to be mapped
@@ -1242,6 +1255,13 @@
 This specifies whether or not text with the underline attribute should be
 underlined.  It may be desirable to disable underlining when color is being
 used for the underline attribute.
+.TP 8
+.B "utf8 (\fPclass\fB Utf8)"
+This specifies whether \fIxterm\fP xterm will run in UTF-8 mode.
+If you set this resource, \fIxterm\fP also sets the \fBwideChars\fP resource as a side-effect.
+When set via a resource, \fIxterm\fP cannot be switched via control sequences out of UTF-8 mode.
+The default is ``0'' (off).
+Any other value will turn on UTF-8 mode.
 .TP 8
 .B "visualBell (\fPclass\fB VisualBell)"
 Specifies whether or not a visible bell (i.e. flashing) should be used instead