xterm-06.patch.txt

xterm - 1996/1/8 - patch #6 - T.Dickey
 
This patch does all of the SGR foreground/background fixes (i.e., clearing the
screen after an SGR color is set causes that color to be used in the foreground
and/or background).  If the FG_COLOR and/or BG_COLOR flags aren't set, then the
xterm foreground and background default to the window's values.  This usage is
consistent with various types of hardware (especially the IBM PC), and is also
used in rxvt.
 
        charproc.c:
                + add/use new macros GET_FG, GET_BG - n/c.
 
                + add/use new functions SGR_Foreground() and SGR_Background()
                  to set corresponding colors in GC's, and to retain sense of
                  "original" colors.
 
                  => This makes redundant some of the corresponding logic
                     in HideCursor to set the foreground and background,
                     but I left it in since it _may_ be fixing an unrelated
                     requirement.
 
                + set GC's in LoadNewFont() according to whether the SGR fg/bg
                  colors are active.
 
                  => This fixes some glitches in the accompanying resize,
                     that leaves parts of the window in the original
                     background color.
 
        screen.c:
                + modified ClearBufRows() to use the SGR fg/bg colors if
                  they're set.
 
                + added function ScrnClearLines(), used this to replace
                  portions of ScrnInsertLine() and ScrnDeleteLine().
                  The new function uses the SGR fg/bg colors if they're
                  set.
                  
                  => Otherwise, selection after an index or reverse index will
                     paint the wrong colors.
 
                + modified ScrnDeleteChar() and ScrnInsertChar()
                  to use SGR fg/bg colors.
 
        util.c:
                + modified ClearRight() so that if either of the SGR fg/bg
                  colors is set, we don't bzero the attributes and color
                  arrays, but instead fill them with the appropriate codes.
 
                + modified ClearLeft to use SGR fg/bg colors.
 
--------------------------------------------------------------------------------
 charproc.c |  126 +++++++++++++++++++++++++++++++++++++++++++++++------------
 screen.c   |   84 ++++++++++++++++++++++++++++-----------
 util.c     |   45 ++++++++++-----------
 3 files changed, 186 insertions, 69 deletions
--------------------------------------------------------------------------------
Index: charproc.c
--- xterm-original/charproc.c   Sun Jan  7 18:30:22 1996
+++ xterm-patched/charproc.c    Mon Jan  8 12:31:35 1996
@@ -123,6 +123,8 @@
 static int set_character_class PROTO((char *s));
 static void DoSetSelectedFont PROTO_XT_SEL_CB_ARGS;
 static void FromAlternate PROTO((TScreen *screen));
+static void SGR_Background PROTO((int color));
+static void SGR_Foreground PROTO((int color));
 static void SwitchBufs PROTO((TScreen *screen));
 static void ToAlternate PROTO((TScreen *screen));
 static void VTGraphicsOrNoExpose PROTO((XEvent *event));
@@ -264,6 +266,9 @@
 
 #define        doinput()               (bcnt-- > 0 ? *bptr++ : in_put())
 
+#define GET_FG(flags,color) ((flags&FG_COLOR) ? screen->colors[color] : screen->foreground)
+#define GET_BG(flags,color) ((flags&BG_COLOR) ? screen->colors[color] : term->core.background_pixel)
+
 static int nparam;
 static ANSI reply;
 static int param[NPARAM];
@@ -700,6 +705,74 @@
 
 WidgetClass xtermWidgetClass = (WidgetClass)&xtermClassRec;
 
+static Pixel   original_fg;
+static Pixel   original_bg;
+
+/*
+ * The terminal's foreground and background colors are set via two mechanisms:
+ *     text (cur_foreground, cur_background values that are passed down to
+ *             XDrawImageString and XDrawString)
+ *     area (X11 graphics context used in XClearArea and XFillRectangle)
+ */
+static void SGR_Foreground(color)
+       int color;
+{
+       register TScreen *screen = &term->screen;
+       Pixel   fg;
+       static  int     initialized;
+
+       if (!initialized) {
+               original_fg = screen->foreground;
+               original_bg = term->core.background_pixel;
+               initialized = TRUE;
+       }
+       
+       if (color >= 0) {
+               fg = COLOR_VALUE(screen,color);
+               term->flags |= FG_COLOR;
+               term->cur_foreground = color;
+       } else {
+               fg = original_fg;
+               term->flags &= ~FG_COLOR;
+       }
+
+       XSetForeground(screen->display, screen->normalGC, fg);
+       XSetBackground(screen->display, screen->reverseGC, fg);
+       XSetForeground(screen->display, screen->normalboldGC, fg);
+       XSetBackground(screen->display, screen->reverseboldGC, fg);
+}
+
+static void SGR_Background(color)
+       int color;
+{
+       register TScreen *screen = &term->screen;
+       Pixel   bg;
+       static  int     initialized;
+
+       if (!initialized) {
+               original_fg = screen->foreground;
+               original_bg = term->core.background_pixel;
+               initialized = TRUE;
+       }
+       
+       if (color >= 0) {
+               bg = COLOR_VALUE(screen,color);
+               term->flags |= BG_COLOR;
+               term->cur_background = color;
+       } else {
+               bg = original_bg;
+               term->flags &= ~BG_COLOR;
+       }
+
+       XSetBackground(screen->display, screen->normalGC, bg);
+       XSetForeground(screen->display, screen->reverseGC, bg);
+       XSetBackground(screen->display, screen->normalboldGC, bg);
+       XSetForeground(screen->display, screen->reverseboldGC, bg);
+
+       /* update the screen's background (for XClearArea) */
+       XSetWindowBackground(screen->display, TextWindow(screen), bg);
+}
+
 static void VTparse()
 {
        register TScreen *screen = &term->screen;
@@ -1035,8 +1108,12 @@
                                switch (param[row]) {
                                 case DEFAULT:
                                 case 0:
+                                       if (term->flags & FG_COLOR)
+                                               SGR_Foreground(-1);
+                                       if (term->flags & BG_COLOR)
+                                               SGR_Background(-1);
                                        term->flags &=
-                                               ~(INVERSE|BOLD|UNDERLINE|FG_COLOR|BG_COLOR);
+                                               ~(INVERSE|BOLD|UNDERLINE);
                                        break;
                                 case 1:
                                 case 5:        /* Blink, really.       */
@@ -1045,8 +1122,7 @@
                                            screen->colorBDMode) {
                                          if (!(term->flags & FG_COLOR) ||
                                              (term->cur_foreground==COLOR_UL)){
-                                           term->flags |= FG_COLOR;
-                                           term->cur_foreground = COLOR_BD;
+                                           SGR_Foreground(COLOR_BD);
                                          }
                                          else   /* Set highlight bit */
                                             if (term->cur_foreground < 8)
@@ -1058,8 +1134,7 @@
                                        if( screen->colorMode && 
                                            screen->colorULMode) {
                                           if (!(term->flags & FG_COLOR)) {
-                                            term->flags |= FG_COLOR;
-                                            term->cur_foreground = COLOR_UL;
+                                            SGR_Foreground(COLOR_UL);
                                          }
                                         }
                                        break;
@@ -1075,11 +1150,11 @@
                                 case 36:
                                 case 37:
                                        if( screen->colorMode ) {
-                                         term->flags |= FG_COLOR;
-                                         term->cur_foreground = param[row]-30;
-                                         /* Set highlight bit if bold on */
-                                         if (term->flags & BOLD)
-                                                   term->cur_foreground |= 8;
+                                         SGR_Foreground(
+                                               (param[row] - 30)
+                                               /* Set highlight bit if bold */
+                                               | ((term->flags & BOLD)
+                                                 ? 8 : 0));
                                        }
                                        break;
                                 case 40:
@@ -1091,13 +1166,15 @@
                                 case 46:
                                 case 47:
                                        if( screen->colorMode ) {
-                                         term->flags |= BG_COLOR;
-                                         term->cur_background = param[row]-40;
+                                         SGR_Background(param[row] - 40);
                                        }
                                        break;
                                 case 100:
                                        if( screen->colorMode ) {
-                                         term->flags &= ~(FG_COLOR|BG_COLOR);
+                                         if (term->flags & FG_COLOR)
+                                           SGR_Foreground(-1);
+                                         if (term->flags & BG_COLOR)
+                                           SGR_Background(-1);
                                        }
                                        break;
                                }
@@ -1740,9 +1817,8 @@
        register Pixel fg_pix, bg_pix;
        GC      currentGC;
  
-       fg_pix = (fgs&FG_COLOR) ? screen->colors[fg] : screen->foreground;
-       bg_pix = (fgs&BG_COLOR) ? screen->colors[bg] :
-               term->core.background_pixel;
+       fg_pix = GET_FG(fgs,fg);
+       bg_pix = GET_BG(fgs,bg);
 
    if(screen->cur_row - screen->topline <= screen->max_row) {
        /*
@@ -3114,10 +3190,8 @@
        fg    = SCRN_BUF_FORES(screen, screen->cursor_row)[screen->cursor_col];
        bg    = SCRN_BUF_BACKS(screen, screen->cursor_row)[screen->cursor_col];
 
-        fg_pix = (flags&FG_COLOR) ?
-                  screen->colors[fg] : screen->foreground;
-        bg_pix = (flags&BG_COLOR) ?
-                  screen->colors[bg] : term->core.background_pixel;
+        fg_pix = GET_FG(flags,fg);
+        bg_pix = GET_BG(flags,bg);
 
        if (screen->cursor_row > screen->endHRow ||
            (screen->cursor_row == screen->endHRow &&
@@ -3551,6 +3625,7 @@
     unsigned long mask;
     GC new_normalGC = NULL, new_normalboldGC = NULL;
     GC new_reverseGC = NULL, new_reverseboldGC = NULL;
+    Pixel new_normal, new_revers;
     char *tmpname = NULL;
 
     if (!nfontname) return 0;
@@ -3576,9 +3651,12 @@
     mask = (GCFont | GCForeground | GCBackground | GCGraphicsExposures |
            GCFunction);
 
+    new_normal = GET_FG(term->flags, term->cur_foreground);
+    new_revers = GET_BG(term->flags, term->cur_background);
+
     xgcv.font = nfs->fid;
-    xgcv.foreground = screen->foreground;
-    xgcv.background = term->core.background_pixel;
+    xgcv.foreground = new_normal;
+    xgcv.background = new_revers;
     xgcv.graphics_exposures = TRUE;    /* default */
     xgcv.function = GXcopy;
 
@@ -3594,8 +3672,8 @@
     }
 
     xgcv.font = nfs->fid;
-    xgcv.foreground = term->core.background_pixel;
-    xgcv.background = screen->foreground;
+    xgcv.foreground = new_revers;
+    xgcv.background = new_normal;
     new_reverseGC = XtGetGC((Widget)term, mask, &xgcv);
     if (!new_reverseGC) goto bad;
 
Index: screen.c
--- xterm-original/screen.c     Sun Jan  7 18:54:31 1996
+++ xterm-patched/screen.c      Mon Jan  8 20:44:08 1996
@@ -66,6 +66,8 @@
 #endif
 
 static int Reallocate PROTO((ScrnBuf *sbuf, Char **sbufaddr, int nrow, int ncol, int oldrow, int oldcol));
+static void ScrnClearLines PROTO((char **save, ScrnBuf sb, int where, int n, int size));
+
 
 ScrnBuf Allocate (nrow, ncol, addr)
 /*
@@ -221,6 +223,38 @@
            *attrs0 |= LINEWRAPPED;
 }
 
+static void
+ScrnClearLines (save, sb, where, n, size)
+/*
+ * Saves pointers to the n lines beginning at sb + where, and clears the lines
+ */
+char **save;
+ScrnBuf sb;
+int where, n, size;
+{
+       register int i;
+
+       /* save n lines at where */
+       memmove( (char *)save,
+                (char *) &sb[MAX_PTRS * where],
+                MAX_PTRS * sizeof(char *) * n);
+
+       /* clear contents of old rows */
+       if (term->flags & (FG_COLOR|BG_COLOR)) {
+               int last = (n * MAX_PTRS);
+               int flags = (term->flags & (FG_COLOR|BG_COLOR));
+               for (i = 0; i < last; i += MAX_PTRS) {
+                       memset(save[i+0], 0, size);
+                       memset(save[i+1], flags, size);
+                       memset(save[i+2], term->cur_foreground, size);
+                       memset(save[i+3], term->cur_background, size);
+               }
+       } else {
+               for (i = MAX_PTRS * n - 1 ; i >= 0 ; i--)
+                       bzero (save[i], size);
+       }
+}
+
 void
 ScrnInsertLine (sb, last, where, n, size)
 /*
@@ -233,16 +267,10 @@
 int last;
 register int where, n, size;
 {
-       register int i;
        char *save [MAX_PTRS * MAX_ROWS];
 
        /* save n lines at bottom */
-       memmove( (char *) save, (char *) &sb [MAX_PTRS * (last -= n - 1)], 
-               MAX_PTRS * sizeof (char *) * n);
-       
-       /* clear contents of old rows */
-       for (i = MAX_PTRS * n - 1; i >= 0; i--)
-               bzero ((char *) save [i], size);
+       ScrnClearLines(save, sb, (last -= n - 1), n, size);
 
        /*
         * WARNING, overlapping copy operation.  Move down lines (pointers).
@@ -275,17 +303,9 @@
 register int n, last, size;
 int where;
 {
-       register int i;
        char *save [MAX_PTRS * MAX_ROWS];
 
-       /* save n lines at where */
-       memmove( (char *)save,
-                (char *) &sb[MAX_PTRS * where],
-                MAX_PTRS * sizeof(char *) * n);
-
-       /* clear contents of old rows */
-       for (i = MAX_PTRS * n - 1 ; i >= 0 ; i--)
-               bzero ((char *) save [i], size);
+       ScrnClearLines(save, sb, where, n, size);
 
        /* move up lines */
        memmove( (char *) &sb[MAX_PTRS * where],
@@ -311,6 +331,7 @@
        register Char *ptr = BUF_CHARS(sb, row);
        register Char *attrs = BUF_ATTRS(sb, row);
        int wrappedbit = attrs[0]&LINEWRAPPED;
+       int flags = CHARDRAWN | (term->flags & (FG_COLOR|BG_COLOR));
 
        attrs[0] &= ~LINEWRAPPED; /* make sure the bit isn't moved */
        for (i = size - 1; i >= col + n; i--) {
@@ -321,7 +342,11 @@
        for (i=col; i<col+n; i++)
            ptr[i] = ' ';
        for (i=col; i<col+n; i++)
-           attrs[i] = CHARDRAWN;
+           attrs[i] = flags;
+       if (flags & FG_COLOR)
+           memset(BUF_FORES(sb, row) + col, term->cur_foreground, n);
+       if (flags & BG_COLOR)
+           memset(BUF_BACKS(sb, row) + col, term->cur_background, n);
 
        if (wrappedbit)
            attrs[0] |= LINEWRAPPED;
@@ -344,7 +369,11 @@
        memmove( ptr + col, ptr + col + n, nbytes);
        memmove( attrs + col, attrs + col + n, nbytes);
        bzero (ptr + size - n, n);
-       bzero (attrs + size - n, n);
+       memset (attrs + size - n, term->flags & (FG_COLOR|BG_COLOR), n);
+       if (term->flags & FG_COLOR)
+           memset(BUF_FORES(sb, row) + size - n, term->cur_foreground, n);
+       if (term->flags & BG_COLOR)
+           memset(BUF_BACKS(sb, row) + size - n, term->cur_background, n);
        if (wrappedbit)
            attrs[0] |= LINEWRAPPED;
 }
@@ -505,7 +534,7 @@
                       XSetForeground(screen->display, gc, fg_pix);
                       XSetBackground(screen->display, gc, bg_pix);
 
-               }
+                  }
                }
 
                if(chars[col] == 0)
@@ -550,10 +579,19 @@
 register TScreen *screen;
 register int first, last;
 {
-       first *= MAX_PTRS;
-       last = MAX_PTRS * last + (MAX_PTRS-1);
-       while (first <= last)
-               bzero (screen->buf [first++], (screen->max_col + 1));
+       ScrnBuf buf = screen->buf;
+       int     len = screen->max_col + 1;
+       register int row;
+       register int flags = term->flags & (FG_COLOR|BG_COLOR);
+
+       for (row = first; row <= last; row++) {
+               bzero (BUF_CHARS(buf, row), len);
+               memset(BUF_ATTRS(buf, row), flags, len);
+               memset(BUF_FORES(buf, row), 
+                       (flags & FG_COLOR) ? term->cur_foreground : 0, len);
+               memset(BUF_BACKS(buf, row), 
+                       (flags & BG_COLOR) ? term->cur_background : 0, len);
+       }
 }
 
 /*
Index: util.c
--- xterm-original/util.c       Sun Jan  7 16:38:55 1996
+++ xterm-patched/util.c        Mon Jan  8 21:01:45 1996
@@ -620,6 +620,10 @@
 ClearRight (screen)
 register TScreen *screen;
 {
+       int     len = (screen->max_col - screen->cur_col + 1);
+       ScrnBuf buf = screen->buf;
+       Char *attrs = BUF_ATTRS(buf, screen->cur_row) + screen->cur_col;
+
        if(screen->cursor_state)
                HideCursor();
        screen->do_wrap = 0;
@@ -635,16 +639,17 @@
                 FontHeight(screen));
            }
        }
-       bzero(SCRN_BUF_CHARS(screen, screen->cur_row) + screen->cur_col,
-              (screen->max_col - screen->cur_col + 1));
-       bzero(SCRN_BUF_ATTRS(screen, screen->cur_row) + screen->cur_col,
-              (screen->max_col - screen->cur_col + 1));
-       bzero(SCRN_BUF_FORES(screen, screen->cur_row) + screen->cur_col,
-              (screen->max_col - screen->cur_col + 1));
-       bzero(SCRN_BUF_BACKS(screen, screen->cur_row) + screen->cur_col,
-              (screen->max_col - screen->cur_col + 1));
+       bzero(BUF_CHARS(buf, screen->cur_row) + screen->cur_col, len);
+       memset(attrs, term->flags & (FG_COLOR|BG_COLOR), len);
+       memset(BUF_FORES(buf, screen->cur_row) + screen->cur_col,
+               (term->flags & FG_COLOR)
+               ? term->cur_foreground : 0, len);
+       memset(BUF_BACKS(buf, screen->cur_row) + screen->cur_col,
+               (term->flags & BG_COLOR)
+               ? term->cur_background : 0, len);
+
        /* with the right part cleared, we can't be wrapping */
-       SCRN_BUF_ATTRS(screen, screen->cur_row) [0] &= ~LINEWRAPPED;
+       attrs[0] &= ~LINEWRAPPED;
 }
 
 /*
@@ -654,8 +659,8 @@
 ClearLeft (screen)
     register TScreen *screen;
 {
-        int i;
-       Char *cp;
+       int len = screen->cur_col + 1;
+       int flags = CHARDRAWN | (term->flags & (FG_COLOR|BG_COLOR));
 
        if(screen->cursor_state)
                HideCursor();
@@ -668,21 +673,17 @@
                     screen->reverseGC,
                     screen->border + screen->scrollbar,
                      CursorY (screen, screen->cur_row),
-                    (screen->cur_col + 1) * FontWidth(screen),
+                    len * FontWidth(screen),
                     FontHeight(screen));
            }
        }
        
-       for ( i=0, cp=SCRN_BUF_CHARS(screen, screen->cur_row);
-             i < screen->cur_col + 1;
-             i++, cp++)
-           *cp = ' ';
-       for ( i=0, cp=SCRN_BUF_ATTRS(screen, screen->cur_row);
-             i < screen->cur_col + 1;
-             i++, cp++)
-           *cp = CHARDRAWN;
-       bzero (SCRN_BUF_FORES(screen, screen->cur_row), (screen->cur_col + 1));
-       bzero (SCRN_BUF_BACKS(screen, screen->cur_row), (screen->cur_col + 1));
+       memset(SCRN_BUF_CHARS(screen, screen->cur_row), ' ',   len);
+       memset(SCRN_BUF_ATTRS(screen, screen->cur_row), flags, len);
+       memset(SCRN_BUF_FORES(screen, screen->cur_row),
+               flags & FG_COLOR ? term->cur_foreground : 0, len);
+       memset(SCRN_BUF_BACKS(screen, screen->cur_row),
+               flags & BG_COLOR ? term->cur_background : 0, len);
 
 }