diff options
Diffstat (limited to 'src/resize.c')
-rw-r--r-- | src/resize.c | 211 |
1 files changed, 127 insertions, 84 deletions
diff --git a/src/resize.c b/src/resize.c index a9a8772..5d1df4b 100644 --- a/src/resize.c +++ b/src/resize.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) @@ -323,6 +323,34 @@ kaablamm() Msg(0, "Aborted because of window size change."); } +/* Kills non-resizable layers. */ +#define RESIZE_OR_KILL_LAYERS(l, wi, he) do \ + { \ + struct layer *_last = NULL, *_iter; \ + flayer = (l); \ + while (flayer->l_next) \ + { \ + if (LayResize(wi, he) == 0) \ + { \ + _last = flayer; \ + flayer = flayer->l_next; \ + } \ + else \ + { \ + struct canvas *_cv; \ + for (_cv = flayer->l_cvlist; _cv; _cv = _cv->c_lnext) \ + _cv->c_display->d_kaablamm = 1; \ + ExitOverlayPage(); \ + if (_last) \ + _last->l_next = flayer; \ + } \ + } \ + /* We assume that the bottom-most layer, i.e. when flayer->l_next == 0, \ + * is always resizable. Currently, WinLf and BlankLf can be the bottom-most layers. \ + */ \ + LayResize(wi, he); \ + } while (0) + void ResizeLayer(l, wi, he, norefdisp) struct layer *l; @@ -338,52 +366,39 @@ struct display *norefdisp; return; p = Layer2Window(l); + /* If 'flayer' and 'l' are for the same window, then we will not + * restore 'flayer'. */ if (oldflayer && (l == oldflayer || Layer2Window(oldflayer) == p)) - while (oldflayer->l_next) - oldflayer = oldflayer->l_next; - + oldflayer = NULL; + + flayer = l; + if (p) { + /* It's a window layer. Kill the overlays on it in all displays. */ for (d = displays; d; d = d->d_next) for (cv = d->d_cvlist; cv; cv = cv->c_next) { if (p == Layer2Window(cv->c_layer)) { - flayer = cv->c_layer; - if (flayer->l_next) - d->d_kaablamm = 1; - while (flayer->l_next) - ExitOverlayPage(); + /* Canvas 'cv' on display 'd' shows this window. Remove any non-resizable + * layers over it. */ + RESIZE_OR_KILL_LAYERS(cv->c_layer, wi, he); } } - l = p->w_savelayer; - } - flayer = l; - if (p == 0 && flayer->l_next && flayer->l_next->l_next == 0 && LayResize(wi, he) == 0) - { - flayer = flayer->l_next; - LayResize(wi, he); - flayer = l; } else { - if (flayer->l_next) - for (cv = flayer->l_cvlist; cv; cv = cv->c_lnext) - cv->c_display->d_kaablamm = 1; - while (flayer->l_next) - ExitOverlayPage(); + /* It's a Blank layer. Just kill the non-resizable overlays over it. */ + RESIZE_OR_KILL_LAYERS(flayer, wi, he); } - if (p) - flayer = &p->w_layer; - LayResize(wi, he); - /* now everybody is on flayer, redisplay */ - l = flayer; + for (display = displays; display; display = display->d_next) { if (display == norefdisp) continue; for (cv = D_cvlist; cv; cv = cv->c_next) - if (cv->c_layer == l) + if (Layer2Window(cv->c_layer) == p) { CV_CALL(cv, LayRedisplayLine(-1, -1, -1, 0)); RefreshArea(cv->c_xs, cv->c_ys, cv->c_xe, cv->c_ye, 0); @@ -394,11 +409,14 @@ struct display *norefdisp; D_kaablamm = 0; } } - flayer = oldflayer; + + /* If we started resizing a non-flayer layer, then restore the flayer. + * Otherwise, flayer should already be updated to the topmost foreground layer. */ + if (oldflayer) + flayer = oldflayer; display = olddisplay; } - static void FreeMline(ml) struct mline *ml; @@ -497,6 +515,7 @@ CheckMaxSize(wi) int wi; { unsigned char *oldnull = null; + unsigned char *oldblank = blank; struct win *p; int i; struct mline *ml; @@ -516,11 +535,11 @@ int wi; #ifdef COLOR mline_old.color = (unsigned char *)xrealloc((char *)mline_old.color, maxwidth); # ifdef COLORS256 - mline_old.colorx = (unsigned char *)xrealloc((char *)mline_old.color, maxwidth); + mline_old.colorx = (unsigned char *)xrealloc((char *)mline_old.colorx, maxwidth); # endif #endif if (!(blank && null && mline_old.image && mline_old.attr IFFONT(&& mline_old.font) IFCOLOR(&& mline_old.color) IFCOLORX(&& mline_old.colorx))) - Panic(0, strnomem); + Panic(0, "%s", strnomem); MakeBlankLine(blank, maxwidth); bzero((char *)null, maxwidth); @@ -542,49 +561,34 @@ int wi; # endif #endif +#define RESET_AFC(x, bl) do { if (x == old##bl) x = bl; } while (0) + +#define RESET_LINES(lines, count) \ + do { \ + ml = lines; \ + for (i = 0; i < count; i++, ml++) \ + { \ + RESET_AFC(ml->image, blank); \ + RESET_AFC(ml->attr, null); \ + IFFONT(RESET_AFC(ml->font, null)); \ + IFCOLOR(RESET_AFC(ml->color, null)); \ + IFCOLORX(RESET_AFC(ml->colorx, null)); \ + } \ + } while (0) + /* We have to run through all windows to substitute - * the null references. + * the null and blank references. */ for (p = windows; p; p = p->w_next) { - ml = p->w_mlines; - for (i = 0; i < p->w_height; i++, ml++) - { - if (ml->attr == oldnull) - ml->attr = null; -#ifdef FONT - if (ml->font == oldnull) - ml->font = null; -#endif -#ifdef COLOR - if (ml->color == oldnull) - ml->color= null; -#ifdef COLORS256 - if (ml->colorx == oldnull) - ml->colorx = null; -#endif -#endif - } + RESET_LINES(p->w_mlines, p->w_height); + #ifdef COPY_PASTE - ml = p->w_hlines; - for (i = 0; i < p->w_histheight; i++, ml++) - { - if (ml->attr == oldnull) - ml->attr = null; -# ifdef FONT - if (ml->font == oldnull) - ml->font = null; -# endif -# ifdef COLOR - if (ml->color == oldnull) - ml->color= null; -# ifdef COLORS256 - if (ml->colorx == oldnull) - ml->colorx = null; -# endif -# endif - } + RESET_LINES(p->w_hlines, p->w_histheight); + RESET_LINES(p->w_alt_hlines, p->w_alt_histheight); #endif + + RESET_LINES(p->w_alt_mlines, p->w_alt_height); } } @@ -642,11 +646,32 @@ int wi, he, hi; int ncx, ncy, naka, t; int y, shift; - if (wi == 0) - he = hi = 0; + if (wi <= 0 || he <= 0) + wi = he = hi = 0; if (p->w_type == W_TYPE_GROUP) return 0; + + if (wi > 1000) + { + Msg(0, "Window width too large. Truncated to 1000."); + wi = 1000; + } + + if (he > 1000) + { + Msg(0, "Window height too large. Truncated to 1000."); + he = 1000; + } + +#ifdef COPY_PASTE + if (hi > 1000) + { + Msg(0, "Window history too big. Truncated to 1000."); + hi = 1000; + } +#endif + if (p->w_width == wi && p->w_height == he && p->w_histheight == hi) { debug("ChangeWindowSize: No change.\n"); @@ -684,7 +709,7 @@ int wi, he, hi; if ((nmlines = (struct mline *)calloc(he, sizeof(struct mline))) == 0) { KillWindow(p); - Msg(0, strnomem); + Msg(0, "%s", strnomem); return -1; } } @@ -917,7 +942,7 @@ int wi, he, hi; #endif } KillWindow(p); - Msg(0, strnomem); + Msg(0, "%s", strnomem); return -1; } for (; t < wi; t++) @@ -1040,16 +1065,20 @@ struct win *p; struct mline *ml; int t; - ml = p->w_alt_mlines; p->w_alt_mlines = p->w_mlines; p->w_mlines = ml; - t = p->w_alt_width; p->w_alt_width = p->w_width; p->w_width = t; - t = p->w_alt_height; p->w_alt_height = p->w_height; p->w_height = t; - t = p->w_alt_histheight; p->w_alt_histheight = p->w_histheight; p->w_histheight = t; - t = p->w_alt_x; p->w_alt_x = p->w_x; p->w_x = t; - t = p->w_alt_y; p->w_alt_y = p->w_y; p->w_y = t; +#define SWAP(item, t) do { (t) = p->w_alt_##item; p->w_alt_##item = p->w_##item; p->w_##item = (t); } while (0) + + SWAP(mlines, ml); + SWAP(width, t); + SWAP(height, t); + SWAP(histheight, t); + SWAP(x, t); + SWAP(y, t); + #ifdef COPY_PASTE - ml = p->w_alt_hlines; p->w_alt_hlines = p->w_hlines; p->w_hlines = ml; - t = p->w_alt_histidx; p->w_alt_histidx = p->w_histidx; p->w_histidx = t; + SWAP(hlines, ml); + SWAP(histidx, t); #endif +#undef SWAP } void @@ -1057,20 +1086,34 @@ EnterAltScreen(p) struct win *p; { int ox = p->w_x, oy = p->w_y; - FreeAltScreen(p); - SwapAltScreen(p); + if (!p->w_alt_current) + { + /* If not already using the alternate screen buffer, then create + a new one and swap it with the 'real' screen buffer. */ + FreeAltScreen(p); + SwapAltScreen(p); + } + else + { + /* Already using the alternate buffer. Just clear the screen. To do so, it + is only necessary to reset the height(s) without resetting the width. */ + p->w_height = 0; + p->w_histheight = 0; + } ChangeWindowSize(p, p->w_alt_width, p->w_alt_height, p->w_alt_histheight); p->w_x = ox; p->w_y = oy; + p->w_alt_current = 1; } void LeaveAltScreen(p) struct win *p; { - if (!p->w_alt_mlines) + if (!p->w_alt_current) return; SwapAltScreen(p); ChangeWindowSize(p, p->w_alt_width, p->w_alt_height, p->w_alt_histheight); FreeAltScreen(p); + p->w_alt_current = 0; } |