Get rid of a bunch of compile warnings
[screen-lua.git] / src / resize.c
blobe66278bbe2c04e4438592b4c19e7ded982d2dae1
1 /* Copyright (c) 1993-2002
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Copyright (c) 1987 Oliver Laumann
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file COPYING); if not, write to the
18 * Free Software Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 ****************************************************************
24 #include <sys/types.h>
25 #include <signal.h>
26 #ifndef sun
27 #include <sys/ioctl.h>
28 #endif
30 #ifdef ISC
31 # include <sys/tty.h>
32 # include <sys/sioctl.h>
33 # include <sys/pty.h>
34 #endif
36 #include "config.h"
37 #include "screen.h"
38 #include "extern.h"
40 static void CheckMaxSize __P((int));
41 static void FreeMline __P((struct mline *));
42 static int AllocMline __P((struct mline *ml, int));
43 static void MakeBlankLine __P((unsigned char *, int));
44 static void kaablamm __P((void));
45 static int BcopyMline __P((struct mline *, int, struct mline *, int, int, int));
46 static void SwapAltScreen __P((struct win *));
48 extern struct layer *flayer;
49 extern struct display *display, *displays;
50 extern unsigned char *blank, *null;
51 extern struct mline mline_blank, mline_null, mline_old;
52 extern struct win *windows;
53 extern int Z0width, Z1width;
54 extern int captionalways;
56 #if defined(TIOCGWINSZ) || defined(TIOCSWINSZ)
57 struct winsize glwz;
58 #endif
60 static struct mline mline_zero = {
61 (unsigned char *)0,
62 (unsigned char *)0
63 #ifdef FONT
64 ,(unsigned char *)0
65 #endif
66 #ifdef COLOR
67 ,(unsigned char *)0
68 # ifdef COLORS256
69 ,(unsigned char *)0
70 # endif
71 #endif
75 * ChangeFlag: 0: try to modify no window
76 * 1: modify fore (and try to modify no other) + redisplay
77 * 2: modify all windows
79 * Note: Activate() is only called if change_flag == 1
80 * i.e. on a WINCH event
83 void
84 CheckScreenSize(change_flag)
85 int change_flag;
87 int wi, he;
89 if (display == 0)
91 debug("CheckScreenSize: No display -> no check.\n");
92 return;
94 #ifdef TIOCGWINSZ
95 if (ioctl(D_userfd, TIOCGWINSZ, (char *)&glwz) != 0)
97 debug2("CheckScreenSize: ioctl(%d, TIOCGWINSZ) errno %d\n", D_userfd, errno);
98 wi = D_CO;
99 he = D_LI;
101 else
103 wi = glwz.ws_col;
104 he = glwz.ws_row;
105 if (wi == 0)
106 wi = D_CO;
107 if (he == 0)
108 he = D_LI;
110 #else
111 wi = D_CO;
112 he = D_LI;
113 #endif
115 debug2("CheckScreenSize: screen is (%d,%d)\n", wi, he);
117 #if 0 /* XXX: Fixme */
118 if (change_flag == 2)
120 debug("Trying to adapt all windows (-A)\n");
121 for (p = windows; p; p = p->w_next)
122 if (p->w_display == 0 || p->w_display == display)
123 ChangeWindowSize(p, wi, he, p->w_histheight);
125 #endif
126 if (D_width == wi && D_height == he)
128 debug("CheckScreenSize: No change -> return.\n");
129 return;
131 #ifdef BLANKER_PRG
132 KillBlanker();
133 #endif
134 ResetIdle();
135 ChangeScreenSize(wi, he, change_flag);
136 /* XXX Redisplay logic */
137 #if 0
138 if (change_flag == 1)
139 Redisplay(D_fore ? D_fore->w_norefresh : 0);
140 #endif
143 void
144 ChangeScreenSize(wi, he, change_fore)
145 int wi, he;
146 int change_fore;
148 struct win *p;
149 struct canvas *cv;
150 int wwi;
152 debug2("ChangeScreenSize from (%d,%d) ", D_width, D_height);
153 debug3("to (%d,%d) (change_fore: %d)\n",wi, he, change_fore);
155 cv = &D_canvas;
156 cv->c_xe = wi - 1;
157 cv->c_ye = he - 1 - ((cv->c_slperp && cv->c_slperp->c_slnext) || captionalways) - (D_has_hstatus == HSTATUS_LASTLINE);
158 if (cv->c_slperp)
160 ResizeCanvas(cv);
161 RecreateCanvasChain();
162 RethinkDisplayViewports();
164 if (D_forecv == 0)
165 D_forecv = D_cvlist;
166 if (D_forecv)
167 D_fore = Layer2Window(D_forecv->c_layer);
169 D_width = wi;
170 D_height = he;
172 CheckMaxSize(wi);
173 if (D_CWS)
175 D_defwidth = D_CO;
176 D_defheight = D_LI;
178 else
180 if (D_CZ0 && (wi == Z0width || wi == Z1width) &&
181 (D_CO == Z0width || D_CO == Z1width))
182 D_defwidth = D_CO;
183 else
184 D_defwidth = wi;
185 D_defheight = he;
187 debug2("Default size: (%d,%d)\n", D_defwidth, D_defheight);
188 if (change_fore)
189 ResizeLayersToCanvases();
190 if (change_fore == 2 && D_CWS == NULL && displays->d_next == 0)
192 /* adapt all windows - to be removed ? */
193 for (p = windows; p; p = p->w_next)
195 debug1("Trying to change window %d.\n", p->w_number);
196 wwi = wi;
197 #if 0
198 if (D_CZ0 && p->w_width != wi && (wi == Z0width || wi == Z1width))
200 if (p->w_width > (Z0width + Z1width) / 2)
201 wwi = Z0width;
202 else
203 wwi = Z1width;
205 #endif
206 if (p->w_savelayer && p->w_savelayer->l_cvlist == 0)
207 ResizeLayer(p->w_savelayer, wwi, he, 0);
208 #if 0
209 ChangeWindowSize(p, wwi, he, p->w_histheight);
210 #endif
215 void
216 ResizeLayersToCanvases()
218 struct canvas *cv;
219 struct layer *l;
220 int lx, ly;
222 debug("ResizeLayersToCanvases\n");
223 D_kaablamm = 0;
224 for (cv = D_cvlist; cv; cv = cv->c_next)
226 l = cv->c_layer;
227 if (l == 0)
228 continue;
229 debug("Doing canvas: ");
230 if (l->l_width == cv->c_xe - cv->c_xs + 1 &&
231 l->l_height == cv->c_ye - cv->c_ys + 1)
233 debug("already fitting.\n");
234 continue;
236 if (!MayResizeLayer(l))
238 debug("may not resize.\n");
240 else
242 debug("doing resize.\n");
243 ResizeLayer(l, cv->c_xe - cv->c_xs + 1, cv->c_ye - cv->c_ys + 1, display);
246 /* normalize window, see screen.c */
247 lx = cv->c_layer->l_x;
248 ly = cv->c_layer->l_y;
249 if (ly + cv->c_yoff < cv->c_ys)
251 cv->c_yoff = cv->c_ys - ly;
252 RethinkViewportOffsets(cv);
254 else if (ly + cv->c_yoff > cv->c_ye)
256 cv->c_yoff = cv->c_ye - ly;
257 RethinkViewportOffsets(cv);
259 if (lx + cv->c_xoff < cv->c_xs)
261 int n = cv->c_xs - (lx + cv->c_xoff);
262 if (n < (cv->c_xe - cv->c_xs + 1) / 2)
263 n = (cv->c_xe - cv->c_xs + 1) / 2;
264 if (cv->c_xoff + n > cv->c_xs)
265 n = cv->c_xs - cv->c_xoff;
266 cv->c_xoff += n;
267 RethinkViewportOffsets(cv);
269 else if (lx + cv->c_xoff > cv->c_xe)
271 int n = lx + cv->c_xoff - cv->c_xe;
272 if (n < (cv->c_xe - cv->c_xs + 1) / 2)
273 n = (cv->c_xe - cv->c_xs + 1) / 2;
274 if (cv->c_xoff - n + cv->c_layer->l_width - 1 < cv->c_xe)
275 n = cv->c_xoff + cv->c_layer->l_width - 1 - cv->c_xe;
276 cv->c_xoff -= n;
277 RethinkViewportOffsets(cv);
280 Redisplay(0);
281 if (D_kaablamm)
283 kaablamm();
284 D_kaablamm = 0;
289 MayResizeLayer(l)
290 struct layer *l;
292 int cvs = 0;
293 debug("MayResizeLayer:\n");
294 for (; l; l = l->l_next)
296 if (l->l_cvlist)
297 if (++cvs > 1 || l->l_cvlist->c_lnext)
299 debug1("may not - cvs %d\n", cvs);
300 return 0;
303 debug("may resize\n");
304 return 1;
308 * Easy implementation: rely on the fact that the only layers
309 * supporting resize are Win and Blank. So just kill all overlays.
311 * This is a lot harder if done the right way...
314 static void
315 kaablamm()
317 Msg(0, "Aborted because of window size change.");
320 void
321 ResizeLayer(l, wi, he, norefdisp)
322 struct layer *l;
323 int wi, he;
324 struct display *norefdisp;
326 struct win *p;
327 struct canvas *cv;
328 struct layer *oldflayer = flayer;
329 struct display *d, *olddisplay = display;
331 if (l->l_width == wi && l->l_height == he)
332 return;
333 p = Layer2Window(l);
335 if (oldflayer && (l == oldflayer || Layer2Window(oldflayer) == p))
336 while (oldflayer->l_next)
337 oldflayer = oldflayer->l_next;
339 if (p)
341 for (d = displays; d; d = d->d_next)
342 for (cv = d->d_cvlist; cv; cv = cv->c_next)
344 if (p == Layer2Window(cv->c_layer))
346 flayer = cv->c_layer;
347 if (flayer->l_next)
348 d->d_kaablamm = 1;
349 while (flayer->l_next)
350 ExitOverlayPage();
353 l = p->w_savelayer;
355 flayer = l;
356 if (p == 0 && flayer->l_next && flayer->l_next->l_next == 0 && LayResize(wi, he) == 0)
358 flayer = flayer->l_next;
359 LayResize(wi, he);
360 flayer = l;
362 else
364 if (flayer->l_next)
365 for (cv = flayer->l_cvlist; cv; cv = cv->c_lnext)
366 cv->c_display->d_kaablamm = 1;
367 while (flayer->l_next)
368 ExitOverlayPage();
370 if (p)
371 flayer = &p->w_layer;
372 LayResize(wi, he);
373 /* now everybody is on flayer, redisplay */
374 l = flayer;
375 for (display = displays; display; display = display->d_next)
377 if (display == norefdisp)
378 continue;
379 for (cv = D_cvlist; cv; cv = cv->c_next)
380 if (cv->c_layer == l)
382 CV_CALL(cv, LayRedisplayLine(-1, -1, -1, 0));
383 RefreshArea(cv->c_xs, cv->c_ys, cv->c_xe, cv->c_ye, 0);
385 if (D_kaablamm)
387 kaablamm();
388 D_kaablamm = 0;
391 flayer = oldflayer;
392 display = olddisplay;
396 static void
397 FreeMline(ml)
398 struct mline *ml;
400 if (ml->image)
401 free(ml->image);
402 if (ml->attr && ml->attr != null)
403 free(ml->attr);
404 #ifdef FONT
405 if (ml->font && ml->font != null)
406 free(ml->font);
407 #endif
408 #ifdef COLOR
409 if (ml->color && ml->color != null)
410 free(ml->color);
411 # ifdef COLORS256
412 if (ml->colorx && ml->colorx != null)
413 free(ml->colorx);
414 # endif
415 #endif
416 *ml = mline_zero;
419 static int
420 AllocMline(ml, w)
421 struct mline *ml;
422 int w;
424 ml->image = malloc(w);
425 ml->attr = null;
426 #ifdef FONT
427 ml->font = null;
428 #endif
429 #ifdef COLOR
430 ml->color = null;
431 # ifdef COLORS256
432 ml->colorx = null;
433 # endif
434 #endif
435 if (ml->image == 0)
436 return -1;
437 return 0;
441 static int
442 BcopyMline(mlf, xf, mlt, xt, l, w)
443 struct mline *mlf, *mlt;
444 int xf, xt, l, w;
446 int r = 0;
448 bcopy((char *)mlf->image + xf, (char *)mlt->image + xt, l);
449 if (mlf->attr != null && mlt->attr == null)
451 if ((mlt->attr = (unsigned char *)malloc(w)) == 0)
452 mlt->attr = null, r = -1;
453 bzero((char *)mlt->attr, w);
455 if (mlt->attr != null)
456 bcopy((char *)mlf->attr + xf, (char *)mlt->attr + xt, l);
457 #ifdef FONT
458 if (mlf->font != null && mlt->font == null)
460 if ((mlt->font = (unsigned char *)malloc(w)) == 0)
461 mlt->font = null, r = -1;
462 bzero((char *)mlt->font, w);
464 if (mlt->font != null)
465 bcopy((char *)mlf->font + xf, (char *)mlt->font + xt, l);
466 #endif
467 #ifdef COLOR
468 if (mlf->color != null && mlt->color == null)
470 if ((mlt->color = (unsigned char *)malloc(w)) == 0)
471 mlt->color = null, r = -1;
472 bzero((char *)mlt->color, w);
474 if (mlt->color != null)
475 bcopy((char *)mlf->color + xf, (char *)mlt->color + xt, l);
476 # ifdef COLORS256
477 if (mlf->colorx != null && mlt->colorx == null)
479 if ((mlt->colorx = (unsigned char *)malloc(w)) == 0)
480 mlt->colorx = null, r = -1;
481 bzero((char *)mlt->colorx, w);
483 if (mlt->colorx != null)
484 bcopy((char *)mlf->colorx + xf, (char *)mlt->colorx + xt, l);
485 # endif
486 #endif
487 return r;
491 static int maxwidth;
493 static void
494 CheckMaxSize(wi)
495 int wi;
497 unsigned char *oldnull = null;
498 struct win *p;
499 int i;
500 struct mline *ml;
502 wi = ((wi + 1) + 255) & ~255;
503 if (wi <= maxwidth)
504 return;
505 maxwidth = wi;
506 debug1("New maxwidth: %d\n", maxwidth);
507 blank = (unsigned char *)xrealloc((char *)blank, maxwidth);
508 null = (unsigned char *)xrealloc((char *)null, maxwidth);
509 mline_old.image = (unsigned char *)xrealloc((char *)mline_old.image, maxwidth);
510 mline_old.attr = (unsigned char *)xrealloc((char *)mline_old.attr, maxwidth);
511 #ifdef FONT
512 mline_old.font = (unsigned char *)xrealloc((char *)mline_old.font, maxwidth);
513 #endif
514 #ifdef COLOR
515 mline_old.color = (unsigned char *)xrealloc((char *)mline_old.color, maxwidth);
516 # ifdef COLORS256
517 mline_old.colorx = (unsigned char *)xrealloc((char *)mline_old.color, maxwidth);
518 # endif
519 #endif
520 if (!(blank && null && mline_old.image && mline_old.attr IFFONT(&& mline_old.font) IFCOLOR(&& mline_old.color) IFCOLORX(&& mline_old.colorx)))
521 Panic(0, strnomem);
523 MakeBlankLine(blank, maxwidth);
524 bzero((char *)null, maxwidth);
526 mline_blank.image = blank;
527 mline_blank.attr = null;
528 mline_null.image = null;
529 mline_null.attr = null;
530 #ifdef FONT
531 mline_blank.font = null;
532 mline_null.font = null;
533 #endif
534 #ifdef COLOR
535 mline_blank.color = null;
536 mline_null.color = null;
537 # ifdef COLORS256
538 mline_blank.colorx = null;
539 mline_null.colorx = null;
540 # endif
541 #endif
543 /* We have to run through all windows to substitute
544 * the null references.
546 for (p = windows; p; p = p->w_next)
548 ml = p->w_mlines;
549 for (i = 0; i < p->w_height; i++, ml++)
551 if (ml->attr == oldnull)
552 ml->attr = null;
553 #ifdef FONT
554 if (ml->font == oldnull)
555 ml->font = null;
556 #endif
557 #ifdef COLOR
558 if (ml->color == oldnull)
559 ml->color= null;
560 #ifdef COLORS256
561 if (ml->colorx == oldnull)
562 ml->colorx = null;
563 #endif
564 #endif
566 #ifdef COPY_PASTE
567 ml = p->w_hlines;
568 for (i = 0; i < p->w_histheight; i++, ml++)
570 if (ml->attr == oldnull)
571 ml->attr = null;
572 # ifdef FONT
573 if (ml->font == oldnull)
574 ml->font = null;
575 # endif
576 # ifdef COLOR
577 if (ml->color == oldnull)
578 ml->color= null;
579 # ifdef COLORS256
580 if (ml->colorx == oldnull)
581 ml->colorx = null;
582 # endif
583 # endif
585 #endif
590 char *
591 xrealloc(mem, len)
592 char *mem;
593 int len;
595 register char *nmem;
597 if (mem == 0)
598 return malloc(len);
599 if ((nmem = realloc(mem, len)))
600 return nmem;
601 free(mem);
602 return (char *)0;
605 static void
606 MakeBlankLine(p, n)
607 register unsigned char *p;
608 register int n;
610 while (n--)
611 *p++ = ' ';
617 #ifdef COPY_PASTE
619 #define OLDWIN(y) ((y < p->w_histheight) \
620 ? &p->w_hlines[(p->w_histidx + y) % p->w_histheight] \
621 : &p->w_mlines[y - p->w_histheight])
623 #define NEWWIN(y) ((y < hi) ? &nhlines[y] : &nmlines[y - hi])
625 #else
627 #define OLDWIN(y) (&p->w_mlines[y])
628 #define NEWWIN(y) (&nmlines[y])
630 #endif
634 ChangeWindowSize(p, wi, he, hi)
635 struct win *p;
636 int wi, he, hi;
638 struct mline *mlf = 0, *mlt = 0, *ml, *nmlines, *nhlines;
639 int fy, ty, l, lx, lf, lt, yy, oty, addone;
640 int ncx, ncy, naka, t;
641 int y, shift;
643 if (wi == 0)
644 he = hi = 0;
646 if (p->w_type == W_TYPE_GROUP)
647 return 0;
648 if (p->w_width == wi && p->w_height == he && p->w_histheight == hi)
650 debug("ChangeWindowSize: No change.\n");
651 return 0;
654 CheckMaxSize(wi);
656 /* XXX */
657 #if 0
658 /* just in case ... */
659 if (wi && (p->w_width != wi || p->w_height != he) && p->w_lay != &p->w_winlay)
661 debug("ChangeWindowSize: No resize because of overlay?\n");
662 return -1;
664 #endif
666 debug("ChangeWindowSize");
667 debug3(" from (%d,%d)+%d", p->w_width, p->w_height, p->w_histheight);
668 debug3(" to(%d,%d)+%d\n", wi, he, hi);
670 fy = p->w_histheight + p->w_height - 1;
671 ty = hi + he - 1;
673 nmlines = nhlines = 0;
674 ncx = 0;
675 ncy = 0;
676 naka = 0;
678 if (wi)
680 if (wi != p->w_width || he != p->w_height)
682 if ((nmlines = (struct mline *)calloc(he, sizeof(struct mline))) == 0)
684 KillWindow(p);
685 Msg(0, strnomem);
686 return -1;
689 else
691 debug1("image stays the same: %d lines\n", he);
692 nmlines = p->w_mlines;
693 fy -= he;
694 ty -= he;
695 ncx = p->w_x;
696 ncy = p->w_y;
697 naka = p->w_autoaka;
700 #ifdef COPY_PASTE
701 if (hi)
703 if ((nhlines = (struct mline *)calloc(hi, sizeof(struct mline))) == 0)
705 Msg(0, "No memory for history buffer - turned off");
706 hi = 0;
707 ty = he - 1;
710 #endif
712 /* special case: cursor is at magic margin position */
713 addone = 0;
714 if (p->w_width && p->w_x == p->w_width)
716 debug2("Special addone case: %d %d\n", p->w_x, p->w_y);
717 addone = 1;
718 p->w_x--;
721 /* handle the cursor and autoaka lines now if the widths are equal */
722 if (p->w_width == wi)
724 ncx = p->w_x + addone;
725 ncy = p->w_y + he - p->w_height;
726 /* never lose sight of the line with the cursor on it */
727 shift = -ncy;
728 for (yy = p->w_y + p->w_histheight - 1; yy >= 0 && ncy + shift < he; yy--)
730 ml = OLDWIN(yy);
731 if (ml->image[p->w_width] == ' ')
732 break;
733 shift++;
735 if (shift < 0)
736 shift = 0;
737 else
738 debug1("resize: cursor out of bounds, shifting %d\n", shift);
739 ncy += shift;
740 if (p->w_autoaka > 0)
742 naka = p->w_autoaka + he - p->w_height + shift;
743 if (naka < 1 || naka > he)
744 naka = 0;
746 while (shift-- > 0)
748 ml = OLDWIN(fy);
749 FreeMline(ml);
750 fy--;
753 debug2("fy %d ty %d\n", fy, ty);
754 if (fy >= 0)
755 mlf = OLDWIN(fy);
756 if (ty >= 0)
757 mlt = NEWWIN(ty);
759 while (fy >= 0 && ty >= 0)
761 if (p->w_width == wi)
763 /* here is a simple shortcut: just copy over */
764 *mlt = *mlf;
765 *mlf = mline_zero;
766 if (--fy >= 0)
767 mlf = OLDWIN(fy);
768 if (--ty >= 0)
769 mlt = NEWWIN(ty);
770 continue;
773 /* calculate lenght */
774 for (l = p->w_width - 1; l > 0; l--)
775 if (mlf->image[l] != ' ' || mlf->attr[l])
776 break;
777 if (fy == p->w_y + p->w_histheight && l < p->w_x)
778 l = p->w_x; /* cursor is non blank */
779 l++;
780 lf = l;
782 /* add wrapped lines to length */
783 for (yy = fy - 1; yy >= 0; yy--)
785 ml = OLDWIN(yy);
786 if (ml->image[p->w_width] == ' ')
787 break;
788 l += p->w_width;
791 /* rewrap lines */
792 lt = (l - 1) % wi + 1; /* lf is set above */
793 oty = ty;
794 while (l > 0 && fy >= 0 && ty >= 0)
796 lx = lt > lf ? lf : lt;
797 if (mlt->image == 0)
799 if (AllocMline(mlt, wi + 1))
800 goto nomem;
801 MakeBlankLine(mlt->image + lt, wi - lt);
802 mlt->image[wi] = ((oty == ty) ? ' ' : 0);
804 if (BcopyMline(mlf, lf - lx, mlt, lt - lx, lx, wi + 1))
805 goto nomem;
807 /* did we copy the cursor ? */
808 if (fy == p->w_y + p->w_histheight && lf - lx <= p->w_x && lf > p->w_x)
810 ncx = p->w_x + lt - lf + addone;
811 ncy = ty - hi;
812 shift = wi ? -ncy + (l - lx) / wi : 0;
813 if (ty + shift > hi + he - 1)
814 shift = hi + he - 1 - ty;
815 if (shift > 0)
817 debug3("resize: cursor out of bounds, shifting %d [%d/%d]\n", shift, lt - lx, wi);
818 for (y = hi + he - 1; y >= ty; y--)
820 mlt = NEWWIN(y);
821 FreeMline(mlt);
822 if (y - shift < ty)
823 continue;
824 ml = NEWWIN(y - shift);
825 *mlt = *ml;
826 *ml = mline_zero;
828 ncy += shift;
829 ty += shift;
830 mlt = NEWWIN(ty);
831 if (naka > 0)
832 naka = naka + shift > he ? 0 : naka + shift;
834 ASSERT(ncy >= 0);
836 /* did we copy autoaka line ? */
837 if (p->w_autoaka > 0 && fy == p->w_autoaka - 1 + p->w_histheight && lf - lx <= 0)
838 naka = ty - hi >= 0 ? 1 + ty - hi : 0;
840 lf -= lx;
841 lt -= lx;
842 l -= lx;
843 if (lf == 0)
845 FreeMline(mlf);
846 lf = p->w_width;
847 if (--fy >= 0)
848 mlf = OLDWIN(fy);
850 if (lt == 0)
852 lt = wi;
853 if (--ty >= 0)
854 mlt = NEWWIN(ty);
857 ASSERT(l != 0 || fy == yy);
859 while (fy >= 0)
861 FreeMline(mlf);
862 if (--fy >= 0)
863 mlf = OLDWIN(fy);
865 while (ty >= 0)
867 if (AllocMline(mlt, wi + 1))
868 goto nomem;
869 MakeBlankLine(mlt->image, wi + 1);
870 if (--ty >= 0)
871 mlt = NEWWIN(ty);
874 #ifdef DEBUG
875 if (nmlines != p->w_mlines)
876 for (fy = 0; fy < p->w_height + p->w_histheight; fy++)
878 ml = OLDWIN(fy);
879 ASSERT(ml->image == 0);
881 #endif
883 if (p->w_mlines && p->w_mlines != nmlines)
884 free((char *)p->w_mlines);
885 p->w_mlines = nmlines;
886 #ifdef COPY_PASTE
887 if (p->w_hlines && p->w_hlines != nhlines)
888 free((char *)p->w_hlines);
889 p->w_hlines = nhlines;
890 #endif
891 nmlines = nhlines = 0;
893 /* change tabs */
894 if (p->w_width != wi)
896 if (wi)
898 t = p->w_tabs ? p->w_width : 0;
899 p->w_tabs = xrealloc(p->w_tabs, wi + 1);
900 if (p->w_tabs == 0)
902 nomem:
903 if (nmlines)
905 for (ty = he + hi - 1; ty >= 0; ty--)
907 mlt = NEWWIN(ty);
908 FreeMline(mlt);
910 if (nmlines && p->w_mlines != nmlines)
911 free((char *)nmlines);
912 #ifdef COPY_PASTE
913 if (nhlines && p->w_hlines != nhlines)
914 free((char *)nhlines);
915 #endif
917 KillWindow(p);
918 Msg(0, strnomem);
919 return -1;
921 for (; t < wi; t++)
922 p->w_tabs[t] = t && !(t & 7) ? 1 : 0;
923 p->w_tabs[wi] = 0;
925 else
927 if (p->w_tabs)
928 free(p->w_tabs);
929 p->w_tabs = 0;
933 /* Change w_Saved_y - this is only an estimate... */
934 p->w_Saved_y += ncy - p->w_y;
936 p->w_x = ncx;
937 p->w_y = ncy;
938 if (p->w_autoaka > 0)
939 p->w_autoaka = naka;
941 /* do sanity checks */
942 if (p->w_x > wi)
943 p->w_x = wi;
944 if (p->w_y >= he)
945 p->w_y = he - 1;
946 if (p->w_Saved_x > wi)
947 p->w_Saved_x = wi;
948 if (p->w_Saved_y < 0)
949 p->w_Saved_y = 0;
950 if (p->w_Saved_y >= he)
951 p->w_Saved_y = he - 1;
953 /* reset scrolling region */
954 p->w_top = 0;
955 p->w_bot = he - 1;
957 /* signal new size to window */
958 #ifdef TIOCSWINSZ
959 if (wi && (p->w_width != wi || p->w_height != he)
960 && p->w_width != 0 && p->w_height != 0 && p->w_ptyfd >= 0 && p->w_pid)
962 glwz.ws_col = wi;
963 glwz.ws_row = he;
964 debug("Setting pty winsize.\n");
965 if (ioctl(p->w_ptyfd, TIOCSWINSZ, (char *)&glwz))
966 debug2("SetPtySize: errno %d (fd:%d)\n", errno, p->w_ptyfd);
968 #endif /* TIOCSWINSZ */
970 /* store new size */
971 p->w_width = wi;
972 p->w_height = he;
973 #ifdef COPY_PASTE
974 p->w_histidx = 0;
975 p->w_histheight = hi;
976 #endif
978 #ifdef BUILTIN_TELNET
979 if (p->w_type == W_TYPE_TELNET)
980 TelWindowSize(p);
981 #endif
983 #ifdef DEBUG
984 /* Test if everything was ok */
985 for (fy = 0; fy < p->w_height + p->w_histheight; fy++)
987 ml = OLDWIN(fy);
988 ASSERT(ml->image);
989 # ifdef UTF8
990 if (p->w_encoding == UTF8)
992 for (l = 0; l < p->w_width; l++)
993 ASSERT(ml->image[l] >= ' ' || ml->font[l]);
995 else
996 #endif
997 for (l = 0; l < p->w_width; l++)
998 ASSERT(ml->image[l] >= ' ');
1000 #endif
1001 return 0;
1004 void
1005 FreeAltScreen(p)
1006 struct win *p;
1008 int i;
1010 if (p->w_alt_mlines)
1012 for (i = 0; i < p->w_alt_height; i++)
1013 FreeMline(p->w_alt_mlines + i);
1014 free(p->w_alt_mlines);
1016 p->w_alt_mlines = 0;
1017 p->w_alt_width = 0;
1018 p->w_alt_height = 0;
1019 p->w_alt_x = 0;
1020 p->w_alt_y = 0;
1021 #ifdef COPY_PASTE
1022 if (p->w_alt_hlines)
1024 for (i = 0; i < p->w_alt_histheight; i++)
1025 FreeMline(p->w_alt_hlines + i);
1026 free(p->w_alt_hlines);
1028 p->w_alt_hlines = 0;
1029 p->w_alt_histidx = 0;
1030 #endif
1031 p->w_alt_histheight = 0;
1034 static void
1035 SwapAltScreen(p)
1036 struct win *p;
1038 struct mline *ml;
1039 int t;
1041 ml = p->w_alt_mlines; p->w_alt_mlines = p->w_mlines; p->w_mlines = ml;
1042 t = p->w_alt_width; p->w_alt_width = p->w_width; p->w_width = t;
1043 t = p->w_alt_height; p->w_alt_height = p->w_height; p->w_height = t;
1044 t = p->w_alt_histheight; p->w_alt_histheight = p->w_histheight; p->w_histheight = t;
1045 t = p->w_alt_x; p->w_alt_x = p->w_x; p->w_x = t;
1046 t = p->w_alt_y; p->w_alt_y = p->w_y; p->w_y = t;
1047 #ifdef COPY_PASTE
1048 ml = p->w_alt_hlines; p->w_alt_hlines = p->w_hlines; p->w_hlines = ml;
1049 t = p->w_alt_histidx; p->w_alt_histidx = p->w_histidx; p->w_histidx = t;
1050 #endif
1053 void
1054 EnterAltScreen(p)
1055 struct win *p;
1057 int ox = p->w_x, oy = p->w_y;
1058 FreeAltScreen(p);
1059 SwapAltScreen(p);
1060 ChangeWindowSize(p, p->w_alt_width, p->w_alt_height, p->w_alt_histheight);
1061 p->w_x = ox;
1062 p->w_y = oy;
1065 void
1066 LeaveAltScreen(p)
1067 struct win *p;
1069 if (!p->w_alt_mlines)
1070 return;
1071 SwapAltScreen(p);
1072 ChangeWindowSize(p, p->w_alt_width, p->w_alt_height, p->w_alt_histheight);
1073 FreeAltScreen(p);