*** empty log message ***
authorroot <root>
Wed, 21 Dec 2005 19:50:16 +0000 (19:50 +0000)
committerroot <root>
Wed, 21 Dec 2005 19:50:16 +0000 (19:50 +0000)
Changes
src/init.C
src/main.C
src/rxvt.h
src/rxvtlib.h.in
src/screen.C

diff --git a/Changes b/Changes
index 4eab39b50debff6a61f1bcef8cbc828ab2609e5a..916f58abb8dc75f87a220fa3c10a0d5085bca5a0 100644 (file)
--- a/Changes
+++ b/Changes
@@ -13,7 +13,10 @@ WISH: just for fun, do shade and tint with XRender.
 6.0
        - make it compile without SMART_RESIZE again.
         - enable slow link support by default.
-        - _major_ rewrite of internal line handling logic:
+        - fix relative cursor-positioning not respecting scrolling regions
+          (also a bug in original rxvt).
+        - major code cleanup (still not complete, though).
+        - _major_ rewrite of internal buffer handling:
 #      - re-flow on resize, lines get wrapped instead of winged.
        - circular line buffer (substantially speeds up scrolling).
         - slightly less code + data memory usage per terminal.
@@ -56,7 +59,7 @@ WISH: just for fun, do shade and tint with XRender.
          even know about the -rootless and -multiwindow Cygwin/X modes).
        - large amounts of text without control sequences or newlines
          could almost freeze output. This has been fixed by adding extra
-         refreshes in these cases (also a problem in oriignal rxvt).
+         refreshes in these cases (also a problem in original rxvt).
 
 5.6  Sun Jun 26 22:11:13 CEST 2005
        - R_SB_RXVT bitset value was 0, so rxvt scrollbar was initialised
@@ -755,7 +758,7 @@ WISH: just for fun, do shade and tint with XRender.
        - much faster x11 font selection
 
 1.2  2003-12-24
-       - fix another segfault-on-resize-bug form the original rxvt
+       - fix another segfault-on-resize-bug from the original rxvt
        - better font matching
        - better memory management (less memory)
        - new fallback: gnu freefont
index 0e2d998baabbea7cf3a198f513220b7598af6b7b..1e7f7bd68b092263dec7ce53fb9b856dcda98bdb 100644 (file)
@@ -36,6 +36,8 @@
 #include "rxvtutil.h"
 #include "init.h"
 
+#include <limits>
+
 #include <csignal>
 
 const char *const def_colorName[] =
@@ -371,17 +373,17 @@ rxvt_term::init_resources (int argc, const char *const *argv)
     }
 
   if (rs[Rs_saveLines] && (i = atoi (rs[Rs_saveLines])) >= 0)
-    saveLines = min (i, MAX_POSITIVE_INT16);
+    saveLines = min (i, std::numeric_limits<int16_t>::max ());
 
 #if ENABLE_FRILLS
   if (rs[Rs_int_bwidth] && (i = atoi (rs[Rs_int_bwidth])) >= 0)
-    int_bwidth = min (i, MAX_POSITIVE_INT16);
+    int_bwidth = min (i, std::numeric_limits<int16_t>::max ());
 
   if (rs[Rs_ext_bwidth] && (i = atoi (rs[Rs_ext_bwidth])) >= 0)
-    ext_bwidth = min (i, MAX_POSITIVE_INT16);
+    ext_bwidth = min (i, std::numeric_limits<int16_t>::max ());
 
   if (rs[Rs_lineSpace] && (i = atoi (rs[Rs_lineSpace])) >= 0)
-    lineSpace = min (i, MAX_POSITIVE_INT16);
+    lineSpace = min (i, std::numeric_limits<int16_t>::max ());
 #endif
 
 #ifdef POINTER_BLANK
index 1af3feb8ef91ff30068c049d6dc608c145904f16..adb86570b71ddc32a10b92827b4946b7957d88c4 100644 (file)
@@ -33,6 +33,8 @@
 #include "../config.h"          /* NECESSARY */
 #include "rxvt.h"               /* NECESSARY */
 
+#include <limits>
+
 #include <csignal>
 #include <cstring>
 
@@ -720,13 +722,13 @@ rxvt_term::window_calc (unsigned int newwidth, unsigned int newheight)
 
       if (flags & WidthValue)
         {
-          ncol = clamp (w, 0, MAX_POSITIVE_INT16);
+          ncol = clamp (w, 0, std::numeric_limits<int16_t>::max ());
           szHint.flags |= USSize;
         }
 
       if (flags & HeightValue)
         {
-          nrow = clamp (h, 0, MAX_POSITIVE_INT16);
+          nrow = clamp (h, 0, std::numeric_limits<int16_t>::max ());
           szHint.flags |= USSize;
         }
 
@@ -891,8 +893,6 @@ rxvt_term::set_fonts ()
 
   fwidth  = prop.width;
   fheight = prop.height;
-  fweight = prop.weight;
-  fslant  = prop.slant;
   fbase   = (*fs)[1]->ascent;
 
   for (int style = 1; style < 4; style++)
index af5ee86cd6839000a823cce6b88eb5553bb6c104..440f66121e8a66feaf91f125f45821c217d06ecb 100644 (file)
@@ -164,8 +164,6 @@ struct mouse_event {
   unsigned int button;   /* detail */
 };
 
-#define MAX_POSITIVE_INT16 (((uint16_t)-1)>>1)  // TODO: configure/limits
-
 #if ENABLE_FRILLS
 typedef struct _mwmhints {
   CARD32 flags;
@@ -355,9 +353,9 @@ enum {
 
 /* flags for rxvt_scr_gotorc () */
 enum {
-  C_RELATIVE = 1    ,       /* col movement is relative */
-  R_RELATIVE =     2,       /* row movement is relative */
-  RELATIVE   = 1 | 2,
+  C_RELATIVE = 1,       /* col movement is relative */
+  R_RELATIVE = 2,       /* row movement is relative */
+  RELATIVE   = C_RELATIVE | R_RELATIVE,
 };
 
 /* modes for rxvt_scr_insdel_chars (), rxvt_scr_insdel_lines () */
@@ -820,21 +818,24 @@ enum {
 #define TermWin_TotalWidth()    ((int32_t)this->width)
 #define TermWin_TotalHeight()   ((int32_t)this->height)
 
-#define LINENO(n) (((n) + term_start + total_rows) % total_rows)
-#define ROW(n) (save [LINENO (n)])
+// for m >= -n, ensure remainder lies between 0..n-1
+#define MOD(m,n) (((m) + (n)) % (n))
+
+#define LINENO(n) MOD (term_start + int(n), total_rows)
+#define ROW(n) row_buf [LINENO (n)]
 
 /* how to build & extract colors and attributes */
 #define GET_BASEFG(x)           (((x) & RS_fgMask))
 #define GET_BASEBG(x)           (((x) & RS_bgMask)>>Color_Bits)
 #ifndef NO_BRIGHTCOLOR
-# define GET_FGCOLOR(x)                                         \
-    ((((x) & RS_Bold) == 0                                      \
+# define GET_FGCOLOR(x)                                          \
+    ((((x) & RS_Bold) == 0                                       \
       || GET_BASEFG (x) < minCOLOR                               \
       || GET_BASEFG (x) >= minBrightCOLOR)                       \
      ? GET_BASEFG (x)                                            \
      : (GET_BASEFG (x) + (minBrightCOLOR - minCOLOR)))
-# define GET_BGCOLOR(x)                                         \
-    ((((x) & RS_Blink) == 0                                     \
+# define GET_BGCOLOR(x)                                          \
+    ((((x) & RS_Blink) == 0                                      \
       || GET_BASEBG (x) < minCOLOR                               \
       || GET_BASEBG (x) >= minBrightCOLOR)                       \
      ? GET_BASEBG (x)                                            \
@@ -1493,7 +1494,6 @@ struct rxvt_term : zero_initialized, rxvt_vars {
   void scr_blank_screen_mem (line_t &l, rend_t efs);
   int scr_scroll_text (int row1, int row2, int count);
   void scr_reset ();
-  void scr_reset_realloc ();
   void scr_release ();
   void scr_clear (bool really = false);
   void scr_refresh (unsigned char refresh_type);
index ed46fc2952af195e8a80c6563a2d067b7a04a77f..3b0ec9942f6fbd59a171f9c440cc8a89c2e961c7 100644 (file)
@@ -79,7 +79,7 @@ typedef uint32_t text_t;
 typedef uint16_t text_t; // saves lots of memory
 #endif
 typedef uint32_t rend_t;
-typedef int16_t  tlen_t;
+typedef  int32_t tlen_t; // was int16_t, but this result sin smaller code and memory use
 
 #define LINE_CONT -1
 
@@ -107,16 +107,38 @@ struct line_t {
 };
 
 /*
- * TermWin elements limits
- *  width     : 1 <= width
- *  height    : 1 <= height
- *  ncol      : 1 <= ncol       <= MAX(int16_t)
- *  nrow      : 1 <= nrow       <= MAX(int16_t)
- *  saveLines : 0 <= saveLines  <= MAX(int16_t)
- *  nlines    : nrow + saveLines
- *  nsaved    : 0 <= nsaved  <= saveLines
- *  term_start: 0 <= term_start < saveLines
- *  view_start: 0 <= view_start < saveLines
+ * terminal limits:
+ *
+ *  width      : 1 <= width
+ *  height     : 1 <= height
+ *  ncol       : 1 <= ncol       <= MAX(int16_t)
+ *  nrow       : 1 <= nrow       <= MAX(int16_t)
+ *  saveLines  : 0 <= saveLines  <= MAX(int16_t)
+ *  total_rows : nrow + saveLines
+ *  nsaved     : 0 <= nsaved     <= saveLines
+ *  term_start : 0 <= term_start < saveLines
+ *  view_start : 0 <= view_start < saveLines
+ *
+ *          | most coordinates are stored relative to term_start,
+ *  ROW_BUF | which is the first line of the terminal screen
+ *  |························= row_buf[0]
+ *  |························= row_buf[1]
+ *  |························= row_buf[2] etc.
+ *  |
+ *  +------------+···········= term_start - nsaved
+ *  | scrollback |                                      
+ *  | scrollback +---------+·= term_start - view_start
+ *  | scrollback | display |
+ *  | scrollback | display |
+ *  +------------+·display·+·= term_start
+ *  |  terminal  | display |
+ *  |  terminal  +---------+
+ *  |  terminal  |
+ *  |  terminal  |
+ *  +------------+···········= term_stat + nrow - 1
+ *  |
+ *  |
+ *  END······················= total_rows
  */
 
 struct TermWin_t {
@@ -124,7 +146,6 @@ struct TermWin_t {
   int            height;        /* window height                   [pixels] */
   int            fwidth;        /* font width                      [pixels] */
   int            fheight;       /* font height                     [pixels] */
-  int            fweight, fslant;
   int            fbase;         /* font ascent (baseline)          [pixels] */
   int            ncol;          /* window columns              [characters] */
   int            nrow;          /* window rows                 [characters] */
@@ -149,12 +170,6 @@ struct TermWin_t {
 /*
  * screen accounting:
  * screen_t elements
- *   text:      Contains all text information including the scrollback buffer.
- *              Each line is length ncol
- *   tlen:      The length of the line or -1 for wrapped lines.
- *   rend:      Contains rendition information: font, bold, colour, etc.
- * * Note: Each line for both text and rend are only allocated on demand, and
- *         text[x] is allocated <=> rend[x] is allocated  for all x.
  *   row:       Cursor row position                   : 0 <= row < nrow
  *   col:       Cursor column position                : 0 <= col < ncol
  *   tscroll:   Scrolling region top row inclusive    : 0 <= row < nrow
@@ -169,18 +184,11 @@ struct TermWin_t {
  * * Note: -nsaved <= beg.row <= mark.row <= end.row < nrow
  * * Note: col == -1 ==> we're left of screen
  *
- * Layout of text/rend information in the screen_t text/rend structures:
- *   Rows [0] ... [saveLines - 1]
- *     scrollback region : we're only here if view_start != 0
- *   Rows [saveLines] ... [saveLines + nrow - 1]
- *     normal `unsaved' screen region
  */
 typedef struct {
-  line_t        **line;
-
-  row_col_t       cur;  /* cursor position on the screen             */
-  unsigned int    tscroll;      /* top of settable scroll region             */
-  unsigned int    bscroll;      /* bottom of settable scroll region          */
+  row_col_t       cur;          /* cursor position on the screen             */
+  int             tscroll;      /* top of settable scroll region             */
+  int             bscroll;      /* bottom of settable scroll region          */
   unsigned int    charset;      /* character set number [0..3]               */
   unsigned int    flags;        /* see below                                 */
   row_col_t       s_cur;        /* saved cursor position                     */
@@ -301,10 +309,10 @@ struct rxvt_vars : TermWin_t {
   int             sb_shadow;    /* scrollbar shadow width                    */
   rxvt_ptytty     pty;
   int             numlock_state;
-  line_t         *save;         // all lines, scorllback + terminal, circular
-  line_t         *drawn;        // text on screen
-  line_t         *buf;          // temporary buffer
-  line_t         *swap_save;    // lines for swap buffer
+  line_t         *row_buf;      // all lines, scrollback + terminal, circular
+  line_t         *drawn_buf;    // text on screen
+  line_t         *temp_buf;     // temporary buffer
+  line_t         *swap_buf;     // lines for swap buffer
   char           *tabs;         /* per location: 1 == tab-stop               */
   screen_t        screen;
   screen_t        swap;
index a1952ca0a9ecfba98e42ccd5aa5261032ce1fba1..b4ac645e9b5836ce2d4ddd524754ef27ce9bae23 100644 (file)
@@ -149,12 +149,10 @@ rxvt_term::scr_blank_screen_mem (line_t &l, rend_t efs)
 /* ------------------------------------------------------------------------- *
  *                          SCREEN INITIALISATION                            *
  * ------------------------------------------------------------------------- */
+
 void
 rxvt_term::scr_reset ()
 {
-  unsigned int p, q;
-  int k;
-
 #if ENABLE_OVERLAY
   scr_overlay_off ();
 #endif
@@ -174,6 +172,7 @@ rxvt_term::scr_reset ()
   // we need at least two lines for wrapping to work correctly
   if (nrow + saveLines < 2)
     {
+      //TODO//FIXME
       saveLines++;
       prev_nrow--;
       nsaved++;
@@ -187,7 +186,7 @@ rxvt_term::scr_reset ()
   screen.tscroll = 0;
   screen.bscroll = nrow - 1;
 
-  if (!save)
+  if (!row_buf)
     {
       /*
        * first time called so just malloc everything: don't rely on realloc
@@ -199,16 +198,16 @@ rxvt_term::scr_reset ()
       talloc = new rxvt_salloc (ncol * sizeof (text_t));
       ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
 
-      save      = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
-      buf       = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
-      drawn     = (line_t *)rxvt_calloc (nrow, sizeof (line_t));
-      swap_save = (line_t *)rxvt_calloc (nrow, sizeof (line_t));
+      row_buf   = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
+      temp_buf  = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
+      drawn_buf = (line_t *)rxvt_calloc (nrow      , sizeof (line_t));
+      swap_buf  = (line_t *)rxvt_calloc (nrow      , sizeof (line_t));
 
-      for (p = nrow; p--; )
+      for (int row = nrow; row--; )
         {
-          scr_blank_screen_mem (ROW(p), DEFAULT_RSTYLE);
-          scr_blank_screen_mem (swap_save[p], DEFAULT_RSTYLE);
-          scr_blank_screen_mem (drawn[p], DEFAULT_RSTYLE);
+          scr_blank_screen_mem (ROW (row), DEFAULT_RSTYLE);
+          scr_blank_screen_mem (swap_buf [row], DEFAULT_RSTYLE);
+          scr_blank_screen_mem (drawn_buf[row], DEFAULT_RSTYLE);
         }
 
       memset (charsets, 'B', sizeof (charsets));
@@ -242,181 +241,122 @@ rxvt_term::scr_reset ()
        * add or delete rows as appropriate
        */
 
-      rxvt_salloc *old_ta;
-      rxvt_salloc *old_ra;
+     printf ("resize %d:%d => %d:%d\n", prev_nrow, prev_ncol, nrow, ncol);//D
 
+      rxvt_salloc *old_ta = talloc; talloc = new rxvt_salloc (ncol * sizeof (text_t));
+      rxvt_salloc *old_ra = ralloc; ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
+
+#if 0
       if (nrow < prev_nrow)
         {
-          /* delete rows */
-          k = min (nsaved, prev_nrow - nrow);
-          // k = max (0, - ( (nrow - 1) - r->screen.cur.row)); // mmc's http://maruska.dyndns.org/wiki/scrolling-bug //make configurable? //D TODO
-          scr_scroll_text (0, (int)prev_nrow - 1, k);
-
-          for (p = nrow; p < prev_nrow; p++)
+          for (int row = nrow; row < prev_nrow; row++)
             {
-              lfree (ROW(p));
-              lfree (swap_save[p]);
-              lfree (drawn[p]);
+              lfree (swap_buf [row]);
+              lfree (drawn_buf[row]);
             }
-
-          /* we have fewer rows so fix up cursor position */
-          min_it (screen.cur.row, (int32_t)nrow - 1);
-
-          scr_reset_realloc (); /* realloc _last_ */
         }
-      else if (nrow > prev_nrow)
-        {
-          /* add rows */
-          scr_reset_realloc (); /* realloc _first_ */
-
-          int ocol = ncol;
-          ncol = prev_ncol; // save b/c scr_blank_screen_mem uses this
-
-          k = min (nsaved, nrow - prev_nrow);
-
-          for (p = prev_total_rows; p < total_rows; p++)
-            save[p].clear ();
-
-          for (p = prev_total_rows; p < total_rows - k; p++)
-            scr_blank_screen_mem (save[p], DEFAULT_RSTYLE);
-
-          for (p = prev_nrow; p < nrow; p++)
-            {
-              swap_save[p].clear (); scr_blank_screen_mem (swap_save[p], DEFAULT_RSTYLE);
-              drawn[p].clear ();     scr_blank_screen_mem (drawn[p], DEFAULT_RSTYLE);
-            }
+#endif
 
-          if (k > 0)
-            {
-              scr_scroll_text (0, (int)nrow - 1, -k);
-              screen.cur.row += k;
-              screen.s_cur.row += k;
-              nsaved -= k;
-            }
+      drawn_buf = (line_t *) rxvt_realloc (drawn_buf, nrow * sizeof (line_t));
+      temp_buf  = (line_t *) rxvt_realloc (temp_buf , nrow * sizeof (line_t));
+      swap_buf  = (line_t *) rxvt_realloc (swap_buf , nrow * sizeof (line_t));
 
-#ifdef DEBUG_STRICT
-          assert (screen.cur.row < nrow);
-#else                           /* drive with your eyes closed */
-          min_it (screen.cur.row, nrow - 1);
-#endif
-          ncol =  ocol; // save b/c scr_blank_screen_mem uses this
+      for (int row = min (nrow, prev_nrow); row--; )
+        {
+          lresize (drawn_buf[row]);
+          lresize (swap_buf [row]);
         }
 
-      /* resize columns */
-      if (ncol != prev_ncol)
+      for (int row = prev_nrow; row < nrow; row++)
         {
-          old_ta = talloc; talloc = new rxvt_salloc (ncol * sizeof (text_t));
-          old_ra = ralloc; ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
-
-          for (p = total_rows; p--; )
-            lresize (save[p]);
-
-          for (p = nrow; p--; )
-            {
-              lresize (drawn[p]);
-              lresize (swap_save[p]);
-            }
-
-          min_it (screen.cur.col, (int16_t)ncol - 1);
-
-          delete old_ta;
-          delete old_ra;
+          swap_buf [row].clear (); scr_blank_screen_mem (swap_buf [row], DEFAULT_RSTYLE);
+          drawn_buf[row].clear (); scr_blank_screen_mem (drawn_buf[row], DEFAULT_RSTYLE);
         }
 
-#if 0
+      line_t *old_buf = row_buf; row_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
+        
       // re-wrap lines, this is rather ugly, possibly because I am too dumb
       // to come up with a lean and mean algorithm.
-      rxvt_salloc *ta = new rxvt_salloc (ncol * sizeof (text_t));
-      rxvt_salloc *ra = new rxvt_salloc (ncol * sizeof (rend_t));
-      
-      text_t **tp = (text_t **)rxvt_calloc (total_rows, sizeof (text_t *));
-      rend_t **rp = (rend_t **)rxvt_calloc (total_rows, sizeof (rend_t *));
-      tlen_t *tl  = (tlen_t *) rxvt_calloc (total_rows, sizeof (tlen_t));
 
-      for (p = 0; p < prev_total_rows; p++) printf ("P %p %d\n", save[p].t, save[p].l);//D
+      int p    = MOD (term_start + nrow  , prev_total_rows);  // previous row
+      int pend = MOD (term_start - nsaved, prev_total_rows);
+      int q    = total_rows; // rewrapped row
 
-      p = prev_total_rows;
-      q = total_rows;
-
-      while (p > 0 && q > 0)
+      while (p != pend && q > 0)
         {
-          --p;
+          p = MOD (p - 1, prev_total_rows);
 
-          printf ("pq %d:%d\n", p, q);
-          if (save[p].t)
-            {
-              int llen = save[p].l;
+          assert (old_buf [MOD (p, prev_total_rows)].t);
+          assert (!old_buf [MOD (p, prev_total_rows)].is_longer ());
 
-              assert (llen >= 0);
+          int llen = old_buf [MOD (p, prev_total_rows)].l;
 
-              while (p && save[p - 1].l < 0)
-                {
-                  --p;
-                  llen += prev_ncol;
-                }
+          while (p != pend && old_buf [MOD (p - 1, prev_total_rows)].is_longer ())
+            {
+              p = MOD (p - 1, prev_total_rows);
 
-              int qlines = llen / ncol + 1;
-              int lofs = 0;
+              llen += prev_ncol;
+            }
+
+          int qlines = llen / ncol + 1;
+          int lofs = 0;
 
-              q -= qlines;
+          q -= qlines;
 
-              int qrow = q;
+          int qrow = q;
 
-                 printf ("QL %d llen %d\n", qlines, llen);//D
-              for (; qlines--; qrow++)
+          for (; qlines--; qrow++)
+            {
+              if (qrow >= 0)
                 {
-                  if (qrow >= 0)
-                    {
-                      tp [qrow] = (text_t *)ta->alloc ();
-                      rp [qrow] = (rend_t *)ra->alloc ();
-                      tl [qrow] = LINE_CONT1;
+                  line_t &qline = row_buf [qrow];
 
-                      int qcol = 0;
+                  lalloc (qline);
+                  qline.set_is_longer ();
 
-                      for (;;)
-                        {
-                          int prow = lofs / prev_ncol + p;
-                          int pcol = lofs % prev_ncol;
+                  int qcol = 0;
 
-                          int len = min (min (prev_ncol - pcol, ncol - qcol), llen - lofs);
+                  for (;;)
+                    {
+                      int prow = lofs / prev_ncol + p;
+                      int pcol = lofs % prev_ncol;
 
-                          printf ("q %d lofs %d>%d len %d pq %d:%d p %d:%d q :%d\n", q, llen, lofs, len, prev_ncol, ncol, prow, pcol, qcol);
+                      line_t &pline = old_buf [p];
 
-                          if (len <= 0)
-                            {
-                              tl [qrow] = qcol;
+                      int len = min (min (prev_ncol - pcol, ncol - qcol), llen - lofs);
 
-                              TODO
-                              scr_blank_line (tp [qrow] + qcol, rp [qrow] + qcol,
-                                              ncol - qcol, DEFAULT_RSTYLE);
+                      printf ("q %d lofs %d>%d len %d pq %d:%d p %d:%d q :%d\n", q, llen, lofs, len, prev_ncol, ncol, prow, pcol, qcol);
 
-                              break;
-                            }
+                      if (len <= 0)
+                        {
+                          qline.l = qcol;
+                          scr_blank_line (qline, qcol, ncol - qcol, DEFAULT_RSTYLE);
+                          break;
+                        }
 
-                          assert (lofs < 1000);
+                      assert (lofs < 1000);
 
-                          memcpy (tp [qrow] + qcol, save[prow].t + pcol, len * sizeof (text_t));
-                          memcpy (rp [qrow] + qcol, save[prow].r + pcol, len * sizeof (rend_t));
+                      memcpy (qline.t + qcol, pline.t + pcol, len * sizeof (text_t));
+                      memcpy (qline.r + qcol, pline.r + pcol, len * sizeof (rend_t));
 
-                          lofs += len;
-                          qcol += len;
+                      lofs += len;
+                      qcol += len;
 
-                          if (qcol == ncol)
-                            break;
-                        }
+                      if (qcol == ncol)
+                        break;
                     }
-                  else
-                    lofs += ncol;
                 }
+              else
+                lofs += ncol;
             }
         }
 
-      free (screen.text); screen.text = tp;
-      free (screen.rend); screen.rend = rp;
-      free (screen.tlen); screen.tlen = tl;
+      free (old_buf);
+      delete old_ta;
+      delete old_ra;
 
-      for (p = 0; p < total_rows; p++) printf ("P %p %d\n", save[p].t, save[p].l);//D
-#endif
+      min_it (screen.cur.row, nrow - 1);
+      min_it (screen.cur.col, ncol - 1);
 
       if (tabs)
         free (tabs);
@@ -427,21 +367,12 @@ rxvt_term::scr_reset ()
 
   tabs = (char *)rxvt_malloc (ncol * sizeof (char));
 
-  for (p = 0; p < ncol; p++)
-    tabs[p] = (p % TABSIZE == 0) ? 1 : 0;
+  for (int col = ncol; col--; )
+    tabs [col] = col % TABSIZE == 0;
 
   tt_winch ();
 }
 
-void
-rxvt_term::scr_reset_realloc ()
-{
-  swap_save   = (line_t *) rxvt_realloc (swap_save  , nrow       * sizeof (line_t));
-  drawn       = (line_t *) rxvt_realloc (drawn      , nrow       * sizeof (line_t));
-  buf         = (line_t *) rxvt_realloc (buf        , nrow       * sizeof (line_t));
-  save        = (line_t *) rxvt_realloc (save       , total_rows * sizeof (line_t));
-}
-
 /* ------------------------------------------------------------------------- */
 /*
  * Free everything.  That way malloc debugging can find leakage.
@@ -452,10 +383,10 @@ rxvt_term::scr_release ()
   delete talloc; talloc = 0;
   delete ralloc; ralloc = 0;
 
-  free (save);
-  free (swap_save);
-  free (drawn);
-  free (buf);
+  free (row_buf);
+  free (swap_buf);
+  free (drawn_buf);
+  free (temp_buf);
   free (tabs);
 }
 
@@ -559,7 +490,7 @@ rxvt_term::scr_change_screen (int scrn)
       num_scr = 0;
 
       for (int i = nrow; i--; )
-        ::swap (ROW(i), swap_save[i]);
+        ::swap (ROW(i), swap_buf [i]);
 
       ::swap (screen.charset, swap.charset);
       ::swap (screen.flags, swap.flags);
@@ -695,16 +626,18 @@ rxvt_term::scr_scroll_text (int row1, int row2, int count)
 
       int rows = row2 - row1 + 1;
 
+      min_it (count, rows);
+
       for (int row = 0; row < rows; row++)
         {
-          buf [row] = ROW(row1 + (row + count + rows) % rows);
+          temp_buf [row] = ROW(row1 + (row + count + rows) % rows);
 
           if (!IN_RANGE_EXC (row + count, 0, rows))
-            scr_blank_screen_mem (buf [row], rstyle);
+            scr_blank_screen_mem (temp_buf [row], rstyle);
         }
 
       for (int row = 0; row < rows; row++)
-        ROW(row1 + row) = buf [row];
+        ROW(row1 + row) = temp_buf [row];
     }
 
   return count;
@@ -732,9 +665,9 @@ rxvt_term::scr_add_lines (const unicode_t *str, int nlines, int len)
   if (nlines > 0)
     {
       nlines += screen.cur.row - screen.bscroll;
-      if ((nlines > 0)
-          && (screen.tscroll == 0)
-          && (screen.bscroll == (nrow - 1)))
+      if (nlines > 0
+          && screen.tscroll == 0
+          && screen.bscroll == (nrow - 1))
         {
           /* _at least_ this many lines need to be scrolled */
           scr_scroll_text (screen.tscroll, screen.bscroll, nlines);
@@ -744,12 +677,11 @@ rxvt_term::scr_add_lines (const unicode_t *str, int nlines, int len)
 
 #ifdef DEBUG_STRICT
   assert (screen.cur.col < last_col);
-  assert ((screen.cur.row < nrow)
-          && (screen.cur.row >= - (int32_t)nsaved));
+  assert (screen.cur.row < nrow
+          && screen.cur.row >= -nsaved);
 #else                           /* drive with your eyes closed */
   min_it (screen.cur.col, last_col - 1);
-  min_it (screen.cur.row, (int32_t)nrow - 1);
-  max_it (screen.cur.row, - (int32_t)nsaved);
+  clamp_it (screen.cur.row, -nsaved, nrow - 1);
 #endif
   row = screen.cur.row;
 
@@ -1136,8 +1068,7 @@ rxvt_term::scr_gotorc (int row, int col, int relative)
   ZERO_SCROLLBACK ();
 
   screen.cur.col = relative & C_RELATIVE ? screen.cur.col + col : col;
-  max_it (screen.cur.col, 0);
-  min_it (screen.cur.col, (int32_t)ncol - 1);
+  clamp_it (screen.cur.col, 0, ncol - 1);
 
   screen.flags &= ~Screen_WrapNext;
 
@@ -1171,8 +1102,7 @@ rxvt_term::scr_gotorc (int row, int col, int relative)
         screen.cur.row = row;
     }
 
-  max_it (screen.cur.row, 0);
-  min_it (screen.cur.row, (int32_t)nrow - 1);
+  clamp_it (screen.cur.row, 0, nrow - 1);
 }
 
 /* ------------------------------------------------------------------------- */
@@ -1197,8 +1127,7 @@ rxvt_term::scr_index (enum page_dirn direction)
   else
     screen.cur.row += dirn;
 
-  max_it (screen.cur.row, 0);
-  min_it (screen.cur.row, (int32_t)nrow - 1);
+  clamp_it (screen.cur.row, 0, nrow - 1);
   selection_check (0);
 }
 
@@ -1226,7 +1155,7 @@ rxvt_term::scr_erase_line (int mode)
       case 0:                     /* erase to end of line */
         col = screen.cur.col;
         num = ncol - col;
-        min_it (ROW(row).l, (int16_t)col);
+        min_it (ROW(row).l, col);
         if (ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur)
             || ROWCOL_IN_ROW_AT_OR_AFTER (selection.end, screen.cur))
           CLEAR_SELECTION ();
@@ -1303,7 +1232,7 @@ rxvt_term::scr_erase_screen (int mode)
   if (row >= nrow) /* Out Of Bounds */
     return;
 
-  min_it (num, (nrow - row));
+  min_it (num, nrow - row);
 
   if (rstyle & (RS_RVid | RS_Uline))
     ren = (rend_t) ~RS_None;
@@ -1326,7 +1255,7 @@ rxvt_term::scr_erase_screen (int mode)
     {
       scr_blank_screen_mem (ROW (row), rstyle);
       ROW (row).l = 0;
-      scr_blank_line (drawn[row], 0, ncol, ren);
+      scr_blank_line (drawn_buf [row], 0, ncol, ren);
     }
 }
 
@@ -1421,7 +1350,7 @@ rxvt_term::scr_insdel_chars (int count, int insdel)
   scr_do_wrap ();
 
   selection_check (1);
-  min_it (count, (ncol - screen.cur.col));
+  min_it (count, ncol - screen.cur.col);
 
   row = screen.cur.row;
 
@@ -1511,7 +1440,7 @@ void
 rxvt_term::scr_scroll_region (int top, int bot)
 {
   max_it (top, 0);
-  min_it (bot, (int)nrow - 1);
+  min_it (bot, nrow - 1);
 
   if (top > bot)
     return;
@@ -1725,7 +1654,7 @@ rxvt_term::scr_refresh_rend (rend_t mask, rend_t value)
   for (int i = 0; i < nrow; i++)
     {
       int col = 0;
-      rend_t *drp = drawn[i].r;
+      rend_t *drp = drawn_buf[i].r;
 
       for (; col < ncol; col++, drp++)
         if ((*drp & mask) == value)
@@ -1753,7 +1682,7 @@ rxvt_term::scr_expose (int x, int y, int ewidth, int eheight, bool refresh)
   int i;
   row_col_t rc[RC_COUNT];
 
-  if (!drawn)  /* sanity check */
+  if (!drawn_buf)  /* sanity check */
     return;
 
 #ifndef NO_SLOW_LINK_SUPPORT
@@ -1787,7 +1716,7 @@ rxvt_term::scr_expose (int x, int y, int ewidth, int eheight, bool refresh)
     }
 
   for (i = rc[PART_BEG].row; i <= rc[PART_END].row; i++)
-    fill_text (&drawn[i].t[rc[PART_BEG].col], 0, rc[PART_END].col - rc[PART_BEG].col + 1);
+    fill_text (&drawn_buf[i].t[rc[PART_BEG].col], 0, rc[PART_END].col - rc[PART_BEG].col + 1);
 
   if (refresh)
     scr_refresh (SLOW_REFRESH);
@@ -2055,7 +1984,7 @@ rxvt_term::scr_refresh (unsigned char refresh_type)
           {
             if (ocrow < nrow
                 && oldcursor.col < ncol)
-              drawn[ocrow].r[oldcursor.col] ^= (RS_RVid | RS_Uline);
+              drawn_buf[ocrow].r[oldcursor.col] ^= (RS_RVid | RS_Uline);
 
             if (focus || !showcursor)
               oldcursor.row = -1;
@@ -2104,8 +2033,8 @@ rxvt_term::scr_refresh (unsigned char refresh_type)
           if (row + i >= 0 && row + i < nrow && row + i != ocrow)
             {
               line_t s  = ROW(row - view_start);
-              line_t d  = drawn[row];
-              line_t d2 = drawn[row + i];
+              line_t d  = drawn_buf[row];
+              line_t d2 = drawn_buf[row + i];
 
               for (nits = 0, col = ncol; col--; )
                 if (s.t[col] != d2.t[col] || s.r[col] != d2.r[col])
@@ -2153,8 +2082,8 @@ rxvt_term::scr_refresh (unsigned char refresh_type)
     {
       text_t *stp = ROW(row - view_start).t;
       rend_t *srp = ROW(row - view_start).r;
-      text_t *dtp = drawn[row].t;
-      rend_t *drp = drawn[row].r;
+      text_t *dtp = drawn_buf[row].t;
+      rend_t *drp = drawn_buf[row].r;
 
       /*
        * E2: OK, now the real pass
@@ -2377,7 +2306,7 @@ rxvt_term::scr_refresh (unsigned char refresh_type)
             col--;
 
           while (col + cursorwidth < ncol
-                 && drawn[oldcursor.row].t[col + cursorwidth] == NOCHAR)
+                 && drawn_buf[oldcursor.row].t[col + cursorwidth] == NOCHAR)
             cursorwidth++;
 
 #ifndef NO_CURSORCOLOR
@@ -2419,12 +2348,12 @@ void
 rxvt_term::scr_remap_chars ()
 {
   for (int i = total_rows; i--; )
-    scr_remap_chars (save[i]);
+    scr_remap_chars (row_buf [i]);
 
   for (int i = nrow; i--; )
     {
-      scr_remap_chars (drawn[i]);
-      scr_remap_chars (swap_save[i]);
+      scr_remap_chars (drawn_buf [i]);
+      scr_remap_chars (swap_buf [i]);
     }
 }
 
@@ -2531,16 +2460,16 @@ rxvt_term::scr_dump (int fd)
   for (row = saveLines - nsaved;
        row < saveLines + nrow - 1; row++)
     {
-      width = save[row].l >= 0 ? save[row].l
+      width = row_buf[row].l >= 0 ? row_buf[row].l
               : ncol;
       for (towrite = width; towrite; towrite -= wrote)
         {
-          wrote = write (fd, & (save[row].t[width - towrite]),
+          wrote = write (fd, & (row_buf[row].t[width - towrite]),
                         towrite);
           if (wrote < 0)
             return;         /* XXX: death, no report */
         }
-      if (save[row].l >= 0)
+      if (row_buf[row].l >= 0)
         if (write (fd, r1, 1) <= 0)
           return; /* XXX: death, no report */
     }
@@ -3612,11 +3541,8 @@ rxvt_term::scr_overlay_new (int x, int y, int w, int h)
   w += 2; min_it (w, ncol);
   h += 2; min_it (h, nrow);
 
-  x -= 1; max_it (x, 0);
-  y -= 1; max_it (y, 0);
-
-  min_it (x, ncol - w);
-  min_it (y, nrow - h);
+  x -= 1; clamp_it (x, 0, ncol - w);
+  y -= 1; clamp_it (y, 0, nrow - h);
 
   ov_x = x; ov_y = y;
   ov_w = w; ov_h = h;