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