1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)ttgeneric.c 3.37 (Berkeley) 10/04/88"; 20 #endif /* not lint */ 21 22 #include "ww.h" 23 #include "tt.h" 24 25 char PC, *BC, *UP; 26 short ospeed; 27 28 /* normal frame */ 29 short gen_frame[16] = { 30 ' ', '|', '-', '+', 31 '|', '|', '+', '+', 32 '-', '+', '-', '+', 33 '+', '+', '+', '+' 34 }; 35 36 /* ANSI graphics frame */ 37 #define G (WWM_GRP << WWC_MSHIFT) 38 short ansi_frame[16] = { 39 ' ', 'x'|G, 'Q'|G, 'm'|G, 40 'x'|G, 'x'|G, 'l'|G, 't'|G, 41 'q'|G, 'j'|G, 'q'|G, 'v'|G, 42 'k'|G, 'u'|G, 'w'|G, 'n'|G 43 }; 44 struct tt_str ansi_AS = { 45 "\033(0", 3 46 }; 47 48 struct tt_str *gen_PC; 49 struct tt_str *gen_CM; 50 struct tt_str *gen_IM; 51 struct tt_str *gen_IC; 52 struct tt_str *gen_IP; 53 struct tt_str *gen_EI; 54 struct tt_str *gen_DC; 55 struct tt_str *gen_AL; 56 struct tt_str *gen_DL; 57 struct tt_str *gen_CE; 58 struct tt_str *gen_CD; 59 struct tt_str *gen_CL; 60 struct tt_str *gen_VS; 61 struct tt_str *gen_VE; 62 struct tt_str *gen_TI; 63 struct tt_str *gen_TE; 64 struct tt_str *gen_SO; 65 struct tt_str *gen_SE; 66 struct tt_str *gen_US; 67 struct tt_str *gen_UE; 68 struct tt_str *gen_LE; 69 struct tt_str *gen_ND; 70 struct tt_str *gen_UP; 71 struct tt_str *gen_DO; 72 struct tt_str *gen_BC; 73 struct tt_str *gen_NL; 74 struct tt_str *gen_CR; 75 struct tt_str *gen_HO; 76 struct tt_str *gen_AS; 77 struct tt_str *gen_AE; 78 struct tt_str *gen_XS; 79 struct tt_str *gen_XE; 80 struct tt_str *gen_SF; 81 struct tt_str *gen_SR; 82 struct tt_str *gen_CS; 83 char gen_MI; 84 char gen_MS; 85 char gen_AM; 86 char gen_OS; 87 char gen_BS; 88 char gen_DA; 89 char gen_DB; 90 char gen_NS; 91 char gen_XN; 92 int gen_CO; 93 int gen_LI; 94 int gen_UG; 95 int gen_SG; 96 97 gen_setinsert(new) 98 char new; 99 { 100 if (new) { 101 if (gen_IM) 102 ttxputs(gen_IM); 103 } else 104 if (gen_EI) 105 ttxputs(gen_EI); 106 tt.tt_insert = new; 107 } 108 109 gen_setmodes(new) 110 register new; 111 { 112 register diff; 113 114 diff = new ^ tt.tt_modes; 115 if (diff & WWM_REV) { 116 if (new & WWM_REV) { 117 if (gen_SO) 118 ttxputs(gen_SO); 119 } else 120 if (gen_SE) 121 ttxputs(gen_SE); 122 } 123 if (diff & WWM_UL) { 124 if (new & WWM_UL) { 125 if (gen_US) 126 ttxputs(gen_US); 127 } else 128 if (gen_UE) 129 ttxputs(gen_UE); 130 } 131 if (diff & WWM_GRP) { 132 if (new & WWM_GRP) { 133 if (gen_AS) 134 ttxputs(gen_AS); 135 } else 136 if (gen_AE) 137 ttxputs(gen_AE); 138 } 139 if (diff & WWM_USR) { 140 if (new & WWM_USR) { 141 if (gen_XS) 142 ttxputs(gen_XS); 143 } else 144 if (gen_XE) 145 ttxputs(gen_XE); 146 } 147 tt.tt_modes = new; 148 } 149 150 gen_insline() 151 { 152 if (tt.tt_modes) /* for concept 100 */ 153 gen_setmodes(0); 154 if (gen_AL) 155 tttputs(gen_AL, gen_LI - tt.tt_row); 156 } 157 158 gen_delline() 159 { 160 if (tt.tt_modes) /* for concept 100 */ 161 gen_setmodes(0); 162 if (gen_DL) 163 tttputs(gen_DL, gen_LI - tt.tt_row); 164 } 165 166 gen_putc(c) 167 register char c; 168 { 169 if (tt.tt_ninsert != tt.tt_insert) 170 gen_setinsert(tt.tt_ninsert); 171 if (tt.tt_nmodes != tt.tt_modes) 172 gen_setmodes(tt.tt_nmodes); 173 if (tt.tt_insert) { 174 if (gen_IC) 175 tttputs(gen_IC, gen_CO - tt.tt_col); 176 ttputc(c); 177 if (gen_IP) 178 tttputs(gen_IP, gen_CO - tt.tt_col); 179 } else 180 ttputc(c); 181 if (++tt.tt_col == gen_CO) 182 if (gen_XN) 183 tt.tt_col = tt.tt_row = -10; 184 else if (gen_AM) 185 tt.tt_col = 0, tt.tt_row++; 186 else 187 tt.tt_col--; 188 } 189 190 gen_write(p, n) 191 register char *p; 192 register n; 193 { 194 if (tt.tt_ninsert != tt.tt_insert) 195 gen_setinsert(tt.tt_ninsert); 196 if (tt.tt_nmodes != tt.tt_modes) 197 gen_setmodes(tt.tt_nmodes); 198 if (tt.tt_insert && (gen_IC || gen_IP)) { 199 while (--n >= 0) { 200 if (gen_IC) 201 tttputs(gen_IC, gen_CO - tt.tt_col); 202 ttputc(*p++); 203 if (gen_IP) 204 tttputs(gen_IP, gen_CO - tt.tt_col); 205 tt.tt_col++; 206 } 207 } else { 208 tt.tt_col += n; 209 ttwrite(p, n); 210 } 211 if (tt.tt_col == gen_CO) 212 if (gen_XN) 213 tt.tt_col = tt.tt_row = -10; 214 else if (gen_AM) 215 tt.tt_col = 0, tt.tt_row++; 216 else 217 tt.tt_col--; 218 } 219 220 gen_move(row, col) 221 register int row, col; 222 { 223 if (tt.tt_row == row && tt.tt_col == col) 224 return; 225 if (!gen_MI && tt.tt_insert) 226 gen_setinsert(0); 227 if (!gen_MS && tt.tt_modes) 228 gen_setmodes(0); 229 if (row < tt.tt_scroll_top || row > tt.tt_scroll_bot) 230 gen_setscroll(tt.tt_nrow - 1, 0); 231 if (tt.tt_row == row) { 232 if (col == 0) { 233 ttxputs(gen_CR); 234 goto out; 235 } 236 if (tt.tt_col == col - 1) { 237 if (gen_ND) { 238 ttxputs(gen_ND); 239 goto out; 240 } 241 } else if (tt.tt_col == col + 1) { 242 if (gen_LE) { 243 ttxputs(gen_LE); 244 goto out; 245 } 246 } 247 } 248 if (tt.tt_col == col) { 249 if (tt.tt_row == row + 1) { 250 if (gen_UP) { 251 ttxputs(gen_UP); 252 goto out; 253 } 254 } else if (tt.tt_row == row - 1) { 255 ttxputs(gen_DO); 256 goto out; 257 } 258 } 259 if (gen_HO && col == 0 && row == 0) { 260 ttxputs(gen_HO); 261 goto out; 262 } 263 tttgoto(gen_CM, col, row); 264 out: 265 tt.tt_col = col; 266 tt.tt_row = row; 267 } 268 269 gen_init() 270 { 271 if (gen_VS) 272 ttxputs(gen_VS); 273 if (gen_TI) 274 ttxputs(gen_TI); 275 ttxputs(gen_CL); 276 tt.tt_col = tt.tt_row = 0; 277 tt.tt_ninsert = tt.tt_insert = 0; 278 tt.tt_nmodes = tt.tt_modes = 0; 279 } 280 281 gen_end() 282 { 283 if (gen_TE) 284 ttxputs(gen_TE); 285 if (gen_VE) 286 ttxputs(gen_VE); 287 } 288 289 gen_clreol() 290 { 291 if (tt.tt_modes) /* for concept 100 */ 292 gen_setmodes(0); 293 tttputs(gen_CE, gen_CO - tt.tt_col); 294 } 295 296 gen_clreos() 297 { 298 if (tt.tt_modes) /* for concept 100 */ 299 gen_setmodes(0); 300 tttputs(gen_CD, gen_LI - tt.tt_row); 301 } 302 303 gen_clear() 304 { 305 if (tt.tt_modes) /* for concept 100 */ 306 gen_setmodes(0); 307 ttxputs(gen_CL); 308 } 309 310 gen_delchar() 311 { 312 tttputs(gen_DC, gen_CO - tt.tt_col); 313 } 314 315 gen_scroll_down() 316 { 317 gen_move(tt.tt_scroll_bot, 0); 318 ttxputs(gen_SF); 319 } 320 321 gen_scroll_up() 322 { 323 gen_move(tt.tt_scroll_top, 0); 324 ttxputs(gen_SR); 325 } 326 327 gen_setscroll(top, bot) 328 { 329 tttgoto(gen_CS, bot, top); 330 tt.tt_scroll_top = top; 331 tt.tt_scroll_bot = bot; 332 tt.tt_row = tt.tt_col = -10; 333 } 334 335 tt_generic() 336 { 337 gen_PC = tttgetstr("pc"); 338 PC = gen_PC ? *gen_PC->ts_str : 0; 339 ospeed = wwoldtty.ww_sgttyb.sg_ospeed; 340 341 gen_CM = ttxgetstr("cm"); /* may not work */ 342 gen_IM = ttxgetstr("im"); 343 gen_IC = tttgetstr("ic"); 344 gen_IP = tttgetstr("ip"); 345 gen_EI = ttxgetstr("ei"); 346 gen_DC = tttgetstr("dc"); 347 gen_AL = tttgetstr("al"); 348 gen_DL = tttgetstr("dl"); 349 gen_CE = tttgetstr("ce"); 350 gen_CD = tttgetstr("cd"); 351 gen_CL = ttxgetstr("cl"); 352 gen_VS = ttxgetstr("vs"); 353 gen_VE = ttxgetstr("ve"); 354 gen_TI = ttxgetstr("ti"); 355 gen_TE = ttxgetstr("te"); 356 gen_SO = ttxgetstr("so"); 357 gen_SE = ttxgetstr("se"); 358 gen_US = ttxgetstr("us"); 359 gen_UE = ttxgetstr("ue"); 360 gen_LE = ttxgetstr("le"); 361 gen_ND = ttxgetstr("nd"); 362 gen_UP = ttxgetstr("up"); 363 gen_DO = ttxgetstr("do"); 364 gen_BC = ttxgetstr("bc"); 365 gen_NL = ttxgetstr("nl"); 366 gen_CR = ttxgetstr("cr"); 367 gen_HO = ttxgetstr("ho"); 368 gen_AS = ttxgetstr("as"); 369 gen_AE = ttxgetstr("ae"); 370 gen_XS = ttxgetstr("XS"); 371 gen_XE = ttxgetstr("XE"); 372 gen_SF = ttxgetstr("sf"); 373 gen_SR = ttxgetstr("sr"); 374 gen_CS = ttxgetstr("cs"); 375 gen_MI = tgetflag("mi"); 376 gen_MS = tgetflag("ms"); 377 gen_AM = tgetflag("am"); 378 gen_OS = tgetflag("os"); 379 gen_BS = tgetflag("bs"); 380 gen_DA = tgetflag("da"); 381 gen_DB = tgetflag("db"); 382 gen_NS = tgetflag("ns"); 383 gen_XN = tgetflag("xn"); 384 gen_CO = tgetnum("co"); 385 gen_LI = tgetnum("li"); 386 gen_UG = tgetnum("ug"); 387 gen_SG = tgetnum("sg"); 388 if (gen_CL == 0 || gen_OS || gen_CM == 0) 389 return -1; 390 391 /* 392 * Deal with obsolete termcap fields. 393 */ 394 if (gen_LE == 0) 395 if (gen_BC) 396 gen_LE = gen_BC; 397 else if (gen_BS) { 398 static struct tt_str bc = { "\b", 1 }; 399 gen_BC = &bc; 400 } 401 if (gen_NL == 0) { 402 static struct tt_str nl = { "\n", 1 }; 403 gen_NL = &nl; 404 } 405 if (gen_DO == 0) 406 gen_DO = gen_NL; 407 if (gen_CR == 0) { 408 static struct tt_str cr = { "\r", 1 }; 409 gen_CR = &cr; 410 } 411 /* 412 * Most terminal will scroll with "nl", but very few specify "sf". 413 * We shouldn't use "do" here. 414 */ 415 if (gen_SF == 0 && !gen_NS) 416 gen_SF = gen_NL; 417 BC = gen_LE ? gen_LE->ts_str : 0; 418 UP = gen_UP ? gen_UP->ts_str : 0; 419 /* 420 * Fix up display attributes that we can't handle, or don't 421 * really exist. 422 */ 423 if (gen_SG > 0) 424 gen_SO = 0; 425 if (gen_UG > 0 || gen_US && gen_SO && ttstrcmp(gen_US, gen_SO) == 0) 426 gen_US = 0; 427 428 if (gen_DC) 429 tt.tt_delchar = gen_delchar; 430 if (gen_AL) 431 tt.tt_insline = gen_insline; 432 if (gen_DL) 433 tt.tt_delline = gen_delline; 434 if (gen_CE) 435 tt.tt_clreol = gen_clreol; 436 if (gen_CD) 437 tt.tt_clreos = gen_clreos; 438 if (gen_SF) 439 tt.tt_scroll_down = gen_scroll_down; 440 /* 441 * Don't allow scroll_up if da or db but not cs. 442 * See comment in wwscroll.c. 443 */ 444 if (gen_SR && (gen_CS || !gen_DA && !gen_DB)) 445 tt.tt_scroll_up = gen_scroll_up; 446 if (gen_CS) 447 tt.tt_setscroll = gen_setscroll; 448 if (gen_SO) 449 tt.tt_availmodes |= WWM_REV; 450 if (gen_US) 451 tt.tt_availmodes |= WWM_UL; 452 if (gen_AS) 453 tt.tt_availmodes |= WWM_GRP; 454 if (gen_XS) 455 tt.tt_availmodes |= WWM_USR; 456 tt.tt_hasinsert = gen_IM || gen_IC; 457 tt.tt_wrap = gen_AM; 458 tt.tt_retain = gen_DB; 459 tt.tt_ncol = gen_CO; 460 tt.tt_nrow = gen_LI; 461 tt.tt_init = gen_init; 462 tt.tt_end = gen_end; 463 tt.tt_write = gen_write; 464 tt.tt_putc = gen_putc; 465 tt.tt_move = gen_move; 466 tt.tt_clear = gen_clear; 467 tt.tt_setinsert = gen_setinsert; 468 tt.tt_setmodes = gen_setmodes; 469 tt.tt_frame = gen_AS && ttstrcmp(gen_AS, &ansi_AS) == 0 ? 470 ansi_frame : gen_frame; 471 return 0; 472 } 473