[40398] trunk/dports/sysutils/screen/files/patch-wrp_vertical_split
digdog at macports.org
digdog at macports.org
Tue Sep 30 05:50:47 PDT 2008
Revision: 40398
http://trac.macports.org/changeset/40398
Author: digdog at macports.org
Date: 2008-09-30 05:50:46 -0700 (Tue, 30 Sep 2008)
Log Message:
-----------
Forgot to add patch for ticket #16535 (sorry).
Added Paths:
-----------
trunk/dports/sysutils/screen/files/patch-wrp_vertical_split
Added: trunk/dports/sysutils/screen/files/patch-wrp_vertical_split
===================================================================
--- trunk/dports/sysutils/screen/files/patch-wrp_vertical_split (rev 0)
+++ trunk/dports/sysutils/screen/files/patch-wrp_vertical_split 2008-09-30 12:50:46 UTC (rev 40398)
@@ -0,0 +1,1256 @@
+--- comm.c.orig 2003-09-08 14:25:08.000000000 +0000
++++ comm.c 2006-07-07 02:39:24.000000000 +0000
+@@ -309,6 +309,7 @@ struct comm comms[RC_LAST + 1] =
+ { "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 },
+--- display.c.orig 2003-12-05 13:45:41.000000000 +0000
++++ display.c 2006-07-07 02:39:26.000000000 +0000
+@@ -476,65 +476,306 @@ struct canvas *cv;
+ free(cv);
+ }
+
++struct canvas *
++get_new_canvas(target)
++struct canvas *target;
++{ /** Allocate a new canvas, and assign it characteristics
++ equal to those of target. */
++ struct canvas *cv;
++
++ if ((cv = (struct canvas *) calloc(1, sizeof *cv)) == 0)
++ return NULL;
++
++ cv -> c_xs = target -> c_xs;
++ cv -> c_xe = target -> c_xe;
++ cv -> c_ys = target -> c_ys;
++ cv -> c_ye = target -> c_ye;
++ cv -> c_xoff = target -> c_xoff;
++ cv -> c_yoff = target -> c_yoff;
++ cv -> c_display = target -> c_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 = target -> c_left;
++ cv -> c_right = target -> c_right;
++ cv -> c_above = target -> c_above;
++ cv -> c_below = target -> c_below;
++
++ return cv;
++}
++
+ int
+-AddCanvas()
+-{
+- int hh, h, i, j;
+- struct canvas *cv, **cvpp;
++share_limits( type, cv0, cv1)
++int type; /* HORIZONTAL or VERTICAL */
++struct canvas *cv0; /* canvas to compare against. */
++struct canvas *cv1; /* canvas to compare against. */
++{ /** Return non-zero if the two canvasses share limits.
++ (ie, their horizontal or veritcal boundaries are the same)
++ */
++ switch (type) {
++ case HORIZONTAL:
++ return cv0 -> c_xs == cv1 -> c_xs && cv0->c_xe == cv1 -> c_xe;
++ case VERTICAL:
++ return cv0 -> c_ys == cv1 -> c_ys && cv0->c_ye == cv1 -> c_ye;
++ }
++ ASSERT(0);
++ return 0;
++}
+
+- 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;
++int
++compute_region(type, a, focus, list)
++int type; /* 0 - horizontal, 1 - vertical */
++struct screen_region *a; /* Return value. */
++struct canvas *focus; /* Canvas to compute around. */
++struct canvas *list; /* List of all canvasses. */
++{ /** Find the start and end of the screen region.*/
++ /*
++ I'm using the term 'region' here differently
++ than elsewhere. Elsewhere, 'region' is synonymous
++ with 'canvas', but I am using it to denote
++ a collection of related canvasses.
+
+- for (cv = D_cvlist; cv; cv = cv->c_next)
+- if (cv == D_forecv)
++ 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 region, as
++ are cavasses 1 and 4. We need to be careful not to
++ lump 1 and 4 together w/8. The
++ type of the region containing 0,1,2 is
++ VERTICAL, since each canvas is created
++ via a vertical split.
++
++ Throughout, I'm assuming that canvasses
++ are created so that any region will
++ be contiguous in D_cvlist.
++
++ Note: this was written before the screen
++ orientation members (c_left, c_above, c_below,
++ c_right) were added to the struct canvas.
++ Might want to rewrite this to use those.
++
++ Written by Bill Pursell, 23/12/2005
++ */
++
++ struct canvas *cv; /* Entry in list. */
++ int seen_focus; /* Flag used when walking the list. */
++
++ seen_focus = 0;
++ a->count = 0;
++ a->type = type;
++
++ if (type == HORIZONTAL) {
++ a->xs = focus -> c_xs;
++ a->xe = focus -> c_xe;
++ a->ys = -1;
++ }
++ if (type == VERTICAL) {
++ a->ys = focus -> c_ys;
++ a->ye = focus -> 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 = list; cv; cv = cv->c_next) {
++ if (cv == focus)
++ seen_focus = 1;
++ if (share_limits( type, cv, focus)) {
++ debug2("cv = %x %s\n", cv, (cv == focus)? "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 HORIZONTAL :
++ if (a->ys == -1) {
++ a->ys = cv -> c_ys;
++ a->start = cv;
++ }
++ a->ye = cv -> c_ye;
+ break;
+- ASSERT(cv);
+- cvpp = &cv->c_next;
++ case VERTICAL:
++ if (a->xs == -1) {
++ a->xs = cv -> c_xs;
++ a->start = cv;
++ }
++ a->xe = cv -> c_xe;
++ break;
++ }
+
+- if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0)
+- return -1;
++ a->end = cv;
++ a->count++;
++ }
++ if (!share_limits(type, cv, focus) || cv -> c_next == NULL) {
++ if (seen_focus) {
++ 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 HORIZONTAL: a->ys = -1; break;
++ case VERTICAL : a->xs = -1; break;
++ }
++ a->count = 0;
++ }
++ }
++ }
+
+- 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;
++ switch (type) {
++ case HORIZONTAL:
++ a->expanse = a->ye - a->ys + 1;
++ ASSERT(a->expanse <= D_height - (D_has_hstatus == HSTATUS_LASTLINE));
++ break;
++ case VERTICAL:
++ a->expanse = a->xe - a->xs + 1;
++ ASSERT(a->expanse <= D_width);
++ break;
++ }
++ ASSERT(seen_focus);
++}
+
+- 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
++reset_region_types(region, type)
++struct screen_region *region;
++int type;
++{ /** Set c_type of all the canvasses in the region to type. */
+
+- cv->c_next = *cvpp;
+- *cvpp = cv;
++ struct canvas *cv;
+
+- 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;
++ for (cv = region->start; cv != region->end->c_next; cv = cv->c_next) {
++ #ifdef DEBUG
++ switch(type) {
++ case HORIZONTAL:
++ ASSERT (cv->c_xs == region -> xs && cv->c_xe == region -> xe);
++ break;
++ case VERTICAL:
++ ASSERT (cv->c_ys == region -> ys && cv->c_ye == region -> ye);
++ break;
++ default:
++ ASSERT(0);
++ }
++ #endif
++ cv -> c_type = type;
+ }
++}
++
++void
++debug_print_canvas(cv)
++struct canvas *cv;
++{ /** Print cv to the debug file. */
++#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);
++ debug2(" next: %x type: %d\n", cv->c_next, cv->c_type);
++#endif
++}
++
++void
++debug_print_all_canvasses(header)
++char *header;
++{ /** Print the dimensions of all the canvasses
++ in the current display to the debug file. Precede
++ with a line containing the header message. */
++ #ifdef DEBUG
++ struct canvas *cv;
++ char message[BUFSIZ];
++
++ sprintf(message, "%10s %5d: ",__FILE__ , __LINE__);
++ strcat (message, header);
++ fprintf(dfp, message);
++ fflush(dfp);
++ for (cv = D_cvlist; cv; cv = cv->c_next) {
++ debug_print_canvas(cv);
++ }
++ #endif
++ return;
++}
++
++set_internal_orientation(region)
++struct screen_region *region;
++{ /** Set the orientation for canvasses inside the region. */
++
++ struct canvas *cv;
++
++ for (cv = region -> start; cv != region -> end; cv = cv->c_next) {
++ ASSERT (cv -> c_type == region -> type);
++ switch (region->type) {
++ case VERTICAL:
++ cv -> c_right = cv -> c_next;
++ cv -> c_next -> c_left = cv;
++ break;
++ case HORIZONTAL:
++ cv -> c_below = cv -> c_next;
++ cv -> c_next -> c_above = cv;
++ break;
++ }
++ }
++}
++
++
++int
++AddCanvas(type)
++int type; /* Horizontal or Vertical. */
++{ /** Add a new canvas, via a split. */
++
++ struct canvas *cv; /* Index into D_cvlist. */
++ struct screen_region vr; /* Canvasses in the same row/column as the
++ canvas with the focus. */
++
++ compute_region(type, &vr, D_forecv, D_cvlist);
++
++ /* Return if the region isn't big enough to split. */
++ if (vr.expanse / vr.count <= 1)
++ return -1;
++
++ /* Allocate a new canvas. */
++ if ( (cv = get_new_canvas(D_forecv)) == NULL)
++ return -1;
++
++ /* Set the type. */
++ cv -> c_type = D_forecv -> c_type = type;
++
++ /* Increment the canvas count to account for the one we will add. */
++ vr.count++;
++
++ debug_print_all_canvasses("AddCanvas start.\n");
++
++ /* 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_internal_orientation(&vr);
++ equalize_canvas_dimensions(&vr);
++
++ debug_print_all_canvasses("AddCanvas end.\n");
+
+ RethinkDisplayViewports();
+ ResizeLayersToCanvases();
+@@ -542,67 +783,595 @@ AddCanvas()
+ }
+
+ void
+-RemCanvas()
++get_endpoints(cv, start, end, off)
++struct canvas *cv;
++int **start;
++int **end;
++int **off;
++{ /** Set *start, *end, and *off appropriate with cv->c_type. */
++ switch (cv->c_type) {
++ case HORIZONTAL:
++ if (start) *start = &cv -> c_ys;
++ if (end) *end = &cv -> c_ye;
++ if (off) *off = &cv -> c_yoff;
++ break;
++ case VERTICAL:
++ if (start) *start = &cv -> c_xs;
++ if (end) *end = &cv -> c_xe;
++ if (off) *off = &cv -> c_xoff;
++ break;
++ default: ASSERT(0);
++ }
++}
++
++#define MIN_HEIGHT 1
++#define MIN_WIDTH 5
++
++int
++adjust_canvas_dimensions(vr, target, amount)
++struct screen_region *vr;
++struct canvas *target;
++int amount;
++{ /** Modify the size of target by amount. */
++
++ /* Other canvasses in the region will gain or lose
++ space to accomodate the change. Return
++ the number of rows/columns by which the size
++ of target is succesfully enlarged. (if amount <= 0,
++ return 0) */
++
++ struct canvas *this; /* for walking the list. */
++ struct canvas *prev; /* for walking the list backwards. */
++ int adjusted; /* Amount already re-allocated. */
++ int *start, *end, *off; /* c->c_{x,y}s, c->c_{x,y}e, and c->c_{x,y}off */
++ int minimum, space;
++
++ debug1("adjust: amount = %d\n", amount);
++ debug_print_all_canvasses("ADJUST \n");
++
++ ASSERT(vr->count > 1);
++
++ if (amount == 0)
++ return 0;
++
++ switch(vr->type) {
++ case HORIZONTAL: minimum = MIN_HEIGHT; space = 2; break;
++ case VERTICAL: minimum = MIN_WIDTH; space = 1; break;
++ default: ASSERT(0);
++ }
++
++ if (amount < 0) {
++ debug_print_all_canvasses("PREADJUST\n");
++
++ get_endpoints(target, &start, &end, &off);
++ if (target == vr -> start) {
++ *end += amount;
++
++ if (*end < *start + minimum)
++ *end = *start + minimum;
++
++ get_endpoints(target->c_next, &start, 0, &off);
++ *start = *off = *end + space;
++
++ debug_print_all_canvasses("POSTADJUST\n\n");
++ }
++ else {
++ for (prev = vr->start; prev->c_next != target; prev = prev->c_next)
++ ;
++ ASSERT(prev && prev -> c_next == target);
++
++ *start -= amount;
++ if (*start > *end - minimum)
++ *start = *end - minimum;
++ get_endpoints(prev, 0, &end, 0);
++ *end = *start - space;
++ }
++ return 0;
++ }
++
++ ASSERT (amount > 0);
++
++ /* Reallocate space from canvasses below target. */
++ this = vr -> end;
++ adjusted = 0;
++ while ( adjusted < amount) {
++ int this_amount; /* amount this canvas can yield. */
++ struct canvas *cv; /* For walking lists. */
++
++ if (this == target)
++ break;
++
++ get_endpoints(this, &start, &end, 0);
++ switch (vr->type) {
++ case HORIZONTAL: this_amount = *end - *start - MIN_HEIGHT; break;
++ case VERTICAL: this_amount = *end - *start - MIN_WIDTH; break;
++ default: ASSERT(0);
++ }
++
++ if (this_amount > amount - adjusted)
++ this_amount = amount - adjusted;
++
++ debug("target:\n");
++ debug_print_canvas(target);
++
++ debug("this:\n");
++ debug_print_canvas(this);
++
++ /* Move all canvasses between target and this by this_amount. */
++ for (cv = target; cv != this; cv = cv -> c_next) {
++ debug1("this_amount = %d\n", this_amount);
++ debug_print_canvas(cv);
++
++ get_endpoints(cv, &start, &end, 0);
++ *end += this_amount;
++ get_endpoints(cv->c_next, &start, &end, &off);
++ *start += this_amount;
++ *off = *start;
++ }
++ adjusted += this_amount;
++ debug1("adjusted: %d\n", adjusted);
++
++ debug("target:\n");
++ debug_print_canvas(target);
++
++ debug("this:\n");
++ debug_print_canvas(this);
++
++
++ /* Get the previous canvas. TODO: include back pointers
++ in struct canvas(?). */
++ for (prev = vr->start; prev->c_next != this; prev = prev->c_next)
++ ASSERT(prev);
++ this = prev;
++ }
++ debug1("adjusted = %d\n", adjusted);
++ if (adjusted == amount || target == vr->start)
++ return adjusted;
++
++ /* Re-allocate space from canvasses above target. */
++ ASSERT(this == target);
++ for (prev = vr->start; prev->c_next != this; prev = prev->c_next)
++ ASSERT(prev);
++ this = prev;
++
++ while (adjusted < amount) {
++ int this_amount; /* amount this canvas can yield. */
++ struct canvas *cv; /* For walking lists. */
++
++ get_endpoints(this, &start, &end, 0);
++ switch (vr->type) {
++ case HORIZONTAL: this_amount = *end - *start - MIN_HEIGHT; break;
++ case VERTICAL: this_amount = *end - *start - MIN_WIDTH; break;
++ default: ASSERT(0);
++ }
++
++ if (this_amount > amount - adjusted)
++ this_amount = amount - adjusted;
++
++ /* Move all canvasses between this and target by this_amount. */
++ for (cv = this; cv != target; cv = cv -> c_next) {
++ ASSERT(cv);
++ debug1("this_amount = %d\n", this_amount);
++ debug_print_canvas(cv);
++ debug("NEXT:\n");
++ debug_print_canvas(cv->c_next);
++
++ debug("getend:\n");
++ get_endpoints(cv, &start, &end, 0);
++ ASSERT(end && start );
++ ASSERT(start);
++ ASSERT(*end >= this_amount);
++ *end -= this_amount;
++ ASSERT(*end > *start);
++
++ debug("getend:\n");
++ ASSERT(cv->c_next);
++ get_endpoints(cv->c_next, &start, &end, &off);
++ ASSERT(start && off);
++ ASSERT(*start >= this_amount);
++ ASSERT(*start == *off);
++ *start -= this_amount;
++ *off = *start;
++
++ debug("adjusted\n");
++ debug_print_canvas(cv);
++ debug("NEXT:\n");
++ debug_print_canvas(cv->c_next);
++ debug("\n");
++ }
++ adjusted += this_amount;
++
++ if (this == vr->start)
++ break;
++
++ for (prev = vr->start; prev->c_next != this; prev = prev->c_next)
++ ASSERT(prev);
++ this = prev;
++ }
++ debug1("returning: %d\n", adjusted);
++ return adjusted;
++}
++
++void
++equalize_canvas_dimensions(vr)
++struct screen_region *vr;
++{ /** Reset the size of each canvas in the region. */
++
++ struct canvas *cv; /* for walking the list. */
++ int this_size; /* new size of cv */
++ int this_start; /* Start coordinate for current canvas. */
++
++ debug("equalize\n");
++
++ debug2("vr start = %#x, vr end = %#x\n", vr->start, vr->end);
++
++ switch(vr->type) {
++ case VERTICAL: this_start = vr->xs; break;
++ case HORIZONTAL: this_start = vr->ys; break;
++ }
++
++ for (cv = vr->start ; ; cv = cv->c_next) {
++ ASSERT(cv);
++
++ /* For the horizontal split, leave space for a status line. */
++ this_size = vr->expanse / vr->count - (vr->type == HORIZONTAL);
++
++ /* Give any additional available rows/columns to the foreground. */
++ if (cv == D_forecv)
++ this_size += vr->expanse % vr->count;
++
++ debug_print_canvas(cv);
++ debug2("cv type = %d, vr type = %d\n", cv->c_type, vr->type);
++ ASSERT(cv -> c_type == vr->type);
++
++ switch(vr->type) {
++ case VERTICAL:
++ cv -> c_xs = cv -> c_xoff = this_start;
++ cv -> c_xe = this_start + this_size - 1;
++ this_start += 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 = this_start;
++ cv -> c_ye = this_start + this_size - 1;
++ this_start += this_size + 1; /* add one for status line. */
++ break;
++ }
++ if (cv == vr->end)
++ break;
++ }
++}
++
++void
++remove_canvas_from_list(list, cv)
++struct canvas **list;
++struct canvas *cv;
++{ /** Prune cv from the list. Does not free cv.*/
++
++ struct canvas *pred; /* Predecssor of cv in list. */
++
++ 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);
++
++ 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.
++ Canvasses are not allowed to be self-referential,
++ so set such pointers to NULL.
++ */
++ 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(list, target, direction, distance)
++struct canvas *list; /* List of canvasses to resize. */
++struct canvas *target; /* Canvas in the list being removed. */
++enum directions direction;
++int distance; /* Amount to squeeze. */
++{ /** Resize canvasses in the list so that target
++ is shrunk by distance and other canvasses are grown in the
++ specified direction. If distance is 0, target
++ is destroyed, and the value returned is
++ the earliest canvas in the list that is grown.
++
++ If distance > 0, the value returned is an int,
++ giving the amount actually sqeezed. (This needs
++ re-writing!)
++ (This becomes the new region head for the region
++ orphaned by target.)
++
++ TODO: this currently only implements distance == 0;
++ */
++
++ struct canvas *ret; /* The return value.*/
++ struct canvas *cv; /* For walking the list.*/
++
++ ret = NULL;
++
++ if (distance == 0) {
++ for (cv = list; cv; cv = cv->c_next) {
++ int *cv_coord, *cv_off, targ_coord;
++ struct canvas **cv_orient, *targ_orient;
++
++ switch (direction) {
++ case RIGHT:
++ cv_orient = &cv->c_right;
++ cv_coord = &cv->c_xe;
++ cv_off = 0;
++ targ_coord = target->c_xe;
++ targ_orient = target->c_right;
++ break;
++ case LEFT:
++ cv_orient = &cv->c_left;
++ cv_coord = &cv->c_xs;
++ cv_off = &cv->c_xoff;
++ targ_coord = target->c_xs;
++ targ_orient = target->c_left;
++ break;
++ case UP:
++ cv_orient = &cv->c_above;
++ cv_coord = &cv->c_ys;
++ cv_off = &cv->c_yoff;
++ targ_coord = target->c_ys;
++ targ_orient = target->c_above;
++ break;
++ case DOWN:
++ cv_orient = &cv->c_below;
++ cv_coord = &cv->c_ye;
++ cv_off = 0;
++ targ_coord = target->c_ye;
++ targ_orient = target->c_below;
++ break;
++ }
++ if (*cv_orient == target) {
++ *cv_coord = targ_coord;
++ if(cv_off)
++ *cv_off = targ_coord;
++ *cv_orient = targ_orient;
++ ret = (ret) ? ret : cv;
++ }
++ }
++ }
++ else {
++ ASSERT(distance > 0);
++ switch (direction) {
++ /* adjust target first. */
++ case RIGHT:
++ if (target->c_xe - target->c_xs + distance < MIN_WIDTH)
++ distance = target->c_xe - target->c_xs - MIN_WIDTH;
++ target->c_xs += distance;
++ target->c_xoff = target -> c_xs;
++ break;
++ case LEFT:
++ if (target->c_xe - target->c_xs + distance < MIN_WIDTH)
++ distance = target->c_xe - target->c_xs - MIN_WIDTH;
++ target->c_xe -= distance;
++ break;
++ case UP:
++ if (target->c_ye - target->c_ys + distance < MIN_HEIGHT)
++ distance = target->c_ye - target->c_ys - MIN_HEIGHT;
++ target->c_ye -= distance;
++ break;
++ case DOWN:
++ if (target->c_ye - target->c_ys + distance < MIN_HEIGHT)
++ distance = target->c_ye - target->c_ys - MIN_HEIGHT;
++ target->c_ys += distance;
++ target->c_yoff = target -> c_ys;
++ break;
++ }
++ for (cv = list; cv; cv = cv->c_next) {
++ int *cv_coord, *cv_off, new_coord;
++ struct canvas **cv_orient;
++
++ debug("SQUEEZE\n");
++ debug_print_canvas(cv);
++
++ if (cv == target)
++ continue;
++
++ switch (direction) {
++ case RIGHT:
++ cv_orient = &cv->c_right;
++ cv_coord = &cv->c_xe;
++ cv_off = 0;
++ new_coord = cv->c_xe + distance;
++ break;
++ case LEFT:
++ cv_orient = &cv->c_left;
++ cv_coord = &cv->c_xs;
++ cv_off = &cv->c_xoff;
++ new_coord = cv->c_xs - distance;
++ break;
++ case UP:
++ cv_orient = &cv->c_above;
++ cv_coord = &cv->c_ys;
++ cv_off = &cv->c_yoff;
++ new_coord = cv->c_ys - distance;
++ break;
++ case DOWN:
++ cv_orient = &cv->c_below;
++ cv_coord = &cv->c_ye;
++ cv_off = 0;
++ new_coord = cv->c_ye + distance;
++ break;
++ }
++ if (*cv_orient == target) {
++ *cv_coord = new_coord;
++ if(cv_off)
++ *cv_off = new_coord;
++ }
++ }
++ ret = (struct canvas *) distance;
++ }
++
++
++ debug2("squeeze: target = %#x, ret = %#x\n", target, ret);
++ return ret;
++}
++
++
++struct canvas *
++grow_surrounding_regions(list, fore, amount)
++ struct canvas *list;
++ struct canvas *fore;
++ int amount;
+ {
+- int hh, h, i, j;
+- struct canvas *cv, **cvpp;
+- int did = 0;
++ /* 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. */
+
+- 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)
++ debug("grow_surrounding_regions\n");
++
++ new_fore = NULL;
++ if (amount == 0) {
++ if (fore != list) {
++ /* Grow the regions from above (the left). */
++ switch (fore -> c_type) {
++ case HORIZONTAL:
++ if ( !(new_fore = squeeze(list, fore, DOWN, 0)))
++ new_fore = squeeze(list, fore, RIGHT, 0);
++ break;
++ case VERTICAL:
++ if ( !(new_fore = squeeze(list, fore, RIGHT, 0)))
++ new_fore = squeeze(list, fore, DOWN, 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;
+ }
++ else { /* Grow the regions from below (the right). */
++ switch (fore -> c_type) {
++ case HORIZONTAL:
++ if ( !(new_fore = squeeze(list, fore, UP, 0)))
++ new_fore = squeeze(list, fore, LEFT, 0);
++ break;
++ case VERTICAL:
++ if ( !(new_fore = squeeze(list, fore, LEFT, 0)))
++ new_fore = squeeze(list, fore, UP, 0);
++ break;
++ }
++ }
++ ASSERT (new_fore);
++ return new_fore;
++ }
++}
++
++
++void
++RemCanvas()
++{ /** 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;
++
++ compute_region(D_forecv->c_type, &vr, D_forecv, D_cvlist);
++
++ debug1("RemCanvas. count = %d\n",vr.count);
++ debug_print_all_canvasses("RemCanvas() start\n");
++
++ 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;
++
++ }
++ 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;
++ }
++ }
++ else { /* Resize all bordering regions. */
++ new_fore = grow_surrounding_regions( D_cvlist, D_forecv,0);
++ }
++ debug_print_canvas(new_fore);
++
++ /* 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;
++
++ debug2("RemCanvas. forecv = %#x new_fore = %#x\n", D_forecv, new_fore);
++ debug_print_all_canvasses("RemCanvas() end.\n");
++
+ RethinkDisplayViewports();
+ ResizeLayersToCanvases();
+ }
+
+ void
+-OneCanvas()
+-{
+- struct canvas *mycv = D_forecv;
+- struct canvas *cv, **cvpp;
++OneCanvas(list, target)
++struct canvas **list;
++struct canvas *target;
++{ /* Free all canvasses in the list except for
++ target. Make *list reference target. */
++ struct canvas *cv;
++ struct canvas *next;
+
+- 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;
++ debug_print_all_canvasses("OneCanvas start.\n");
++ for (cv = *list; cv; cv = next) {
++ next = cv -> c_next;
++ if (cv == target) {
++ cv -> c_xoff = 0;
++ cv -> c_xs = 0;
++ cv -> c_xe = D_width-1;
++ cv -> c_yoff = 0;
++ cv -> c_ys = 0;
++ cv -> c_ye = D_height - 1 - (D_has_hstatus ==
++ HSTATUS_LASTLINE) - captionalways;
++ cv -> c_left = cv->c_right = NULL;
++ cv -> c_above = cv->c_below = NULL;
++ cv -> c_next = NULL;
++ } else {
+ FreeCanvas(cv);
+ }
+ }
++ *list = target;
++ debug_print_all_canvasses("OneCanvas end.\n");
++
+ RethinkDisplayViewports();
+ ResizeLayersToCanvases();
+ }
+--- display.h.orig 2003-07-01 14:01:42.000000000 +0000
++++ display.h 2006-07-07 02:39:25.000000000 +0000
+@@ -58,6 +58,11 @@ struct canvas
+ 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
+--- extern.h.orig 2003-08-22 12:27:57.000000000 +0000
++++ extern.h 2006-07-07 02:39:25.000000000 +0000
+@@ -289,9 +289,9 @@ extern void NukePending __P((void));
+ #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 void OneCanvas __P((struct canvas **, struct canvas *));
+ extern int RethinkDisplayViewports __P((void));
+ extern void RethinkViewportOffsets __P((struct canvas *));
+ #ifdef RXVT_OSC
+@@ -490,3 +490,16 @@ extern int PrepareEncodedChar __P((int
+ # endif
+ #endif
+ extern int EncodeChar __P((char *, int, int, int *));
++extern int compute_region __P((int,struct screen_region *, struct canvas *, struct canvas *));
++extern void reset_region_types __P((struct screen_region *, int));
++extern void equalize_canvas_dimensions __P((struct screen_region *));
++extern int adjust_canvas_dimensions __P((struct screen_region *, struct canvas *, int));
++enum directions {
++ LEFT,
++ RIGHT,
++ UP,
++ DOWN
++};
++
++extern struct canvas * squeeze __P(( struct canvas *, struct canvas *,
++ enum directions, int distance));
+--- process.c.orig 2003-09-18 12:53:54.000000000 +0000
++++ process.c 2006-07-07 02:39:26.000000000 +0000
+@@ -548,6 +548,7 @@ InitKeytab()
+ 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,7 +3650,11 @@ int key;
+ break;
+ #endif /* MULTIUSER */
+ case RC_SPLIT:
+- AddCanvas();
++ AddCanvas(HORIZONTAL);
++ Activate(-1);
++ break;
++ case RC_VERT_SPLIT:
++ AddCanvas(VERTICAL);
+ Activate(-1);
+ break;
+ case RC_REMOVE:
+@@ -3657,7 +3662,7 @@ int key;
+ Activate(-1);
+ break;
+ case RC_ONLY:
+- OneCanvas();
++ OneCanvas(&D_cvlist, D_forecv);
+ Activate(-1);
+ break;
+ case RC_FIT:
+@@ -5877,104 +5882,51 @@ static void
+ ResizeRegions(arg)
+ char *arg;
+ {
+- struct canvas *cv;
+- int nreg, dsize, diff, siz;
++ struct screen_region region; /* Region in which D_forecv resides. */
++ int adjusted;
++
++ /* Note: there's a nomenclature problem here. I'm using 'region'
++ to mean a set of canvasses that are related geographically
++ in the display. The documentation uses 'region' to refer to
++ a single canvas (that's the usage in the error message
++ below). */
+
+ ASSERT(display);
+- for (nreg = 0, cv = D_cvlist; cv; cv = cv->c_next)
+- nreg++;
+- if (nreg < 2)
+- {
+- Msg(0, "resize: need more than one region");
+- return;
+- }
+- dsize = D_height - (D_has_hstatus == HSTATUS_LASTLINE);
+- if (*arg == '=')
+- {
+- /* make all regions the same height */
+- int h = dsize;
+- int hh, i = 0;
+- for (cv = D_cvlist; cv; cv = cv->c_next)
+- {
+- hh = h / nreg-- - 1;
+- cv->c_ys = i;
+- cv->c_ye = i + hh - 1;
+- cv->c_yoff = i;
+- i += hh + 1;
+- h -= hh + 1;
+- }
+- RethinkDisplayViewports();
+- ResizeLayersToCanvases();
++ if (D_cvlist -> c_next == NULL) {
++ Msg(0, "More than one region required.");
+ return;
+ }
+- siz = D_forecv->c_ye - D_forecv->c_ys + 1;
+- if (*arg == '+')
+- diff = atoi(arg + 1);
+- else if (*arg == '-')
+- diff = -atoi(arg + 1);
+- else if (!strcmp(arg, "min"))
+- diff = 1 - siz;
+- else if (!strcmp(arg, "max"))
+- diff = dsize - (nreg - 1) * 2 - 1 - siz;
+- else
+- diff = atoi(arg) - siz;
+- if (diff == 0)
+- return;
+- if (siz + diff < 1)
+- diff = 1 - siz;
+- if (siz + diff > dsize - (nreg - 1) * 2 - 1)
+- diff = dsize - (nreg - 1) * 2 - 1 - siz;
+- if (diff == 0 || siz + diff < 1)
+- return;
+
+- if (diff < 0)
+- {
+- if (D_forecv->c_next)
+- {
+- D_forecv->c_ye += diff;
+- D_forecv->c_next->c_ys += diff;
+- D_forecv->c_next->c_yoff += diff;
+- }
+- else
+- {
+- for (cv = D_cvlist; cv; cv = cv->c_next)
+- if (cv->c_next == D_forecv)
++ compute_region(D_forecv->c_type, ®ion, D_forecv, D_cvlist);
++ reset_region_types(®ion, D_forecv->c_type);
++
++ if (region.count > 1) {
++ switch (*arg) {
++ case '=': equalize_canvas_dimensions(®ion); break;
++ case '-': adjust_canvas_dimensions(®ion, D_forecv, -atoi(arg+1)); break;
++ case '+':
++ adjusted = adjust_canvas_dimensions(®ion, D_forecv, atoi(arg+1));
+ break;
+- ASSERT(cv);
+- cv->c_ye -= diff;
+- D_forecv->c_ys -= diff;
+- D_forecv->c_yoff -= diff;
+- }
+- }
+- else
+- {
+- int s, i = 0, found = 0, di = diff, d2;
+- s = dsize - (nreg - 1) * 2 - 1 - siz;
+- for (cv = D_cvlist; cv; i = cv->c_ye + 2, cv = cv->c_next)
+- {
+- if (cv == D_forecv)
+- {
+- cv->c_ye = i + (cv->c_ye - cv->c_ys) + diff;
+- cv->c_yoff -= cv->c_ys - i;
+- cv->c_ys = i;
+- found = 1;
+- continue;
++ case 'm':
++ if (!strcmp(arg, "min"))
++ adjust_canvas_dimensions(®ion, D_forecv, -region.expanse);
++ else if (!strcmp(arg, "max"))
++ adjust_canvas_dimensions(®ion, D_forecv, region.expanse);
++ break;
++ default:
++ Msg(0, "resize: arguments munged");
+ }
+- s -= cv->c_ye - cv->c_ys;
+- if (!found)
+- {
+- if (s >= di)
+- continue;
+- d2 = di - s;
+ }
+- else
+- d2 = di > cv->c_ye - cv->c_ys ? cv->c_ye - cv->c_ys : di;
+- di -= d2;
+- cv->c_ye = i + (cv->c_ye - cv->c_ys) - d2;
+- cv->c_yoff -= cv->c_ys - i;
+- cv->c_ys = i;
++ else {
++ /*TODO Need to expand this canvas into surrounding regions...*/
++ switch(*arg) {
++ case '=': Msg(0, "More than one region required."); return;
++ // http://lists.gnu.org/archive/html/screen-users/2006-06/msg00012.html
++ // case '-': squeeze(D_cvlist, D_forecv, RIGHT, atoi(arg+1)); break;
++ default : Msg(0, "More than one region required."); return;
+ }
+ }
++
+ RethinkDisplayViewports();
+ ResizeLayersToCanvases();
+ }
+--- screen.h.orig 2003-08-22 12:28:43.000000000 +0000
++++ screen.h 2006-07-07 02:39:26.000000000 +0000
+@@ -288,8 +288,25 @@ struct baud_values
+ int sym; /* symbol defined in ttydev.h */
+ };
+
++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 expanse; /* Range in the appropriate direction. */
++ int count; /* Number of canvasses in the region. */
++ int type; /* HORIZONTAL or VERTICAL. */
++ int xs; /* starting x coordinate */
++ int xe; /* ending x coordinate */
++ int ys; /* starting y coordinate */
++ int ye; /* ending y coordinate */
++};
++
+ /*
+ * windowlist orders
+ */
+ #define WLIST_NUM 0
+ #define WLIST_MRU 1
++
++#define HORIZONTAL 0
++#define VERTICAL 1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20080930/f9438a2d/attachment-0001.html
More information about the macports-changes
mailing list