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