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