1 | --- comm.c.orig 2003-09-08 14:25:08.000000000 +0000 |
---|
2 | +++ comm.c 2006-07-07 02:39:24.000000000 +0000 |
---|
3 | @@ -309,6 +309,7 @@ struct comm comms[RC_LAST + 1] = |
---|
4 | { "vbellwait", ARGS_1 }, |
---|
5 | { "verbose", ARGS_01 }, |
---|
6 | { "version", ARGS_0 }, |
---|
7 | + { "vert_split", NEED_DISPLAY|ARGS_0 }, |
---|
8 | { "wall", NEED_DISPLAY|ARGS_1}, |
---|
9 | { "width", ARGS_0123 }, |
---|
10 | { "windowlist", NEED_DISPLAY|ARGS_012 }, |
---|
11 | --- display.c.orig 2003-12-05 13:45:41.000000000 +0000 |
---|
12 | +++ display.c 2006-07-07 02:39:26.000000000 +0000 |
---|
13 | @@ -476,65 +476,306 @@ struct canvas *cv; |
---|
14 | free(cv); |
---|
15 | } |
---|
16 | |
---|
17 | +struct canvas * |
---|
18 | +get_new_canvas(target) |
---|
19 | +struct canvas *target; |
---|
20 | +{ /** Allocate a new canvas, and assign it characteristics |
---|
21 | + equal to those of target. */ |
---|
22 | + struct canvas *cv; |
---|
23 | + |
---|
24 | + if ((cv = (struct canvas *) calloc(1, sizeof *cv)) == 0) |
---|
25 | + return NULL; |
---|
26 | + |
---|
27 | + cv -> c_xs = target -> c_xs; |
---|
28 | + cv -> c_xe = target -> c_xe; |
---|
29 | + cv -> c_ys = target -> c_ys; |
---|
30 | + cv -> c_ye = target -> c_ye; |
---|
31 | + cv -> c_xoff = target -> c_xoff; |
---|
32 | + cv -> c_yoff = target -> c_yoff; |
---|
33 | + cv -> c_display = target -> c_display; |
---|
34 | + cv -> c_vplist = 0; |
---|
35 | + cv -> c_captev.type = EV_TIMEOUT; |
---|
36 | + cv -> c_captev.data = (char *) cv; |
---|
37 | + cv -> c_captev.handler = cv_winid_fn; |
---|
38 | + |
---|
39 | + cv -> c_blank.l_cvlist = cv; |
---|
40 | + cv -> c_blank.l_width = cv->c_xe - cv->c_xs + 1; |
---|
41 | + cv -> c_blank.l_height = cv->c_ye - cv->c_ys + 1; |
---|
42 | + cv -> c_blank.l_x = cv->c_blank.l_y = 0; |
---|
43 | + cv -> c_blank.l_layfn = &BlankLf; |
---|
44 | + cv -> c_blank.l_data = 0; |
---|
45 | + cv -> c_blank.l_next = 0; |
---|
46 | + cv -> c_blank.l_bottom = &cv->c_blank; |
---|
47 | + cv -> c_blank.l_blocking = 0; |
---|
48 | + cv -> c_layer = &cv->c_blank; |
---|
49 | + cv -> c_lnext = 0; |
---|
50 | + |
---|
51 | + cv -> c_left = target -> c_left; |
---|
52 | + cv -> c_right = target -> c_right; |
---|
53 | + cv -> c_above = target -> c_above; |
---|
54 | + cv -> c_below = target -> c_below; |
---|
55 | + |
---|
56 | + return cv; |
---|
57 | +} |
---|
58 | + |
---|
59 | int |
---|
60 | -AddCanvas() |
---|
61 | -{ |
---|
62 | - int hh, h, i, j; |
---|
63 | - struct canvas *cv, **cvpp; |
---|
64 | +share_limits( type, cv0, cv1) |
---|
65 | +int type; /* HORIZONTAL or VERTICAL */ |
---|
66 | +struct canvas *cv0; /* canvas to compare against. */ |
---|
67 | +struct canvas *cv1; /* canvas to compare against. */ |
---|
68 | +{ /** Return non-zero if the two canvasses share limits. |
---|
69 | + (ie, their horizontal or veritcal boundaries are the same) |
---|
70 | + */ |
---|
71 | + switch (type) { |
---|
72 | + case HORIZONTAL: |
---|
73 | + return cv0 -> c_xs == cv1 -> c_xs && cv0->c_xe == cv1 -> c_xe; |
---|
74 | + case VERTICAL: |
---|
75 | + return cv0 -> c_ys == cv1 -> c_ys && cv0->c_ye == cv1 -> c_ye; |
---|
76 | + } |
---|
77 | + ASSERT(0); |
---|
78 | + return 0; |
---|
79 | +} |
---|
80 | |
---|
81 | - for (cv = D_cvlist, j = 0; cv; cv = cv->c_next) |
---|
82 | - j++; |
---|
83 | - j++; /* new canvas */ |
---|
84 | - h = D_height - (D_has_hstatus == HSTATUS_LASTLINE); |
---|
85 | - if (h / j <= 1) |
---|
86 | - return -1; |
---|
87 | +int |
---|
88 | +compute_region(type, a, focus, list) |
---|
89 | +int type; /* 0 - horizontal, 1 - vertical */ |
---|
90 | +struct screen_region *a; /* Return value. */ |
---|
91 | +struct canvas *focus; /* Canvas to compute around. */ |
---|
92 | +struct canvas *list; /* List of all canvasses. */ |
---|
93 | +{ /** Find the start and end of the screen region.*/ |
---|
94 | + /* |
---|
95 | + I'm using the term 'region' here differently |
---|
96 | + than elsewhere. Elsewhere, 'region' is synonymous |
---|
97 | + with 'canvas', but I am using it to denote |
---|
98 | + a collection of related canvasses. |
---|
99 | |
---|
100 | - for (cv = D_cvlist; cv; cv = cv->c_next) |
---|
101 | - if (cv == D_forecv) |
---|
102 | + Suppose the screen currently looks |
---|
103 | + like this: |
---|
104 | + --------------------------- |
---|
105 | + | 0 | 1 | 2 | |
---|
106 | + --------------------------- |
---|
107 | + | 3 | 4 | 5 | |
---|
108 | + --------------------------- |
---|
109 | + | 6 | |
---|
110 | + --------------------------- |
---|
111 | + | 7 | 8 | 9 | |
---|
112 | + --------------------------- |
---|
113 | + Where there are 10 entries in D_cvlist. |
---|
114 | + Canvasses 0,1,2 are in the same region, as |
---|
115 | + are cavasses 1 and 4. We need to be careful not to |
---|
116 | + lump 1 and 4 together w/8. The |
---|
117 | + type of the region containing 0,1,2 is |
---|
118 | + VERTICAL, since each canvas is created |
---|
119 | + via a vertical split. |
---|
120 | + |
---|
121 | + Throughout, I'm assuming that canvasses |
---|
122 | + are created so that any region will |
---|
123 | + be contiguous in D_cvlist. |
---|
124 | + |
---|
125 | + Note: this was written before the screen |
---|
126 | + orientation members (c_left, c_above, c_below, |
---|
127 | + c_right) were added to the struct canvas. |
---|
128 | + Might want to rewrite this to use those. |
---|
129 | + |
---|
130 | + Written by Bill Pursell, 23/12/2005 |
---|
131 | + */ |
---|
132 | + |
---|
133 | + struct canvas *cv; /* Entry in list. */ |
---|
134 | + int seen_focus; /* Flag used when walking the list. */ |
---|
135 | + |
---|
136 | + seen_focus = 0; |
---|
137 | + a->count = 0; |
---|
138 | + a->type = type; |
---|
139 | + |
---|
140 | + if (type == HORIZONTAL) { |
---|
141 | + a->xs = focus -> c_xs; |
---|
142 | + a->xe = focus -> c_xe; |
---|
143 | + a->ys = -1; |
---|
144 | + } |
---|
145 | + if (type == VERTICAL) { |
---|
146 | + a->ys = focus -> c_ys; |
---|
147 | + a->ye = focus -> c_ye; |
---|
148 | + a->xs = -1; |
---|
149 | + } |
---|
150 | + /* Count the canvasses in the same region as the |
---|
151 | + canvas with the focus, and find the limits of the region. */ |
---|
152 | + for (cv = list; cv; cv = cv->c_next) { |
---|
153 | + if (cv == focus) |
---|
154 | + seen_focus = 1; |
---|
155 | + if (share_limits( type, cv, focus)) { |
---|
156 | + debug2("cv = %x %s\n", cv, (cv == focus)? "FORE":""); |
---|
157 | + debug2("x range: %d - %d\n", cv->c_xs, cv->c_xe); |
---|
158 | + debug2("y range: %d - %d\n", cv->c_ys, cv->c_ye); |
---|
159 | + switch (type) { |
---|
160 | + case HORIZONTAL : |
---|
161 | + if (a->ys == -1) { |
---|
162 | + a->ys = cv -> c_ys; |
---|
163 | + a->start = cv; |
---|
164 | + } |
---|
165 | + a->ye = cv -> c_ye; |
---|
166 | break; |
---|
167 | - ASSERT(cv); |
---|
168 | - cvpp = &cv->c_next; |
---|
169 | + case VERTICAL: |
---|
170 | + if (a->xs == -1) { |
---|
171 | + a->xs = cv -> c_xs; |
---|
172 | + a->start = cv; |
---|
173 | + } |
---|
174 | + a->xe = cv -> c_xe; |
---|
175 | + break; |
---|
176 | + } |
---|
177 | |
---|
178 | - if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0) |
---|
179 | - return -1; |
---|
180 | + a->end = cv; |
---|
181 | + a->count++; |
---|
182 | + } |
---|
183 | + if (!share_limits(type, cv, focus) || cv -> c_next == NULL) { |
---|
184 | + if (seen_focus) { |
---|
185 | + debug2("x range of Region: %d-%d\n", a->xs, a->xe); |
---|
186 | + debug2("y range of Region: %d-%d\n", a->ys, a->ye); |
---|
187 | + break; |
---|
188 | + } |
---|
189 | + else { |
---|
190 | + switch(type) { |
---|
191 | + case HORIZONTAL: a->ys = -1; break; |
---|
192 | + case VERTICAL : a->xs = -1; break; |
---|
193 | + } |
---|
194 | + a->count = 0; |
---|
195 | + } |
---|
196 | + } |
---|
197 | + } |
---|
198 | |
---|
199 | - cv->c_xs = 0; |
---|
200 | - cv->c_xe = D_width - 1; |
---|
201 | - cv->c_ys = 0; |
---|
202 | - cv->c_ye = D_height - 1; |
---|
203 | - cv->c_xoff = 0; |
---|
204 | - cv->c_yoff = 0; |
---|
205 | - cv->c_display = display; |
---|
206 | - cv->c_vplist = 0; |
---|
207 | - cv->c_captev.type = EV_TIMEOUT; |
---|
208 | - cv->c_captev.data = (char *)cv; |
---|
209 | - cv->c_captev.handler = cv_winid_fn; |
---|
210 | + switch (type) { |
---|
211 | + case HORIZONTAL: |
---|
212 | + a->expanse = a->ye - a->ys + 1; |
---|
213 | + ASSERT(a->expanse <= D_height - (D_has_hstatus == HSTATUS_LASTLINE)); |
---|
214 | + break; |
---|
215 | + case VERTICAL: |
---|
216 | + a->expanse = a->xe - a->xs + 1; |
---|
217 | + ASSERT(a->expanse <= D_width); |
---|
218 | + break; |
---|
219 | + } |
---|
220 | + ASSERT(seen_focus); |
---|
221 | +} |
---|
222 | |
---|
223 | - cv->c_blank.l_cvlist = cv; |
---|
224 | - cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1; |
---|
225 | - cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1; |
---|
226 | - cv->c_blank.l_x = cv->c_blank.l_y = 0; |
---|
227 | - cv->c_blank.l_layfn = &BlankLf; |
---|
228 | - cv->c_blank.l_data = 0; |
---|
229 | - cv->c_blank.l_next = 0; |
---|
230 | - cv->c_blank.l_bottom = &cv->c_blank; |
---|
231 | - cv->c_blank.l_blocking = 0; |
---|
232 | - cv->c_layer = &cv->c_blank; |
---|
233 | - cv->c_lnext = 0; |
---|
234 | +void |
---|
235 | +reset_region_types(region, type) |
---|
236 | +struct screen_region *region; |
---|
237 | +int type; |
---|
238 | +{ /** Set c_type of all the canvasses in the region to type. */ |
---|
239 | |
---|
240 | - cv->c_next = *cvpp; |
---|
241 | - *cvpp = cv; |
---|
242 | + struct canvas *cv; |
---|
243 | |
---|
244 | - i = 0; |
---|
245 | - for (cv = D_cvlist; cv; cv = cv->c_next) |
---|
246 | - { |
---|
247 | - hh = h / j-- - 1; |
---|
248 | - cv->c_ys = i; |
---|
249 | - cv->c_ye = i + hh - 1; |
---|
250 | - cv->c_yoff = i; |
---|
251 | - i += hh + 1; |
---|
252 | - h -= hh + 1; |
---|
253 | + for (cv = region->start; cv != region->end->c_next; cv = cv->c_next) { |
---|
254 | + #ifdef DEBUG |
---|
255 | + switch(type) { |
---|
256 | + case HORIZONTAL: |
---|
257 | + ASSERT (cv->c_xs == region -> xs && cv->c_xe == region -> xe); |
---|
258 | + break; |
---|
259 | + case VERTICAL: |
---|
260 | + ASSERT (cv->c_ys == region -> ys && cv->c_ye == region -> ye); |
---|
261 | + break; |
---|
262 | + default: |
---|
263 | + ASSERT(0); |
---|
264 | + } |
---|
265 | + #endif |
---|
266 | + cv -> c_type = type; |
---|
267 | } |
---|
268 | +} |
---|
269 | + |
---|
270 | +void |
---|
271 | +debug_print_canvas(cv) |
---|
272 | +struct canvas *cv; |
---|
273 | +{ /** Print cv to the debug file. */ |
---|
274 | +#ifdef DEBUG |
---|
275 | + debug2("%x %s\n", cv, (cv == D_forecv)?" HAS FOCUS":""); |
---|
276 | + debug2(" above: %x below: %x\n", cv->c_above, cv->c_below); |
---|
277 | + debug2(" left: %x right: %x\n", cv->c_left, cv->c_right); |
---|
278 | + debug3(" x range: %2d-%2d, xoff = %d\n", |
---|
279 | + cv->c_xs, cv->c_xe, cv->c_xoff); |
---|
280 | + debug3(" y range: %2d-%2d yoff = %d\n", |
---|
281 | + cv->c_ys, cv->c_ye, cv->c_yoff); |
---|
282 | + debug2(" next: %x type: %d\n", cv->c_next, cv->c_type); |
---|
283 | +#endif |
---|
284 | +} |
---|
285 | + |
---|
286 | +void |
---|
287 | +debug_print_all_canvasses(header) |
---|
288 | +char *header; |
---|
289 | +{ /** Print the dimensions of all the canvasses |
---|
290 | + in the current display to the debug file. Precede |
---|
291 | + with a line containing the header message. */ |
---|
292 | + #ifdef DEBUG |
---|
293 | + struct canvas *cv; |
---|
294 | + char message[BUFSIZ]; |
---|
295 | + |
---|
296 | + sprintf(message, "%10s %5d: ",__FILE__ , __LINE__); |
---|
297 | + strcat (message, header); |
---|
298 | + fprintf(dfp, message); |
---|
299 | + fflush(dfp); |
---|
300 | + for (cv = D_cvlist; cv; cv = cv->c_next) { |
---|
301 | + debug_print_canvas(cv); |
---|
302 | + } |
---|
303 | + #endif |
---|
304 | + return; |
---|
305 | +} |
---|
306 | + |
---|
307 | +set_internal_orientation(region) |
---|
308 | +struct screen_region *region; |
---|
309 | +{ /** Set the orientation for canvasses inside the region. */ |
---|
310 | + |
---|
311 | + struct canvas *cv; |
---|
312 | + |
---|
313 | + for (cv = region -> start; cv != region -> end; cv = cv->c_next) { |
---|
314 | + ASSERT (cv -> c_type == region -> type); |
---|
315 | + switch (region->type) { |
---|
316 | + case VERTICAL: |
---|
317 | + cv -> c_right = cv -> c_next; |
---|
318 | + cv -> c_next -> c_left = cv; |
---|
319 | + break; |
---|
320 | + case HORIZONTAL: |
---|
321 | + cv -> c_below = cv -> c_next; |
---|
322 | + cv -> c_next -> c_above = cv; |
---|
323 | + break; |
---|
324 | + } |
---|
325 | + } |
---|
326 | +} |
---|
327 | + |
---|
328 | + |
---|
329 | +int |
---|
330 | +AddCanvas(type) |
---|
331 | +int type; /* Horizontal or Vertical. */ |
---|
332 | +{ /** Add a new canvas, via a split. */ |
---|
333 | + |
---|
334 | + struct canvas *cv; /* Index into D_cvlist. */ |
---|
335 | + struct screen_region vr; /* Canvasses in the same row/column as the |
---|
336 | + canvas with the focus. */ |
---|
337 | + |
---|
338 | + compute_region(type, &vr, D_forecv, D_cvlist); |
---|
339 | + |
---|
340 | + /* Return if the region isn't big enough to split. */ |
---|
341 | + if (vr.expanse / vr.count <= 1) |
---|
342 | + return -1; |
---|
343 | + |
---|
344 | + /* Allocate a new canvas. */ |
---|
345 | + if ( (cv = get_new_canvas(D_forecv)) == NULL) |
---|
346 | + return -1; |
---|
347 | + |
---|
348 | + /* Set the type. */ |
---|
349 | + cv -> c_type = D_forecv -> c_type = type; |
---|
350 | + |
---|
351 | + /* Increment the canvas count to account for the one we will add. */ |
---|
352 | + vr.count++; |
---|
353 | + |
---|
354 | + debug_print_all_canvasses("AddCanvas start.\n"); |
---|
355 | + |
---|
356 | + /* Insert the new canvas after the current foreground. */ |
---|
357 | + cv -> c_next = D_forecv->c_next; |
---|
358 | + D_forecv -> c_next = cv; |
---|
359 | + if (vr.end == D_forecv) |
---|
360 | + vr.end = cv; |
---|
361 | + |
---|
362 | + set_internal_orientation(&vr); |
---|
363 | + equalize_canvas_dimensions(&vr); |
---|
364 | + |
---|
365 | + debug_print_all_canvasses("AddCanvas end.\n"); |
---|
366 | |
---|
367 | RethinkDisplayViewports(); |
---|
368 | ResizeLayersToCanvases(); |
---|
369 | @@ -542,67 +783,595 @@ AddCanvas() |
---|
370 | } |
---|
371 | |
---|
372 | void |
---|
373 | -RemCanvas() |
---|
374 | +get_endpoints(cv, start, end, off) |
---|
375 | +struct canvas *cv; |
---|
376 | +int **start; |
---|
377 | +int **end; |
---|
378 | +int **off; |
---|
379 | +{ /** Set *start, *end, and *off appropriate with cv->c_type. */ |
---|
380 | + switch (cv->c_type) { |
---|
381 | + case HORIZONTAL: |
---|
382 | + if (start) *start = &cv -> c_ys; |
---|
383 | + if (end) *end = &cv -> c_ye; |
---|
384 | + if (off) *off = &cv -> c_yoff; |
---|
385 | + break; |
---|
386 | + case VERTICAL: |
---|
387 | + if (start) *start = &cv -> c_xs; |
---|
388 | + if (end) *end = &cv -> c_xe; |
---|
389 | + if (off) *off = &cv -> c_xoff; |
---|
390 | + break; |
---|
391 | + default: ASSERT(0); |
---|
392 | + } |
---|
393 | +} |
---|
394 | + |
---|
395 | +#define MIN_HEIGHT 1 |
---|
396 | +#define MIN_WIDTH 5 |
---|
397 | + |
---|
398 | +int |
---|
399 | +adjust_canvas_dimensions(vr, target, amount) |
---|
400 | +struct screen_region *vr; |
---|
401 | +struct canvas *target; |
---|
402 | +int amount; |
---|
403 | +{ /** Modify the size of target by amount. */ |
---|
404 | + |
---|
405 | + /* Other canvasses in the region will gain or lose |
---|
406 | + space to accomodate the change. Return |
---|
407 | + the number of rows/columns by which the size |
---|
408 | + of target is succesfully enlarged. (if amount <= 0, |
---|
409 | + return 0) */ |
---|
410 | + |
---|
411 | + struct canvas *this; /* for walking the list. */ |
---|
412 | + struct canvas *prev; /* for walking the list backwards. */ |
---|
413 | + int adjusted; /* Amount already re-allocated. */ |
---|
414 | + int *start, *end, *off; /* c->c_{x,y}s, c->c_{x,y}e, and c->c_{x,y}off */ |
---|
415 | + int minimum, space; |
---|
416 | + |
---|
417 | + debug1("adjust: amount = %d\n", amount); |
---|
418 | + debug_print_all_canvasses("ADJUST \n"); |
---|
419 | + |
---|
420 | + ASSERT(vr->count > 1); |
---|
421 | + |
---|
422 | + if (amount == 0) |
---|
423 | + return 0; |
---|
424 | + |
---|
425 | + switch(vr->type) { |
---|
426 | + case HORIZONTAL: minimum = MIN_HEIGHT; space = 2; break; |
---|
427 | + case VERTICAL: minimum = MIN_WIDTH; space = 1; break; |
---|
428 | + default: ASSERT(0); |
---|
429 | + } |
---|
430 | + |
---|
431 | + if (amount < 0) { |
---|
432 | + debug_print_all_canvasses("PREADJUST\n"); |
---|
433 | + |
---|
434 | + get_endpoints(target, &start, &end, &off); |
---|
435 | + if (target == vr -> start) { |
---|
436 | + *end += amount; |
---|
437 | + |
---|
438 | + if (*end < *start + minimum) |
---|
439 | + *end = *start + minimum; |
---|
440 | + |
---|
441 | + get_endpoints(target->c_next, &start, 0, &off); |
---|
442 | + *start = *off = *end + space; |
---|
443 | + |
---|
444 | + debug_print_all_canvasses("POSTADJUST\n\n"); |
---|
445 | + } |
---|
446 | + else { |
---|
447 | + for (prev = vr->start; prev->c_next != target; prev = prev->c_next) |
---|
448 | + ; |
---|
449 | + ASSERT(prev && prev -> c_next == target); |
---|
450 | + |
---|
451 | + *start -= amount; |
---|
452 | + if (*start > *end - minimum) |
---|
453 | + *start = *end - minimum; |
---|
454 | + get_endpoints(prev, 0, &end, 0); |
---|
455 | + *end = *start - space; |
---|
456 | + } |
---|
457 | + return 0; |
---|
458 | + } |
---|
459 | + |
---|
460 | + ASSERT (amount > 0); |
---|
461 | + |
---|
462 | + /* Reallocate space from canvasses below target. */ |
---|
463 | + this = vr -> end; |
---|
464 | + adjusted = 0; |
---|
465 | + while ( adjusted < amount) { |
---|
466 | + int this_amount; /* amount this canvas can yield. */ |
---|
467 | + struct canvas *cv; /* For walking lists. */ |
---|
468 | + |
---|
469 | + if (this == target) |
---|
470 | + break; |
---|
471 | + |
---|
472 | + get_endpoints(this, &start, &end, 0); |
---|
473 | + switch (vr->type) { |
---|
474 | + case HORIZONTAL: this_amount = *end - *start - MIN_HEIGHT; break; |
---|
475 | + case VERTICAL: this_amount = *end - *start - MIN_WIDTH; break; |
---|
476 | + default: ASSERT(0); |
---|
477 | + } |
---|
478 | + |
---|
479 | + if (this_amount > amount - adjusted) |
---|
480 | + this_amount = amount - adjusted; |
---|
481 | + |
---|
482 | + debug("target:\n"); |
---|
483 | + debug_print_canvas(target); |
---|
484 | + |
---|
485 | + debug("this:\n"); |
---|
486 | + debug_print_canvas(this); |
---|
487 | + |
---|
488 | + /* Move all canvasses between target and this by this_amount. */ |
---|
489 | + for (cv = target; cv != this; cv = cv -> c_next) { |
---|
490 | + debug1("this_amount = %d\n", this_amount); |
---|
491 | + debug_print_canvas(cv); |
---|
492 | + |
---|
493 | + get_endpoints(cv, &start, &end, 0); |
---|
494 | + *end += this_amount; |
---|
495 | + get_endpoints(cv->c_next, &start, &end, &off); |
---|
496 | + *start += this_amount; |
---|
497 | + *off = *start; |
---|
498 | + } |
---|
499 | + adjusted += this_amount; |
---|
500 | + debug1("adjusted: %d\n", adjusted); |
---|
501 | + |
---|
502 | + debug("target:\n"); |
---|
503 | + debug_print_canvas(target); |
---|
504 | + |
---|
505 | + debug("this:\n"); |
---|
506 | + debug_print_canvas(this); |
---|
507 | + |
---|
508 | + |
---|
509 | + /* Get the previous canvas. TODO: include back pointers |
---|
510 | + in struct canvas(?). */ |
---|
511 | + for (prev = vr->start; prev->c_next != this; prev = prev->c_next) |
---|
512 | + ASSERT(prev); |
---|
513 | + this = prev; |
---|
514 | + } |
---|
515 | + debug1("adjusted = %d\n", adjusted); |
---|
516 | + if (adjusted == amount || target == vr->start) |
---|
517 | + return adjusted; |
---|
518 | + |
---|
519 | + /* Re-allocate space from canvasses above target. */ |
---|
520 | + ASSERT(this == target); |
---|
521 | + for (prev = vr->start; prev->c_next != this; prev = prev->c_next) |
---|
522 | + ASSERT(prev); |
---|
523 | + this = prev; |
---|
524 | + |
---|
525 | + while (adjusted < amount) { |
---|
526 | + int this_amount; /* amount this canvas can yield. */ |
---|
527 | + struct canvas *cv; /* For walking lists. */ |
---|
528 | + |
---|
529 | + get_endpoints(this, &start, &end, 0); |
---|
530 | + switch (vr->type) { |
---|
531 | + case HORIZONTAL: this_amount = *end - *start - MIN_HEIGHT; break; |
---|
532 | + case VERTICAL: this_amount = *end - *start - MIN_WIDTH; break; |
---|
533 | + default: ASSERT(0); |
---|
534 | + } |
---|
535 | + |
---|
536 | + if (this_amount > amount - adjusted) |
---|
537 | + this_amount = amount - adjusted; |
---|
538 | + |
---|
539 | + /* Move all canvasses between this and target by this_amount. */ |
---|
540 | + for (cv = this; cv != target; cv = cv -> c_next) { |
---|
541 | + ASSERT(cv); |
---|
542 | + debug1("this_amount = %d\n", this_amount); |
---|
543 | + debug_print_canvas(cv); |
---|
544 | + debug("NEXT:\n"); |
---|
545 | + debug_print_canvas(cv->c_next); |
---|
546 | + |
---|
547 | + debug("getend:\n"); |
---|
548 | + get_endpoints(cv, &start, &end, 0); |
---|
549 | + ASSERT(end && start ); |
---|
550 | + ASSERT(start); |
---|
551 | + ASSERT(*end >= this_amount); |
---|
552 | + *end -= this_amount; |
---|
553 | + ASSERT(*end > *start); |
---|
554 | + |
---|
555 | + debug("getend:\n"); |
---|
556 | + ASSERT(cv->c_next); |
---|
557 | + get_endpoints(cv->c_next, &start, &end, &off); |
---|
558 | + ASSERT(start && off); |
---|
559 | + ASSERT(*start >= this_amount); |
---|
560 | + ASSERT(*start == *off); |
---|
561 | + *start -= this_amount; |
---|
562 | + *off = *start; |
---|
563 | + |
---|
564 | + debug("adjusted\n"); |
---|
565 | + debug_print_canvas(cv); |
---|
566 | + debug("NEXT:\n"); |
---|
567 | + debug_print_canvas(cv->c_next); |
---|
568 | + debug("\n"); |
---|
569 | + } |
---|
570 | + adjusted += this_amount; |
---|
571 | + |
---|
572 | + if (this == vr->start) |
---|
573 | + break; |
---|
574 | + |
---|
575 | + for (prev = vr->start; prev->c_next != this; prev = prev->c_next) |
---|
576 | + ASSERT(prev); |
---|
577 | + this = prev; |
---|
578 | + } |
---|
579 | + debug1("returning: %d\n", adjusted); |
---|
580 | + return adjusted; |
---|
581 | +} |
---|
582 | + |
---|
583 | +void |
---|
584 | +equalize_canvas_dimensions(vr) |
---|
585 | +struct screen_region *vr; |
---|
586 | +{ /** Reset the size of each canvas in the region. */ |
---|
587 | + |
---|
588 | + struct canvas *cv; /* for walking the list. */ |
---|
589 | + int this_size; /* new size of cv */ |
---|
590 | + int this_start; /* Start coordinate for current canvas. */ |
---|
591 | + |
---|
592 | + debug("equalize\n"); |
---|
593 | + |
---|
594 | + debug2("vr start = %#x, vr end = %#x\n", vr->start, vr->end); |
---|
595 | + |
---|
596 | + switch(vr->type) { |
---|
597 | + case VERTICAL: this_start = vr->xs; break; |
---|
598 | + case HORIZONTAL: this_start = vr->ys; break; |
---|
599 | + } |
---|
600 | + |
---|
601 | + for (cv = vr->start ; ; cv = cv->c_next) { |
---|
602 | + ASSERT(cv); |
---|
603 | + |
---|
604 | + /* For the horizontal split, leave space for a status line. */ |
---|
605 | + this_size = vr->expanse / vr->count - (vr->type == HORIZONTAL); |
---|
606 | + |
---|
607 | + /* Give any additional available rows/columns to the foreground. */ |
---|
608 | + if (cv == D_forecv) |
---|
609 | + this_size += vr->expanse % vr->count; |
---|
610 | + |
---|
611 | + debug_print_canvas(cv); |
---|
612 | + debug2("cv type = %d, vr type = %d\n", cv->c_type, vr->type); |
---|
613 | + ASSERT(cv -> c_type == vr->type); |
---|
614 | + |
---|
615 | + switch(vr->type) { |
---|
616 | + case VERTICAL: |
---|
617 | + cv -> c_xs = cv -> c_xoff = this_start; |
---|
618 | + cv -> c_xe = this_start + this_size - 1; |
---|
619 | + this_start += this_size; |
---|
620 | + break; |
---|
621 | + case HORIZONTAL: |
---|
622 | + if (cv == vr->end && cv->c_ye == D_height-1- |
---|
623 | + (D_has_hstatus == HSTATUS_LASTLINE)) |
---|
624 | + this_size += 1; /* Don't make space for status line |
---|
625 | + in the bottom region (it already has one). */ |
---|
626 | + |
---|
627 | + cv -> c_ys = cv -> c_yoff = this_start; |
---|
628 | + cv -> c_ye = this_start + this_size - 1; |
---|
629 | + this_start += this_size + 1; /* add one for status line. */ |
---|
630 | + break; |
---|
631 | + } |
---|
632 | + if (cv == vr->end) |
---|
633 | + break; |
---|
634 | + } |
---|
635 | +} |
---|
636 | + |
---|
637 | +void |
---|
638 | +remove_canvas_from_list(list, cv) |
---|
639 | +struct canvas **list; |
---|
640 | +struct canvas *cv; |
---|
641 | +{ /** Prune cv from the list. Does not free cv.*/ |
---|
642 | + |
---|
643 | + struct canvas *pred; /* Predecssor of cv in list. */ |
---|
644 | + |
---|
645 | + if (cv == *list ) { |
---|
646 | + *list = cv -> c_next; |
---|
647 | + } |
---|
648 | + else { |
---|
649 | + /* Find the predecessor of cv. */ |
---|
650 | + for (pred = *list; pred->c_next != cv; pred = pred->c_next) |
---|
651 | + ASSERT(pred); |
---|
652 | + |
---|
653 | + pred -> c_next = cv -> c_next; |
---|
654 | + } |
---|
655 | +} |
---|
656 | + |
---|
657 | +void |
---|
658 | +redirect_pointers(list, old, new) |
---|
659 | +struct canvas *list; |
---|
660 | +struct canvas *old; |
---|
661 | +struct canvas *new; |
---|
662 | +{ /** For each canvas in the list, change any |
---|
663 | + of its screen orientation pointers from old to new. |
---|
664 | + Canvasses are not allowed to be self-referential, |
---|
665 | + so set such pointers to NULL. |
---|
666 | + */ |
---|
667 | + struct canvas *cv; |
---|
668 | + for (cv=list; cv; cv = cv->c_next) { |
---|
669 | + if (cv -> c_left == old) |
---|
670 | + cv -> c_left = (cv==new)?NULL:new; |
---|
671 | + if (cv -> c_above == old) |
---|
672 | + cv -> c_above = (cv==new)?NULL:new; |
---|
673 | + if (cv -> c_right == old) |
---|
674 | + cv -> c_right = (cv==new)?NULL:new; |
---|
675 | + if (cv -> c_below == old) |
---|
676 | + cv -> c_below = (cv==new)?NULL:new; |
---|
677 | + } |
---|
678 | +} |
---|
679 | + |
---|
680 | +struct canvas * |
---|
681 | +squeeze(list, target, direction, distance) |
---|
682 | +struct canvas *list; /* List of canvasses to resize. */ |
---|
683 | +struct canvas *target; /* Canvas in the list being removed. */ |
---|
684 | +enum directions direction; |
---|
685 | +int distance; /* Amount to squeeze. */ |
---|
686 | +{ /** Resize canvasses in the list so that target |
---|
687 | + is shrunk by distance and other canvasses are grown in the |
---|
688 | + specified direction. If distance is 0, target |
---|
689 | + is destroyed, and the value returned is |
---|
690 | + the earliest canvas in the list that is grown. |
---|
691 | + |
---|
692 | + If distance > 0, the value returned is an int, |
---|
693 | + giving the amount actually sqeezed. (This needs |
---|
694 | + re-writing!) |
---|
695 | + (This becomes the new region head for the region |
---|
696 | + orphaned by target.) |
---|
697 | + |
---|
698 | + TODO: this currently only implements distance == 0; |
---|
699 | + */ |
---|
700 | + |
---|
701 | + struct canvas *ret; /* The return value.*/ |
---|
702 | + struct canvas *cv; /* For walking the list.*/ |
---|
703 | + |
---|
704 | + ret = NULL; |
---|
705 | + |
---|
706 | + if (distance == 0) { |
---|
707 | + for (cv = list; cv; cv = cv->c_next) { |
---|
708 | + int *cv_coord, *cv_off, targ_coord; |
---|
709 | + struct canvas **cv_orient, *targ_orient; |
---|
710 | + |
---|
711 | + switch (direction) { |
---|
712 | + case RIGHT: |
---|
713 | + cv_orient = &cv->c_right; |
---|
714 | + cv_coord = &cv->c_xe; |
---|
715 | + cv_off = 0; |
---|
716 | + targ_coord = target->c_xe; |
---|
717 | + targ_orient = target->c_right; |
---|
718 | + break; |
---|
719 | + case LEFT: |
---|
720 | + cv_orient = &cv->c_left; |
---|
721 | + cv_coord = &cv->c_xs; |
---|
722 | + cv_off = &cv->c_xoff; |
---|
723 | + targ_coord = target->c_xs; |
---|
724 | + targ_orient = target->c_left; |
---|
725 | + break; |
---|
726 | + case UP: |
---|
727 | + cv_orient = &cv->c_above; |
---|
728 | + cv_coord = &cv->c_ys; |
---|
729 | + cv_off = &cv->c_yoff; |
---|
730 | + targ_coord = target->c_ys; |
---|
731 | + targ_orient = target->c_above; |
---|
732 | + break; |
---|
733 | + case DOWN: |
---|
734 | + cv_orient = &cv->c_below; |
---|
735 | + cv_coord = &cv->c_ye; |
---|
736 | + cv_off = 0; |
---|
737 | + targ_coord = target->c_ye; |
---|
738 | + targ_orient = target->c_below; |
---|
739 | + break; |
---|
740 | + } |
---|
741 | + if (*cv_orient == target) { |
---|
742 | + *cv_coord = targ_coord; |
---|
743 | + if(cv_off) |
---|
744 | + *cv_off = targ_coord; |
---|
745 | + *cv_orient = targ_orient; |
---|
746 | + ret = (ret) ? ret : cv; |
---|
747 | + } |
---|
748 | + } |
---|
749 | + } |
---|
750 | + else { |
---|
751 | + ASSERT(distance > 0); |
---|
752 | + switch (direction) { |
---|
753 | + /* adjust target first. */ |
---|
754 | + case RIGHT: |
---|
755 | + if (target->c_xe - target->c_xs + distance < MIN_WIDTH) |
---|
756 | + distance = target->c_xe - target->c_xs - MIN_WIDTH; |
---|
757 | + target->c_xs += distance; |
---|
758 | + target->c_xoff = target -> c_xs; |
---|
759 | + break; |
---|
760 | + case LEFT: |
---|
761 | + if (target->c_xe - target->c_xs + distance < MIN_WIDTH) |
---|
762 | + distance = target->c_xe - target->c_xs - MIN_WIDTH; |
---|
763 | + target->c_xe -= distance; |
---|
764 | + break; |
---|
765 | + case UP: |
---|
766 | + if (target->c_ye - target->c_ys + distance < MIN_HEIGHT) |
---|
767 | + distance = target->c_ye - target->c_ys - MIN_HEIGHT; |
---|
768 | + target->c_ye -= distance; |
---|
769 | + break; |
---|
770 | + case DOWN: |
---|
771 | + if (target->c_ye - target->c_ys + distance < MIN_HEIGHT) |
---|
772 | + distance = target->c_ye - target->c_ys - MIN_HEIGHT; |
---|
773 | + target->c_ys += distance; |
---|
774 | + target->c_yoff = target -> c_ys; |
---|
775 | + break; |
---|
776 | + } |
---|
777 | + for (cv = list; cv; cv = cv->c_next) { |
---|
778 | + int *cv_coord, *cv_off, new_coord; |
---|
779 | + struct canvas **cv_orient; |
---|
780 | + |
---|
781 | + debug("SQUEEZE\n"); |
---|
782 | + debug_print_canvas(cv); |
---|
783 | + |
---|
784 | + if (cv == target) |
---|
785 | + continue; |
---|
786 | + |
---|
787 | + switch (direction) { |
---|
788 | + case RIGHT: |
---|
789 | + cv_orient = &cv->c_right; |
---|
790 | + cv_coord = &cv->c_xe; |
---|
791 | + cv_off = 0; |
---|
792 | + new_coord = cv->c_xe + distance; |
---|
793 | + break; |
---|
794 | + case LEFT: |
---|
795 | + cv_orient = &cv->c_left; |
---|
796 | + cv_coord = &cv->c_xs; |
---|
797 | + cv_off = &cv->c_xoff; |
---|
798 | + new_coord = cv->c_xs - distance; |
---|
799 | + break; |
---|
800 | + case UP: |
---|
801 | + cv_orient = &cv->c_above; |
---|
802 | + cv_coord = &cv->c_ys; |
---|
803 | + cv_off = &cv->c_yoff; |
---|
804 | + new_coord = cv->c_ys - distance; |
---|
805 | + break; |
---|
806 | + case DOWN: |
---|
807 | + cv_orient = &cv->c_below; |
---|
808 | + cv_coord = &cv->c_ye; |
---|
809 | + cv_off = 0; |
---|
810 | + new_coord = cv->c_ye + distance; |
---|
811 | + break; |
---|
812 | + } |
---|
813 | + if (*cv_orient == target) { |
---|
814 | + *cv_coord = new_coord; |
---|
815 | + if(cv_off) |
---|
816 | + *cv_off = new_coord; |
---|
817 | + } |
---|
818 | + } |
---|
819 | + ret = (struct canvas *) distance; |
---|
820 | + } |
---|
821 | + |
---|
822 | + |
---|
823 | + debug2("squeeze: target = %#x, ret = %#x\n", target, ret); |
---|
824 | + return ret; |
---|
825 | +} |
---|
826 | + |
---|
827 | + |
---|
828 | +struct canvas * |
---|
829 | +grow_surrounding_regions(list, fore, amount) |
---|
830 | + struct canvas *list; |
---|
831 | + struct canvas *fore; |
---|
832 | + int amount; |
---|
833 | { |
---|
834 | - int hh, h, i, j; |
---|
835 | - struct canvas *cv, **cvpp; |
---|
836 | - int did = 0; |
---|
837 | + /* Grow all the regions in the list that border |
---|
838 | + fore appropriately. */ |
---|
839 | + struct canvas *cv; /* For walking the list. */ |
---|
840 | + struct canvas *new_fore; /* Replacement for fore. */ |
---|
841 | |
---|
842 | - h = D_height - (D_has_hstatus == HSTATUS_LASTLINE); |
---|
843 | - for (cv = D_cvlist, j = 0; cv; cv = cv->c_next) |
---|
844 | - j++; |
---|
845 | - if (j == 1) |
---|
846 | - return; |
---|
847 | - i = 0; |
---|
848 | - j--; |
---|
849 | - for (cvpp = &D_cvlist; (cv = *cvpp); cvpp = &cv->c_next) |
---|
850 | - { |
---|
851 | - if (cv == D_forecv && !did) |
---|
852 | - { |
---|
853 | - *cvpp = cv->c_next; |
---|
854 | - FreeCanvas(cv); |
---|
855 | - cv = *cvpp; |
---|
856 | - D_forecv = cv ? cv : D_cvlist; |
---|
857 | - D_fore = Layer2Window(D_forecv->c_layer); |
---|
858 | - flayer = D_forecv->c_layer; |
---|
859 | - if (cv == 0) |
---|
860 | + debug("grow_surrounding_regions\n"); |
---|
861 | + |
---|
862 | + new_fore = NULL; |
---|
863 | + if (amount == 0) { |
---|
864 | + if (fore != list) { |
---|
865 | + /* Grow the regions from above (the left). */ |
---|
866 | + switch (fore -> c_type) { |
---|
867 | + case HORIZONTAL: |
---|
868 | + if ( !(new_fore = squeeze(list, fore, DOWN, 0))) |
---|
869 | + new_fore = squeeze(list, fore, RIGHT, 0); |
---|
870 | + break; |
---|
871 | + case VERTICAL: |
---|
872 | + if ( !(new_fore = squeeze(list, fore, RIGHT, 0))) |
---|
873 | + new_fore = squeeze(list, fore, DOWN, 0); |
---|
874 | break; |
---|
875 | - did = 1; |
---|
876 | } |
---|
877 | - hh = h / j-- - 1; |
---|
878 | - if (!captionalways && i == 0 && j == 0) |
---|
879 | - hh++; |
---|
880 | - cv->c_ys = i; |
---|
881 | - cv->c_ye = i + hh - 1; |
---|
882 | - cv->c_yoff = i; |
---|
883 | - i += hh + 1; |
---|
884 | - h -= hh + 1; |
---|
885 | } |
---|
886 | + else { /* Grow the regions from below (the right). */ |
---|
887 | + switch (fore -> c_type) { |
---|
888 | + case HORIZONTAL: |
---|
889 | + if ( !(new_fore = squeeze(list, fore, UP, 0))) |
---|
890 | + new_fore = squeeze(list, fore, LEFT, 0); |
---|
891 | + break; |
---|
892 | + case VERTICAL: |
---|
893 | + if ( !(new_fore = squeeze(list, fore, LEFT, 0))) |
---|
894 | + new_fore = squeeze(list, fore, UP, 0); |
---|
895 | + break; |
---|
896 | + } |
---|
897 | + } |
---|
898 | + ASSERT (new_fore); |
---|
899 | + return new_fore; |
---|
900 | + } |
---|
901 | +} |
---|
902 | + |
---|
903 | + |
---|
904 | +void |
---|
905 | +RemCanvas() |
---|
906 | +{ /** Remove the foreground canvas. */ |
---|
907 | + |
---|
908 | + struct screen_region vr; /*Canvasses in the same row/column as D_forecv.*/ |
---|
909 | + struct canvas *new_fore; /* Canvas which will replace D_forecv. */ |
---|
910 | + |
---|
911 | + /* Do nothing if the foreground is the only canvas. */ |
---|
912 | + if (D_cvlist->c_next == NULL) |
---|
913 | + return; |
---|
914 | + |
---|
915 | + compute_region(D_forecv->c_type, &vr, D_forecv, D_cvlist); |
---|
916 | + |
---|
917 | + debug1("RemCanvas. count = %d\n",vr.count); |
---|
918 | + debug_print_all_canvasses("RemCanvas() start\n"); |
---|
919 | + |
---|
920 | + if (vr.count > 1) { /* Resize the neighboring canvas in region. */ |
---|
921 | + debug2("D_forecv = %x vr.start = %x\n",D_forecv, vr.start); |
---|
922 | + /* If there is a canvas before D_forecv, then |
---|
923 | + grow that canvas to take up the space. */ |
---|
924 | + if (D_forecv != vr.start) { |
---|
925 | + struct canvas *pred; /* Predecssor of D_forecv. */ |
---|
926 | + for (pred = vr.start; pred->c_next != D_forecv; ) |
---|
927 | + pred = pred->c_next; |
---|
928 | + |
---|
929 | + new_fore = pred; |
---|
930 | + new_fore -> c_ye = D_forecv->c_ye; |
---|
931 | + new_fore -> c_xe = D_forecv->c_xe; |
---|
932 | + |
---|
933 | + } |
---|
934 | + else { |
---|
935 | + new_fore = D_forecv -> c_next; |
---|
936 | + new_fore -> c_ys = D_forecv -> c_ys; |
---|
937 | + new_fore -> c_xs = D_forecv -> c_xs; |
---|
938 | + new_fore -> c_yoff = new_fore -> c_ys; |
---|
939 | + new_fore -> c_xoff = new_fore -> c_xs; |
---|
940 | + } |
---|
941 | + } |
---|
942 | + else { /* Resize all bordering regions. */ |
---|
943 | + new_fore = grow_surrounding_regions( D_cvlist, D_forecv,0); |
---|
944 | + } |
---|
945 | + debug_print_canvas(new_fore); |
---|
946 | + |
---|
947 | + /* Redirect all pointers in the list. */ |
---|
948 | + redirect_pointers(D_cvlist, D_forecv, new_fore); |
---|
949 | + |
---|
950 | + remove_canvas_from_list(&D_cvlist, D_forecv); |
---|
951 | + FreeCanvas(D_forecv); |
---|
952 | + D_forecv = new_fore; |
---|
953 | + D_fore = Layer2Window(D_forecv->c_layer); |
---|
954 | + flayer = D_forecv->c_layer; |
---|
955 | + |
---|
956 | + debug2("RemCanvas. forecv = %#x new_fore = %#x\n", D_forecv, new_fore); |
---|
957 | + debug_print_all_canvasses("RemCanvas() end.\n"); |
---|
958 | + |
---|
959 | RethinkDisplayViewports(); |
---|
960 | ResizeLayersToCanvases(); |
---|
961 | } |
---|
962 | |
---|
963 | void |
---|
964 | -OneCanvas() |
---|
965 | -{ |
---|
966 | - struct canvas *mycv = D_forecv; |
---|
967 | - struct canvas *cv, **cvpp; |
---|
968 | +OneCanvas(list, target) |
---|
969 | +struct canvas **list; |
---|
970 | +struct canvas *target; |
---|
971 | +{ /* Free all canvasses in the list except for |
---|
972 | + target. Make *list reference target. */ |
---|
973 | + struct canvas *cv; |
---|
974 | + struct canvas *next; |
---|
975 | |
---|
976 | - for (cvpp = &D_cvlist; (cv = *cvpp);) |
---|
977 | - { |
---|
978 | - if (cv == mycv) |
---|
979 | - { |
---|
980 | - cv->c_ys = 0; |
---|
981 | - cv->c_ye = D_height - 1 - (D_has_hstatus == HSTATUS_LASTLINE) - captionalways; |
---|
982 | - cv->c_yoff = 0; |
---|
983 | - cvpp = &cv->c_next; |
---|
984 | - } |
---|
985 | - else |
---|
986 | - { |
---|
987 | - *cvpp = cv->c_next; |
---|
988 | + debug_print_all_canvasses("OneCanvas start.\n"); |
---|
989 | + for (cv = *list; cv; cv = next) { |
---|
990 | + next = cv -> c_next; |
---|
991 | + if (cv == target) { |
---|
992 | + cv -> c_xoff = 0; |
---|
993 | + cv -> c_xs = 0; |
---|
994 | + cv -> c_xe = D_width-1; |
---|
995 | + cv -> c_yoff = 0; |
---|
996 | + cv -> c_ys = 0; |
---|
997 | + cv -> c_ye = D_height - 1 - (D_has_hstatus == |
---|
998 | + HSTATUS_LASTLINE) - captionalways; |
---|
999 | + cv -> c_left = cv->c_right = NULL; |
---|
1000 | + cv -> c_above = cv->c_below = NULL; |
---|
1001 | + cv -> c_next = NULL; |
---|
1002 | + } else { |
---|
1003 | FreeCanvas(cv); |
---|
1004 | } |
---|
1005 | } |
---|
1006 | + *list = target; |
---|
1007 | + debug_print_all_canvasses("OneCanvas end.\n"); |
---|
1008 | + |
---|
1009 | RethinkDisplayViewports(); |
---|
1010 | ResizeLayersToCanvases(); |
---|
1011 | } |
---|
1012 | --- display.h.orig 2003-07-01 14:01:42.000000000 +0000 |
---|
1013 | +++ display.h 2006-07-07 02:39:25.000000000 +0000 |
---|
1014 | @@ -58,6 +58,11 @@ struct canvas |
---|
1015 | int c_ys; |
---|
1016 | int c_ye; |
---|
1017 | struct event c_captev; /* caption changed event */ |
---|
1018 | + int c_type; /* which type of split created the canvas. */ |
---|
1019 | + struct canvas *c_right; /* canvas to the right. */ |
---|
1020 | + struct canvas *c_left; /* canvas to the left. */ |
---|
1021 | + struct canvas *c_above; /* canvas above. */ |
---|
1022 | + struct canvas *c_below; /* canvas below. */ |
---|
1023 | }; |
---|
1024 | |
---|
1025 | struct viewport |
---|
1026 | --- extern.h.orig 2003-08-22 12:27:57.000000000 +0000 |
---|
1027 | +++ extern.h 2006-07-07 02:39:25.000000000 +0000 |
---|
1028 | @@ -289,9 +289,9 @@ extern void NukePending __P((void)); |
---|
1029 | #endif |
---|
1030 | extern void SetCanvasWindow __P((struct canvas *, struct win *)); |
---|
1031 | extern int MakeDefaultCanvas __P((void)); |
---|
1032 | -extern int AddCanvas __P((void)); |
---|
1033 | +extern int AddCanvas __P((int)); |
---|
1034 | extern void RemCanvas __P((void)); |
---|
1035 | -extern void OneCanvas __P((void)); |
---|
1036 | +extern void OneCanvas __P((struct canvas **, struct canvas *)); |
---|
1037 | extern int RethinkDisplayViewports __P((void)); |
---|
1038 | extern void RethinkViewportOffsets __P((struct canvas *)); |
---|
1039 | #ifdef RXVT_OSC |
---|
1040 | @@ -490,3 +490,16 @@ extern int PrepareEncodedChar __P((int |
---|
1041 | # endif |
---|
1042 | #endif |
---|
1043 | extern int EncodeChar __P((char *, int, int, int *)); |
---|
1044 | +extern int compute_region __P((int,struct screen_region *, struct canvas *, struct canvas *)); |
---|
1045 | +extern void reset_region_types __P((struct screen_region *, int)); |
---|
1046 | +extern void equalize_canvas_dimensions __P((struct screen_region *)); |
---|
1047 | +extern int adjust_canvas_dimensions __P((struct screen_region *, struct canvas *, int)); |
---|
1048 | +enum directions { |
---|
1049 | + LEFT, |
---|
1050 | + RIGHT, |
---|
1051 | + UP, |
---|
1052 | + DOWN |
---|
1053 | +}; |
---|
1054 | + |
---|
1055 | +extern struct canvas * squeeze __P(( struct canvas *, struct canvas *, |
---|
1056 | + enum directions, int distance)); |
---|
1057 | --- process.c.orig 2003-09-18 12:53:54.000000000 +0000 |
---|
1058 | +++ process.c 2006-07-07 02:39:26.000000000 +0000 |
---|
1059 | @@ -548,6 +548,7 @@ InitKeytab() |
---|
1060 | ktab['B'].nr = RC_POW_BREAK; |
---|
1061 | ktab['_'].nr = RC_SILENCE; |
---|
1062 | ktab['S'].nr = RC_SPLIT; |
---|
1063 | + ktab['V'].nr = RC_VERT_SPLIT; |
---|
1064 | ktab['Q'].nr = RC_ONLY; |
---|
1065 | ktab['X'].nr = RC_REMOVE; |
---|
1066 | ktab['F'].nr = RC_FIT; |
---|
1067 | @@ -3649,7 +3650,11 @@ int key; |
---|
1068 | break; |
---|
1069 | #endif /* MULTIUSER */ |
---|
1070 | case RC_SPLIT: |
---|
1071 | - AddCanvas(); |
---|
1072 | + AddCanvas(HORIZONTAL); |
---|
1073 | + Activate(-1); |
---|
1074 | + break; |
---|
1075 | + case RC_VERT_SPLIT: |
---|
1076 | + AddCanvas(VERTICAL); |
---|
1077 | Activate(-1); |
---|
1078 | break; |
---|
1079 | case RC_REMOVE: |
---|
1080 | @@ -3657,7 +3662,7 @@ int key; |
---|
1081 | Activate(-1); |
---|
1082 | break; |
---|
1083 | case RC_ONLY: |
---|
1084 | - OneCanvas(); |
---|
1085 | + OneCanvas(&D_cvlist, D_forecv); |
---|
1086 | Activate(-1); |
---|
1087 | break; |
---|
1088 | case RC_FIT: |
---|
1089 | @@ -5877,104 +5882,51 @@ static void |
---|
1090 | ResizeRegions(arg) |
---|
1091 | char *arg; |
---|
1092 | { |
---|
1093 | - struct canvas *cv; |
---|
1094 | - int nreg, dsize, diff, siz; |
---|
1095 | + struct screen_region region; /* Region in which D_forecv resides. */ |
---|
1096 | + int adjusted; |
---|
1097 | + |
---|
1098 | + /* Note: there's a nomenclature problem here. I'm using 'region' |
---|
1099 | + to mean a set of canvasses that are related geographically |
---|
1100 | + in the display. The documentation uses 'region' to refer to |
---|
1101 | + a single canvas (that's the usage in the error message |
---|
1102 | + below). */ |
---|
1103 | |
---|
1104 | ASSERT(display); |
---|
1105 | - for (nreg = 0, cv = D_cvlist; cv; cv = cv->c_next) |
---|
1106 | - nreg++; |
---|
1107 | - if (nreg < 2) |
---|
1108 | - { |
---|
1109 | - Msg(0, "resize: need more than one region"); |
---|
1110 | - return; |
---|
1111 | - } |
---|
1112 | - dsize = D_height - (D_has_hstatus == HSTATUS_LASTLINE); |
---|
1113 | - if (*arg == '=') |
---|
1114 | - { |
---|
1115 | - /* make all regions the same height */ |
---|
1116 | - int h = dsize; |
---|
1117 | - int hh, i = 0; |
---|
1118 | - for (cv = D_cvlist; cv; cv = cv->c_next) |
---|
1119 | - { |
---|
1120 | - hh = h / nreg-- - 1; |
---|
1121 | - cv->c_ys = i; |
---|
1122 | - cv->c_ye = i + hh - 1; |
---|
1123 | - cv->c_yoff = i; |
---|
1124 | - i += hh + 1; |
---|
1125 | - h -= hh + 1; |
---|
1126 | - } |
---|
1127 | - RethinkDisplayViewports(); |
---|
1128 | - ResizeLayersToCanvases(); |
---|
1129 | + if (D_cvlist -> c_next == NULL) { |
---|
1130 | + Msg(0, "More than one region required."); |
---|
1131 | return; |
---|
1132 | } |
---|
1133 | - siz = D_forecv->c_ye - D_forecv->c_ys + 1; |
---|
1134 | - if (*arg == '+') |
---|
1135 | - diff = atoi(arg + 1); |
---|
1136 | - else if (*arg == '-') |
---|
1137 | - diff = -atoi(arg + 1); |
---|
1138 | - else if (!strcmp(arg, "min")) |
---|
1139 | - diff = 1 - siz; |
---|
1140 | - else if (!strcmp(arg, "max")) |
---|
1141 | - diff = dsize - (nreg - 1) * 2 - 1 - siz; |
---|
1142 | - else |
---|
1143 | - diff = atoi(arg) - siz; |
---|
1144 | - if (diff == 0) |
---|
1145 | - return; |
---|
1146 | - if (siz + diff < 1) |
---|
1147 | - diff = 1 - siz; |
---|
1148 | - if (siz + diff > dsize - (nreg - 1) * 2 - 1) |
---|
1149 | - diff = dsize - (nreg - 1) * 2 - 1 - siz; |
---|
1150 | - if (diff == 0 || siz + diff < 1) |
---|
1151 | - return; |
---|
1152 | |
---|
1153 | - if (diff < 0) |
---|
1154 | - { |
---|
1155 | - if (D_forecv->c_next) |
---|
1156 | - { |
---|
1157 | - D_forecv->c_ye += diff; |
---|
1158 | - D_forecv->c_next->c_ys += diff; |
---|
1159 | - D_forecv->c_next->c_yoff += diff; |
---|
1160 | - } |
---|
1161 | - else |
---|
1162 | - { |
---|
1163 | - for (cv = D_cvlist; cv; cv = cv->c_next) |
---|
1164 | - if (cv->c_next == D_forecv) |
---|
1165 | + compute_region(D_forecv->c_type, ®ion, D_forecv, D_cvlist); |
---|
1166 | + reset_region_types(®ion, D_forecv->c_type); |
---|
1167 | + |
---|
1168 | + if (region.count > 1) { |
---|
1169 | + switch (*arg) { |
---|
1170 | + case '=': equalize_canvas_dimensions(®ion); break; |
---|
1171 | + case '-': adjust_canvas_dimensions(®ion, D_forecv, -atoi(arg+1)); break; |
---|
1172 | + case '+': |
---|
1173 | + adjusted = adjust_canvas_dimensions(®ion, D_forecv, atoi(arg+1)); |
---|
1174 | break; |
---|
1175 | - ASSERT(cv); |
---|
1176 | - cv->c_ye -= diff; |
---|
1177 | - D_forecv->c_ys -= diff; |
---|
1178 | - D_forecv->c_yoff -= diff; |
---|
1179 | - } |
---|
1180 | - } |
---|
1181 | - else |
---|
1182 | - { |
---|
1183 | - int s, i = 0, found = 0, di = diff, d2; |
---|
1184 | - s = dsize - (nreg - 1) * 2 - 1 - siz; |
---|
1185 | - for (cv = D_cvlist; cv; i = cv->c_ye + 2, cv = cv->c_next) |
---|
1186 | - { |
---|
1187 | - if (cv == D_forecv) |
---|
1188 | - { |
---|
1189 | - cv->c_ye = i + (cv->c_ye - cv->c_ys) + diff; |
---|
1190 | - cv->c_yoff -= cv->c_ys - i; |
---|
1191 | - cv->c_ys = i; |
---|
1192 | - found = 1; |
---|
1193 | - continue; |
---|
1194 | + case 'm': |
---|
1195 | + if (!strcmp(arg, "min")) |
---|
1196 | + adjust_canvas_dimensions(®ion, D_forecv, -region.expanse); |
---|
1197 | + else if (!strcmp(arg, "max")) |
---|
1198 | + adjust_canvas_dimensions(®ion, D_forecv, region.expanse); |
---|
1199 | + break; |
---|
1200 | + default: |
---|
1201 | + Msg(0, "resize: arguments munged"); |
---|
1202 | } |
---|
1203 | - s -= cv->c_ye - cv->c_ys; |
---|
1204 | - if (!found) |
---|
1205 | - { |
---|
1206 | - if (s >= di) |
---|
1207 | - continue; |
---|
1208 | - d2 = di - s; |
---|
1209 | } |
---|
1210 | - else |
---|
1211 | - d2 = di > cv->c_ye - cv->c_ys ? cv->c_ye - cv->c_ys : di; |
---|
1212 | - di -= d2; |
---|
1213 | - cv->c_ye = i + (cv->c_ye - cv->c_ys) - d2; |
---|
1214 | - cv->c_yoff -= cv->c_ys - i; |
---|
1215 | - cv->c_ys = i; |
---|
1216 | + else { |
---|
1217 | + /*TODO Need to expand this canvas into surrounding regions...*/ |
---|
1218 | + switch(*arg) { |
---|
1219 | + case '=': Msg(0, "More than one region required."); return; |
---|
1220 | + // http://lists.gnu.org/archive/html/screen-users/2006-06/msg00012.html |
---|
1221 | + // case '-': squeeze(D_cvlist, D_forecv, RIGHT, atoi(arg+1)); break; |
---|
1222 | + default : Msg(0, "More than one region required."); return; |
---|
1223 | } |
---|
1224 | } |
---|
1225 | + |
---|
1226 | RethinkDisplayViewports(); |
---|
1227 | ResizeLayersToCanvases(); |
---|
1228 | } |
---|
1229 | --- screen.h.orig 2003-08-22 12:28:43.000000000 +0000 |
---|
1230 | +++ screen.h 2006-07-07 02:39:26.000000000 +0000 |
---|
1231 | @@ -288,8 +288,25 @@ struct baud_values |
---|
1232 | int sym; /* symbol defined in ttydev.h */ |
---|
1233 | }; |
---|
1234 | |
---|
1235 | +struct screen_region { |
---|
1236 | + /* This is a group of canvasses that are all in |
---|
1237 | + the same column or row. */ |
---|
1238 | + struct canvas *start; /* First canvas in the region. */ |
---|
1239 | + struct canvas *end; /* Last canvas in the region. */ |
---|
1240 | + int expanse; /* Range in the appropriate direction. */ |
---|
1241 | + int count; /* Number of canvasses in the region. */ |
---|
1242 | + int type; /* HORIZONTAL or VERTICAL. */ |
---|
1243 | + int xs; /* starting x coordinate */ |
---|
1244 | + int xe; /* ending x coordinate */ |
---|
1245 | + int ys; /* starting y coordinate */ |
---|
1246 | + int ye; /* ending y coordinate */ |
---|
1247 | +}; |
---|
1248 | + |
---|
1249 | /* |
---|
1250 | * windowlist orders |
---|
1251 | */ |
---|
1252 | #define WLIST_NUM 0 |
---|
1253 | #define WLIST_MRU 1 |
---|
1254 | + |
---|
1255 | +#define HORIZONTAL 0 |
---|
1256 | +#define VERTICAL 1 |
---|