home *** CD-ROM | disk | FTP | other *** search
- /*
- * plotter.c
- * output driver for HP7470A plotter
- * copyright 1986 Maple Lawn Farm, Inc.
- *
- * options:
- * -t reads points scaled to Tektronix (4096x3120)
- * -p reads xmin,ymin,xmax,ymax scaling points from input
- * -l title left-justified title
- * -c title centered title
- * -d dev specifies output device (tty00 is default)
- *
- * compile: cc -O -s -o plotter plotter.c
- */
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <termio.h>
- #include <signal.h>
-
- #define CENTER 02
- #define SCALED 04
- #define TEK 01
- #define BAUD B9600
- #define HPXON "\033.I80;;17:" /* 80 char buffer, xon char */
- #define HPXOFF "\033.N;19:" /* xoff char */
- #define HPSTAT "\033.O"
- #define HPABORT "\033.K"
- #define HPRSERR "\033.E"
- #define LOCK "/usr/spool/uucp/LCK.."
- #define USAGE "usage: %s [-tp] [-d device] [-c | -l title]\n"
- #define ERR(a,b) fprintf(stderr, "%s: ", prognm),\
- fprintf(stderr, a, b)
-
- char *title,
- *prognm,
- *plotdev = "/dev/tty00", /* default device */
- lock[sizeof(LOCK) + 5] = LOCK;
- FILE *plr,
- *plw,
- *fi = stdin;
- int hflag, /* heading flag */
- pflag, /* points, not HP-GL */
- die(), quit();
-
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int fd, hperr, alrmint();
- char buf[BUFSIZ];
-
- prognm = *argv;
- scanarg(argc, argv);
- /* check/make lock */
- do_lock();
- /* trap exits */
- signal(SIGQUIT, die);
- signal(SIGINT, die);
- signal(SIGALRM, alrmint);
- /* line OK? */
- if ((fd=open(plotdev, O_RDWR|O_NDELAY)) < 0 )
- perror(plotdev), die();
- /* set line & handshake */
- setline(fd);
- fputs(HPXON, plw);
- fputs(HPXOFF, plw);
- /* check plotter */
- alarm(5);
- do {
- hperr = readhp(HPSTAT);
- } while (hperr < 0 || hperr > 40);
- if (hperr > 8)
- ERR("not ready\n", NULL);
- alarm(0);
- /* make sure we clean up */
- signal(SIGINT, quit);
- /* initialize plotter */
- fputs("in;", plw);
- if (hflag)
- heading(title);
- /* pen 1 */
- fputs("sp1;", plw);
- /* xy points ? */
- if (pflag)
- points();
- /* HP-GL instructions */
- else
- while (fgets(buf, sizeof buf, fi) != NULL)
- fputs(buf, plw);
- /* check for errors */
- alarm(60);
- if ((hperr = readhp("OE;")))
- ERR("HP-GL error = %d\n", hperr);
- if ((hperr = readhp(HPRSERR)))
- ERR("rs232 error = %d\n", hperr);
- alarm(0);
- /* pen home, unlock */
- fputs("sp0;", plw);
- die();
- }
-
-
- heading(title)
- char *title;
- {
- int tx, ty;
- /* fix location of title */
- ty = 7350;
- tx = (hflag & CENTER) ? 5150 : 500;
- /* pen 2, char size */
- fprintf(plw, "sp2;si.30,.48;pu%d,%d;", tx, ty);
- if (hflag & CENTER)
- fprintf(plw, "cp -%d,0;", strlen(title)/2);
- fprintf(plw, "lb%s\003", title);
- }
-
-
- points()
- {
- int first=0;
- double x, y, ipx1,
- xmin = 0.0, /* default tektronix scaling */
- ymin = 0.0,
- xmax = 4096.0,
- ymax = 3120.0;
-
- /* need scaling points? */
- if (pflag & SCALED) {
- if (fscanf(fi, "%f%f%f%f",
- &xmin, &ymin, &xmax, &ymax) == EOF)
- quit();
- if (xmin >= xmax || ymin >= ymax)
- ERR("invalid scaling points", NULL), quit();
- }
- /* get aspect ratio
- * set new p1
- */
- ipx1 = 10250 - (7200 * (xmax-xmin)/(ymax-ymin));
- fprintf(plw, "ip %.f,279,10250,7479;", ipx1);
-
- /* scale to user units */
- fprintf(plw, "sc %.f,%.f,%.f,%.f;",
- xmin, xmax, ymin, ymax);
- /* read and output points */
- while (fscanf(fi, "%f%f", &x, &y) != EOF)
- fprintf(plw,(++first==1) ?\
- "pu%.4f,%.4f;pd" : "%.4f,%.4f ",x,y);
- fputs("pu;", plw);
- }
-
-
- alrmint()
- {
- ERR("no response\n", NULL);
- die();
- }
-
-
- die()
- {
- if (unlink(lock) == -1)
- perror(lock);
- exit(0);
- }
-
-
- quit()
- {
- fputs(HPABORT, plw);
- fputs(" sp0;", plw);
- die();
- }
-
-
- scanarg(argc, argv)
- int argc;
- char **argv;
- {
- extern int optind;
- extern char *optarg;
- int i;
-
- while ((i = getopt(argc, argv, "d:tpc:l:h?")) != EOF)
- switch (i) {
- case 'd' : /* device specified */
- strcpy(plotdev, optarg);
- break;
- case 'p' : /* scaling points */
- pflag |= SCALED;
- break;
- case 't' : /* tektronix points */
- pflag |= TEK;
- break;
- case 'c' : /* centered title */
- hflag |= CENTER;
- case 'l' : /* left-justified */
- hflag |= 01;
- title = optarg;
- break;
- case 'h' :
- case '?' :
- fprintf(stderr, USAGE, prognm), exit(1);
- }
- if (argc > 1 && argc != optind)
- if ((fi=fopen(argv[optind], "r")) == NULL)
- ERR("cannot find %s\n",
- argv[optind]), exit(1);
- }
-
-
- setline(fd)
- int fd;
- {
- struct termio term;
-
- ioctl(fd, TCGETA, &term);
-
- term.c_cflag &= ~CBAUD;
- term.c_cflag |= BAUD|CLOCAL;
- term.c_lflag &= ~ECHO;
- term.c_iflag |= ICRNL|IXON;
- term.c_cc[VMIN] = 1;
- term.c_cc[VTIME] = 0;
- /* drain output
- * flush input queue
- */
- ioctl(fd, TCSETAF, &term);
- if(!(plr=fopen(plotdev,"r")) || !(plw=fopen(plotdev,"w")))
- die();
- /* unbuffered output */
- setbuf(plw,0);
- }
-
-
- readhp(query)
- char *query;
- {
- int hperr;
-
- fputs(query, plw);
- if (fscanf(plr, "%d", &hperr) == EOF)
- die();
- return(hperr);
- }
-
-
- do_lock()
- {
- /* alternate lock */
- char *cu = "/usr/spool/uucp/LCK..cul ",
- dvc[5], *strchr();
- int ld;
-
- /* parse device name */
- if (strncmp(plotdev, "/dev/", 5)) {
- strcpy(dvc, plotdev);
- strcpy(plotdev, "/dev/");
- strcat(plotdev, dvc);
- }
- else
- strcpy(dvc, strchr(plotdev, 't'));
- /* setup lock file names */
- strcat(lock, dvc);
- cu[strlen(cu) -1] = dvc[strlen(dvc) -1];
- /* check for locks */
- if (!access(lock,0) || !access(cu,0))
- ERR("%s is locked\n", dvc), exit(1);
- /* create a lock */
- if ((ld = creat(lock, 0644)) < 0)
- perror(lock), exit(1);
- close(ld);
- }