1: #include <errno.h>
   2: #include <signal.h>
   3: #include <stdio.h>
   4: #include <sgtty.h>
   5: #include <pwd.h>
   6: #include <sys/vcmd.h>
   7: #include <vfont.h>
   8: 
   9: /*
  10:  * Cat Simulator for Versatec and Varian
  11:  */
  12: 
  13: int prtmode[] = {VPRINT, 0, 0};
  14: int pltmode[] = {VPLOT, 0, 0};
  15: 
  16: #define DISPATCHSIZE        256 /* must be a power of two */
  17: #define CHARMASK        (DISPATCHSIZE-1)
  18: #define NFONTS          25
  19: #define SPECIALFONT     3
  20: #define DSIZ            ((sizeof *dispatch)*DISPATCHSIZE)
  21: #define MAXF            4
  22: 
  23: #define LOCAL_RAILMAG       ".railmag"
  24: #define GLOBAL_RAILMAG      "/usr/lib/vfont/railmag"
  25: 
  26: #define CONVERT(n)      (n*(200./432.))
  27: #define RECONVERT(n)        (n*(432./200.))
  28: 
  29: #define VA_RASTER_LENGTH    2112
  30: #define VP_RASTER_LENGTH    7040
  31: #define VA_BYTES_PER_LINE   (VA_RASTER_LENGTH/8)
  32: #define VP_BYTES_PER_LINE   (VP_RASTER_LENGTH/8)
  33: #define NLINES          110
  34: #define VA_BUFFER_SIZE      (NLINES*VA_BYTES_PER_LINE)
  35: #define VP_BUFFER_SIZE      (NLINES*VP_BYTES_PER_LINE)
  36: 
  37: #define TOF_TO_BOF      83  /* lf's from top to bottom of page */
  38: #define BAN_TO_BOF      49  /* lf's from bottom of banner to bottom of page */
  39: 
  40: char    buffer[VP_BUFFER_SIZE]; /* Big line buffers  */
  41: char    *buf0p = &buffer[0];    /* Zero origin in circular buffer  */
  42: 
  43: char    *calloc();
  44: char    *nalloc();
  45: char    *allpanic();
  46: struct  passwd *getpwuid();
  47: char    chrtab[][16];
  48: 
  49: struct  header  header;
  50: struct dispatch *dispatch;
  51: 
  52: struct  fontdes {
  53:     int fnum;
  54:     int psize;
  55:     struct  dispatch *disp;
  56:     char    *bits;
  57: } fontdes[NFONTS] = {
  58:     -1,
  59:     -1
  60: };
  61: 
  62: struct point_sizes {
  63:     int stupid_code;
  64:     int real_code;
  65: } point_sizes[] = {
  66:     010, 6,
  67:     0, 7,
  68:     01, 8,
  69:     07, 9,
  70:     02, 10,
  71:     03, 11,
  72:     04, 12,
  73:     05, 14,
  74:     0211, 16,
  75:     06, 18,
  76:     0212, 20,
  77:     0213, 22,
  78:     0214, 24,
  79:     0215, 28,
  80:     0216, 36,
  81:     0, 0
  82: };
  83: 
  84: #define VA_FFLINES  2200
  85: #define VP_FFLINES  650
  86: #define VP_EOTLINES 1400
  87: #define VA_ACCTFILE "/usr/adm/vaacct"
  88: #define VP_ACCTFILE "/usr/adm/vpacct"
  89: 
  90: int lines;
  91: 
  92: int vc;     /* varian/versatec output file descriptor */
  93: int varian;     /* 0 for versatec, 1 for varian. */
  94: int BYTES_PER_LINE; /* VA_BYTES_PER_LINE or VP_BYTES_PER_LINE. */
  95: int BUFFER_SIZE;    /* VA_BUFFER_SIZE or VP_BUFFER_SIZE. */
  96: int cfnum = -1;
  97: int cpsize = 10;
  98: int cfont = 1;
  99: char    *bits;
 100: int nfontnum = -1;
 101: int fontwanted = 1;
 102: int npsize = 10;
 103: int last_ssize = 02;
 104: int xpos, ypos;
 105: int esc, lead, back, verd, mcase, railmag;
 106: double  row, col;
 107: char    *fontname[MAXF];
 108: char    fnbuf[120];
 109: char    *scanline;
 110: int linecount;
 111: 
 112: char    asctab[128] = {
 113:     '\0',   /*blank*/
 114:     'h',    /*h*/
 115:     't',    /*t*/
 116:     'n',    /*n*/
 117:     'm',    /*m*/
 118:     'l',    /*l*/
 119:     'i',    /*i*/
 120:     'z',    /*z*/
 121:     's',    /*s*/
 122:     'd',    /*d*/
 123:     'b',    /*b*/
 124:     'x',    /*x*/
 125:     'f',    /*f*/
 126:     'j',    /*j*/
 127:     'u',    /*u*/
 128:     'k',    /*k*/
 129:     '\0',   /*blank*/
 130:     'p',    /*p*/
 131:     '\06',  /*_ 3/4 em dash*/
 132:     ';',    /*;*/
 133:     '\0',   /*blank*/
 134:     'a',    /*a*/
 135:     '\05',  /*rule*/
 136:     'c',    /*c*/
 137:     '`',    /*` open*/
 138:     'e',    /*e*/
 139:     '\'',   /*' close*/
 140:     'o',    /*o*/
 141:     '\021', /*1/4*/
 142:     'r',    /*r*/
 143:     '\022', /*1/2*/
 144:     'v',    /*v*/
 145:     '-',    /*- hyphen*/
 146:     'w',    /*w*/
 147:     'q',    /*q*/
 148:     '/',    /*/*/
 149:     '.',    /*.*/
 150:     'g',    /*g*/
 151:     '\023', /*3/4*/
 152:     ',',    /*,*/
 153:     '&',    /*&*/
 154:     'y',    /*y*/
 155:     '\0',   /*blank*/
 156:     '%',    /*%*/
 157:     '\0',   /*blank*/
 158:     'Q',    /*Q*/
 159:     'T',    /*T*/
 160:     'O',    /*O*/
 161:     'H',    /*H*/
 162:     'N',    /*N*/
 163:     'M',    /*M*/
 164:     'L',    /*L*/
 165:     'R',    /*R*/
 166:     'G',    /*G*/
 167:     'I',    /*I*/
 168:     'P',    /*P*/
 169:     'C',    /*C*/
 170:     'V',    /*V*/
 171:     'E',    /*E*/
 172:     'Z',    /*Z*/
 173:     'D',    /*D*/
 174:     'B',    /*B*/
 175:     'S',    /*S*/
 176:     'Y',    /*Y*/
 177:     '\0',   /*blank*/
 178:     'F',    /*F*/
 179:     'X',    /*X*/
 180:     'A',    /*A*/
 181:     'W',    /*W*/
 182:     'J',    /*J*/
 183:     'U',    /*U*/
 184:     'K',    /*K*/
 185:     '0',    /*0*/
 186:     '1',    /*1*/
 187:     '2',    /*2*/
 188:     '3',    /*3*/
 189:     '4',    /*4*/
 190:     '5',    /*5*/
 191:     '6',    /*6*/
 192:     '7',    /*7*/
 193:     '8',    /*8*/
 194:     '9',    /*9*/
 195:     '*',    /***/
 196:     '\04',  /*minus*/
 197:     '\01',  /*fi*/
 198:     '\02',  /*fl*/
 199:     '\03',  /*ff*/
 200:     '\020', /* cent sign */
 201:     '\012', /*ffl*/
 202:     '\011', /*ffi*/
 203:     '(',    /*(*/
 204:     ')',    /*)*/
 205:     '[',    /*[*/
 206:     ']',    /*]*/
 207:     '\013', /* degree */
 208:     '\014', /* dagger */
 209:     '=',    /*=*/
 210:     '\017', /* registered */
 211:     ':',    /*:*/
 212:     '+',    /*+*/
 213:     '\0',   /*blank*/
 214:     '!',    /*!*/
 215:     '\07',  /* bullet */
 216:     '?',    /*?*/
 217:     '\015', /*foot mark*/
 218:     '|',    /*|*/
 219:     '\0',   /*blank*/
 220:     '\016', /* copyright */
 221:     '\010', /* square */
 222:     '$',    /*$*/
 223:     '\0',
 224:     '\0',
 225:     '"',    /*"*/
 226:     '#',    /*#*/
 227:     '<',    /*<*/
 228:     '>',    /*>*/
 229:     '@',    /*@*/
 230:     '\\',   /*\\*/
 231:     '^',    /*^*/
 232:     '{',    /*{*/
 233:     '}',    /*}*/
 234:     '~' /*~*/
 235: };
 236: 
 237: char spectab[128] = {
 238:     '\0',   /*blank*/
 239:     'w',    /*psi*/
 240:     'h',    /*theta*/
 241:     'm',    /*nu*/
 242:     'l',    /*mu*/
 243:     'k',    /*lambda*/
 244:     'i',    /*iota*/
 245:     'f',    /*zeta*/
 246:     'r',    /*sigma*/
 247:     'd',    /*delta*/
 248:     'b',    /*beta*/
 249:     'n',    /*xi*/
 250:     'g',    /*eta*/
 251:     'u',    /*phi*/
 252:     't',    /*upsilon*/
 253:     'j',    /*kappa*/
 254:     '\0',   /*blank*/
 255:     'p',    /*pi*/
 256:     '@',    /*at-sign*/
 257:     '7',    /*down arrow*/
 258:     '\0',   /*blank*/
 259:     'a',    /*alpha*/
 260:     '|',    /*or*/
 261:     'v',    /*chi*/
 262:     '"',    /*"*/
 263:     'e',    /*epsilon*/
 264:     '=',    /*=*/
 265:     'o',    /*omicron*/
 266:     '4',    /*left arrow*/
 267:     'q',    /*rho*/
 268:     '6',    /*up arrow*/
 269:     's',    /*tau*/
 270:     '_',    /*underrule*/
 271:     '\\',   /*\*/
 272:     'W',    /*Psi*/
 273:     '\07',  /*bell system sign*/
 274:     '\001', /*infinity*/
 275:     'c',    /*gamma*/
 276:     '\002', /*improper superset*/
 277:     '\003', /*proportional to*/
 278:     '\004', /*right hand*/
 279:     'x',    /*omega*/
 280:     '\0',   /*blank*/
 281:     '(',    /*gradient*/
 282:     '\0',   /*blank*/
 283:     'U',    /*Phi*/
 284:     'H',    /*Theta*/
 285:     'X',    /*Omega*/
 286:     '\005', /*cup (union)*/
 287:     '\006', /*root en*/
 288:     '\014', /*terminal sigma*/
 289:     'K',    /*Lambda*/
 290:     '-',    /*minus*/
 291:     'C',    /*Gamma*/
 292:     '\015', /*integral sign*/
 293:     'P',    /*Pi*/
 294:     '\032', /*subset of*/
 295:     '\033', /*superset of*/
 296:     '2',    /*approximates*/
 297:     'y',    /*partial derivative*/
 298:     'D',    /*Delta*/
 299:     '\013', /*square root*/
 300:     'R',    /*Sigma*/
 301:     '1',    /*approx =*/
 302:     '\0',   /*blank*/
 303:     '>',    /*>*/
 304:     'N',    /*Xi*/
 305:     '<',    /*<*/
 306:     '\016', /*slash (longer)*/
 307:     '\034', /*cap (intersection)*/
 308:     'T',    /*Upsilon*/
 309:     '\035', /*not*/
 310:     '\023', /*right ceiling (rt of ")*/
 311:     '\024', /*left top (of big curly)*/
 312:     '\017', /*bold vertical*/
 313:     '\030', /*left center of big curly bracket*/
 314:     '\025', /*left bottom*/
 315:     '\026', /*right top*/
 316:     '\031', /*right center of big curly bracket*/
 317:     '\027', /*right bot*/
 318:     '\021', /*right floor (rb of ")*/
 319:     '\020', /*left floor (left bot of big sq bract)*/
 320:     '\022', /*left ceiling (lt of ")*/
 321:     '*',    /*multiply*/
 322:     '/',    /*divide*/
 323:     '\010', /*plus-minus*/
 324:     '\011', /*<=*/
 325:     '\012', /*>=*/
 326:     '0',    /*identically equal*/
 327:     '3',    /*not equal*/
 328:     '{',    /*{*/
 329:     '}',    /*}*/
 330:     '\'',   /*' acute accent*/
 331:     '\`',   /*` grave accent*/
 332:     '^',    /*^*/
 333:     '#',    /*sharp*/
 334:     '\036', /*left hand*/
 335:     '\037', /*member of*/
 336:     '~',    /*~*/
 337:     'z',    /*empty set*/
 338:     '\0',   /*blank*/
 339:     'Y',    /*dbl dagger*/
 340:     'Z',    /*box rule*/
 341:     '9',    /*asterisk*/
 342:     '[',    /*improper subset*/
 343:     ']',    /*circle*/
 344:     '\0',   /*blank*/
 345:     '+',    /*eqn plus*/
 346:     '5',    /*right arrow*/
 347:     '8' /*section mark*/
 348: };
 349: 
 350: 
 351: onintr()
 352: {
 353:     signal(SIGINT, SIG_IGN);
 354:     signal(SIGHUP, SIG_IGN);
 355:     signal(SIGTERM, SIG_IGN);
 356:     exit(1);
 357: }
 358: 
 359: main(argc, argv)
 360:     int argc;
 361:     char *argv[];
 362: {
 363:     register int wait = 0;
 364:     char *banarg;
 365: 
 366:     if (signal(SIGINT, SIG_IGN) == SIG_DFL) {
 367:         signal(SIGPIPE, SIG_IGN);
 368:         signal(SIGINT, onintr);
 369:         signal(SIGHUP, onintr);
 370:     } else
 371:         signal(SIGHUP, SIG_IGN);
 372:     if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
 373:         signal(SIGTERM, onintr);
 374:     argc--, argv++;
 375: 
 376:     varian = 1;     /* Assume varian unless -W. */
 377:     banarg = NULL;
 378:     BYTES_PER_LINE = VA_BYTES_PER_LINE;
 379:     BUFFER_SIZE = VA_BUFFER_SIZE;
 380: 
 381:     while (argc > 0 && argv[0][0] == '-') {
 382:         switch (argv[0][1]) {
 383: 
 384:         case 'W':       /* Wide: the versatec. */
 385:             varian = 0;
 386:             BYTES_PER_LINE = VP_BYTES_PER_LINE;
 387:             BUFFER_SIZE = VP_BUFFER_SIZE;
 388:             break;
 389: 
 390:         case 't':
 391:             vc = 1;
 392:             break;
 393: 
 394:         case 'w':
 395:             wait = 1;
 396:             break;
 397: 
 398:         case '3':
 399:             vc = 3;     /* from vpd */
 400:             break;
 401: 
 402:         case 'b':
 403:             if (argc != 1) {
 404:                 banarg = argv[1];
 405:                 argc--, argv++;
 406:             }
 407:             break;
 408: 
 409:         default:
 410:             fprintf(stderr, "usage: vcat  [ -W ] [ -t ] [ -w ] [ -b banner ] [ file... ]\n");
 411:             exit(1);
 412:         }
 413:         argc--, argv++;
 414:     }
 415:     if (vc == 0) {
 416:         /* directly to plotter */
 417:         for (;;) {
 418:             extern int errno;
 419: 
 420:             if ((vc = open((varian ? "/dev/va0" : "/dev/vp0"), 1)) >= 0)
 421:                 break;
 422:             if (!wait)
 423:                 break;
 424:             if (errno != EIO && errno != ENXIO)
 425:                 break;
 426:             sleep(10);
 427:         }
 428: 
 429: /* * This should be handled by daemon.
 430: 		if (vc < 0) {
 431: 			fprintf(stderr, varian ? "Varian " : "Versatec ");
 432: 			if (errno == EIO)
 433: 				fprintf(stderr, "off line\n");
 434: 			else if (errno == ENXIO)
 435: 				fprintf(stderr, "in use\n");
 436: 			else
 437: 				fprintf(stderr, "not available\n");
 438: 			exit(1);
 439: 		}
 440: */
 441:     }
 442:     ioctl(vc, VSETSTATE, prtmode);
 443:     banner(banarg);
 444:     ioctl(vc, VSETSTATE, pltmode);
 445:     readrm();
 446:     for (;;) {
 447:         if (argc > 0) {
 448:             if (freopen(argv[0], "r", stdin) == NULL) {
 449:                 perror(argv[0]);
 450:                 argc--, argv++;
 451:                 continue;
 452:             }
 453:             argc--, argv++;
 454:         }
 455:         ofile();
 456:         if (argc <= 0)
 457:             break;
 458:         ioctl(vc, VSETSTATE, prtmode);
 459:         if (varian) {
 460:             write(vc, "\014\0", 2);
 461:             newlines(TOF_TO_BOF);
 462:         } else
 463:             write (vc, "\n\n\n\n\n", 5);
 464:         ioctl(vc, VSETSTATE, pltmode);
 465:     }
 466:     ioctl(vc, VSETSTATE, prtmode);
 467:     account(banarg);
 468:     exit(0);
 469: }
 470: 
 471: readrm()
 472: {
 473:     register int i;
 474:     register char *cp;
 475:     register int rmfd;
 476:     char c;
 477: 
 478:     if ((rmfd = open(LOCAL_RAILMAG, 0)) < 0)
 479:         if ((rmfd = open(GLOBAL_RAILMAG, 0)) < 0) {
 480:             fprintf(stderr, "No railmag file\n");
 481:             exit(1);
 482:         }
 483:     cp = fnbuf;
 484:     for (i = 0; i < 4; i++) {
 485:         fontname[i] = cp;
 486:         while (read(rmfd, &c, 1) == 1 && c != '\n')
 487:             *cp++ = c;
 488:         *cp++ = '\0';
 489:     }
 490:     close(rmfd);
 491: }
 492: 
 493: ofile()
 494: {
 495:     register int c;
 496:     double scol;
 497:     static int initialized;
 498: 
 499:     lines = 0;
 500:     while ((c = getchar()) != EOF) {
 501:         if (!c)
 502:             continue;
 503:         if (c & 0200) {
 504:             esc += (~c) & 0177;
 505:             continue;
 506:         }
 507:         if (esc) {
 508:             if (back)
 509:                 esc = -esc;
 510:             col += esc;
 511:             ypos = CONVERT(col);
 512:             esc = 0;
 513:         }
 514:         if ((c & 0377) < 0100)  /*  Purely for efficiency  */
 515:             goto normal_char;
 516:         switch (c) {
 517: 
 518:         case 0100:
 519:             if (initialized)
 520:                 goto out;
 521:             initialized = 1;
 522:             row = 25;
 523:             xpos = CONVERT(row);
 524:             for (c = 0; c < BUFFER_SIZE; c++)
 525:                 buffer[c] = 0;
 526:             col = 0;
 527:             esc = 0;
 528:             lead = 0;
 529:             ypos = 0;
 530:             linecount = 0;
 531:             verd = 0;
 532:             back = 0;
 533:             mcase = 0;
 534:             railmag = 0;
 535:             if (loadfont(railmag, cpsize) < 0)
 536:                 fprintf(stderr, "Can't load inital font\n");
 537:             break;
 538: 
 539:         case 0101:  /* lower rail */
 540:             crail(railmag &= ~01);
 541:             break;
 542: 
 543:         case 0102:  /* upper rail */
 544:             crail(railmag |= 01);
 545:             break;
 546: 
 547:         case 0103:  /* upper mag */
 548:             crail(railmag |= 02);
 549:             break;
 550: 
 551:         case 0104:  /* lower mag */
 552:             crail(railmag &= ~02);
 553:             break;
 554: 
 555:         case 0105:  /* lower case */
 556:             mcase = 0;
 557:             break;
 558: 
 559:         case 0106:  /* upper case */
 560:             mcase = 0100;
 561:             break;
 562: 
 563:         case 0107:  /* escape forward */
 564:             back = 0;
 565:             break;
 566: 
 567:         case 0110:  /* escape backwards */
 568:             back = 1;
 569:             break;
 570: 
 571:         case 0111:  /* stop */
 572:             break;
 573: 
 574:         case 0112:  /* lead forward */
 575:             verd = 0;
 576:             break;
 577: 
 578:         case 0113:  /* undefined */
 579:             break;
 580: 
 581:         case 0114:  /* lead backward */
 582:             verd = 1;
 583:             break;
 584: 
 585:         case 0115:  /* undefined */
 586:         case 0116:
 587:         case 0117:
 588:             break;
 589: 
 590:         default:
 591:             if ((c & 0340) == 0140) /* leading */ {
 592:                 lead = (~c) & 037;
 593:                 if (verd)
 594:                     lead = -lead;
 595:                 row += lead*3;  /*  Lead is 3 units  */
 596:                 c = CONVERT(row);
 597:                 while (c >= NLINES) {
 598:                     slop_lines(15);
 599:                     c = CONVERT(row);
 600:                 }
 601:                 xpos = c;
 602:                 continue;
 603:             }
 604:             if ((c & 0360) == 0120) /* size change */ {
 605:                 loadfont(railmag, findsize(c & 017));
 606:                 continue;
 607:             }
 608:             if (c & 0300)
 609:                 continue;
 610: 
 611: normal_char:
 612:             c = (c & 077) | mcase;
 613:             outc(c);
 614:         }
 615:     }
 616: out:
 617:     slop_lines(NLINES);
 618: }
 619: 
 620: findsize(code)
 621:     register int code;
 622: {
 623:     register struct point_sizes *psp;
 624: 
 625:     psp = point_sizes;
 626:     while (psp->real_code != 0) {
 627:         if ((psp->stupid_code & 017) == code)
 628:             break;
 629:         psp++;
 630:     }
 631:     code = 0;
 632:     if (!(last_ssize & 0200) && (psp->stupid_code & 0200))
 633:         code = -55;
 634:     else if ((last_ssize & 0200) && !(psp->stupid_code & 0200))
 635:         code = 55;
 636:     if (back)
 637:         code = -code;
 638:     esc += code;
 639:     last_ssize = psp->stupid_code;
 640:     return (psp->real_code);
 641: }
 642: 
 643: account(who)
 644: char *who;
 645: {
 646:     register FILE *a;
 647: 
 648:     if (who == NULL)
 649:         return;
 650:     a = fopen(varian ? VA_ACCTFILE : VP_ACCTFILE, "a");
 651:     if (a == NULL)
 652:         return;
 653:     /* Varian accounting is done by 11 inch pages;
 654: 	   Versatec accounting is by the (12 inch) foot.
 655: 	 */
 656:     fprintf(a, "t%6.2f\t%s\n",
 657:            (lines / 200.0) / (varian ? 11.0 : 12.0), who);
 658:     fclose(a);
 659: }
 660: 
 661: crail(nrail)
 662:     register int nrail;
 663: {
 664:     register int psize;
 665: 
 666:     psize = cpsize;
 667:     if (fontwanted && psize != npsize)
 668:         psize = npsize;
 669:     loadfont(nrail, psize);
 670: }
 671: 
 672: 
 673: loadfont(fnum, size)
 674:     register int fnum;
 675:     register int size;
 676:     {
 677:     register int i;
 678:     char cbuf[80];
 679: 
 680:     fontwanted = 0;
 681:     if (fnum == cfnum && size == cpsize)
 682:         return(0);
 683:     for (i = 0; i < NFONTS; i++)
 684:         if (fontdes[i].fnum == fnum && fontdes[i].psize == size) {
 685:             cfnum = fontdes[i].fnum;
 686:             cpsize = fontdes[i].psize;
 687:             dispatch = &fontdes[i].disp[0];
 688:             bits = fontdes[i].bits;
 689:             cfont = i;
 690:             return (0);
 691:         }
 692:     if (fnum < 0 || fnum >= MAXF) {
 693:         fprintf(stderr, "Internal error: illegal font\n");
 694:         return(-1);
 695:     }
 696:     nfontnum = fnum;
 697:     npsize = size;
 698:     fontwanted++;
 699:     return (0);
 700: }
 701: 
 702: 
 703: getfont()
 704: {
 705:     register int fnum, size, font;
 706:     int d;
 707:     char cbuf[BUFSIZ];
 708: 
 709:     if (!fontwanted)
 710:         return(0);
 711:     fnum = nfontnum;
 712:     size = npsize;
 713:     sprintf(cbuf, "%s.%d", fontname[fnum], size);
 714:     font = open(cbuf, 0);
 715:     if (font == -1) {
 716:         perror(cbuf);
 717:         fontwanted = 0;
 718:         return (-1);
 719:     }
 720:     if (read(font, &header, sizeof header)!=sizeof header || header.magic!=0436)
 721:         fprintf(stderr, "%s: Bad font file", cbuf);
 722:     else {
 723:         cfont = relfont();
 724:         if (((bits=nalloc(header.size+DSIZ+1,1))== NULL)
 725:             && ((bits=allpanic(header.size+DSIZ+1))== NULL)) {
 726:                 fprintf(stderr, "%s: ran out of memory\n", cbuf);
 727:                 exit(1);
 728:         } else {
 729:             /*
 730: 			 * have allocated one chunk of mem for font, dispatch.
 731: 			 * get the dispatch addr, align to word boundary.
 732: 			 */
 733:             d = (int) bits+header.size;
 734:             d += 1;
 735:             d &= ~1;
 736:             if (read(font, d, DSIZ)!=DSIZ
 737:               || read(font, bits, header.size)!=header.size)
 738:                 fprintf(stderr, "bad font header");
 739:             else {
 740:                 close(font);
 741:                 cfnum = fontdes[cfont].fnum = fnum;
 742:                 cpsize = fontdes[cfont].psize = size;
 743:                 fontdes[cfont].bits = bits;
 744:                 fontdes[cfont].disp = (struct dispatch *) d;
 745:                 dispatch = &fontdes[cfont].disp[0];
 746:                 fontwanted = 0;
 747:                 return (0);
 748:             }
 749:         }
 750:     }
 751:     close(font);
 752:     fontwanted = 0;
 753:     return(-1);
 754: }
 755: 
 756: int lastloaded  = -1;
 757: 
 758: relfont()
 759: {
 760:     register int newfont;
 761: 
 762:     newfont = lastloaded;
 763:     /*
 764: 	 * optimization for special font.  since we think that usually
 765: 	 * there is only one character at a time from any special math
 766: 	 * font, make it the candidate for removal.
 767: 	 */
 768:     if (fontdes[cfont].fnum != SPECIALFONT || fontdes[cfont].bits==0)
 769:         if (++newfont>=NFONTS)
 770:             newfont = 0;
 771:     lastloaded = newfont;
 772:     if ((int)fontdes[newfont].bits != -1 && fontdes[newfont].bits != 0) {
 773:         /* fprintf(stderr, "freeing position %d\n", newfont); */
 774:         nfree(fontdes[newfont].bits);
 775:     } else
 776:         /* fprintf(stderr, "taking without freeing position %d\n", newfont); */
 777:         ;
 778:     fontdes[newfont].bits = 0;
 779:     return (newfont);
 780: }
 781: 
 782: char *
 783: allpanic(nbytes)
 784:     int nbytes;
 785: {
 786:     register int i;
 787: 
 788:     for (i = 0; i <= NFONTS; i++)
 789:         if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0)
 790:             nfree(fontdes[i].bits);
 791:     lastloaded = cfont;
 792:     for (i = 0; i <= NFONTS; i++) {
 793:         fontdes[i].fnum = fontdes[i].psize = -1;
 794:         fontdes[i].bits = 0;
 795:         cfnum = cpsize = -1;
 796:     }
 797:     return(nalloc(nbytes,1));
 798: }
 799: 
 800: int M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
 801:         0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
 802: int N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
 803:         0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
 804: int strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
 805: 
 806: outc(code)
 807:     int code;
 808: {
 809:     char c;             /* character to print */
 810:     register struct dispatch *d;    /* ptr to character font record */
 811:     register char *addr;        /* addr of font data */
 812:     int llen;           /* length of each font line */
 813:     int nlines;         /* number of font lines */
 814:     register char *scanp;       /* ptr to output buffer */
 815:     int scanp_inc;          /* increment to start of next buffer */
 816:     int offset;         /* bit offset to start of font data */
 817:     int i;              /* loop counter */
 818:     register int count;     /* font data ptr */
 819:     register unsigned fontdata; /* font data temporary */
 820:     register int off8;      /* offset + 8 */
 821: 
 822:     if (fontwanted)
 823:         getfont();
 824:     if (railmag == SPECIALFONT) {
 825:         if ((c = spectab[code]) < 0)
 826:             return(0);
 827:     } else if ((c = asctab[code]) < 0)
 828:         return(0);
 829:     d = dispatch+c;
 830:     if (d->nbytes) {
 831:         addr = bits+d->addr;
 832:         llen = (d->left+d->right+7)/8;
 833:         nlines = d->up+d->down;
 834:         if (xpos+d->down >= NLINES)
 835:             slop_lines(xpos+d->down-NLINES+1);
 836:         scanp = ((xpos-d->up-1)*BYTES_PER_LINE+(ypos-d->left)/8)+buf0p;
 837:         if (scanp < &buffer[0])
 838:             scanp += BUFFER_SIZE;
 839:         scanp_inc = BYTES_PER_LINE-llen;
 840:         offset = -((ypos-d->left)&07);
 841:         off8 = offset+8;
 842:         for (i = 0; i < nlines; i++) {
 843:             if (scanp >= &buffer[BUFFER_SIZE])
 844:                 scanp -= BUFFER_SIZE;
 845:             count = llen;
 846:             if (scanp + count <= &buffer[BUFFER_SIZE])
 847:                 do {
 848:                     fontdata = *(unsigned *)addr;
 849:                     addr += 4;
 850:                     if (count < 4)
 851:                         fontdata &= ~strim[count];
 852:                     *(unsigned *)scanp |= (fontdata << offset) &~ M[off8];
 853:                     scanp++;
 854:                     *(unsigned *)scanp |= (fontdata << off8) &~ N[off8];
 855:                     scanp += 3;
 856:                     count -= 4;
 857:                 } while (count > 0);
 858:             scanp += scanp_inc+count;
 859:             addr += count;
 860:         }
 861:         return (1);
 862:     }
 863:     return (0);
 864: }
 865: 
 866: slop_lines(nlines)
 867:     int nlines;
 868: {
 869:     register int i, rlines;
 870: 
 871:     lines += nlines;
 872:     rlines = (&buffer[BUFFER_SIZE] - buf0p) / BYTES_PER_LINE;
 873:     if (rlines < nlines) {
 874:         if (write(vc, buf0p, BYTES_PER_LINE * rlines) < 0)
 875:             exit(1);
 876:         clear(buf0p, rlines * BYTES_PER_LINE);
 877:         buf0p = buffer;
 878:         nlines -= rlines;
 879:         xpos -= rlines;
 880:         row -= RECONVERT(rlines);
 881:     }
 882:     if (write(vc, buf0p, BYTES_PER_LINE * nlines) < 0)
 883:         exit(1);
 884:     clear(buf0p, BYTES_PER_LINE * nlines);
 885:     buf0p += BYTES_PER_LINE * nlines;
 886:     if (buf0p >= &buffer[BUFFER_SIZE])
 887:         buf0p -= BUFFER_SIZE;
 888:     xpos -= nlines;
 889:     row -= RECONVERT(nlines);
 890:     /* ioctl(vc, VSETSTATE, pltmode);  WHY? */
 891: }
 892: 
 893: /*ARGSUSED*/
 894: clear(lp, nbytes)
 895:     int *lp;
 896:     int nbytes;
 897: {
 898: 
 899:     asm("movc5 $0,(sp),$0,8(ap),*4(ap)");
 900: 
 901: }
 902: 
 903: char *
 904: nalloc(i, j)
 905:     int i, j;
 906: {
 907:     register char *cp;
 908: 
 909:     cp = calloc(i, j);
 910:     /* fprintf(stderr, "allocated %d bytes at %x\n", i * j, cp); */
 911:     return(cp);
 912: }
 913: 
 914: nfree(cp)
 915:     char *cp;
 916: {
 917: 
 918:     /* fprintf(stderr, "freeing at %x\n", cp); */
 919:     free(cp);
 920: }
 921: 
 922: banner(s)
 923: char *s;
 924: {
 925:     long timeb;
 926:     register char *sp;
 927:     int i, j, t;
 928: 
 929:     if (!varian) {      /* Versatec uses just a small banner. */
 930:         if (s == NULL)  /* No banner, just return. */
 931:             return;
 932:         write(vc, s, strlen(s));
 933:         write(vc, " ", 1);
 934:         time(&timeb);
 935:         write(vc, ctime(&timeb), 26);
 936:         return;
 937:     }
 938: 
 939:     write(vc, "\014\0", 2);
 940:     if (s == NULL) {
 941:         /* Do enough newlines to get exactly to the perforation. */
 942:         newlines(TOF_TO_BOF);
 943:         return;
 944:     }
 945:     newlines(8);
 946:     for (i=0; i<16; i++)
 947:     {
 948:         write(vc, "               ", 16);
 949:         for (sp=s; *sp; sp++)
 950:         {
 951:             char obuf[10];
 952:             char *cp = obuf;
 953: 
 954:             if (*sp<=' '|| *sp >'}')
 955:                 continue;
 956:             *cp++ = ' ', *cp++ = ' ';
 957:             t = chrtab[*sp - ' '][i];
 958:             for (j=7; j>=0; j--)
 959:                 if ((t>>j) & 01)
 960:                     *cp++ = 'X';
 961:                 else
 962:                     *cp++ = ' ';
 963:             write(vc, obuf, 10);
 964:         }
 965:         write (vc, " \n", 2);
 966:     }
 967:     newlines(8);
 968:     write(vc, "                ", 16);
 969:     time(&timeb);
 970:     write(vc, ctime(&timeb), 26);
 971:     newlines(BAN_TO_BOF);
 972: }
 973: 
 974: newlines(count)
 975: int count;
 976: {
 977:     char buf[100];
 978:     register int i;
 979: 
 980:     for (i = 0; i < count; i++)
 981:         buf[i] = '\n';
 982:     buf[i] = '\0';
 983:     write(vc, buf, i+1);
 984: }

Defined functions

account defined in line 643; used 1 times
allpanic defined in line 782; used 2 times
banner defined in line 922; used 1 times
clear defined in line 894; used 2 times
crail defined in line 661; used 4 times
findsize defined in line 620; used 1 times
getfont defined in line 703; used 1 times
loadfont defined in line 673; used 3 times
main defined in line 359; never used
nalloc defined in line 903; used 3 times
newlines defined in line 974; used 5 times
nfree defined in line 914; used 2 times
ofile defined in line 493; used 1 times
onintr defined in line 351; used 3 times
outc defined in line 806; used 1 times
readrm defined in line 471; used 1 times
relfont defined in line 758; used 1 times
slop_lines defined in line 866; used 3 times

Defined variables

BUFFER_SIZE defined in line 95; used 10 times
BYTES_PER_LINE defined in line 94; used 10 times
M defined in line 800; used 1 times
N defined in line 802; used 1 times
asctab defined in line 112; used 1 times
back defined in line 105; used 5 times
bits defined in line 99; used 19 times
buf0p defined in line 41; used 10 times
buffer defined in line 40; used 8 times
cfnum defined in line 96; used 4 times
cfont defined in line 98; used 10 times
chrtab defined in line 47; used 1 times
col defined in line 106; used 3 times
cpsize defined in line 97; used 6 times
dispatch defined in line 50; used 4 times
esc defined in line 105; used 8 times
fnbuf defined in line 108; used 1 times
fontdes defined in line 57; used 23 times
fontname defined in line 107; used 2 times
fontwanted defined in line 101; used 8 times
header defined in line 49; used 9 times
last_ssize defined in line 103; used 3 times
lastloaded defined in line 756; used 3 times
lead defined in line 105; used 5 times
linecount defined in line 110; used 1 times
lines defined in line 90; used 3 times
mcase defined in line 105; used 4 times
nfontnum defined in line 100; used 2 times
npsize defined in line 102; used 4 times
pltmode defined in line 14; used 2 times
point_sizes defined in line 65; used 1 times
prtmode defined in line 13; used 3 times
railmag defined in line 105; used 8 times
row defined in line 106; used 7 times
scanline defined in line 109; never used
spectab defined in line 237; used 1 times
strim defined in line 804; used 1 times
varian defined in line 93; used 7 times
vc defined in line 92; used 23 times
verd defined in line 105; used 4 times
xpos defined in line 104; used 7 times
ypos defined in line 104; used 4 times

Defined struct's

fontdes defined in line 52; never used
point_sizes defined in line 62; used 2 times
  • in line 623(2)

Defined macros

BAN_TO_BOF defined in line 38; used 1 times
CHARMASK defined in line 17; never used
CONVERT defined in line 26; used 4 times
DISPATCHSIZE defined in line 16; used 2 times
DSIZ defined in line 20; used 4 times
GLOBAL_RAILMAG defined in line 24; used 1 times
LOCAL_RAILMAG defined in line 23; used 1 times
MAXF defined in line 21; used 2 times
NFONTS defined in line 18; used 5 times
NLINES defined in line 33; used 6 times
RECONVERT defined in line 27; used 2 times
SPECIALFONT defined in line 19; used 2 times
TOF_TO_BOF defined in line 37; used 2 times
VA_ACCTFILE defined in line 87; used 1 times
VA_BUFFER_SIZE defined in line 34; used 1 times
VA_BYTES_PER_LINE defined in line 31; used 2 times
VA_FFLINES defined in line 84; never used
VA_RASTER_LENGTH defined in line 29; used 1 times
  • in line 31
VP_ACCTFILE defined in line 88; used 1 times
VP_BUFFER_SIZE defined in line 35; used 2 times
VP_BYTES_PER_LINE defined in line 32; used 2 times
VP_EOTLINES defined in line 86; never used
VP_FFLINES defined in line 85; never used
VP_RASTER_LENGTH defined in line 30; used 1 times
  • in line 32
Last modified: 1982-08-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3143
Valid CSS Valid XHTML 1.0 Strict