ANSI
[unix-history] / usr / src / usr.bin / window / xxflush.c
CommitLineData
1cb6db79
EW
1/*
2 * Copyright (c) 1989 Regents of the University of California.
3 * All rights reserved.
4 *
3dd3a9e5
KB
5 * This code is derived from software contributed to Berkeley by
6 * Edward Wang at The University of California, Berkeley.
7 *
87f529ec 8 * %sccs.include.redist.c%
1cb6db79
EW
9 */
10
11#ifndef lint
3dd3a9e5 12static char sccsid[] = "@(#)xxflush.c 3.6 (Berkeley) %G%";
1cb6db79
EW
13#endif /* not lint */
14
15#include "ww.h"
16#include "xx.h"
17#include "tt.h"
18
19xxflush(intr)
20 register intr;
21{
22 register struct xx *xp, *xq;
23
24 for (xp = xx_head; xp != 0 && !(intr && wwinterrupt()); xp = xq) {
25 switch (xp->cmd) {
26 case xc_move:
27 if (xp->link == 0)
28 (*tt.tt_move)(xp->arg0, xp->arg1);
29 break;
30 case xc_scroll:
31 xxflush_scroll(xp);
32 break;
33 case xc_inschar:
1cb6db79 34 (*tt.tt_move)(xp->arg0, xp->arg1);
d9375810
EW
35 tt.tt_nmodes = xp->arg3;
36 (*tt.tt_inschar)(xp->arg2);
37 break;
38 case xc_insspace:
39 (*tt.tt_move)(xp->arg0, xp->arg1);
40 (*tt.tt_insspace)(xp->arg2);
1cb6db79
EW
41 break;
42 case xc_delchar:
1cb6db79
EW
43 (*tt.tt_move)(xp->arg0, xp->arg1);
44 (*tt.tt_delchar)(xp->arg2);
45 break;
46 case xc_clear:
47 (*tt.tt_clear)();
48 break;
49 case xc_clreos:
50 (*tt.tt_move)(xp->arg0, xp->arg1);
51 (*tt.tt_clreos)();
52 break;
53 case xc_clreol:
54 (*tt.tt_move)(xp->arg0, xp->arg1);
55 (*tt.tt_clreol)();
56 break;
57 case xc_write:
58 (*tt.tt_move)(xp->arg0, xp->arg1);
59 tt.tt_nmodes = xp->arg3;
17f96a0f 60 (*tt.tt_write)(xp->buf, xp->arg2);
1cb6db79
EW
61 break;
62 }
63 xq = xp->link;
64 xxfree(xp);
65 }
66 if ((xx_head = xp) == 0) {
67 xx_tail = 0;
68 xxbufp = xxbuf;
1cb6db79 69 }
17f96a0f 70 (*tt.tt_flush)();
1cb6db79
EW
71}
72
73xxflush_scroll(xp)
74 register struct xx *xp;
75{
76 register struct xx *xq;
77
78 top:
79 if (xp->arg0 == 0)
80 return;
81 /*
82 * We handle retain (da and db) by putting the burden on scrolling up,
83 * which is the less common operation. It must ensure that
84 * text is not pushed below the screen, so scrolling down doesn't
85 * have to worry about it.
86 *
87 * Try scrolling region (or scrolling the whole screen) first.
88 * Can we assume "sr" doesn't push text below the screen
89 * so we don't have to worry about retain below?
90 * What about scrolling down with a newline? It probably does
91 * push text above (with da). Scrolling up would then have
92 * to take care of that.
93 * It's easy to be fool proof, but that slows things down.
94 * The current solution is to disallow tt_scroll_up if da or db is true
95 * but cs (scrolling region) is not. Again, we sacrifice scrolling
96 * up in favor of scrolling down. The idea is having scrolling regions
97 * probably means we can scroll (even the whole screen) with impunity.
98 * This lets us work efficiently on simple terminals (use newline
99 * on the bottom to scroll), on any terminal without retain, and
100 * on vt100 style scrolling regions (I think).
101 */
102 if (xp->arg0 > 0) {
103 if ((xq = xp->link) != 0 && xq->cmd == xc_scroll &&
104 xp->arg2 == xq->arg2 && xq->arg0 < 0) {
105 if (xp->arg1 < xq->arg1) {
106 if (xp->arg2 - xp->arg0 <= xq->arg1) {
107 xq->arg0 = xp->arg0;
108 xq->arg1 = xp->arg1;
109 xq->arg2 = xp->arg2;
110 return;
111 }
112 xp->arg2 = xq->arg1 + xp->arg0;
113 xq->arg0 += xp->arg0;
114 xq->arg1 = xp->arg2;
115 if (xq->arg0 > 0)
116 xq->arg1 -= xq->arg0;
117 goto top;
118 } else {
119 if (xp->arg1 - xq->arg0 >= xp->arg2)
120 return;
121 xq->arg2 = xp->arg1 - xq->arg0;
122 xp->arg0 += xq->arg0;
123 xp->arg1 = xq->arg2;
124 if (xp->arg0 < 0)
125 xp->arg1 += xp->arg0;
126 goto top;
127 }
128 }
129 if (xp->arg0 > xp->arg2 - xp->arg1)
130 xp->arg0 = xp->arg2 - xp->arg1;
131 if (tt.tt_scroll_down) {
132 if (tt.tt_scroll_top != xp->arg1 ||
133 tt.tt_scroll_bot != xp->arg2 - 1) {
134 if (tt.tt_setscroll == 0)
135 goto down;
136 (*tt.tt_setscroll)(xp->arg1, xp->arg2 - 1);
137 }
138 tt.tt_scroll_down(xp->arg0);
139 } else {
140 down:
141 (*tt.tt_move)(xp->arg1, 0);
142 (*tt.tt_delline)(xp->arg0);
143 if (xp->arg2 < tt.tt_nrow) {
144 (*tt.tt_move)(xp->arg2 - xp->arg0, 0);
145 (*tt.tt_insline)(xp->arg0);
146 }
147 }
148 } else {
149 xp->arg0 = - xp->arg0;
150 if (xp->arg0 > xp->arg2 - xp->arg1)
151 xp->arg0 = xp->arg2 - xp->arg1;
152 if (tt.tt_scroll_up) {
153 if (tt.tt_scroll_top != xp->arg1 ||
154 tt.tt_scroll_bot != xp->arg2 - 1) {
155 if (tt.tt_setscroll == 0)
156 goto up;
157 (*tt.tt_setscroll)(xp->arg1, xp->arg2 - 1);
158 }
159 tt.tt_scroll_up(xp->arg0);
160 } else {
161 up:
162 if (tt.tt_retain || xp->arg2 != tt.tt_nrow) {
163 (*tt.tt_move)(xp->arg2 - xp->arg0, 0);
164 (*tt.tt_delline)(xp->arg0);
165 }
166 (*tt.tt_move)(xp->arg1, 0);
167 (*tt.tt_insline)(xp->arg0);
168 }
169 }
170}