138745Sedward /* 238745Sedward * Copyright (c) 1989 Regents of the University of California. 338745Sedward * All rights reserved. 438745Sedward * 5*42954Sbostic * This code is derived from software contributed to Berkeley by 6*42954Sbostic * Edward Wang at The University of California, Berkeley. 7*42954Sbostic * 842835Sbostic * %sccs.include.redist.c% 938745Sedward */ 1038745Sedward 1138745Sedward #ifndef lint 12*42954Sbostic static char sccsid[] = "@(#)xxflush.c 3.6 (Berkeley) 06/06/90"; 1338745Sedward #endif /* not lint */ 1438745Sedward 1538745Sedward #include "ww.h" 1638745Sedward #include "xx.h" 1738745Sedward #include "tt.h" 1838745Sedward 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 } 7039159Sedward (*tt.tt_flush)(); 7138745Sedward } 7238745Sedward 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