screen-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[screen-devel] vertical split


From: bill
Subject: [screen-devel] vertical split
Date: Sat, 24 Dec 2005 23:08:51 +0000
User-agent: Mozilla Thunderbird 1.0.7-1.1.fc3 (X11/20050929)

Here's a much improved patch for the vertical split.  It
handles creation (^A-S, ^A-V), deletion (^A-X), and growing via
(^A-Q), but does not implement resizing.  There are some issues:

Status lines don't display properly.  If your screen looks like this:
----------------------------
|          |        |      |
| a | b | c | | | | |
----------------------------
and you do a horizontal split on the middle screen, the regions are built
correctly, but the status line is trying to go full width and munges the
screen until regions a and c redisplay.

Also, titles only appear in status lines if the region abuts the left side
of the display.

I made some implementation decisions that I'd like some feedback on
before I start fully implementing the resize functions.  Currently,
I keep track of state.  eg, there are (at least) 2 ways to get
a screen that looks like:
----------------------------
|   d      |        |      |
|          |        |      |
|--------------------------|
|          |   b    |      |
|          |---------------|
| a | c | | | | | | | |
----------------------------
In particular, if a was created by doing a horizontal split, then destroying
a (via ^A-X) will cause d to grow down into a.  If a was created via a
vertical split, then destroying a will cause b and c to grow into a.  I was
thinking that attempts to resize would use the same state.  Ie an attempt
to grow a by 5 lines will grow it into d in the one case, or into b and c
in the other.  Also, 'resize =' would equalize real-estate with the
appropriate regions.  That seems cleaner than putting an extra argument
into the resize function to determine which direction to grow.

Also, as in the screen pictured above, what should happen if you try
to grow a by 8 columns, but c is only 6 columns wide?  Should the attempt
silently fail, or should c be squeezed down to some mimimum, or should c
simply be deleted? I favor destroying c.
I've tested this, but I am by no means a power user and am not really
sure of what configuration options might affect things.  (Basically
I tested with and without hardstatus lines.)  I would love to get
some feed back on what key sequences with what configurations cause
the dungeon to collapse.

Also, I decided to put the regions right up against each other, with
no space in between.  That could be configurable.  The main reason
I did that was that the status lines seemed to munge less...I plan
on looking into that issue, as I'd like to get titles to display
properly.  But Santa is coming in about an hour, so I need to set
out the cookies....Merry Christmas!
diff -u screen-4.0.2/comm.c vs_screen-4.0.2/comm.c
--- screen-4.0.2/comm.c 2003-09-08 15:25:08.000000000 +0100
+++ vs_screen-4.0.2/comm.c      2005-12-24 22:35:01.234593680 +0000
@@ -309,6 +309,7 @@
   { "vbellwait",       ARGS_1 },
   { "verbose",         ARGS_01 },
   { "version",         ARGS_0 },
+  { "vert_split",              NEED_DISPLAY|ARGS_0 },
   { "wall",            NEED_DISPLAY|ARGS_1},
   { "width",           ARGS_0123 },
   { "windowlist",      NEED_DISPLAY|ARGS_012 },
diff -u screen-4.0.2/display.c vs_screen-4.0.2/display.c
--- screen-4.0.2/display.c      2003-12-05 13:45:41.000000000 +0000
+++ vs_screen-4.0.2/display.c   2005-12-24 22:30:24.003739176 +0000
@@ -33,6 +33,7 @@
 #include "extern.h"
 #include "braille.h"
 
+
 static int  CountChars __P((int));
 static int  DoAddChar __P((int));
 static int  BlankResize __P((int, int));
@@ -163,6 +164,7 @@
 DefResize(wi, he)
 int wi, he;
 {
+    debug("DefResize\n");
   return -1;
 }
 
@@ -456,246 +458,714 @@
 FreeCanvas(cv)
 struct canvas *cv;
 {
-  struct viewport *vp, *nvp;
-  struct win *p;
+    struct viewport *vp, *nvp;
+    struct win     *p;
 
-  p = Layer2Window(cv->c_layer);
-  SetCanvasWindow(cv, 0);
-  if (p)
-    WindowChanged(p, 'u');
-  if (flayer == cv->c_layer)
-    flayer = 0;
-  for (vp = cv->c_vplist; vp; vp = nvp)
-    {
-      vp->v_canvas = 0;
-      nvp = vp->v_next;
-      vp->v_next = 0;
-      free(vp);
+    p = Layer2Window(cv->c_layer);
+    SetCanvasWindow(cv, 0);
+    if (p)
+        WindowChanged(p, 'u');
+    if (flayer == cv->c_layer)
+        flayer = 0;
+    for (vp = cv->c_vplist; vp; vp = nvp) {
+        vp->v_canvas = 0;
+        nvp          = vp->v_next;
+        vp->v_next   = 0;
+        free(vp);
+    }
+    evdeq(&cv->c_captev);
+    free(cv);
+}
+
+struct canvas *
+get_new_canvas(void)
+{   /* Allocate a new canvas, and assign it characteristics
+    equal to those of the current foreground. */
+    struct canvas *cv;
+
+    if ((cv = (struct canvas *) calloc(1, sizeof *cv)) == 0)
+        return NULL;
+
+    cv -> c_xs               = D_forecv -> c_xs;
+    cv -> c_xe               = D_forecv -> c_xe;
+    cv -> c_ys               = D_forecv -> c_ys;
+    cv -> c_ye               = D_forecv -> c_ye;
+    cv -> c_xoff             = D_forecv -> c_xoff;
+    cv -> c_yoff             = D_forecv -> c_yoff;
+    cv -> c_display          = display;
+    cv -> c_vplist           = 0;
+    cv -> c_captev.type      = EV_TIMEOUT;
+    cv -> c_captev.data      = (char *) cv;
+    cv -> c_captev.handler   = cv_winid_fn;
+
+    cv -> c_blank.l_cvlist   = cv;
+    cv -> c_blank.l_width    = cv->c_xe - cv->c_xs + 1;
+    cv -> c_blank.l_height   = cv->c_ye - cv->c_ys + 1;
+    cv -> c_blank.l_x        = cv->c_blank.l_y = 0;
+    cv -> c_blank.l_layfn    = &BlankLf;
+    cv -> c_blank.l_data     = 0;
+    cv -> c_blank.l_next     = 0;
+    cv -> c_blank.l_bottom   = &cv->c_blank;
+    cv -> c_blank.l_blocking = 0;
+    cv -> c_layer            = &cv->c_blank;
+    cv -> c_lnext            = 0;
+
+    cv -> c_left  = D_forecv -> c_left;
+    cv -> c_right = D_forecv -> c_right;
+    cv -> c_above = D_forecv -> c_above;
+    cv -> c_below = D_forecv -> c_below;
+
+    return cv;
+}
+
+struct screen_region {
+    /* This is a group of canvasses that are all in 
+    the same column or row. */
+    struct canvas *start;   /* First canvas in the region. */
+    struct canvas *end;     /* Last canvas in the region. */
+    int            count;   /* Number of canvasses in the region. */
+    int            type;    /* Whether HORIZONTAL or VERTICAL. */
+    int            xs;      /* starting x coordinate */
+    int            xe;      /* ending   x coordinate */
+    int            ys;      /* starting y coordinate */
+    int            ye;      /* ending   y coordinate */
+};
+
+int
+share_limits( type, cv)
+int type;       /* HORIZONTAL or VERTICAL */
+struct canvas *cv;  /* canvas to compare against D_forecv. */
+{  /* Return non-zero if the cv shares limits with D_forecv. 
+    ie, their horizontal or veritcal boundaries are the same.
+    */
+    switch (type) {
+    case VERTICAL:
+        return cv -> c_xs == D_forecv -> c_xs && cv->c_xe == D_forecv -> c_xe;
+    case HORIZONTAL:
+        return cv -> c_ys == D_forecv -> c_ys && cv->c_ye == D_forecv -> c_ye;
     }
-  evdeq(&cv->c_captev);
-  free(cv);
+    ASSERT(0);
+    return 0;
 }
 
 int
-AddCanvas()
+get_regional_dimensions(type,a)
+int type;  /* 0 - horizontal, 1 - vertical */
+struct screen_region *a;
+{  /* Find the start and end of the screen region.
+    I'm using the term 'region' here differently
+    than elsewhere.
+
+    Suppose the screen currently looks
+    like this:
+    ---------------------------
+    |  0   |   1    |    2    |
+    ---------------------------
+    |  3   |   4    |    5    |
+    ---------------------------
+    |          6              |
+    ---------------------------
+    |   7  |   8    |    9    |
+    ---------------------------
+    Where there are 10 entries in D_cvlist.
+    Canvasses 0,1,2 are in the same horizontal
+    region, and 1,4 are in the same vertical
+    region.  We need to be careful not to
+    lump 1 and 4 together w/8.
+
+    Throughout, I'm assuming that the only
+    way canvasses are created is through
+    AddCanvas() as  I'm not
+    aware of any other methods to create a canvas.
+    If that assumption fails, then changes must be
+    made.
+
+    Written by Bill Pursell. 23/12/2005
+    */
+
+    struct canvas *cv; /* Pointer into D_cvlist. */
+    int seen_fore;     /* Flag used when walking the list. */
+
+    seen_fore = 0;
+    a->count = 0;
+    a->type  = type;
+
+    if (type == VERTICAL) {
+        a->xs = D_forecv -> c_xs;
+        a->xe = D_forecv -> c_xe;
+        a->ys = -1;
+    }
+    if (type == HORIZONTAL) {
+        a->ys = D_forecv -> c_ys;
+        a->ye = D_forecv -> c_ye;
+        a->xs = -1;
+    }
+    /* Count the canvasses in the same region as the
+    canvas with the focus, and find the limits of the region. */
+    for (cv = D_cvlist; cv; cv = cv->c_next) {
+        if (cv == D_forecv)
+            seen_fore = 1;
+        if (share_limits( type, cv)) {
+            debug2("cv = %x  %s\n", cv, (cv == D_forecv)? "FORE":"");
+            debug2("x range: %d - %d\n", cv->c_xs, cv->c_xe);
+            debug2("y range: %d - %d\n", cv->c_ys, cv->c_ye);
+            switch (type) {
+            case VERTICAL  : 
+                if (a->ys == -1) {
+                    a->ys = cv -> c_ys; 
+                    a->start = cv;
+                }
+                a->ye = cv -> c_ye;
+                break;
+            case HORIZONTAL:
+                if (a->xs == -1) {
+                    a->xs = cv -> c_xs; 
+                    a->start = cv;
+                }
+                a->xe = cv -> c_xe;
+                break;
+            }
+
+            a->end = cv;
+            a->count++;
+        }
+        if (!share_limits(type, cv) || cv -> c_next == NULL) {
+            if (seen_fore) {
+                debug2("x range of Region: %d-%d\n", a->xs, a->xe);
+                debug2("y range of Region: %d-%d\n", a->ys, a->ye);
+                break;
+            }
+            else {
+                switch(type) {
+                case VERTICAL  : a->ys = -1; break;
+                case HORIZONTAL: a->xs = -1; break;
+                }
+                a->count = 0;
+            }
+        }
+    }
+    ASSERT(seen_fore);
+}
+
+void
+debug_print_canvas(cv)
+struct canvas *cv;
 {
-  int hh, h, i, j;
-  struct canvas *cv, **cvpp;
+#ifdef DEBUG
+    debug2("%x %s\n", cv, (cv == D_forecv)?"  HAS FOCUS":"");
+    debug2("    above: %x    below: %x\n", cv->c_above, cv->c_below);
+    debug2("    left: %x     right: %x\n", cv->c_left,  cv->c_right);
+    debug3("    x range: %2d-%2d, xoff = %d\n", 
+        cv->c_xs, cv->c_xe, cv->c_xoff);
+    debug3("    y range: %2d-%2d yoff = %d\n", 
+        cv->c_ys, cv->c_ye, cv->c_yoff);
+    debug1("    next: %x\n", cv->c_next);
+#endif
+}
 
-  for (cv = D_cvlist, j = 0; cv; cv = cv->c_next)
-    j++;
-  j++; /* new canvas */
-  h = D_height - (D_has_hstatus == HSTATUS_LASTLINE);
-  if (h / j <= 1)
-    return -1;
+void
+debug_print_canvas_dimensions()
+{
+    #ifdef DEBUG
+    struct canvas *cv;
 
-  for (cv = D_cvlist; cv; cv = cv->c_next)
-    if (cv == D_forecv)
-      break;
-  ASSERT(cv);
-  cvpp = &cv->c_next;
+    for (cv = D_cvlist; cv; cv = cv->c_next) {
+        debug_print_canvas(cv);
+    }
+    #endif
+    return;
+}
 
-  if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0)
-    return -1;
+int
+AddCanvas(type)
+int type;  /* Horizontal or Vertical. */
+{   /** Add a new canvas */
+
+    struct canvas  *cv;   /* Index into D_cvlist. */
+    int    expanse;       /* Usable rows/columns in region. */
+    struct screen_region  vr;  /* Canvasses in the same row/column as the 
+                                  canvas with the focus.   */
+
+    switch(type) {
+    case VERTICAL:   
+        get_regional_dimensions(HORIZONTAL,&vr);
+        expanse  = vr.xe - vr.xs + 1; 
+        debug2("vr range: %d - %d\n", vr.xs, vr.xe);
+        ASSERT(expanse <=  D_width);
+        break;
+    case HORIZONTAL: 
+        get_regional_dimensions(VERTICAL,&vr);
+        expanse = vr.ye - vr.ys + 1; 
+        debug2("vr range: %d - %d\n", vr.ys, vr.ye);
+        ASSERT(expanse <=  D_height - (D_has_hstatus == HSTATUS_LASTLINE));
+        break;
+    }
+
+    /* Return if the region isn't big enough to split. */
+    if (expanse / vr.count <= 1)
+        return -1; 
+
+    /* Allocate a new canvas. */
+    if ( (cv = get_new_canvas()) == NULL)
+        return -1;
+
+    /* Increment the canvas count to account for the one we will add. */
+    vr.count++;
+
+    debug_print_canvas_dimensions();
+
+    /* Insert the new canvas after the current foreground. */
+    cv -> c_next = D_forecv->c_next;
+    D_forecv -> c_next = cv;
+    if (vr.end == D_forecv)
+        vr.end = cv;
+
+    /* Set the orientation. */
+    switch (type) {
+    case VERTICAL:
+        D_forecv -> c_right = cv;
+        cv -> c_left        = D_forecv;
+        break;
+    case HORIZONTAL:
+        D_forecv -> c_below = cv;
+        cv -> c_above       = D_forecv;
+        break;
+    }
+
+    /* Reset the size of each canvas in the region. */
+    for (cv = vr.start; cv; cv = cv->c_next) {
+        int this_size; /* new size of cv */
+
+        /* For the horizontal split, we leave space for a status line. */
+        this_size = expanse/ vr.count - (type ==HORIZONTAL);
+
+        /* Give any additional available rows/columns to the foreground. */
+        if (cv == D_forecv)
+            this_size += expanse % vr.count;
+
+        /* Set the type to use when  resizing. */
+        cv -> c_type = type;
+
+        switch(type) {
+        case VERTICAL:
+            cv -> c_xs = cv -> c_xoff = vr.xs;
+            cv -> c_xe = vr.xs + this_size - 1;
+            vr.xs += this_size;
+            break;
+        case HORIZONTAL:
+            if (cv == vr.end && cv->c_ye != D_height-1-
+                D_has_hstatus == HSTATUS_LASTLINE)
+                this_size += 1;  /* Don't make space for status line 
+                    in the bottom region (it already has one). */
+
+            cv -> c_ys = cv -> c_yoff = vr.ys;
+            cv -> c_ye = vr.ys + this_size - 1;
+            vr.ys += this_size + 1;  /* add one for status line. */
+            break;
+        }
+        if (cv == vr.end)
+            break;
+    }
+    debug("CANVASSES RESIZED:\n");
+    debug2("height = %d, D_has_hstatus %s HSTATUS_LASTLINE\n", 
+        D_height, (D_has_hstatus == HSTATUS_LASTLINE)?"=":"!=");
+    debug_print_canvas_dimensions();
 
-  cv->c_xs      = 0;
-  cv->c_xe      = D_width - 1;
-  cv->c_ys      = 0;
-  cv->c_ye      = D_height - 1;
-  cv->c_xoff    = 0;
-  cv->c_yoff    = 0;
-  cv->c_display = display;
-  cv->c_vplist  = 0;
-  cv->c_captev.type = EV_TIMEOUT;
-  cv->c_captev.data = (char *)cv;
-  cv->c_captev.handler = cv_winid_fn;
+    RethinkDisplayViewports();
+    ResizeLayersToCanvases();
+    return 0;
+}
 
-  cv->c_blank.l_cvlist = cv;
-  cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1;
-  cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1;
-  cv->c_blank.l_x = cv->c_blank.l_y = 0;
-  cv->c_blank.l_layfn = &BlankLf;
-  cv->c_blank.l_data = 0;
-  cv->c_blank.l_next = 0;
-  cv->c_blank.l_bottom = &cv->c_blank;
-  cv->c_blank.l_blocking = 0;
-  cv->c_layer = &cv->c_blank;
-  cv->c_lnext = 0;
+void
+remove_canvas_from_list(list, cv)
+struct canvas **list;
+struct canvas *cv;
+{   /** Prune cv from the list.  Does not free cv.*/
 
-  cv->c_next    = *cvpp;
-  *cvpp = cv;
+    struct canvas *pred;  /* Predecssor of cv in list. */
 
-  i = 0;
-  for (cv = D_cvlist; cv; cv = cv->c_next)
-    {
-      hh = h / j-- - 1;
-      cv->c_ys = i;
-      cv->c_ye = i + hh - 1;
-      cv->c_yoff = i;
-      i += hh + 1;
-      h -= hh + 1;
+    if (cv == *list ) {
+        *list = cv -> c_next;
     }
+    else {
+        /* Find the predecessor of cv. */
+        for (pred = *list; pred->c_next != cv; pred = pred->c_next)
+            ASSERT(pred);
 
-  RethinkDisplayViewports();
-  ResizeLayersToCanvases();
-  return 0;
+        pred -> c_next = cv -> c_next;
+    }
+}
+
+void
+redirect_pointers(list, old, new)
+struct canvas *list;
+struct canvas *old;
+struct canvas *new;
+{  /* For each canvas in the list, change any
+    of its screen orientation pointers from old to new. */
+    struct canvas *cv;
+    for (cv=list; cv; cv = cv->c_next) {
+        if (cv -> c_left == old)
+            cv -> c_left = (cv==new)?NULL:new;
+        if (cv -> c_above == old)
+            cv -> c_above = (cv==new)?NULL:new;;
+        if (cv -> c_right == old)
+            cv -> c_right = (cv==new)?NULL:new;;
+        if (cv -> c_below == old)
+            cv -> c_below = (cv==new)?NULL:new;;
+    }
+}
+
+struct canvas *
+squeeze_from_the_left(list, target)
+struct canvas *list;    /* List of canvasses to resize. */
+struct canvas *target;  /* Canvas in the list being removed. */
+{   /* Resize canvasses in the list so that
+    those to the left of the target get its space.
+
+    Return the earliest canvas in the list that is grown.
+    */
+
+    struct canvas *ret;  /* The return value.*/
+    struct canvas *cv;   /* For walking the list.*/
+
+    debug("squeeze from the left\n");
+    ret = NULL;
+
+    /* Resize all canvasses to the left of the target. */
+    for (cv = list; cv; cv = cv->c_next) {
+        if (cv -> c_right == target) {
+            cv -> c_xe = target -> c_xe; 
+            cv -> c_right = target -> c_right;
+            ret = (ret) ? ret : cv;
+        }
+    }
+
+
+    return ret;
+}
+
+struct canvas *
+squeeze_from_the_right(list, target)
+struct canvas *list;    /* List of canvasses to resize. */
+struct canvas *target;  /* Canvas in the list being removed. */
+{   /* Resize canvasses in the list so that
+    those to the right of the target get its space.
+
+    Return the earliest canvas in the list that is grown.
+    */
+
+    struct canvas *ret;  /* The return value.*/
+    struct canvas *cv;   /* For walking the list. */
+
+    debug("squeeze from the right\n");
+    ret = NULL;
+
+    /* Resize all canvasses to the right of the target. */
+    for (cv = list; cv; cv = cv->c_next) {
+        if (cv -> c_left == target) {
+            cv -> c_xs = target -> c_xs; 
+            cv -> c_left = target -> c_left;
+            ret = (ret) ? ret : cv;
+        }
+    }
+
+    return ret;
+}
+
+struct canvas *
+squeeze_from_below(list, target)
+struct canvas *list;    /* List of canvasses to resize. */
+struct canvas *target;  /* Canvas in the list being removed. */
+{   /* Resize canvasses in the list so that
+    those below the target get its space.
+
+    Return the earliest canvas in the list that is grown.
+    */
+
+    struct canvas *ret;  /* The return value.*/
+    struct canvas *cv;   /* For walking the list. */
+
+    ret = NULL;
+    debug("sqeeze from below\n");
+
+    /* Resize all canvasses below the target. */
+    for (cv = list; cv; cv = cv->c_next) {
+        if (cv -> c_above == target) {
+            cv -> c_ys = target -> c_ys; 
+            cv -> c_above = target -> c_above;
+            ret = (ret) ? ret : cv;
+        }
+    }
+
+    return ret;
+}
+
+struct canvas *
+squeeze_from_above(list, target)
+struct canvas *list;    /* List of canvasses to resize. */
+struct canvas *target;  /* Canvas in the list being removed. */
+{   /* Resize canvasses in the list so that
+    those above the target get its space.
+
+    Return the earliest canvas in the list that is grown.
+    */
+
+    struct canvas *ret;  /* The return value.*/
+    struct canvas *cv;   /* For walking the list. */
+
+    ret = NULL;
+
+    debug("sqeeze from above\n");
+
+    /* Resize all canvasses above the target. */
+    for (cv = list; cv; cv = cv->c_next) {
+        if (cv -> c_below == target) {
+            cv -> c_ye = target -> c_ye; 
+            cv -> c_below = target -> c_below;
+            ret = (ret) ? ret : cv;
+        }
+    }
+
+    return ret;
 }
 
+struct canvas *
+grow_surrounding_regions(list, fore)
+    struct canvas *list;
+    struct canvas *fore;
+{
+    /* Grow all the regions in the list that border
+    fore appropriately.  */
+    struct canvas *cv;        /* For walking the list. */
+    struct canvas *new_fore;  /* Replacement for fore. */
+
+    debug("grow_surrounding_regions\n");
+
+    new_fore = NULL;
+    if (fore != list) {
+        /* Grow the regions from above (the left). */
+        switch (fore -> c_type) {
+        case HORIZONTAL: 
+            if ( !(new_fore = squeeze_from_above(list, fore))) 
+                new_fore = squeeze_from_the_left(list, fore);
+            break;
+        case VERTICAL:   
+            if ( !(new_fore = squeeze_from_the_left(list, fore)))
+                new_fore = squeeze_from_above(list, fore);
+            break;
+        }
+    }
+    else {  /* Grow the regions from below (the right). */
+        switch (fore -> c_type) {
+        case HORIZONTAL: 
+            if ( !(new_fore = squeeze_from_below(list, fore)))
+                new_fore = squeeze_from_the_right(list, fore); 
+            break;
+        case VERTICAL:   
+            if ( !(new_fore = squeeze_from_the_right(list, fore)))
+                new_fore = squeeze_from_below(list, fore);
+            break;
+        }
+    }
+    ASSERT (new_fore);
+    return new_fore;
+}
+
+
 void
 RemCanvas()
-{
-  int hh, h, i, j;
-  struct canvas *cv, **cvpp;
-  int did = 0;
-
-  h = D_height - (D_has_hstatus == HSTATUS_LASTLINE);
-  for (cv = D_cvlist, j = 0; cv; cv = cv->c_next)
-    j++;
-  if (j == 1)
-    return;
-  i = 0;
-  j--;
-  for (cvpp = &D_cvlist; (cv = *cvpp); cvpp = &cv->c_next)
-    {
-      if (cv == D_forecv && !did)
-       {
-         *cvpp = cv->c_next;
-         FreeCanvas(cv);
-         cv = *cvpp;
-         D_forecv = cv ? cv : D_cvlist;
-         D_fore = Layer2Window(D_forecv->c_layer);
-         flayer = D_forecv->c_layer;
-         if (cv == 0)
-           break;
-         did = 1;
-       }
-      hh = h / j-- - 1;
-      if (!captionalways && i == 0 && j == 0)
-       hh++;
-      cv->c_ys = i;
-      cv->c_ye = i + hh - 1;
-      cv->c_yoff = i;
-      i += hh + 1;
-      h -= hh + 1;
+{   /** Remove the foreground canvas. */
+
+    struct screen_region  vr; /*Canvasses in the same row/column as D_forecv.*/
+    struct canvas *new_fore;  /* Canvas which will replace D_forecv. */
+
+    /* Do nothing if the foreground is the only canvas. */
+    if (D_cvlist->c_next == NULL)
+        return;
+
+    /* Get the region in which the foreground resides. */
+    switch (D_forecv -> c_type) {
+    case VERTICAL:   get_regional_dimensions(HORIZONTAL, &vr); break;
+    case HORIZONTAL: get_regional_dimensions(VERTICAL, &vr);   break;
+    default:         ASSERT(0);
+    };
+
+    debug1("RemCanvas. count = %d\n",vr.count);
+    debug_print_canvas_dimensions();
+
+    if (vr.count > 1) {  /* Resize the neighboring canvas in region. */
+        debug2("D_forecv = %x  vr.start = %x\n",D_forecv, vr.start);
+        /* If there is a canvas before D_forecv, then
+        grow that canvas to take up the space. */
+        if (D_forecv != vr.start) {
+            struct canvas *pred;  /* Predecssor of D_forecv. */
+            for (pred = vr.start; pred->c_next != D_forecv; )
+                pred = pred->c_next;
+
+            new_fore         = pred;
+            new_fore -> c_ye = D_forecv->c_ye;
+            new_fore -> c_xe = D_forecv->c_xe;
+
+            /* Redirect locaters. */
+            switch(D_forecv -> c_type) {
+            case VERTICAL: 
+                new_fore -> c_right = D_forecv -> c_right;
+                if (new_fore -> c_right)
+                    new_fore -> c_right -> c_left = new_fore;
+                break;
+            case HORIZONTAL: 
+                new_fore -> c_below = D_forecv -> c_below;
+                if (new_fore -> c_below)
+                    new_fore -> c_below -> c_above = new_fore;
+                break;
+            }
+        } 
+        else {
+            new_fore           = D_forecv -> c_next;
+            new_fore -> c_ys   = D_forecv -> c_ys;
+            new_fore -> c_xs   = D_forecv -> c_xs;
+            new_fore -> c_yoff = new_fore -> c_ys;
+            new_fore -> c_xoff = new_fore -> c_xs;
+            debug_print_canvas(new_fore);
+        }
     }
-  RethinkDisplayViewports();
-  ResizeLayersToCanvases();
+    else { /* Resize all bordering regions. */
+        new_fore = grow_surrounding_regions( D_cvlist, D_forecv);
+    }
+
+    /* Redirect all pointers in the list. */
+    redirect_pointers(D_cvlist, D_forecv, new_fore);
+
+    remove_canvas_from_list(&D_cvlist, D_forecv);
+    FreeCanvas(D_forecv);
+    D_forecv = new_fore;
+    D_fore   = Layer2Window(D_forecv->c_layer);
+    flayer   = D_forecv->c_layer;
+
+    debug1("Removed Canvas: %x\n",D_forecv);
+    debug_print_canvas_dimensions();
+    debug("RRRRRRRRRRRvas:\n\n");
+
+    RethinkDisplayViewports();
+    ResizeLayersToCanvases();
 }
 
 void
 OneCanvas()
 {
-  struct canvas *mycv = D_forecv;
-  struct canvas *cv, **cvpp;
+    struct canvas  *mycv = D_forecv;
+    struct canvas  *cv, **cvpp;
 
-  for (cvpp = &D_cvlist; (cv = *cvpp);)
-    {
-      if (cv == mycv)
-        {
-         cv->c_ys = 0;
-         cv->c_ye = D_height - 1 - (D_has_hstatus == HSTATUS_LASTLINE) - 
captionalways;
-         cv->c_yoff = 0;
-         cvpp = &cv->c_next;
-        }
-      else
-        {
-         *cvpp = cv->c_next;
-         FreeCanvas(cv);
+    for (cvpp = &D_cvlist; (cv = *cvpp);) {
+        if (cv == mycv) {
+            cv->c_xs = 0;
+            cv->c_xe = D_width-1;
+            cv->c_xoff = 0;
+
+            cv->c_ys = 0;
+            cv->c_ye =
+                    D_height - 1 - (D_has_hstatus ==
+                    HSTATUS_LASTLINE) - captionalways;
+            cv->c_yoff = 0;
+            cvpp = &cv->c_next;
+        } else {
+            *cvpp = cv->c_next;
+            FreeCanvas(cv);
         }
     }
-  RethinkDisplayViewports();
-  ResizeLayersToCanvases();
+    RethinkDisplayViewports();
+    ResizeLayersToCanvases();
 }
 
 int
 RethinkDisplayViewports()
 {
-  struct canvas *cv;
-  struct viewport *vp, *vpn;
+    struct canvas  *cv;
+    struct viewport *vp, *vpn;
 
-  /* free old viewports */
-  for (cv = display->d_cvlist; cv; cv = cv->c_next)
-    {
-      for (vp = cv->c_vplist; vp; vp = vpn)
-       {
-         vp->v_canvas = 0;
-         vpn = vp->v_next;
-          bzero((char *)vp, sizeof(*vp));
-          free(vp);
-       }
-      cv->c_vplist = 0;
+    debug("RethinkDisplayViewports\n");
+    /* free old viewports */
+    for (cv = display->d_cvlist; cv; cv = cv->c_next) {
+        for (vp = cv->c_vplist; vp; vp = vpn) {
+            vp->v_canvas = 0;
+            vpn = vp->v_next;
+            bzero((char *) vp, sizeof(*vp));
+            free(vp);
+        }
+        cv->c_vplist = 0;
     }
-  display->d_vpxmin = -1;
-  display->d_vpxmax = -1;
+    display->d_vpxmin = -1;
+    display->d_vpxmax = -1;
 
-  for (cv = display->d_cvlist; cv; cv = cv->c_next)
-    {
-      if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
-       return -1;
+    /* Allocate new viewports. */
+    for (cv = display->d_cvlist; cv; cv = cv->c_next) {
+        if ((vp = (struct viewport *) malloc(sizeof *vp)) == 0)
+            return -1;
 #ifdef HOLE
-      vp->v_canvas = cv;
-      vp->v_xs = cv->c_xs;
-      vp->v_ys = (cv->c_ys + cv->c_ye) / 2;
-      vp->v_xe = cv->c_xe;
-      vp->v_ye = cv->c_ye;
-      vp->v_xoff = cv->c_xoff;
-      vp->v_yoff = cv->c_yoff;
-      vp->v_next = cv->c_vplist;
-      cv->c_vplist = vp;
-
-      if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
-       return -1;
-      vp->v_canvas = cv;
-      vp->v_xs = (cv->c_xs + cv->c_xe) / 2;
-      vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4;
-      vp->v_xe = cv->c_xe;
-      vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1;
-      vp->v_xoff = cv->c_xoff;
-      vp->v_yoff = cv->c_yoff;
-      vp->v_next = cv->c_vplist;
-      cv->c_vplist = vp;
-
-      if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
-       return -1;
-      vp->v_canvas = cv;
-      vp->v_xs = cv->c_xs;
-      vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4;
-      vp->v_xe = (3 * cv->c_xs + cv->c_xe) / 4 - 1;
-      vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1;
-      vp->v_xoff = cv->c_xoff;
-      vp->v_yoff = cv->c_yoff;
-      vp->v_next = cv->c_vplist;
-      cv->c_vplist = vp;
-
-      if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
-       return -1;
-      vp->v_canvas = cv;
-      vp->v_xs = cv->c_xs;
-      vp->v_ys = cv->c_ys;
-      vp->v_xe = cv->c_xe;
-      vp->v_ye = (3 * cv->c_ys + cv->c_ye) / 4 - 1;
-      vp->v_xoff = cv->c_xoff;
-      vp->v_yoff = cv->c_yoff;
-      vp->v_next = cv->c_vplist;
-      cv->c_vplist = vp;
+        vp->v_canvas = cv;
+        vp->v_xs = cv->c_xs;
+        vp->v_ys = (cv->c_ys + cv->c_ye) / 2;
+        vp->v_xe = cv->c_xe;
+        vp->v_ye = cv->c_ye;
+        vp->v_xoff = cv->c_xoff;
+        vp->v_yoff = cv->c_yoff;
+        vp->v_next = cv->c_vplist;
+        cv->c_vplist = vp;
+
+        if ((vp = (struct viewport *) malloc(sizeof *vp)) == 0)
+            return -1;
+        vp->v_canvas = cv;
+        vp->v_xs = (cv->c_xs + cv->c_xe) / 2;
+        vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4;
+        vp->v_xe = cv->c_xe;
+        vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1;
+        vp->v_xoff = cv->c_xoff;
+        vp->v_yoff = cv->c_yoff;
+        vp->v_next = cv->c_vplist;
+        cv->c_vplist = vp;
+
+        if ((vp = (struct viewport *) malloc(sizeof *vp)) == 0)
+            return -1;
+        vp->v_canvas = cv;
+        vp->v_xs = cv->c_xs;
+        vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4;
+        vp->v_xe = (3 * cv->c_xs + cv->c_xe) / 4 - 1;
+        vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1;
+        vp->v_xoff = cv->c_xoff;
+        vp->v_yoff = cv->c_yoff;
+        vp->v_next = cv->c_vplist;
+        cv->c_vplist = vp;
+
+        if ((vp = (struct viewport *) malloc(sizeof *vp)) == 0)
+            return -1;
+        vp->v_canvas = cv;
+        vp->v_xs = cv->c_xs;
+        vp->v_ys = cv->c_ys;
+        vp->v_xe = cv->c_xe;
+        vp->v_ye = (3 * cv->c_ys + cv->c_ye) / 4 - 1;
+        vp->v_xoff = cv->c_xoff;
+        vp->v_yoff = cv->c_yoff;
+        vp->v_next = cv->c_vplist;
+        cv->c_vplist = vp;
 #else
-      vp->v_canvas = cv;
-      vp->v_xs = cv->c_xs;
-      vp->v_ys = cv->c_ys;
-      vp->v_xe = cv->c_xe;
-      vp->v_ye = cv->c_ye;
-      vp->v_xoff = cv->c_xoff;
-      vp->v_yoff = cv->c_yoff;
-      vp->v_next = cv->c_vplist;
-      cv->c_vplist = vp;
+        vp->v_canvas = cv;
+        vp->v_xs     = cv->c_xs;
+        vp->v_ys     = cv->c_ys;
+        vp->v_xe     = cv->c_xe;
+        vp->v_ye     = cv->c_ye;
+        vp->v_xoff   = cv->c_xoff;
+        vp->v_yoff   = cv->c_yoff;
+        vp->v_next   = cv->c_vplist;
+        cv->c_vplist = vp;
 #endif
 
-      if (cv->c_xs < display->d_vpxmin || display->d_vpxmin == -1)
-        display->d_vpxmin = cv->c_xs;
-      if (cv->c_xe > display->d_vpxmax || display->d_vpxmax == -1)
-        display->d_vpxmax = cv->c_xe;
+        if (cv->c_xs < display->d_vpxmin || display->d_vpxmin == -1)
+            display->d_vpxmin = cv->c_xs;
+        if (cv->c_xe > display->d_vpxmax || display->d_vpxmax == -1)
+            display->d_vpxmax = cv->c_xe;
     }
-  return 0;
+    return 0;
 }
 
 void
@@ -1406,112 +1876,109 @@
 ClearArea(x1, y1, xs, xe, x2, y2, bce, uselayfn)
 int x1, y1, xs, xe, x2, y2, bce, uselayfn;
 {
-  int y, xxe;
-  struct canvas *cv;
-  struct viewport *vp;
-
-  debug2("Clear %d,%d", x1, y1);
-  debug2(" %d-%d", xs, xe);
-  debug2(" %d,%d", x2, y2);
-  debug2(" uselayfn=%d bce=%d\n", uselayfn, bce);
-  ASSERT(display);
-  if (x1 == D_width)
-    x1--;
-  if (x2 == D_width)
-    x2--;
-  if (xs == -1)
-    xs = x1;
-  if (xe == -1)
-    xe = x2;
-  if (D_UT)    /* Safe to erase ? */
-    SetRendition(&mchar_null);
+    int             y, xxe;
+    struct canvas  *cv;
+    struct viewport *vp;
+
+    debug2("Clear %d,%d ",x1,y1);
+    debug2("%d-%d ",xs,xe);
+    debug2("%d,%d\n",  x2, y2);
+    debug2(" uselayfn=%d bce=%d\n", uselayfn, bce);
+    ASSERT(display);
+    if (x1 == D_width)
+        x1--;
+    if (x2 == D_width)
+        x2--;
+    if (xs == -1)
+        xs = x1;
+    if (xe == -1)
+        xe = x2;
+    if (D_UT)                   /* Safe to erase ? */
+        SetRendition(&mchar_null);
 #ifdef COLOR
-  if (D_BE)
-    SetBackColor(bce);
+    if (D_BE)
+        SetBackColor(bce);
 #endif
-  if (D_lp_missing && y1 <= D_bot && xe >= D_width - 1)
-    {
-      if (y2 > D_bot || (y2 == D_bot && x2 >= D_width - 1))
-       D_lp_missing = 0;
+    if (D_lp_missing && y1 <= D_bot && xe >= D_width - 1) {
+        if (y2 > D_bot || (y2 == D_bot && x2 >= D_width - 1))
+            D_lp_missing = 0;
     }
-  if (x2 == D_width - 1 && (xs == 0 || y1 == y2) && xe == D_width - 1 && y2 == 
D_height - 1 && (!bce || D_BE))
-    {
+    if (x2 == D_width - 1 && (xs == 0 || y1 == y2) && xe == D_width - 1
+            && y2 == D_height - 1 && (!bce || D_BE)) {
 #ifdef AUTO_NUKE
-      if (x1 == 0 && y1 == 0 && D_auto_nuke)
-       NukePending();
+        if (x1 == 0 && y1 == 0 && D_auto_nuke)
+            NukePending();
 #endif
-      if (x1 == 0 && y1 == 0 && D_CL)
-       {
-         AddCStr(D_CL);
-         D_y = D_x = 0;
-         return;
-       }
-      /* 
-       * Workaround a hp700/22 terminal bug. Do not use CD where CE
-       * is also appropriate.
-       */
-      if (D_CD && (y1 < y2 || !D_CE))
-       {
-         GotoPos(x1, y1);
-         AddCStr(D_CD);
-         return;
-       }
-    }
-  if (x1 == 0 && xs == 0 && (xe == D_width - 1 || y1 == y2) && y1 == 0 && 
D_CCD && (!bce || D_BE))
-    {
-      GotoPos(x1, y1);
-      AddCStr(D_CCD);
-      return;
+        if (x1 == 0 && y1 == 0 && D_CL) {
+            AddCStr(D_CL);
+            D_y = D_x = 0;
+            return;
+        }
+        /* 
+         * Workaround a hp700/22 terminal bug. Do not use CD where CE
+         * is also appropriate.
+         */
+        if (D_CD && (y1 < y2 || !D_CE)) {
+            GotoPos(x1, y1);
+            AddCStr(D_CD);
+            return;
+        }
     }
-  xxe = xe;
-  for (y = y1; y <= y2; y++, x1 = xs)
-    {
-      if (y == y2)
-       xxe = x2;
-      if (x1 == 0 && D_CB && (xxe != D_width - 1 || (D_x == xxe && D_y == y)) 
&& (!bce || D_BE))
-       {
-         GotoPos(xxe, y);
-         AddCStr(D_CB);
-         continue;
-       }
-      if (xxe == D_width - 1 && D_CE && (!bce || D_BE))
-       {
-         GotoPos(x1, y);
-         AddCStr(D_CE);
-         continue;
-       }
-      if (uselayfn)
-       {
-         vp = 0;
-         for (cv = D_cvlist; cv; cv = cv->c_next)
-           {
-             if (y < cv->c_ys || y > cv->c_ye || xxe < cv->c_xs || x1 > 
cv->c_xe)
-               continue;
-             for (vp = cv->c_vplist; vp; vp = vp->v_next)
-               if (y >= vp->v_ys && y <= vp->v_ye && xxe >= vp->v_xs && x1 <= 
vp->v_xe)
-                 break;
-             if (vp)
-               break;
-           }
-         if (cv && cv->c_layer && x1 >= vp->v_xs && xxe <= vp->v_xe &&
-              y - vp->v_yoff >= 0 && y - vp->v_yoff < cv->c_layer->l_height &&
-              xxe - vp->v_xoff >= 0 && x1 - vp->v_xoff < cv->c_layer->l_width)
-           {
-             struct layer *oldflayer = flayer;
-             struct canvas *cvlist, *cvlnext;
-             flayer = cv->c_layer;
-             cvlist = flayer->l_cvlist;
-             cvlnext = cv->c_lnext;
-             flayer->l_cvlist = cv;
-             cv->c_lnext = 0;
-              LayClearLine(y - vp->v_yoff, x1 - vp->v_xoff, xxe - vp->v_xoff, 
bce);
-             flayer->l_cvlist = cvlist;
-             cv->c_lnext = cvlnext;
-             flayer = oldflayer;
-             continue;
-           }
-       }
-      ClearLine((struct mline *)0, y, x1, xxe, bce);
+    if (x1 == 0 && xs == 0 && (xe == D_width - 1 || y1 == y2) && y1 == 0
+            && D_CCD && (!bce || D_BE)) {
+        GotoPos(x1, y1);
+        AddCStr(D_CCD);
+        return;
+    }
+    xxe = xe;
+    for (y = y1; y <= y2; y++, x1 = xs) {
+        if (y == y2)
+            xxe = x2;
+        if (x1 == 0 && D_CB && (xxe != D_width - 1 || (D_x == xxe
+                                && D_y == y)) && (!bce || D_BE)) {
+            GotoPos(xxe, y);
+            AddCStr(D_CB);
+            continue;
+        }
+        if (xxe == D_width - 1 && D_CE && (!bce || D_BE)) {
+            GotoPos(x1, y);
+            AddCStr(D_CE);
+            continue;
+        }
+        if (uselayfn) {
+            vp = 0;
+            for (cv = D_cvlist; cv; cv = cv->c_next) {
+                if (y < cv->c_ys || y > cv->c_ye || xxe < cv->c_xs
+                        || x1 > cv->c_xe)
+                    continue;
+                for (vp = cv->c_vplist; vp; vp = vp->v_next)
+                    if (y >= vp->v_ys && y <= vp->v_ye && xxe >= vp->v_xs
+                            && x1 <= vp->v_xe)
+                        break;
+                if (vp)
+                    break;
+            }
+            if (cv && cv->c_layer && x1 >= vp->v_xs && xxe <= vp->v_xe &&
+                    y - vp->v_yoff >= 0
+                    && y - vp->v_yoff < cv->c_layer->l_height
+                    && xxe - vp->v_xoff >= 0
+                    && x1 - vp->v_xoff < cv->c_layer->l_width) {
+                struct layer   *oldflayer = flayer;
+                struct canvas  *cvlist, *cvlnext;
+                flayer = cv->c_layer;
+                cvlist = flayer->l_cvlist;
+                cvlnext = cv->c_lnext;
+                flayer->l_cvlist = cv;
+                cv->c_lnext = 0;
+                LayClearLine(y - vp->v_yoff, x1 - vp->v_xoff,
+                        xxe - vp->v_xoff, bce);
+                flayer->l_cvlist = cvlist;
+                cv->c_lnext = cvlnext;
+                flayer = oldflayer;
+                continue;
+            }
+        }
+        ClearLine((struct mline *) 0, y, x1, xxe, bce);
     }
 }
 
@@ -1661,134 +2128,117 @@
 ScrollV(xs, ys, xe, ye, n, bce)
 int xs, ys, xe, ye, n, bce;
 {
-  int i;
-  int up;
-  int oldtop, oldbot;
-  int alok, dlok, aldlfaster;
-  int missy = 0;
-
-  ASSERT(display);
-  if (n == 0)
-    return;
-  if (n >= ye - ys + 1 || -n >= ye - ys + 1)
-    {
-      ClearArea(xs, ys, xs, xe, xe, ye, bce, 0);
-      return;
-    }
-  if (xs > D_vpxmin || xe < D_vpxmax)
-    {
-      RefreshArea(xs, ys, xe, ye, 0);
-      return;
-    }
-
-  if (D_lp_missing)
-    {
-      if (D_bot > ye || D_bot < ys)
-       missy = D_bot;
-      else
-       {
-         missy = D_bot - n;
-          if (missy > ye || missy < ys)
-           D_lp_missing = 0;
-       }
-    }
-
-  up = 1;
-  if (n < 0)
-    {
-      up = 0;
-      n = -n;
+    int             i;
+    int             up;
+    int             oldtop, oldbot;
+    int             alok, dlok, aldlfaster;
+    int             missy = 0;
+
+    ASSERT(display);
+    if (n == 0)
+        return;
+    if (n >= ye - ys + 1 || -n >= ye - ys + 1) {
+        ClearArea(xs, ys, xs, xe, xe, ye, bce, 0);
+        return;
+    }
+    if (xs > D_vpxmin || xe < D_vpxmax) {
+        RefreshArea(xs, ys, xe, ye, 0);
+        return;
+    }
+
+    if (D_lp_missing) {
+        if (D_bot > ye || D_bot < ys)
+            missy = D_bot;
+        else {
+            missy = D_bot - n;
+            if (missy > ye || missy < ys)
+                D_lp_missing = 0;
+        }
     }
-  if (n >= ye - ys + 1)
-    n = ye - ys + 1;
-
-  oldtop = D_top;
-  oldbot = D_bot;
-  if (ys < D_top || D_bot != ye)
-    ChangeScrollRegion(ys, ye);
-  alok = (D_AL || D_CAL || (ys >= D_top && ye == D_bot &&  up));
-  dlok = (D_DL || D_CDL || (ys >= D_top && ye == D_bot && !up));
-  if (D_top != ys && !(alok && dlok))
-    ChangeScrollRegion(ys, ye);
 
-  if (D_lp_missing && 
-      (oldbot != D_bot ||
-       (oldbot == D_bot && up && D_top == ys && D_bot == ye)))
-    {
-      WriteLP(D_width - 1, oldbot);
-      if (oldbot == D_bot)             /* have scrolled */
-       {
-         if (--n == 0)
-           {
+    up = 1;
+    if (n < 0) {
+        up = 0;
+        n = -n;
+    }
+    if (n >= ye - ys + 1)
+        n = ye - ys + 1;
+
+    oldtop = D_top;
+    oldbot = D_bot;
+    if (ys < D_top || D_bot != ye)
+        ChangeScrollRegion(ys, ye);
+    alok = (D_AL || D_CAL || (ys >= D_top && ye == D_bot && up));
+    dlok = (D_DL || D_CDL || (ys >= D_top && ye == D_bot && !up));
+    if (D_top != ys && !(alok && dlok))
+        ChangeScrollRegion(ys, ye);
+
+    if (D_lp_missing &&
+            (oldbot != D_bot ||
+                    (oldbot == D_bot && up && D_top == ys && D_bot == ye)))
+    {
+        WriteLP(D_width - 1, oldbot);
+        if (oldbot == D_bot) {  /* have scrolled */
+            if (--n == 0) {
 /* XXX
              ChangeScrollRegion(oldtop, oldbot);
 */
-             if (bce && !D_BE)
-               ClearLine((struct mline *)0, ye, xs, xe, bce);
-             return;
-           }
-       }
+                if (bce && !D_BE)
+                    ClearLine((struct mline *) 0, ye, xs, xe, bce);
+                return;
+            }
+        }
     }
 
-  if (D_UT)
-    SetRendition(&mchar_null);
+    if (D_UT)
+        SetRendition(&mchar_null);
 #ifdef COLOR
-  if (D_BE)
-    SetBackColor(bce);
+    if (D_BE)
+        SetBackColor(bce);
 #endif
 
-  aldlfaster = (n > 1 && ys >= D_top && ye == D_bot && ((up && D_CDL) || (!up 
&& D_CAL)));
+    aldlfaster = (n > 1 && ys >= D_top && ye == D_bot && ((up && D_CDL)
+                    || (!up && D_CAL)));
 
-  if ((up || D_SR) && D_top == ys && D_bot == ye && !aldlfaster)
-    {
-      if (up)
-       {
-         GotoPos(0, ye);
-         for(i = n; i-- > 0; )
-           AddCStr(D_NL);              /* was SF, I think NL is faster */
-       }
-      else
-       {
-         GotoPos(0, ys);
-         for(i = n; i-- > 0; )
-           AddCStr(D_SR);
-       }
-    }
-  else if (alok && dlok)
-    {
-      if (up || ye != D_bot)
-       {
-          GotoPos(0, up ? ys : ye+1-n);
-          if (D_CDL && !(n == 1 && D_DL))
-           AddCStr2(D_CDL, n);
-         else
-           for(i = n; i--; )
-             AddCStr(D_DL);
-       }
-      if (!up || ye != D_bot)
-       {
-          GotoPos(0, up ? ye+1-n : ys);
-          if (D_CAL && !(n == 1 && D_AL))
-           AddCStr2(D_CAL, n);
-         else
-           for(i = n; i--; )
-             AddCStr(D_AL);
-       }
-    }
-  else
-    {
-      RefreshArea(xs, ys, xe, ye, 0);
-      return;
-    }
-  if (bce && !D_BE)
-    {
-      if (up)
-        ClearArea(xs, ye - n + 1, xs, xe, xe, ye, bce, 0);
-      else
-        ClearArea(xs, ys, xs, xe, xe, ys + n - 1, bce, 0);
+    if ((up || D_SR) && D_top == ys && D_bot == ye && !aldlfaster) {
+        if (up) {
+            GotoPos(0, ye);
+            for (i = n; i-- > 0;)
+                AddCStr(D_NL);  /* was SF, I think NL is faster */
+        } else {
+            GotoPos(0, ys);
+            for (i = n; i-- > 0;)
+                AddCStr(D_SR);
+        }
+    } else if (alok && dlok) {
+        if (up || ye != D_bot) {
+            GotoPos(0, up ? ys : ye + 1 - n);
+            if (D_CDL && !(n == 1 && D_DL))
+                AddCStr2(D_CDL, n);
+            else
+                for (i = n; i--;)
+                    AddCStr(D_DL);
+        }
+        if (!up || ye != D_bot) {
+            GotoPos(0, up ? ye + 1 - n : ys);
+            if (D_CAL && !(n == 1 && D_AL))
+                AddCStr2(D_CAL, n);
+            else
+                for (i = n; i--;)
+                    AddCStr(D_AL);
+        }
+    } else {
+        RefreshArea(xs, ys, xe, ye, 0);
+        return;
+    }
+    if (bce && !D_BE) {
+        if (up)
+            ClearArea(xs, ye - n + 1, xs, xe, xe, ye, bce, 0);
+        else
+            ClearArea(xs, ys, xs, xe, xe, ys + n - 1, bce, 0);
     }
-  if (D_lp_missing && missy != D_bot)
-    WriteLP(D_width - 1, missy);
+    if (D_lp_missing && missy != D_bot)
+        WriteLP(D_width - 1, missy);
 /* XXX
   ChangeScrollRegion(oldtop, oldbot);
   if (D_lp_missing && missy != D_bot)
@@ -2507,137 +2957,132 @@
 RefreshLine(y, from, to, isblank)
 int y, from, to, isblank;
 {
-  struct viewport *vp, *lvp;
-  struct canvas *cv, *lcv, *cvlist, *cvlnext;
-  struct layer *oldflayer;
-  int xx, yy;
-  char *buf;
-  struct win *p;
-
-  ASSERT(display);
-
-  debug2("RefreshLine %d %d", y, from);
-  debug2(" %d %d\n", to, isblank);
-
-  if (D_status == STATUS_ON_WIN && y == STATLINE)
-    return;    /* can't refresh status */
-
-  if (isblank == 0 && D_CE && to == D_width - 1 && from < to)
-    {
-      GotoPos(from, y);
-      if (D_UT || D_BE)
-       SetRendition(&mchar_null);
-      AddCStr(D_CE);
-      isblank = 1;
-    }
-  while (from <= to)
-    {
-      lcv = 0;
-      lvp = 0;
-      for (cv = display->d_cvlist; cv; cv = cv->c_next)
-       {
-         if (y < cv->c_ys || y > cv->c_ye || to < cv->c_xs || from > cv->c_xe)
-           continue;
-         debug2("- canvas hit: %d %d", cv->c_xs, cv->c_ys);
-         debug2("  %d %d\n", cv->c_xe, cv->c_ye);
-         for (vp = cv->c_vplist; vp; vp = vp->v_next)
-           {
-             debug2("  - vp: %d %d", vp->v_xs, vp->v_ys);
-             debug2("  %d %d\n", vp->v_xe, vp->v_ye);
-             /* find leftmost overlapping vp */
-             if (y >= vp->v_ys && y <= vp->v_ye && from <= vp->v_xe && to >= 
vp->v_xs && (lvp == 0 || lvp->v_xs > vp->v_xs))
-               {
-                 lcv = cv;
-                 lvp = vp;
-               }
-           }
-       }
-      if (lvp == 0)
-       break;
-      if (from < lvp->v_xs)
-       {
-         if (!isblank)
-           DisplayLine(&mline_null, &mline_blank, y, from, lvp->v_xs - 1);
-         from = lvp->v_xs;
-       }
-
-      /* call LayRedisplayLine on canvas lcv viewport lvp */
-      yy = y - lvp->v_yoff;
-      xx = to < lvp->v_xe ? to : lvp->v_xe;
-
-      if (lcv->c_layer && yy == lcv->c_layer->l_height)
-       {
-         GotoPos(from, y);
-         SetRendition(&mchar_blank);
-         while (from <= lvp->v_xe && from - lvp->v_xoff < 
lcv->c_layer->l_width)
-           {
-             PUTCHARLP('-');
-             from++;
-           }
-         if (from >= lvp->v_xe + 1)
-           continue;
-       }
-      if (lcv->c_layer == 0 || yy >= lcv->c_layer->l_height || from - 
lvp->v_xoff >= lcv->c_layer->l_width)
-       {
-         if (!isblank)
-           DisplayLine(&mline_null, &mline_blank, y, from, lvp->v_xe);
-         from = lvp->v_xe + 1;
-         continue;
-       }
-
-      if (xx - lvp->v_xoff >= lcv->c_layer->l_width)
-       xx = lcv->c_layer->l_width + lvp->v_xoff - 1;
-      oldflayer = flayer;
-      flayer = lcv->c_layer;
-      cvlist = flayer->l_cvlist;
-      cvlnext = lcv->c_lnext;
-      flayer->l_cvlist = lcv;
-      lcv->c_lnext = 0;
-      LayRedisplayLine(yy, from - lvp->v_xoff, xx - lvp->v_xoff, isblank);
-      flayer->l_cvlist = cvlist;
-      lcv->c_lnext = cvlnext;
-      flayer = oldflayer;
-
-      from = xx + 1;
-    }
-  if (from > to)
-    return;            /* all done */
-
-  if (y == D_height - 1 && D_has_hstatus == HSTATUS_LASTLINE)
-    {
-      RefreshHStatus();
-      return;
-    }
+    struct viewport *vp, *lvp;
+    struct canvas  *cv, *lcv, *cvlist, *cvlnext;
+    struct layer   *oldflayer;
+    int             xx, yy;
+    char           *buf;
+    struct win     *p;
+
+    ASSERT(display);
+
+    debug2("RefreshLine y=%d from=%d  ",y,from);
+    debug2("to=%d isblank=%d\n", to, isblank); 
+
+    if (D_status == STATUS_ON_WIN && y == STATLINE)
+        return;                 /* can't refresh status */
+
+    if (isblank == 0 && D_CE && to == D_width - 1 && from < to) {
+        GotoPos(from, y);
+        if (D_UT || D_BE)
+            SetRendition(&mchar_null);
+        AddCStr(D_CE);
+        isblank = 1;
+    }
+    while (from <= to) {
+        lcv = 0;
+        lvp = 0;
+        for (cv = display->d_cvlist; cv; cv = cv->c_next) {
+            if (y < cv->c_ys || y > cv->c_ye || to < cv->c_xs
+                    || from > cv->c_xe)
+                continue;
+            debug2("- canvas hit: %d %d", cv->c_xs, cv->c_ys);
+            debug2("  %d %d\n", cv->c_xe, cv->c_ye);
+            for (vp = cv->c_vplist; vp; vp = vp->v_next) {
+                debug2("  - vp: %d %d", vp->v_xs, vp->v_ys);
+                debug2("  %d %d\n", vp->v_xe, vp->v_ye);
+                /* find leftmost overlapping vp */
+                if (y >= vp->v_ys && y <= vp->v_ye && from <= vp->v_xe
+                        && to >= vp->v_xs && (lvp == 0
+                                || lvp->v_xs > vp->v_xs)) {
+                    lcv = cv;
+                    lvp = vp;
+                }
+            }
+        }
+        if (lvp == 0)
+            break;
+        if (from < lvp->v_xs) {
+            if (!isblank)
+                DisplayLine(&mline_null, &mline_blank, y, from,
+                        lvp->v_xs - 1);
+            from = lvp->v_xs;
+        }
 
-  for (cv = display->d_cvlist; cv; cv = cv->c_next)
-    if (y == cv->c_ye + 1)
-      break;
-  if (cv == 0)
-    {
-      if (!isblank)
-       DisplayLine(&mline_null, &mline_blank, y, from, to);
-      return;
-    }
+        /* call LayRedisplayLine on canvas lcv viewport lvp */
+        yy = y - lvp->v_yoff;
+        xx = to < lvp->v_xe ? to : lvp->v_xe;
+
+        if (lcv->c_layer && yy == lcv->c_layer->l_height) {
+            GotoPos(from, y);
+            SetRendition(&mchar_blank);
+            while (from <= lvp->v_xe
+                    && from - lvp->v_xoff < lcv->c_layer->l_width) {
+                PUTCHARLP('-');
+                from++;
+            }
+            if (from >= lvp->v_xe + 1)
+                continue;
+        }
+        if (lcv->c_layer == 0 || yy >= lcv->c_layer->l_height
+                || from - lvp->v_xoff >= lcv->c_layer->l_width) {
+            if (!isblank)
+                DisplayLine(&mline_null, &mline_blank, y, from, lvp->v_xe);
+            from = lvp->v_xe + 1;
+            continue;
+        }
 
-  p = Layer2Window(cv->c_layer);
-  buf = MakeWinMsgEv(captionstring, p, '%', D_width - !D_CLP, &cv->c_captev, 
0);
-  if (cv->c_captev.timeout.tv_sec)
-    evenq(&cv->c_captev);
-  xx = strlen(buf);
-  GotoPos(from, y);
-  SetRendition(&mchar_so);
-  if (PutWinMsg(buf, from, to + 1))
-    from = xx > to + 1 ? to + 1 : xx;
-  else
-    {
-      while (from <= to && from < xx)
-       {
-         PUTCHARLP(buf[from]);
-         from++;
-       }
+        if (xx - lvp->v_xoff >= lcv->c_layer->l_width)
+            xx = lcv->c_layer->l_width + lvp->v_xoff - 1;
+        oldflayer = flayer;
+        flayer = lcv->c_layer;
+        cvlist = flayer->l_cvlist;
+        cvlnext = lcv->c_lnext;
+        flayer->l_cvlist = lcv;
+        lcv->c_lnext = 0;
+        LayRedisplayLine(yy, from - lvp->v_xoff, xx - lvp->v_xoff,
+                isblank);
+        flayer->l_cvlist = cvlist;
+        lcv->c_lnext = cvlnext;
+        flayer = oldflayer;
+
+        from = xx + 1;
+    }
+    if (from > to)
+        return;                 /* all done */
+
+    if (y == D_height - 1 && D_has_hstatus == HSTATUS_LASTLINE) {
+        RefreshHStatus();
+        return;
+    }
+
+    for (cv = display->d_cvlist; cv; cv = cv->c_next)
+        if (y == cv->c_ye + 1)
+            break;
+    if (cv == 0) {
+        if (!isblank)
+            DisplayLine(&mline_null, &mline_blank, y, from, to);
+        return;
+    }
+
+    p = Layer2Window(cv->c_layer);
+    buf = MakeWinMsgEv(captionstring, p, '%', D_width - !D_CLP,
+            &cv->c_captev, 0);
+    if (cv->c_captev.timeout.tv_sec)
+        evenq(&cv->c_captev);
+    xx = strlen(buf);
+    GotoPos(from, y);
+    SetRendition(&mchar_so);
+    if (PutWinMsg(buf, from, to + 1))
+        from = xx > to + 1 ? to + 1 : xx;
+    else {
+        while (from <= to && from < xx) {
+            PUTCHARLP(buf[from]);
+            from++;
+        }
     }
-  while (from++ <= to)
-    PUTCHARLP(' ');
+    while (from++ <= to)
+        PUTCHARLP(' ');
 }
 
 /*********************************************************************/
diff -u screen-4.0.2/display.h vs_screen-4.0.2/display.h
--- screen-4.0.2/display.h      2003-07-01 15:01:42.000000000 +0100
+++ vs_screen-4.0.2/display.h   2005-12-24 22:31:47.270080768 +0000
@@ -58,6 +58,11 @@
   int              c_ys;
   int              c_ye;
   struct event     c_captev;   /* caption changed event */
+  int              c_type;     /* which type of split created the canvas. */
+  struct canvas   *c_right;    /* canvas to the right. */
+  struct canvas   *c_left;     /* canvas to the left.  */
+  struct canvas   *c_above;    /* canvas above. */
+  struct canvas   *c_below;    /* canvas below. */
 };
 
 struct viewport
Common subdirectories: screen-4.0.2/doc and vs_screen-4.0.2/doc
Common subdirectories: screen-4.0.2/etc and vs_screen-4.0.2/etc
diff -u screen-4.0.2/extern.h vs_screen-4.0.2/extern.h
--- screen-4.0.2/extern.h       2003-08-22 13:27:57.000000000 +0100
+++ vs_screen-4.0.2/extern.h    2005-12-24 22:42:01.053771464 +0000
@@ -289,7 +289,7 @@
 #endif
 extern void  SetCanvasWindow __P((struct canvas *, struct win *));
 extern int   MakeDefaultCanvas __P((void));
-extern int   AddCanvas __P((void));
+extern int   AddCanvas __P((int));
 extern void  RemCanvas __P((void));
 extern void  OneCanvas __P((void));
 extern int   RethinkDisplayViewports __P((void));
diff -u screen-4.0.2/process.c vs_screen-4.0.2/process.c
--- screen-4.0.2/process.c      2003-09-18 13:53:54.000000000 +0100
+++ vs_screen-4.0.2/process.c   2005-12-24 22:35:54.033567016 +0000
@@ -548,6 +548,7 @@
   ktab['B'].nr = RC_POW_BREAK;
   ktab['_'].nr = RC_SILENCE;
   ktab['S'].nr = RC_SPLIT;
+  ktab['V'].nr = RC_VERT_SPLIT;
   ktab['Q'].nr = RC_ONLY;
   ktab['X'].nr = RC_REMOVE;
   ktab['F'].nr = RC_FIT;
@@ -3649,9 +3650,13 @@
       break;
 #endif /* MULTIUSER */
     case RC_SPLIT:
-      AddCanvas();
-      Activate(-1);
-      break;
+        AddCanvas(HORIZONTAL);
+        Activate(-1);
+        break;
+    case RC_VERT_SPLIT:
+        AddCanvas(VERTICAL);
+        Activate(-1);
+        break;
     case RC_REMOVE:
       RemCanvas();
       Activate(-1);
diff -u screen-4.0.2/screen.h vs_screen-4.0.2/screen.h
--- screen-4.0.2/screen.h       2003-08-22 13:28:43.000000000 +0100
+++ vs_screen-4.0.2/screen.h    2005-12-24 22:39:19.834280552 +0000
@@ -293,3 +293,6 @@
  */
 #define WLIST_NUM 0
 #define WLIST_MRU 1
+
+#define HORIZONTAL 0
+#define VERTICAL 1
Common subdirectories: screen-4.0.2/terminfo and vs_screen-4.0.2/terminfo
Common subdirectories: screen-4.0.2/utf8encodings and 
vs_screen-4.0.2/utf8encodings

reply via email to

[Prev in Thread] Current Thread [Next in Thread]