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