1 #ifndef lint 2 static char sccsid[]="@(#)n10.c 1.2 (CWI) 86/08/15"; 3 #endif 4 5 /* 6 n10.c 7 8 Device interfaces 9 */ 10 11 #include "tdef.h" 12 #include "ext.h" 13 #include "tw.h" 14 #include <sgtty.h> 15 #include <ctype.h> 16 #include <sys/types.h> 17 #include <sys/stat.h> 18 19 struct t t; /* terminal characteristics */ 20 21 int dtab; 22 int plotmode; 23 int esct; 24 25 char xchname[4 * (NROFFCHARS-128)]; /* hy, em, etc. */ 26 short xchtab[NROFFCHARS-128]; /* indexes into chname[] */ 27 char *codestr; 28 char *chname = xchname; 29 short *chtab = xchtab; 30 31 32 int Inch; 33 int Hor; 34 int Vert; 35 int nfonts = 4; /* R, I, B, S */ 36 37 /* these characters are used as various signals or values 38 /* in miscellaneous places. 39 /* values are set in specnames in t10.c 40 */ 41 42 int c_hyphen; 43 int c_emdash; 44 int c_rule; 45 int c_minus; 46 int c_fi; 47 int c_fl; 48 int c_ff; 49 int c_ffi; 50 int c_ffl; 51 int c_acute; 52 int c_grave; 53 int c_under; 54 int c_rooten; 55 int c_boxrule; 56 int c_lefthand; 57 int c_dagger; 58 int c_isalnum; 59 60 ptinit() 61 { 62 register int i, j; 63 register char *p, *cp, *q; 64 int nread, fd; 65 extern char *skipstr(), *getstr(), *getint(); 66 extern char *setbrk(); 67 struct stat stbuf; 68 char check[50]; 69 70 strcat(termtab, devname); 71 if ((fd = open(termtab, 0)) < 0) { 72 errprint("cannot open %s", termtab); 73 exit(-1); 74 } 75 76 fstat(fd, &stbuf); 77 codestr = setbrk((int) stbuf.st_size); 78 79 nread = read(fd, codestr, (int) stbuf.st_size); 80 close(fd); 81 82 p = codestr; 83 p = skipstr(p); /* skip over type, could check */ 84 p = skipstr(p); p = getint(p, &t.bset); 85 p = skipstr(p); p = getint(p, &t.breset); 86 p = skipstr(p); p = getint(p, &t.Hor); 87 p = skipstr(p); p = getint(p, &t.Vert); 88 p = skipstr(p); p = getint(p, &t.Newline); 89 p = skipstr(p); p = getint(p, &t.Char); 90 p = skipstr(p); p = getint(p, &t.Em); 91 p = skipstr(p); p = getint(p, &t.Halfline); 92 p = skipstr(p); p = getint(p, &t.Adj); 93 p = skipstr(p); p = getstr(p, t.twinit = p); 94 p = skipstr(p); p = getstr(p, t.twrest = p); 95 p = skipstr(p); p = getstr(p, t.twnl = p); 96 p = skipstr(p); p = getstr(p, t.hlr = p); 97 p = skipstr(p); p = getstr(p, t.hlf = p); 98 p = skipstr(p); p = getstr(p, t.flr = p); 99 p = skipstr(p); p = getstr(p, t.bdon = p); 100 p = skipstr(p); p = getstr(p, t.bdoff = p); 101 p = skipstr(p); p = getstr(p, t.iton = p); 102 p = skipstr(p); p = getstr(p, t.itoff = p); 103 p = skipstr(p); p = getstr(p, t.ploton = p); 104 p = skipstr(p); p = getstr(p, t.plotoff = p); 105 p = skipstr(p); p = getstr(p, t.up = p); 106 p = skipstr(p); p = getstr(p, t.down = p); 107 p = skipstr(p); p = getstr(p, t.right = p); 108 p = skipstr(p); p = getstr(p, t.left = p); 109 p = skipstr(p); p = getstr(p, t.eject = p); 110 111 getstr(p, check); 112 if (strcmp(check, "charset") != 0) { 113 errprint("device table apparently curdled"); 114 exit(1); 115 } 116 117 for (i = 0; i < 128; i++) 118 t.width[i] = 1; /* default ascii widths */ 119 120 i = 0; 121 /* this ought to be a pointer array and in place in codestr */ 122 cp = chname + 1; /* bug if starts at 0, in setch */ 123 while (p < codestr + nread) { 124 while (*p == ' ' || *p == '\t' || *p == '\n') 125 p++; 126 chtab[i] = cp - chname; /* index, not pointer */ 127 *cp++ = *p++; /* 2-char names */ 128 *cp++ = *p++; 129 *cp++ = '\0'; 130 while (*p == ' ' || *p == '\t') 131 p++; 132 t.width[i+128] = *p++ - '0'; 133 while (*p == ' ' || *p == '\t') 134 p++; 135 t.codetab[i] = p; 136 p = getstr(p, p); /* compress string */ 137 p++; 138 i++; 139 } 140 141 sps = EM; 142 ics = EM * 2; 143 dtab = 8 * t.Em; 144 for (i = 0; i < 16; i++) 145 tabtab[i] = dtab * (i + 1); 146 pl = 11 * INCH; 147 po = PO; 148 spacesz = SS; 149 lss = lss1 = VS; 150 ll = ll1 = lt = lt1 = LL; 151 smnt = nfonts = 5; /* R I B BI S */ 152 specnames(); /* install names like "hyphen", etc. */ 153 if (eqflg) 154 t.Adj = t.Hor; 155 } 156 157 char *skipstr(s) /* skip over leading space plus string */ 158 char *s; 159 { 160 while (*s == ' ' || *s == '\t' || *s == '\n') 161 s++; 162 while (*s != ' ' && *s != '\t' && *s != '\n') 163 if (*s++ == '\\') 164 s++; 165 return s; 166 } 167 168 char *getstr(s, t) /* find next string in s, copy to t */ 169 char *s, *t; 170 { 171 int quote = 0; 172 173 while (*s == ' ' || *s == '\t' || *s == '\n') 174 s++; 175 if (*s == '"') { 176 s++; 177 quote = 1; 178 } 179 for (;;) { 180 if (quote && *s == '"') { 181 s++; 182 break; 183 } 184 if (!quote && (*s == ' ' || *s == '\t' || *s == '\n')) 185 break; 186 if (*s != '\\') 187 *t++ = *s++; 188 else { 189 s++; /* skip \\ */ 190 if (isdigit(s[0]) && isdigit(s[1]) && isdigit(s[2])) { 191 *t++ = (s[0]-'0')<<6 | (s[1]-'0')<<3 | s[2]-'0'; 192 s += 2; 193 } else if (isdigit(s[0])) { 194 *t++ = *s - '0'; 195 } else if (*s == 'b') { 196 *t++ = '\b'; 197 } else if (*s == 'n') { 198 *t++ = '\n'; 199 } else if (*s == 'r') { 200 *t++ = '\r'; 201 } else if (*s == 't') { 202 *t++ = '\t'; 203 } else { 204 *t++ = *s; 205 } 206 s++; 207 } 208 } 209 *t = '\0'; 210 return s; 211 } 212 213 char *getint(s, pn) /* find integer at s */ 214 char *s; 215 int *pn; 216 { 217 while (*s == ' ' || *s == '\t' || *s == '\n') 218 s++; 219 *pn = 0; 220 while (isdigit(*s)) 221 *pn = 10 * *pn + *s++ - '0'; 222 return s; 223 } 224 225 specnames() 226 { 227 static struct { 228 int *n; 229 char *v; 230 } spnames[] = { 231 &c_hyphen, "hy", 232 &c_emdash, "em", 233 &c_rule, "ru", 234 &c_minus, "\\-", 235 &c_fi, "fi", 236 &c_fl, "fl", 237 &c_ff, "ff", 238 &c_ffi, "Fi", 239 &c_ffl, "Fl", 240 &c_acute, "aa", 241 &c_grave, "ga", 242 &c_under, "ul", 243 &c_rooten, "rn", 244 &c_boxrule, "br", 245 &c_lefthand, "lh", 246 &c_isalnum, "__", 247 0, 0 248 }; 249 int i; 250 251 for (i = 0; spnames[i].n; i++) 252 *spnames[i].n = findch(spnames[i].v); 253 if (c_isalnum == 0) 254 c_isalnum = NROFFCHARS; 255 } 256 257 258 findch(s) /* find char s in chname */ 259 register char *s; 260 { 261 register int i; 262 263 for (i = 0; chtab[i] != 0; i++) 264 if (strcmp(s, &chname[chtab[i]]) == 0) 265 return(i + 128); 266 return(0); 267 } 268 269 twdone() 270 { 271 int waitf; 272 273 obufp = obuf; 274 oputs(t.twrest); 275 flusho(); 276 if (pipeflg) { 277 close(ptid); 278 wait(&waitf); 279 } 280 if (ttysave != -1) { 281 ttys.sg_flags = ttysave; 282 stty(1, &ttys); 283 } 284 } 285 286 287 ptout(i) 288 tchar i; 289 { 290 *olinep++ = i; 291 if (olinep >= &oline[LNSIZE]) 292 olinep--; 293 if (cbits(i) != '\n') 294 return; 295 olinep--; 296 lead += dip->blss + lss - t.Newline; 297 dip->blss = 0; 298 esct = esc = 0; 299 if (olinep > oline) { 300 move(); 301 ptout1(); 302 oputs(t.twnl); 303 } else { 304 lead += t.Newline; 305 move(); 306 } 307 lead += dip->alss; 308 dip->alss = 0; 309 olinep = oline; 310 } 311 312 313 ptout1() 314 { 315 register k; 316 register char *codep; 317 extern char *plot(); 318 int w, j, phyw; 319 tchar * q, i; 320 static int oxfont = FT; /* start off in roman */ 321 322 for (q = oline; q < olinep; q++) { 323 i = *q; 324 if (ismot(i)) { 325 j = absmot(i); 326 if (isnmot(i)) 327 j = -j; 328 if (isvmot(i)) 329 lead += j; 330 else 331 esc += j; 332 continue; 333 } 334 if ((k = cbits(i)) <= 040) { 335 switch (k) { 336 case ' ': /*space*/ 337 esc += t.Char; 338 break; 339 case '\033': 340 case '\007': 341 case '\016': 342 case '\017': 343 oput(k); 344 break; 345 } 346 continue; 347 } 348 phyw = w = t.Char * t.width[k]; 349 if (iszbit(i)) 350 w = 0; 351 if (esc || lead) 352 move(); 353 esct += w; 354 xfont = fbits(i); 355 if (xfont != oxfont) { 356 switch (oxfont) { 357 case ULFONT: oputs(t.itoff); break; 358 case BDFONT: oputs(t.bdoff); break; 359 case BIFONT: oputs(t.itoff); oputs(t.bdoff); break; 360 } 361 switch (xfont) { 362 case ULFONT: 363 if (*t.iton & 0377) oputs(t.iton); break; 364 case BDFONT: 365 if (*t.bdon & 0377) oputs(t.bdon); break; 366 case BIFONT: 367 if (*t.bdon & 0377) oputs(t.bdon); 368 if (*t.iton & 0377) oputs(t.iton); 369 break; 370 } 371 oxfont = xfont; 372 } 373 if ((xfont == ULFONT || xfont == BIFONT) && !(*t.iton & 0377)) { 374 for (j = w / t.Char; j > 0; j--) 375 oput('_'); 376 for (j = w / t.Char; j > 0; j--) 377 oput('\b'); 378 } 379 if (!(*t.bdon & 0377) && ((j = bdtab[xfont]) || xfont == BDFONT || xfont == BIFONT)) 380 j++; 381 else 382 j = 1; /* number of overstrikes for bold */ 383 if (k < 128) { /* ordinary ascii */ 384 oput(k); 385 while (--j > 0) { 386 oput('\b'); 387 oput(k); 388 } 389 } else { 390 int oj = j; 391 codep = t.codetab[k-128]; 392 while (*codep != 0) { 393 if (*codep & 0200) { 394 codep = plot(codep); 395 oput(' '); 396 } else { 397 if (*codep == '%') /* escape */ 398 codep++; 399 oput(*codep); 400 if (*codep != '\b') 401 for (j = oj; --j > 0; ) { 402 oput('\b'); 403 oput(*codep); 404 } 405 codep++; 406 } 407 } 408 } 409 if (!w) 410 for (j = phyw / t.Char; j > 0; j--) 411 oput('\b'); 412 } 413 } 414 415 416 char *plot(x) 417 char *x; 418 { 419 register int i; 420 register char *j, *k; 421 422 oputs(t.ploton); 423 k = x; 424 if ((*k & 0377) == 0200) 425 k++; 426 for (; *k; k++) { 427 if (*k == '%') { /* quote char within plot mode */ 428 oput(*++k); 429 } else if (*k & 0200) { 430 if (*k & 0100) { 431 if (*k & 040) 432 j = t.up; 433 else 434 j = t.down; 435 } else { 436 if (*k & 040) 437 j = t.left; 438 else 439 j = t.right; 440 } 441 if ((i = *k & 037) == 0) { /* 2nd 0200 turns it off */ 442 ++k; 443 break; 444 } 445 while (i--) 446 oputs(j); 447 } else 448 oput(*k); 449 } 450 oputs(t.plotoff); 451 return(k); 452 } 453 454 455 move() 456 { 457 register k; 458 register char *i, *j; 459 char *p, *q; 460 int iesct, dt; 461 462 iesct = esct; 463 if (esct += esc) 464 i = "\0"; 465 else 466 i = "\n\0"; 467 j = t.hlf; 468 p = t.right; 469 q = t.down; 470 if (lead) { 471 if (lead < 0) { 472 lead = -lead; 473 i = t.flr; 474 /* if(!esct)i = t.flr; else i = "\0";*/ 475 j = t.hlr; 476 q = t.up; 477 } 478 if (*i & 0377) { 479 k = lead / t.Newline; 480 lead = lead % t.Newline; 481 while (k--) 482 oputs(i); 483 } 484 if (*j & 0377) { 485 k = lead / t.Halfline; 486 lead = lead % t.Halfline; 487 while (k--) 488 oputs(j); 489 } else { /* no half-line forward, not at line begining */ 490 k = lead / t.Newline; 491 lead = lead % t.Newline; 492 if (k > 0) 493 esc = esct; 494 i = "\n"; 495 while (k--) 496 oputs(i); 497 } 498 } 499 if (esc) { 500 if (esc < 0) { 501 esc = -esc; 502 j = "\b"; 503 p = t.left; 504 } else { 505 j = " "; 506 if (hflg) 507 while ((dt = dtab - (iesct % dtab)) <= esc) { 508 if (dt % t.Em) 509 break; 510 oput(TAB); 511 esc -= dt; 512 iesct += dt; 513 } 514 } 515 k = esc / t.Em; 516 esc = esc % t.Em; 517 while (k--) 518 oputs(j); 519 } 520 if ((*t.ploton & 0377) && (esc || lead)) { 521 oputs(t.ploton); 522 esc /= t.Hor; 523 lead /= t.Vert; 524 while (esc--) 525 oputs(p); 526 while (lead--) 527 oputs(q); 528 oputs(t.plotoff); 529 } 530 esc = lead = 0; 531 } 532 533 534 ptlead() 535 { 536 move(); 537 } 538 539 540 dostop() 541 { 542 char junk; 543 544 flusho(); 545 read(2, &junk, 1); 546 } 547 548 549 newpage(){;} 550 pttrailer(){;} 551