|
|
1.1 root 1: /*
2: * Copyright (c) 1989 Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Edward Wang at The University of California, Berkeley.
7: *
8: * Redistribution and use in source and binary forms are permitted provided
9: * that: (1) source distributions retain this entire copyright notice and
10: * comment, and (2) distributions including binaries display the following
11: * acknowledgement: ``This product includes software developed by the
12: * University of California, Berkeley and its contributors'' in the
13: * documentation or other materials provided with the distribution and in
14: * all advertising materials mentioning features or use of this software.
15: * Neither the name of the University nor the names of its contributors may
16: * be used to endorse or promote products derived from this software without
17: * specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)xxflush.c 3.6 (Berkeley) 6/6/90";
25: #endif /* not lint */
26:
27: #include "ww.h"
28: #include "xx.h"
29: #include "tt.h"
30:
31: xxflush(intr)
32: register intr;
33: {
34: register struct xx *xp, *xq;
35:
36: for (xp = xx_head; xp != 0 && !(intr && wwinterrupt()); xp = xq) {
37: switch (xp->cmd) {
38: case xc_move:
39: if (xp->link == 0)
40: (*tt.tt_move)(xp->arg0, xp->arg1);
41: break;
42: case xc_scroll:
43: xxflush_scroll(xp);
44: break;
45: case xc_inschar:
46: (*tt.tt_move)(xp->arg0, xp->arg1);
47: tt.tt_nmodes = xp->arg3;
48: (*tt.tt_inschar)(xp->arg2);
49: break;
50: case xc_insspace:
51: (*tt.tt_move)(xp->arg0, xp->arg1);
52: (*tt.tt_insspace)(xp->arg2);
53: break;
54: case xc_delchar:
55: (*tt.tt_move)(xp->arg0, xp->arg1);
56: (*tt.tt_delchar)(xp->arg2);
57: break;
58: case xc_clear:
59: (*tt.tt_clear)();
60: break;
61: case xc_clreos:
62: (*tt.tt_move)(xp->arg0, xp->arg1);
63: (*tt.tt_clreos)();
64: break;
65: case xc_clreol:
66: (*tt.tt_move)(xp->arg0, xp->arg1);
67: (*tt.tt_clreol)();
68: break;
69: case xc_write:
70: (*tt.tt_move)(xp->arg0, xp->arg1);
71: tt.tt_nmodes = xp->arg3;
72: (*tt.tt_write)(xp->buf, xp->arg2);
73: break;
74: }
75: xq = xp->link;
76: xxfree(xp);
77: }
78: if ((xx_head = xp) == 0) {
79: xx_tail = 0;
80: xxbufp = xxbuf;
81: }
82: (*tt.tt_flush)();
83: }
84:
85: xxflush_scroll(xp)
86: register struct xx *xp;
87: {
88: register struct xx *xq;
89:
90: top:
91: if (xp->arg0 == 0)
92: return;
93: /*
94: * We handle retain (da and db) by putting the burden on scrolling up,
95: * which is the less common operation. It must ensure that
96: * text is not pushed below the screen, so scrolling down doesn't
97: * have to worry about it.
98: *
99: * Try scrolling region (or scrolling the whole screen) first.
100: * Can we assume "sr" doesn't push text below the screen
101: * so we don't have to worry about retain below?
102: * What about scrolling down with a newline? It probably does
103: * push text above (with da). Scrolling up would then have
104: * to take care of that.
105: * It's easy to be fool proof, but that slows things down.
106: * The current solution is to disallow tt_scroll_up if da or db is true
107: * but cs (scrolling region) is not. Again, we sacrifice scrolling
108: * up in favor of scrolling down. The idea is having scrolling regions
109: * probably means we can scroll (even the whole screen) with impunity.
110: * This lets us work efficiently on simple terminals (use newline
111: * on the bottom to scroll), on any terminal without retain, and
112: * on vt100 style scrolling regions (I think).
113: */
114: if (xp->arg0 > 0) {
115: if ((xq = xp->link) != 0 && xq->cmd == xc_scroll &&
116: xp->arg2 == xq->arg2 && xq->arg0 < 0) {
117: if (xp->arg1 < xq->arg1) {
118: if (xp->arg2 - xp->arg0 <= xq->arg1) {
119: xq->arg0 = xp->arg0;
120: xq->arg1 = xp->arg1;
121: xq->arg2 = xp->arg2;
122: return;
123: }
124: xp->arg2 = xq->arg1 + xp->arg0;
125: xq->arg0 += xp->arg0;
126: xq->arg1 = xp->arg2;
127: if (xq->arg0 > 0)
128: xq->arg1 -= xq->arg0;
129: goto top;
130: } else {
131: if (xp->arg1 - xq->arg0 >= xp->arg2)
132: return;
133: xq->arg2 = xp->arg1 - xq->arg0;
134: xp->arg0 += xq->arg0;
135: xp->arg1 = xq->arg2;
136: if (xp->arg0 < 0)
137: xp->arg1 += xp->arg0;
138: goto top;
139: }
140: }
141: if (xp->arg0 > xp->arg2 - xp->arg1)
142: xp->arg0 = xp->arg2 - xp->arg1;
143: if (tt.tt_scroll_down) {
144: if (tt.tt_scroll_top != xp->arg1 ||
145: tt.tt_scroll_bot != xp->arg2 - 1) {
146: if (tt.tt_setscroll == 0)
147: goto down;
148: (*tt.tt_setscroll)(xp->arg1, xp->arg2 - 1);
149: }
150: tt.tt_scroll_down(xp->arg0);
151: } else {
152: down:
153: (*tt.tt_move)(xp->arg1, 0);
154: (*tt.tt_delline)(xp->arg0);
155: if (xp->arg2 < tt.tt_nrow) {
156: (*tt.tt_move)(xp->arg2 - xp->arg0, 0);
157: (*tt.tt_insline)(xp->arg0);
158: }
159: }
160: } else {
161: xp->arg0 = - xp->arg0;
162: if (xp->arg0 > xp->arg2 - xp->arg1)
163: xp->arg0 = xp->arg2 - xp->arg1;
164: if (tt.tt_scroll_up) {
165: if (tt.tt_scroll_top != xp->arg1 ||
166: tt.tt_scroll_bot != xp->arg2 - 1) {
167: if (tt.tt_setscroll == 0)
168: goto up;
169: (*tt.tt_setscroll)(xp->arg1, xp->arg2 - 1);
170: }
171: tt.tt_scroll_up(xp->arg0);
172: } else {
173: up:
174: if (tt.tt_retain || xp->arg2 != tt.tt_nrow) {
175: (*tt.tt_move)(xp->arg2 - xp->arg0, 0);
176: (*tt.tt_delline)(xp->arg0);
177: }
178: (*tt.tt_move)(xp->arg1, 0);
179: (*tt.tt_insline)(xp->arg0);
180: }
181: }
182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.