xterm-89.patch.txt

# ------------------------------------------------------------------------------
#  charproc.c     |    8 +--
#  doublechr.c    |   79 +++++++++++++++++++++++++++++++++++++-
#  fontutils.c    |  112 ++++++++++++++++++++++++++++++++++++-------------------
#  fontutils.h    |    4 +
#  main.c         |   10 ++--
#  ptyx.h         |   10 +++-
#  resize.c       |    4 -
#  util.c         |   54 +++++++++++++++++++++++---
#  version.h      |    2 
#  xterm.h        |    5 +-
#  xterm.log.html |   32 +++++++++++++++
#  xterm.man      |    4 +
#  12 files changed, 257 insertions, 67 deletions
# ------------------------------------------------------------------------------
Index: charproc.c
--- xterm-88+/charproc.c        Sun Oct 25 13:31:39 1998
+++ xterm-89/charproc.c Wed Nov 18 20:35:49 1998
@@ -4419,7 +4419,7 @@
                }
        }
 
-       TRACE(("%s @%d, calling drawXtermText\n", __FILE__, __LINE__))
+       TRACE(("%s @%d, ShowCursor calling drawXtermText\n", __FILE__, __LINE__))
 
        drawXtermText(screen, flags, currentGC,
                x = CurCursorX(screen, screen->cur_row, screen->cur_col),
@@ -4485,11 +4485,11 @@
        if (c == 0)
                c = ' ';
 
-       TRACE(("%s @%d, calling drawXtermText\n", __FILE__, __LINE__))
+       TRACE(("%s @%d, HideCursor calling drawXtermText\n", __FILE__, __LINE__))
        drawXtermText(screen, flags, currentGC,
-               CursorX(screen, screen->cursor_col),
+               CurCursorX(screen, screen->cursor_row, screen->cursor_col),
                CursorY(screen, screen->cursor_row),
-               curXtermChrSet(screen->cur_row),
+               curXtermChrSet(screen->cursor_row),
                &c, 1);
 
        screen->cursor_state = OFF;
Index: doublechr.c
--- xterm-88+/doublechr.c       Sun Oct 25 13:31:39 1998
+++ xterm-89/doublechr.c        Fri Nov 20 06:22:59 1998
@@ -36,6 +36,7 @@
 
 #include <xterm.h>
 #include <data.h>
+#include <fontutils.h>
 
 /*
  * The first column is all that matters for double-size characters (since the
@@ -50,10 +51,19 @@
 {
        register TScreen *screen = &term->screen;
        int curcol = screen->cur_col;
+       int currow = screen->cur_row;
        int len = screen->max_col + 1;
        int width = len;
+       unsigned oldChrSet = SCRN_BUF_CSETS(screen, currow)[0];
 
-       TRACE(("repaint_line(%2d,%2d) (%d)\n", screen->cur_row, screen->cur_col, newChrSet))
+       /*
+        * Ignore repetition.
+        */
+       if (oldChrSet == newChrSet)
+               return;
+
+       TRACE(("repaint_line(%2d,%2d) (%d)\n", currow, screen->cur_col, newChrSet))
+       HideCursor();
 
        /* If switching from single-width, keep the cursor in the visible part
         * of the line.
@@ -64,11 +74,24 @@
                        curcol = width;
        }
 
+       /*
+        * ScrnRefresh won't paint blanks for us if we're switching between a
+        * single-size and double-size font.
+        */
+       if (CSET_DOUBLE(oldChrSet) != CSET_DOUBLE(newChrSet)) {
+               ClearCurBackground(
+                       screen,
+                       CursorY (screen, currow),
+                       CurCursorX (screen, currow, 0),
+                       FontHeight(screen),
+                       len * CurFontWidth(screen,currow));
+       }
+
        /* FIXME: do VT220 softchars allow double-sizes? */
-       memset(SCRN_BUF_CSETS(screen, screen->cur_row), newChrSet, len);
+       memset(SCRN_BUF_CSETS(screen, currow), newChrSet, len);
 
        screen->cur_col = 0;
-       ScrnRefresh (screen, screen->cur_row, 0, 1, len, True);
+       ScrnRefresh (screen, currow, 0, 1, len, True);
        screen->cur_col = curcol;
 }
 #endif
@@ -106,3 +129,53 @@
        repaint_line(CSET_DWL);
 #endif
 }
+
+
+#if OPT_DEC_CHRSET
+/*
+ * Lookup/cache a GC for the double-size character display.  We save up to
+ * NUM_CHRSET values.
+ */
+GC
+xterm_DoubleGC(unsigned chrset, unsigned flags, GC old_gc)
+{
+       XGCValues gcv;
+       register TScreen *screen = &term->screen;
+       unsigned long mask = (GCForeground | GCBackground | GCFont);
+       int n = (chrset % NUM_CHRSET);
+       char *name = xtermSpecialFont(flags, chrset);
+
+       if (name == 0)
+               return 0;
+
+       if (screen->double_fn[n] != 0) {
+               if (!strcmp(screen->double_fn[n], name)) {
+                       if (screen->double_fs[n] != 0) {
+                               XCopyGC(screen->display, old_gc, ~GCFont, screen->double_gc[n]);
+                               return screen->double_gc[n];
+                       }
+               }
+       }
+       screen->double_fn[n] = name;
+
+       if (screen->double_fs[n] != 0) {
+               XFreeFont(screen->display, screen->double_fs[n]);
+               screen->double_fs[n] = 0;
+       }
+
+       TRACE(("xterm_DoubleGC %s %d: %s\n", flags&BOLD ? "BOLD" : "NORM", chrset, name))
+
+       if ((screen->double_fs[n] = XLoadQueryFont (screen->display, name)) == 0)
+               return 0;
+       TRACE(("-> OK\n"))
+
+       gcv.graphics_exposures = TRUE;  /* default */
+       gcv.font       = screen->double_fs[n]->fid;
+       gcv.foreground = screen->foreground;
+       gcv.background = term->core.background_pixel;
+
+       screen->double_gc[n] = XCreateGC (screen->display, TextWindow(screen), mask, &gcv);
+       XCopyGC(screen->display, old_gc, ~GCFont, screen->double_gc[n]);
+       return screen->double_gc[n];
+}
+#endif
Index: fontutils.c
--- xterm-88+/fontutils.c       Sun Nov  1 14:10:30 1998
+++ xterm-89/fontutils.c        Wed Nov 18 20:25:57 1998
@@ -121,6 +121,7 @@
 get_font_name_props(Display *dpy, XFontStruct *fs)
 {
        static FontNameProperties props;
+       static char *last_name;
 
        register XFontProp *fp;
        register int i;
@@ -141,6 +142,13 @@
                return 0;
 
        /*
+        * XGetAtomName allocates memory - don't leak
+        */
+       if (last_name != 0)
+               XFree(last_name);
+       last_name = name;
+
+       /*
        * Now split it up into parts and put them in
        * their places. Since we are using parts of
        * the original string, we must not free the Atom Name
@@ -222,59 +230,86 @@
      return ret;
 }
 
-#if 0
 #ifdef OPT_DEC_CHRSET
 /*
  * Take the given font props and try to make a well formed font name specifying
- * the same base font but changed depending on the given attributes and lflags.
+ * the same base font but changed depending on the given attributes and chrset.
  *
  * For double width fonts, we just double the X-resolution, for double height
  * fonts we double the pixel-size and Y-resolution
  */
 char *
-special_font_name(FontNameProperties *props, unsigned char atts,
-                 LineFlagsElem lflags)
+xtermSpecialFont(unsigned atts, unsigned chrset)
 {
-     char tmp[MAX_FONTNAME];
-     char *ret;
+#if OPT_TRACE
+       static char old_spacing[80];
+       static FontNameProperties old_props;
+#endif
+       TScreen *screen = &term->screen;
+       FontNameProperties *props;
+       char tmp[MAX_FONTNAME];
+       char *ret;
+       char *width;
+       int pixel_size;
+       int res_x;
+       int res_y;
+
+       props = get_font_name_props(screen->display, screen->fnt_norm);
+       if (props == 0)
+               return 0;
+
+       pixel_size = props->pixel_size;
+       res_x = props->res_x;
+       res_y = props->res_y;
+       if (atts & BOLD)
+               width = "bold";
+       else
+               width = props->width;
+
+       if (CSET_DOUBLE(chrset))
+               res_x *= 2;
+
+       if (chrset == CSET_DHL_TOP 
+        || chrset == CSET_DHL_BOT) {
+               res_y *= 2;
+               pixel_size *= 2;
+       }
 
-     char *width;
-     int pixel_size = props->pixel_size;
-     int res_x = props->res_x;
-     int res_y = props->res_y;
-
-     if (atts & ATT_BOLD)
-         width = "bold";
-     else
-         width = props->width;
-
-     if (lflags & LINE_D_WIDE)
-         res_x *= 2;
-
-     if (lflags & (LINE_D_UPPER | LINE_D_LOWER)) {
-         res_x *= 2;
-         res_y *= 2;
-         pixel_size *= 2;
-     }
+#if OPT_TRACE
+       if (old_props.res_x      != res_x
+        || old_props.res_x      != res_y
+        || old_props.pixel_size != pixel_size
+        || strcmp(old_props.spacing, props->spacing)) {
+               TRACE(("xtermSpecialFont(atts = %#x, chrset = %#x)\n", atts, chrset))
+               TRACE(("res_x      = %d\n", res_x))
+               TRACE(("res_y      = %d\n", res_y))
+               TRACE(("point_size = %s\n", props->point_size))
+               TRACE(("pixel_size = %d\n", pixel_size))
+               TRACE(("spacing    = %s\n", props->spacing))
+               old_props.res_x      = res_x;
+               old_props.res_x      = res_y;
+               old_props.pixel_size = pixel_size;
+               old_props.spacing    = strcpy(old_spacing, props->spacing);
+       }
+#endif
 
-     sprintf(tmp, "%s-%s-%s-%d-%s-%d-%d-%s-*-%s",
-            props->beginning,
-            width,
-            props->middle,
-            pixel_size,
-            props->point_size,
-            res_x,
-            res_y,
-            props->spacing,
-            props->end);
+       sprintf(tmp, "%s-%s-%s-%d-%s-%d-%d-%s-*-%s",
+               props->beginning,
+               width,
+               props->middle,
+               pixel_size,
+               props->point_size,
+               res_x,
+               res_y,
+               props->spacing,
+               props->end);
 
-     ret = XtMalloc(strlen(tmp) + 1);
-     strcpy(ret, tmp);
+       ret = XtMalloc(strlen(tmp) + 1);
+       strcpy(ret, tmp);
 
-     return ret;
+       return ret;
 }
 #endif /* OPT_DEC_CHRSET */
-#endif
 
 /*
  * Double-check the fontname that we asked for versus what the font server
@@ -330,6 +365,7 @@
        Bool doresize,
        int fontnum)
 {
+       /* FIXME: use XFreeFontInfo */
        FontNameProperties *fp;
        XFontStruct *nfs = NULL;
        XFontStruct *bfs = NULL;
Index: fontutils.h
--- xterm-88+/fontutils.h       Sun Oct 25 13:31:39 1998
+++ xterm-89/fontutils.h        Tue Nov  3 21:40:32 1998
@@ -43,4 +43,8 @@
 extern void xtermUpdateFontInfo (TScreen *screen, Bool doresize);
 extern void xtermSetCursorBox (TScreen *screen);
 
+#if OPT_DEC_CHRSET
+extern char *xtermSpecialFont(unsigned atts, unsigned chrset);
+#endif
+
 #endif /* included_fontutils_h */
Index: main.c
--- xterm-88+/main.c    Sun Oct 25 13:31:39 1998
+++ xterm-89/main.c     Fri Nov 20 06:23:47 1998
@@ -3122,7 +3122,7 @@
                               sizeof(utmp.ut_name));
 
                utmp.ut_pid = getpid();
-#if defined(SVR4) || defined(SCO325) || (defined(linux) && __GLIBC__ >= 2)
+#if defined(SVR4) || defined(SCO325) || (defined(linux) && __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;
@@ -3138,7 +3138,7 @@
                if (term->misc.login_shell)
                    updwtmpx(WTMPX_FILE, &utmp);
 #else
-#if defined(linux) && __GLIBC__ >= 2
+#if defined(linux) && __GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
                if (term->misc.login_shell)
                    updwtmp(etc_wtmp, &utmp);
 #else
@@ -3899,7 +3899,7 @@
 #endif
        char* ptyname;
        char* ptynameptr = 0;
-#if defined(WTMP) && !defined(SVR4) && !(defined(linux) && __GLIBC__ >= 2)
+#if defined(WTMP) && !defined(SVR4) && !(defined(linux) && __GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0))
        int fd;                 /* for /etc/wtmp */
        int i;
 #endif
@@ -3931,7 +3931,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) && __GLIBC__ >= 2)
+#if defined(SVR4) || defined(SCO325) || (defined(linux) && __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;
@@ -3945,7 +3945,7 @@
                    if (term->misc.login_shell)
                        updwtmpx(WTMPX_FILE, utptr);
 #else
-#if defined(linux) && __GLIBC__ >= 2
+#if defined(linux) && __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: ptyx.h
--- xterm-88+/ptyx.h    Sun Oct 25 13:31:39 1998
+++ xterm-89/ptyx.h     Fri Nov 20 06:20:11 1998
@@ -421,15 +421,16 @@
 
 #if OPT_DEC_CHRSET
 #define if_OPT_DEC_CHRSET(code) code
-       /* Use 3 bits for encoding the double high/wide sense of characters */
+       /* Use 2 bits for encoding the double high/wide sense of characters */
 #define CSET_SWL        0
 #define CSET_DHL_TOP    1
 #define CSET_DHL_BOT    2
-#define CSET_DWL        4
+#define CSET_DWL        3
+#define NUM_CHRSET      4
        /* Use remaining bits for encoding the other character-sets */
 #define CSET_NORMAL(code)  ((code) == CSET_SWL)
 #define CSET_DOUBLE(code)  (!CSET_NORMAL(code) && !CSET_EXTEND(code))
-#define CSET_EXTEND(code)  ((code) >= 8)
+#define CSET_EXTEND(code)  ((code) > CSET_DWL)
 #define CurMaxCol(screen, row) \
        (CSET_DOUBLE(SCRN_BUF_CSETS(screen, row)[0]) \
        ? (screen->max_col / 2) \
@@ -627,6 +628,9 @@
 #endif
 #if OPT_DEC_CHRSET
        Char            chrset;         /* character-set index & code   */
+       XFontStruct *   double_fs[NUM_CHRSET];
+       GC              double_gc[NUM_CHRSET];
+       char *          double_fn[NUM_CHRSET];
 #endif
        int             border;         /* inner border                 */
        Cursor          arrow;          /* arrow cursor                 */
Index: resize.c
--- xterm-88+/resize.c  Sun Oct 25 13:31:39 1998
+++ xterm-89/resize.c   Fri Nov 20 06:38:44 1998
@@ -536,10 +536,8 @@
                         setname, termcap);
 #endif /* USE_TERMCAP */
 #ifdef USE_TERMINFO
-#ifndef SVR4
                printf ("%sCOLUMNS=%d;\nLINES=%d;\nexport COLUMNS LINES;\n",
                        setname, cols, rows);
-#endif /* !SVR4 */
 #endif /* USE_TERMINFO */
 
        } else {                /* not Bourne shell */
@@ -550,10 +548,8 @@
                         setname, termcap);
 #endif /* USE_TERMCAP */
 #ifdef USE_TERMINFO
-#ifndef SVR4
                printf ("set noglob;\n%ssetenv COLUMNS '%d';\nsetenv LINES '%d';\nunset noglob;\n",
                        setname, cols, rows);
-#endif /* !SVR4 */
 #endif /* USE_TERMINFO */
        }
        exit(0);
Index: util.c
--- xterm-88+/util.c    Sun Oct 25 13:31:39 1998
+++ xterm-89/util.c     Tue Nov  3 21:40:32 1998
@@ -1310,17 +1310,57 @@
 {
 #if OPT_DEC_CHRSET
        if (CSET_DOUBLE(chrset)) {
-               Char *temp = (Char *) malloc(2 * len);
-               int n = 0;
+               GC gc2 = xterm_DoubleGC(chrset, flags, gc);
+
                TRACE(("DRAWTEXT%c[%4d,%4d] (%d) %d:%.*s\n",
                        screen->cursor_state == OFF ? ' ' : '*',
                        y, x, chrset, len, len, text))
-               while (len--) {
-                       temp[n++] = *text++;
-                       temp[n++] = ' ';
+
+               if (gc2 != 0) { /* draw actual double-sized characters */
+                       XRectangle rect, *rp = &rect;
+                       Cardinal nr = 1;
+
+                       rect.x = 0;
+                       rect.y = 0;
+                       rect.width = 2 * len * FontWidth(screen);
+                       rect.height = FontHeight(screen);
+
+                       switch (chrset) {
+                       case CSET_DHL_TOP:
+                               rect.y = - (rect.height / 2);
+                               y -= rect.y;
+                               break;
+                       case CSET_DHL_BOT:
+                               rect.y = (rect.height / 2);
+                               y -= rect.y;
+                               break;
+                       default:
+                               nr = 0;
+                               break;
+                       }
+
+                       if (nr)
+                               XSetClipRectangles(screen->display, gc2,
+                                       x, y, rp, nr, YXBanded);
+                       else
+                               XSetClipMask(screen->display, gc2, None);
+
+                       x = drawXtermText(screen, flags, gc2,
+                               x, y, 0, text, len);
+                       x += len * FontWidth(screen);
+
+                       TRACE(("drewtext [%4d,%4d]\n", y, x))
+
+               } else {        /* simulate double-sized characters */
+                       Char *temp = (Char *) malloc(2 * len);
+                       int n = 0;
+                       while (len--) {
+                               temp[n++] = *text++;
+                               temp[n++] = ' ';
+                       }
+                       x = drawXtermText(screen, flags, gc, x, y, 0, temp, n);
+                       free(temp);
                }
-               x = drawXtermText(screen, flags, gc, x, y, 0, temp, n);
-               free(temp);
                return x;
        }
 #endif
Index: version.h
--- xterm-88+/version.h Sun Nov  1 14:10:30 1998
+++ xterm-89/version.h  Thu Nov 19 06:43:45 1998
@@ -6,4 +6,4 @@
  * version of xterm has been built.  The number in parentheses is my patch
  * number (T.Dickey).
  */
-#define XTERM_VERSION "XFree86 3.9Nk(88)"
+#define XTERM_VERSION "XFree86 3.9Nm(89)"
Index: xterm.h
--- xterm-88+/xterm.h   Sun Oct 25 13:31:39 1998
+++ xterm-89/xterm.h    Fri Nov 20 06:21:03 1998
@@ -36,8 +36,8 @@
 
 #ifndef X_NOT_STDC_ENV
 #define HAVE_STDLIB_H 1
-#else
 #define DECL_ERRNO 1
+#else
 #define size_t int
 #define time_t long
 #endif
@@ -167,6 +167,9 @@
 extern void xterm_DECDHL (Bool top);
 extern void xterm_DECSWL (void);
 extern void xterm_DECDWL (void);
+#if OPT_DEC_CHRSET
+extern GC xterm_DoubleGC(unsigned chrset, unsigned flags, GC old_gc);
+#endif
 
 /* input.c */
 extern void Input (TKeyboard *keyboard, TScreen *screen, XKeyEvent *event, Bool eightbit);
Index: xterm.log.html
--- xterm-88+/xterm.log.html    Sun Nov  1 14:10:30 1998
+++ xterm-89/xterm.log.html     Fri Nov 20 06:48:21 1998
@@ -41,6 +41,7 @@
 xc/programs/Xserver/hw/xfree86).
 
 <UL>
+<LI><A HREF="#xterm_89">Patch #89 - 1998/11/20 - XFree86 3.9Nm</A>
 <LI><A HREF="#xterm_88">Patch #88 - 1998/10/31 - XFree86 3.9Nk and 3.3.2h</A>
 <LI><A HREF="#xterm_87">Patch #87 - 1998/10/21 - XFree86 3.9Nj and 3.3.2f</A>
 <LI><A HREF="#xterm_86">Patch #86 - 1998/10/14 - XFree86 3.9Nj and 3.3.2e</A>
@@ -131,6 +132,37 @@
 <LI><A HREF="#xterm_02">Patch #2 - 1996/1/7</A>
 <LI><A HREF="#xterm_01">Patch #1 - 1996/1/6</A>
 </UL>
+
+<H1><A NAME="xterm_89">Patch #89 - 1998/11/20 - XFree86 3.9Nm</A></H1>
+This patch completes the implementation of double-sized character support
+for the VT100 emulation, and fixes a few minor bugs:
+
+<ul>
+<li>corrected the cursor position in HideCursor, which did not multiply
+the column by two when in doublesize mode.
+This bug, which did not appear in normal use, 
+dates back to my original <a href="#xterm_44">changes</a> to partly implement
+double-sized characters.
+I noticed it when cat'ing a typescript from vttest's double-sized character
+test.
+<li>ensure that the current line is repainted when switching between
+single and double width characters.
+<li>reduce the number of bits used for double-sized character coding
+from 3 to 2, to make more room for soft-font codes.
+<li>copy newer ifdef's from the XFree86 3.3.3 release's main.c,
+which address details of glibc and powerpc.
+<li>moved definition of DECL_ERRNO in xterm.h to match XFree86 3.3.3
+<li>modify <em>resize</em> to remove the ifdef on SVr4 that suppressed
+printing the script for $LINES and $COLUMNS.
+Solaris' resize utility does this; suppressing the behavior is unnecessary.
+</ul>
+I tested the double-sized characters using vttest and the xfsft patch.
+These fonts worked reasonably well:
+<pre>
+       -bitstream-courier-medium-r-normal--0-0-0-0-m-0-iso8859-1
+       9x15
+</pre>
+The iso8859 font does not include box characters, of course, but looks good.
 
 <H1><A NAME="xterm_88">Patch #88 - 1998/10/31 - XFree86 3.9Nk and 3.3.2h</A></H1>
 This refines my #85 patch by checking for a case where the font server
Index: xterm.man
--- xterm-88+/xterm.man Sun Oct 11 13:00:35 1998
+++ xterm-89/xterm.man  Wed Nov 11 19:44:01 1998
@@ -58,7 +58,9 @@
 .SH EMULATIONS
 The VT102 emulation is fairly complete, but does not support
 autorepeat.
-Double-size and blinking characters are partially implemented;
+Double-size characters are displayed properly if your font server supports
+scalable fonts.
+Blinking characters are partially implemented;
 the emulation is functional but does not have the appearance of a real VT102.
 The VT220 emulation does not support soft fonts, it is otherwise complete.
 .IR Termcap (5)