Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 213906 Details for
Bug 171277
app-misc/screen vertical split patch
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
wrp_vertical_split_0.3_4.0.2.patch
wrp_vertical_split_0.3_4.0.2.patch (text/plain), 38.59 KB, created by
gtlinuxman
on 2009-12-23 08:39:23 UTC
(
hide
)
Description:
wrp_vertical_split_0.3_4.0.2.patch
Filename:
MIME Type:
Creator:
gtlinuxman
Created:
2009-12-23 08:39:23 UTC
Size:
38.59 KB
patch
obsolete
>diff -BENbdpru old/comm.c new/comm.c >--- old/comm.c 2003-09-08 14:25:08.000000000 +0000 >+++ new/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 }, >diff -BENbdpru old/display.c new/display.c >--- old/display.c 2003-12-05 13:45:41.000000000 +0000 >+++ new/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(); > } >diff -BENbdpru old/display.h new/display.h >--- old/display.h 2003-07-01 14:01:42.000000000 +0000 >+++ new/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 >diff -BENbdpru old/extern.h new/extern.h >--- old/extern.h 2003-08-22 12:27:57.000000000 +0000 >+++ new/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)); >diff -BENbdpru old/process.c new/process.c >--- old/process.c 2003-09-18 12:53:54.000000000 +0000 >+++ new/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(); > } >diff -BENbdpru old/screen.h new/screen.h >--- old/screen.h 2003-08-22 12:28:43.000000000 +0000 >+++ new/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
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 171277
:
213904
|
213905
| 213906