summaryrefslogtreecommitdiff
path: root/src/resize.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/resize.c')
-rw-r--r--src/resize.c211
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;
}