1 /* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. 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, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)xx.c 8.1 (Berkeley) 6/6/93 37 * $FreeBSD: src/usr.bin/window/xx.c,v 1.2.12.1 2001/05/17 09:45:02 obrien Exp $ 38 * $DragonFly: src/usr.bin/window/xx.c,v 1.2 2003/06/17 04:29:34 dillon Exp $ 39 */ 40 41 #include <stdlib.h> 42 #include <string.h> 43 44 #include "ww.h" 45 #include "xx.h" 46 #include "tt.h" 47 48 xxinit() 49 { 50 if (ttinit() < 0) 51 return -1; 52 xxbufsize = tt.tt_nrow * tt.tt_ncol * 2; 53 /* ccinit may choose to change xxbufsize */ 54 if (tt.tt_ntoken > 0 && ccinit() < 0) 55 return -1; 56 xxbuf = malloc((unsigned) xxbufsize * sizeof *xxbuf); 57 if (xxbuf == 0) { 58 wwerrno = WWE_NOMEM; 59 return -1; 60 } 61 xxbufp = xxbuf; 62 xxbufe = xxbuf + xxbufsize; 63 return 0; 64 } 65 66 xxstart() 67 { 68 (*tt.tt_start)(); 69 if (tt.tt_ntoken > 0) 70 ccstart(); 71 xxreset1(); /* might be a restart */ 72 } 73 74 xxreset() 75 { 76 if (tt.tt_ntoken > 0) 77 ccreset(); 78 xxreset1(); 79 (*tt.tt_reset)(); 80 } 81 82 xxreset1() 83 { 84 register struct xx *xp, *xq; 85 86 for (xp = xx_head; xp != 0; xp = xq) { 87 xq = xp->link; 88 xxfree(xp); 89 } 90 xx_tail = xx_head = 0; 91 xxbufp = xxbuf; 92 } 93 94 xxend() 95 { 96 if (tt.tt_scroll_top != 0 || tt.tt_scroll_bot != tt.tt_nrow - 1) 97 /* tt.tt_setscroll is known to be defined */ 98 (*tt.tt_setscroll)(0, tt.tt_nrow - 1); 99 if (tt.tt_modes) 100 (*tt.tt_setmodes)(0); 101 if (tt.tt_scroll_down) 102 (*tt.tt_scroll_down)(1); 103 (*tt.tt_move)(tt.tt_nrow - 1, 0); 104 if (tt.tt_ntoken > 0) 105 ccend(); 106 (*tt.tt_end)(); 107 ttflush(); 108 } 109 110 struct xx * 111 xxalloc() 112 { 113 register struct xx *xp; 114 115 if (xxbufp > xxbufe) 116 abort(); 117 if ((xp = xx_freelist) == 0) 118 /* XXX can't deal with failure */ 119 xp = (struct xx *) malloc((unsigned) sizeof *xp); 120 else 121 xx_freelist = xp->link; 122 if (xx_head == 0) 123 xx_head = xp; 124 else 125 xx_tail->link = xp; 126 xx_tail = xp; 127 xp->link = 0; 128 return xp; 129 } 130 131 xxfree(xp) 132 register struct xx *xp; 133 { 134 xp->link = xx_freelist; 135 xx_freelist = xp; 136 } 137 138 xxmove(row, col) 139 { 140 register struct xx *xp = xx_tail; 141 142 if (xp == 0 || xp->cmd != xc_move) { 143 xp = xxalloc(); 144 xp->cmd = xc_move; 145 } 146 xp->arg0 = row; 147 xp->arg1 = col; 148 } 149 150 xxscroll(dir, top, bot) 151 { 152 register struct xx *xp = xx_tail; 153 154 if (xp != 0 && xp->cmd == xc_scroll && 155 xp->arg1 == top && xp->arg2 == bot && 156 (xp->arg0 < 0 && dir < 0 || xp->arg0 > 0 && dir > 0)) { 157 xp->arg0 += dir; 158 return; 159 } 160 xp = xxalloc(); 161 xp->cmd = xc_scroll; 162 xp->arg0 = dir; 163 xp->arg1 = top; 164 xp->arg2 = bot; 165 } 166 167 xxinschar(row, col, c, m) 168 { 169 register struct xx *xp; 170 171 xp = xxalloc(); 172 xp->cmd = xc_inschar; 173 xp->arg0 = row; 174 xp->arg1 = col; 175 xp->arg2 = c; 176 xp->arg3 = m; 177 } 178 179 xxinsspace(row, col) 180 { 181 register struct xx *xp = xx_tail; 182 183 if (xp != 0 && xp->cmd == xc_insspace && xp->arg0 == row && 184 col >= xp->arg1 && col <= xp->arg1 + xp->arg2) { 185 xp->arg2++; 186 return; 187 } 188 xp = xxalloc(); 189 xp->cmd = xc_insspace; 190 xp->arg0 = row; 191 xp->arg1 = col; 192 xp->arg2 = 1; 193 } 194 195 xxdelchar(row, col) 196 { 197 register struct xx *xp = xx_tail; 198 199 if (xp != 0 && xp->cmd == xc_delchar && 200 xp->arg0 == row && xp->arg1 == col) { 201 xp->arg2++; 202 return; 203 } 204 xp = xxalloc(); 205 xp->cmd = xc_delchar; 206 xp->arg0 = row; 207 xp->arg1 = col; 208 xp->arg2 = 1; 209 } 210 211 xxclear() 212 { 213 register struct xx *xp; 214 215 xxreset1(); 216 xp = xxalloc(); 217 xp->cmd = xc_clear; 218 } 219 220 xxclreos(row, col) 221 { 222 register struct xx *xp = xxalloc(); 223 224 xp->cmd = xc_clreos; 225 xp->arg0 = row; 226 xp->arg1 = col; 227 } 228 229 xxclreol(row, col) 230 { 231 register struct xx *xp = xxalloc(); 232 233 xp->cmd = xc_clreol; 234 xp->arg0 = row; 235 xp->arg1 = col; 236 } 237 238 xxwrite(row, col, p, n, m) 239 char *p; 240 { 241 register struct xx *xp; 242 243 if (xxbufp + n + 1 > xxbufe) 244 xxflush(0); 245 xp = xxalloc(); 246 xp->cmd = xc_write; 247 xp->arg0 = row; 248 xp->arg1 = col; 249 xp->arg2 = n; 250 xp->arg3 = m; 251 xp->buf = xxbufp; 252 bcopy(p, xxbufp, n); 253 xxbufp += n; 254 *xxbufp++ = char_sep; 255 } 256