1 /*
2 Copyright (c) 1991 - 1994 Heinz W. Werntges. All rights reserved.
3 Distributed by Free Software Foundation, Inc.
4
5 This file is part of HP2xx.
6
7 HP2xx is distributed in the hope that it will be useful, but
8 WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
9 to anyone for the consequences of using it or for whether it serves any
10 particular purpose or works at all, unless he says so in writing. Refer
11 to the GNU General Public License, Version 2 or later, for full details.
12
13 Everyone is granted permission to copy, modify and redistribute
14 HP2xx, but only under the conditions described in the GNU General Public
15 License. A copy of this license is supposed to have been
16 given to you along with HP2xx so you can know your rights and
17 responsibilities. It should be in a file named COPYING. Among other
18 things, the copyright notice and this notice must be preserved on all
19 copies.
20
21 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22 */
23
24 /** std_main.c: Traditional user interface for hp2xx
25 **
26 ** 94/02/14 V 1.00 HWW Derived from hp2xx.c
27 **/
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <string.h>
33 #ifdef WIN32
34 #include <fcntl.h>
35 #include <io.h>
36 #endif /* WIN32 */
37 #include "bresnham.h"
38 #include "pendef.h"
39 #include "hp2xx.h"
40 #include "getopt.h"
41
42
43 extern mode_list ModeList[];
44
45 static short Logfile_flag = FALSE;
46
47
48
49
Eprintf(const char * fmt,...)50 void Eprintf(const char *fmt, ...)
51 {
52 va_list ap;
53
54 va_start(ap, fmt);
55 vfprintf(stderr, fmt, ap);
56 va_end(ap);
57 }
58
59
60
PError(const char * msg)61 void PError(const char *msg)
62 {
63 perror(msg);
64 }
65
66
67
68
SilentWait(void)69 void SilentWait(void)
70 {
71 char dummy[80];
72 #ifdef UNIX
73 FILE *tty;
74 #endif
75 /**
76 ** Get anything typed including '\n' if stderr does NOT go to a file
77 ** or else the user may be invisibly prompted.
78 **
79 ** According to a suggestion from A. Bagge, in UNIX pipe mode stdin
80 ** will be replaced by /dev/tty.
81 **/
82 if (!Logfile_flag) {
83 #ifdef UNIX
84 if ((tty = fopen("/dev/tty", "r")) != NULL) {
85 (void) fgets(dummy, 80, tty);
86 fclose(tty);
87 } else
88 #endif
89 (void) fgets(dummy, 80, stdin);
90 }
91 }
92
93
94
95
NormalWait(void)96 void NormalWait(void)
97 {
98 #ifdef UNIX
99 if (getenv("TERM") == (char *) NULL)
100 return;
101 #endif
102 Eprintf("\nPress <Return> to continue ...\n");
103 SilentWait();
104 }
105
106
107
108
action_oldstyle(GEN_PAR * pg,IN_PAR * pi,OUT_PAR * po)109 void action_oldstyle(GEN_PAR * pg, IN_PAR * pi, OUT_PAR * po)
110 {
111 int err;
112 char savedname[100];
113 /*int counter=-1;*/
114 char thepage[4];
115
116
117 if (!pg->quiet)
118 Send_version();
119
120 strcpy(savedname, po->outfile);
121 for (;;) {
122 /**
123 ** Phase 1: HP-GL --> TMP file data
124 **/
125 err = HPGL_to_TMP(pg, pi);
126 if (err) {
127 /* po->outfile=realloc(po->outfile,2*sizeof(char));*/
128 strcpy(po->outfile, "");
129 cleanup_i(pi);
130 cleanup_g(pg);
131 cleanup_o(po);
132 return;
133 }
134 if (strcmp(pg->mode, "pre")) {
135 po->pagecount++;
136 if (po->outfile != "-" && po->pagecount > 0) {
137 sprintf(thepage, "%d", po->pagecount);
138 strcpy(po->outfile, savedname);
139 if (strstr(po->outfile, pg->mode))
140 strcpy(strstr
141 (po->outfile, pg->mode),
142 thepage);
143 else
144 strcat(po->outfile, thepage);
145 strcat(po->outfile, ".");
146 strcat(po->outfile, pg->mode);
147 }
148 }
149 /**
150 ** Phase 2: TMP file re-scaling
151 **/
152 adjust_input_transform(pg, pi, po);
153
154 /**
155 ** Phase 3: (a) TMP file --> Vector formats
156 **/
157 err = TMP_to_VEC(pg, po);
158 if (err == 0)
159 continue;
160 if (err == ERROR) {
161 cleanup(pg, pi, po);
162 return;
163 }
164
165 /**
166 ** Phase 3: (b) TMP file --> Raster image
167 **/
168 if (TMP_to_BUF(pg, po)) {
169 cleanup(pg, pi, po);
170 return;
171 }
172
173 /**
174 ** Phase 3: (c) Raster image --> output formats
175 **/
176 err = BUF_to_RAS(pg, po);
177
178 if (err == 1)
179 Eprintf("%s: Not implemented!\n", pg->mode);
180 cleanup_g(pg);
181 cleanup_o(po);
182 }
183
184 }
185
186
187 static void
process_opts(int argc,char * argv[],const char * shortopts,struct option longopts[],GEN_PAR * pg,IN_PAR * pi,OUT_PAR * po)188 process_opts(int argc, char *argv[],
189 const char *shortopts, struct option longopts[],
190 GEN_PAR * pg, IN_PAR * pi, OUT_PAR * po)
191 {
192 int c, i, j, longind;
193 char *p, cdummy;
194
195 while ((c =
196 getopt_long(argc, argv, shortopts, longopts,
197 &longind)) != EOF)
198 switch (c) { /* Easy addition of options ... */
199 case 'a':
200 pi->aspectfactor = atof(optarg);
201 if (pi->aspectfactor <= 0.0) {
202 Eprintf("Aspect factor: %g illegal\n",
203 pi->aspectfactor);
204 exit(ERROR);
205 }
206 break;
207
208 case 'c':
209 i = (int) strlen(optarg);
210 if ((i < 1) || (i > 8)) {
211 Eprintf("Invalid pencolor string: %s\n",
212 optarg);
213 exit(ERROR);
214 }
215 for (j = 1, p = optarg; j <= i; j++, p++) {
216 switch (*p - '0') {
217 case xxBackground:
218 pt.color[j] = xxBackground;
219 break;
220 case xxForeground:
221 pt.color[j] = xxForeground;
222 break;
223 case xxRed:
224 pt.color[j] = xxRed;
225 break;
226 case xxGreen:
227 pt.color[j] = xxGreen;
228 break;
229 case xxBlue:
230 pt.color[j] = xxBlue;
231 break;
232 case xxCyan:
233 pt.color[j] = xxCyan;
234 break;
235 case xxMagenta:
236 pt.color[j] = xxMagenta;
237 break;
238 case xxYellow:
239 pt.color[j] = xxYellow;
240 break;
241 default:
242 Eprintf
243 ("Invalid color of pen %d: %c\n",
244 j, *p);
245 exit(ERROR);
246 }
247 if (pt.color[j] != xxBackground &&
248 pt.color[j] != xxForeground)
249 pg->is_color = TRUE;
250 }
251 pi->hwcolor = TRUE;
252 break;
253
254 case 'C':
255 pi->center_mode = TRUE;
256 break;
257
258 case 'd':
259 switch (po->dpi_x = atoi(optarg)) {
260 case 75:
261 break;
262 case 100:
263 case 150:
264 case 300:
265 case 600:
266 if ((!pg->quiet)
267 && (strcmp(pg->mode, "pcl") == 0)
268 && po->specials == 0)
269 Eprintf
270 ("Warning: DPI setting is no PCL level 3 feature!\n");
271 break;
272 default:
273 if ((!pg->quiet)
274 && (strcmp(pg->mode, "pcl") == 0))
275 Eprintf
276 ("Warning: DPI value %d is invalid for PCL mode\n",
277 po->dpi_x);
278 break;
279 }
280 break;
281
282 case 'D':
283 po->dpi_y = atoi(optarg);
284 if ((!pg->quiet) && strcmp(pg->mode, "pcl") == 0
285 && po->specials == 0)
286 Eprintf("Warning: %s\n",
287 "Different DPI for x & y is invalid for PCL mode");
288 break;
289
290 case 'e':
291 pg->extraclip = atoi(optarg);
292 break;
293
294 case 'F':
295 po->formfeed = TRUE;
296 break;
297
298 case 'f':
299 po->outfile = optarg;
300 break;
301
302 case 'h':
303 if (!strncmp(optarg, "elp", 3)) {
304 usage_msg(pg, pi, po);
305 exit(ERROR);
306 }
307 pi->height = atof(optarg);
308 if (pi->height < 0.1)
309 Eprintf("Warning: Small height: %g mm\n",
310 pi->height);
311 if (pi->height > 300.0)
312 Eprintf("Warning: Huge height: %g mm\n",
313 pi->height);
314 break;
315
316 case 'i':
317 po->init_p = TRUE;
318 break;
319
320 case 'I':
321 po->init_p = TRUE;
322 po->init_p3gui = TRUE;
323 break;
324
325 case 'l':
326 pg->logfile = optarg;
327 if (freopen(pg->logfile, "w", stderr) == NULL) {
328 PError("Cannot open log file");
329 Eprintf("Error redirecting stderr\n");
330 Eprintf
331 ("Continuing with output to stderr\n");
332 } else
333 Logfile_flag = TRUE;
334 break;
335 /*MJR These are NOT sanity checked, GIGO*/
336 case 'z':
337 po->zengage = atof(optarg);
338 break;
339 case 'Z':
340 po->zretract = atof(optarg);
341 break;
342
343 case 'M':
344 pg->mapzero = atof(optarg);
345 if (pg->mapzero < 0 || pg->mapzero > 255)
346 pg->mapzero = -1;
347 break;
348
349 case 'm':
350 pg->mode = optarg;
351 for (i = 0; ModeList[i].mode != XX_TERM; i++)
352 if (strcmp(ModeList[i].modestr, pg->mode)
353 == 0)
354 break;
355 if (ModeList[i].mode == XX_TERM) {
356 Eprintf("'%s': unknown mode!\n", pg->mode);
357 Eprintf("Supported are:\n\t");
358 print_supported_modes();
359 Send_Copyright();
360 }
361 break;
362
363 case 'n':
364 pg->nofill = TRUE;
365 break;
366
367 case 'N':
368 pg->no_ps = TRUE;
369 break;
370
371 case 'o':
372 pi->xoff = atof(optarg);
373 break;
374
375 case 'O':
376 pi->yoff = atof(optarg);
377 break;
378
379 case 'p':
380 i = (int) strlen(optarg);
381 if ((i < 1) || (i > 8)) {
382 Eprintf("Invalid pensize string: %s\n",
383 optarg);
384 exit(ERROR);
385 }
386 for (j = 1, p = optarg; j <= i; j++, p++) {
387 if ((*p < '0') || (*p > '9')) {
388 if ((*p < 'A') || (*p > 'Z')) {
389 Eprintf
390 ("Invalid size of pen %d: %c\n",
391 j, *p);
392 exit(ERROR);
393 } else {
394 pt.width[j] =
395 1 + (*p - 'A') / 10.0;
396 if (pg->maxpensize <
397 pt.width[j])
398 pg->maxpensize =
399 pt.width[j];
400 }
401 } else {
402 pt.width[j] = (*p - '0') / 10.0;
403 if (pg->maxpensize < pt.width[j])
404 pg->maxpensize =
405 pt.width[j];
406 }
407 }
408 pi->hwsize = TRUE;
409 break;
410
411 case 'P':
412 if (*optarg == ':') {
413 pi->first_page = 0;
414 optarg++;
415 if (sscanf(optarg, "%d", &pi->last_page) !=
416 1)
417 pi->last_page = 0;
418 } else
419 switch (sscanf(optarg, "%d%c%d",
420 &pi->first_page, &cdummy,
421 &pi->last_page)) {
422 case 1:
423 pi->last_page = pi->first_page;
424 break;
425
426 case 2:
427 if (cdummy == ':') {
428 pi->last_page = 0;
429 break;
430 }
431 /* not ':' Syntax error -- drop through */
432 case 3:
433 if (cdummy == ':')
434 break;
435 /* not ':' Syntax error -- drop through */
436 default:
437 Eprintf("Illegal page range.\n");
438 usage_msg(pg, pi, po);
439 exit(ERROR);
440 }
441 break;
442
443 case 'q':
444 pg->quiet = TRUE;
445 break;
446
447 case 'r':
448 pi->rotation = atof(optarg);
449 break;
450
451 case 'S':
452 po->specials = atoi(optarg);
453 break;
454
455 case 's':
456 pg->swapfile = optarg;
457 break;
458
459 case 't':
460 pi->truesize = TRUE;
461 break;
462
463 case 'V':
464 po->vga_mode = (Byte) atoi(optarg);
465 break;
466
467 case 'w':
468 pi->width = atof(optarg);
469 if (pi->width < 0.1)
470 Eprintf("Warning: Small width: %g mm\n",
471 pi->width);
472 if (pi->width > 300.0)
473 Eprintf("Warning: Huge width: %g mm\n",
474 pi->width);
475 break;
476
477 case 'v':
478 Send_version();
479 exit(NOERROR);
480
481 case 'x':
482 pi->x0 = atof(optarg);
483 break;
484
485 case 'X':
486 pi->x1 = atof(optarg);
487 break;
488
489 case 'y':
490 pi->y0 = atof(optarg);
491 break;
492
493 case 'Y':
494 pi->y1 = atof(optarg);
495 break;
496 case 'H':
497 pi->hwlimit.y = atof(optarg);
498 break;
499 case 'W':
500 pi->hwlimit.x = atof(optarg);
501 break;
502 case '?':
503 default:
504 usage_msg(pg, pi, po);
505 exit(ERROR);
506 }
507 }
508
509
510
511 /**
512 ** main(): Process command line & call action routine
513 **/
514
main(int argc,char * argv[])515 int main(int argc, char *argv[])
516 {
517 GEN_PAR Pg;
518 IN_PAR Pi;
519 OUT_PAR Po;
520 int i;
521 char outname[128] = "";
522
523 char *shortopts =
524 "a:c:d:D:e:f:h:l:m:M:o:O:p:P:r:s:S:V:w:x:X:y:Y:z:Z:CFH:W:inqtvNI?";
525 struct option longopts[] = {
526 {"mode", 1, NULL, 'm'},
527 {"pencolors", 1, NULL, 'c'},
528 {"pensizes", 1, NULL, 'p'},
529 {"pages", 1, NULL, 'P'},
530 {"quiet", 0, NULL, 'q'},
531 {"nofill", 0, NULL, 'n'},
532 {"no_ps", 0, NULL, 'N'},
533 {"mapzero", 1, NULL, 'M'},
534
535 {"DPI", 1, NULL, 'd'},
536 {"DPI_x", 1, NULL, 'd'},
537 {"DPI_y", 1, NULL, 'D'},
538 {"extraclip", 1, NULL, 'e'},
539
540 {"PCL_formfeed", 0, NULL, 'F'},
541 {"PCL_init", 0, NULL, 'i'},
542 {"PCL_Deskjet", 1, NULL, 'S'},
543 {"PCL_PCL3GUI", 0, NULL, 'I'},
544
545 {"outfile", 1, NULL, 'f'},
546 {"logfile", 1, NULL, 'l'},
547 {"swapfile", 1, NULL, 's'},
548
549 {"aspectfactor", 1, NULL, 'a'},
550 {"height", 1, NULL, 'h'},
551 {"width", 1, NULL, 'w'},
552 {"truesize", 0, NULL, 't'},
553
554 {"x0", 1, NULL, 'x'},
555 {"x1", 1, NULL, 'X'},
556 {"y0", 1, NULL, 'y'},
557 {"y1", 1, NULL, 'Y'},
558 {"zengage", 1, NULL, 'z'},
559 {"zretract", 1, NULL, 'Z'},
560
561 {"xoffset", 1, NULL, 'o'},
562 {"yoffset", 1, NULL, 'O'},
563 {"center", 0, NULL, 'C'},
564
565 #ifdef DOS
566 {"VGAmodebyte", 1, NULL, 'V'},
567 #endif
568 {"help", 0, NULL, '?'},
569 {"version", 0, NULL, 'v'},
570 {NULL, 0, NULL, '\0'}
571 };
572
573
574 preset_par(&Pg, &Pi, &Po);
575 if (argc == 1) {
576 usage_msg(&Pg, &Pi, &Po);
577 exit(ERROR);
578 }
579 #ifdef WIN32
580 /* set stdin and stdout to binary mode: */
581 _setmode(_fileno(stdin), _O_BINARY);
582 _setmode(_fileno(stdout), _O_BINARY);
583 #endif /* WIN32 */
584 process_opts(argc, argv, shortopts, longopts, &Pg, &Pi, &Po);
585
586 /**
587 ** Determine internal mode code
588 **/
589
590 for (i = 0; ModeList[i].mode != XX_TERM; i++)
591 /* if (strncmp(Pg.mode, ModeList[i].modestr,
592 strlen(ModeList[i].modestr)) == 0)*/
593 if (strcmp(Pg.mode, ModeList[i].modestr) == 0) {
594 Pg.xx_mode = ModeList[i].mode;
595 break;
596 }
597 /**
598 ** Place consistency checks & adjustments here if you like
599 **/
600
601 if (Po.dpi_y == 0)
602 Po.dpi_y = Po.dpi_x;
603
604 Po.pagecount = -1;
605 if (strlen(Po.outfile) > 0)
606 strcpy(outname, Po.outfile); /* store fixed outfile name if present */
607 else {
608 Po.outfile = malloc(1 * sizeof(char));
609 strcpy(Po.outfile, "");
610 }
611 /**
612 ** Action loop over all input files
613 **/
614
615 if (optind == argc) { /* No filename: use stdin */
616 Pi.in_file = "-";
617 autoset_outfile_name(Pg.mode, Pi.in_file, &Po.outfile);
618 action_oldstyle(&Pg, &Pi, &Po);
619 } else
620 for (; optind < argc; optind++) { /* Multiple-input file handling: */
621 Pi.in_file = argv[optind];
622 /* if output file name given on commandline, use it for all files */
623 if (strlen(outname) > 0) {
624 strcpy(Po.outfile, outname);
625 } else {
626 Po.pagecount = -1; /* reset page counter for new file */
627 }
628 autoset_outfile_name(Pg.mode, Pi.in_file,
629 &Po.outfile);
630 action_oldstyle(&Pg, &Pi, &Po);
631 reset_par(&Pi);
632 }
633
634 cleanup(&Pg, &Pi, &Po);
635 if (!strcmp(Pg.mode, "pre"))
636 free(Po.outfile);
637 if (*Pg.logfile)
638 fclose(stderr);
639 return NOERROR;
640 }
641