138745Sedward /*
2*62479Sbostic * Copyright (c) 1989, 1993
3*62479Sbostic * The Regents of the University of California. All rights reserved.
438745Sedward *
542954Sbostic * This code is derived from software contributed to Berkeley by
642954Sbostic * Edward Wang at The University of California, Berkeley.
742954Sbostic *
842835Sbostic * %sccs.include.redist.c%
938745Sedward */
1038745Sedward
1138745Sedward #ifndef lint
12*62479Sbostic static char sccsid[] = "@(#)xxflush.c 8.1 (Berkeley) 06/06/93";
1338745Sedward #endif /* not lint */
1438745Sedward
1538745Sedward #include "ww.h"
1638745Sedward #include "xx.h"
1738745Sedward #include "tt.h"
1838745Sedward
xxflush(intr)1938745Sedward xxflush(intr)
2038745Sedward register intr;
2138745Sedward {
2238745Sedward register struct xx *xp, *xq;
2338745Sedward
2438745Sedward for (xp = xx_head; xp != 0 && !(intr && wwinterrupt()); xp = xq) {
2538745Sedward switch (xp->cmd) {
2638745Sedward case xc_move:
2738745Sedward if (xp->link == 0)
2838745Sedward (*tt.tt_move)(xp->arg0, xp->arg1);
2938745Sedward break;
3038745Sedward case xc_scroll:
3138745Sedward xxflush_scroll(xp);
3238745Sedward break;
3338745Sedward case xc_inschar:
3438745Sedward (*tt.tt_move)(xp->arg0, xp->arg1);
3538747Sedward tt.tt_nmodes = xp->arg3;
3638747Sedward (*tt.tt_inschar)(xp->arg2);
3738745Sedward break;
3838747Sedward case xc_insspace:
3938747Sedward (*tt.tt_move)(xp->arg0, xp->arg1);
4038747Sedward (*tt.tt_insspace)(xp->arg2);
4138747Sedward break;
4238745Sedward case xc_delchar:
4338745Sedward (*tt.tt_move)(xp->arg0, xp->arg1);
4438745Sedward (*tt.tt_delchar)(xp->arg2);
4538745Sedward break;
4638745Sedward case xc_clear:
4738745Sedward (*tt.tt_clear)();
4838745Sedward break;
4938745Sedward case xc_clreos:
5038745Sedward (*tt.tt_move)(xp->arg0, xp->arg1);
5138745Sedward (*tt.tt_clreos)();
5238745Sedward break;
5338745Sedward case xc_clreol:
5438745Sedward (*tt.tt_move)(xp->arg0, xp->arg1);
5538745Sedward (*tt.tt_clreol)();
5638745Sedward break;
5738745Sedward case xc_write:
5838745Sedward (*tt.tt_move)(xp->arg0, xp->arg1);
5938745Sedward tt.tt_nmodes = xp->arg3;
6039159Sedward (*tt.tt_write)(xp->buf, xp->arg2);
6138745Sedward break;
6238745Sedward }
6338745Sedward xq = xp->link;
6438745Sedward xxfree(xp);
6538745Sedward }
6638745Sedward if ((xx_head = xp) == 0) {
6738745Sedward xx_tail = 0;
6838745Sedward xxbufp = xxbuf;
6938745Sedward }
7056710Sedward ttflush();
7138745Sedward }
7238745Sedward
xxflush_scroll(xp)7338745Sedward xxflush_scroll(xp)
7438745Sedward register struct xx *xp;
7538745Sedward {
7638745Sedward register struct xx *xq;
7738745Sedward
7838745Sedward top:
7938745Sedward if (xp->arg0 == 0)
8038745Sedward return;
8138745Sedward /*
8238745Sedward * We handle retain (da and db) by putting the burden on scrolling up,
8338745Sedward * which is the less common operation. It must ensure that
8438745Sedward * text is not pushed below the screen, so scrolling down doesn't
8538745Sedward * have to worry about it.
8638745Sedward *
8738745Sedward * Try scrolling region (or scrolling the whole screen) first.
8838745Sedward * Can we assume "sr" doesn't push text below the screen
8938745Sedward * so we don't have to worry about retain below?
9038745Sedward * What about scrolling down with a newline? It probably does
9138745Sedward * push text above (with da). Scrolling up would then have
9238745Sedward * to take care of that.
9338745Sedward * It's easy to be fool proof, but that slows things down.
9438745Sedward * The current solution is to disallow tt_scroll_up if da or db is true
9538745Sedward * but cs (scrolling region) is not. Again, we sacrifice scrolling
9638745Sedward * up in favor of scrolling down. The idea is having scrolling regions
9738745Sedward * probably means we can scroll (even the whole screen) with impunity.
9838745Sedward * This lets us work efficiently on simple terminals (use newline
9938745Sedward * on the bottom to scroll), on any terminal without retain, and
10038745Sedward * on vt100 style scrolling regions (I think).
10138745Sedward */
10238745Sedward if (xp->arg0 > 0) {
10338745Sedward if ((xq = xp->link) != 0 && xq->cmd == xc_scroll &&
10438745Sedward xp->arg2 == xq->arg2 && xq->arg0 < 0) {
10538745Sedward if (xp->arg1 < xq->arg1) {
10638745Sedward if (xp->arg2 - xp->arg0 <= xq->arg1) {
10738745Sedward xq->arg0 = xp->arg0;
10838745Sedward xq->arg1 = xp->arg1;
10938745Sedward xq->arg2 = xp->arg2;
11038745Sedward return;
11138745Sedward }
11238745Sedward xp->arg2 = xq->arg1 + xp->arg0;
11338745Sedward xq->arg0 += xp->arg0;
11438745Sedward xq->arg1 = xp->arg2;
11538745Sedward if (xq->arg0 > 0)
11638745Sedward xq->arg1 -= xq->arg0;
11738745Sedward goto top;
11838745Sedward } else {
11938745Sedward if (xp->arg1 - xq->arg0 >= xp->arg2)
12038745Sedward return;
12138745Sedward xq->arg2 = xp->arg1 - xq->arg0;
12238745Sedward xp->arg0 += xq->arg0;
12338745Sedward xp->arg1 = xq->arg2;
12438745Sedward if (xp->arg0 < 0)
12538745Sedward xp->arg1 += xp->arg0;
12638745Sedward goto top;
12738745Sedward }
12838745Sedward }
12938745Sedward if (xp->arg0 > xp->arg2 - xp->arg1)
13038745Sedward xp->arg0 = xp->arg2 - xp->arg1;
13138745Sedward if (tt.tt_scroll_down) {
13238745Sedward if (tt.tt_scroll_top != xp->arg1 ||
13338745Sedward tt.tt_scroll_bot != xp->arg2 - 1) {
13438745Sedward if (tt.tt_setscroll == 0)
13538745Sedward goto down;
13638745Sedward (*tt.tt_setscroll)(xp->arg1, xp->arg2 - 1);
13738745Sedward }
13838745Sedward tt.tt_scroll_down(xp->arg0);
13938745Sedward } else {
14038745Sedward down:
14138745Sedward (*tt.tt_move)(xp->arg1, 0);
14238745Sedward (*tt.tt_delline)(xp->arg0);
14338745Sedward if (xp->arg2 < tt.tt_nrow) {
14438745Sedward (*tt.tt_move)(xp->arg2 - xp->arg0, 0);
14538745Sedward (*tt.tt_insline)(xp->arg0);
14638745Sedward }
14738745Sedward }
14838745Sedward } else {
14938745Sedward xp->arg0 = - xp->arg0;
15038745Sedward if (xp->arg0 > xp->arg2 - xp->arg1)
15138745Sedward xp->arg0 = xp->arg2 - xp->arg1;
15238745Sedward if (tt.tt_scroll_up) {
15338745Sedward if (tt.tt_scroll_top != xp->arg1 ||
15438745Sedward tt.tt_scroll_bot != xp->arg2 - 1) {
15538745Sedward if (tt.tt_setscroll == 0)
15638745Sedward goto up;
15738745Sedward (*tt.tt_setscroll)(xp->arg1, xp->arg2 - 1);
15838745Sedward }
15938745Sedward tt.tt_scroll_up(xp->arg0);
16038745Sedward } else {
16138745Sedward up:
16238745Sedward if (tt.tt_retain || xp->arg2 != tt.tt_nrow) {
16338745Sedward (*tt.tt_move)(xp->arg2 - xp->arg0, 0);
16438745Sedward (*tt.tt_delline)(xp->arg0);
16538745Sedward }
16638745Sedward (*tt.tt_move)(xp->arg1, 0);
16738745Sedward (*tt.tt_insline)(xp->arg0);
16838745Sedward }
16938745Sedward }
17038745Sedward }
171