Annotation of OpenXM_contrib/gnuplot/term.c, Revision 1.1.1.3
1.1 maekawa 1: #ifndef lint
1.1.1.3 ! ohara 2: static char *RCSid = "$Id: term.c,v 1.19.2.5 2002/02/01 18:41:05 broeker Exp $";
1.1 maekawa 3: #endif
4:
5: /* GNUPLOT - term.c */
6:
7: /*[
8: * Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
9: *
10: * Permission to use, copy, and distribute this software and its
11: * documentation for any purpose with or without fee is hereby granted,
12: * provided that the above copyright notice appear in all copies and
13: * that both that copyright notice and this permission notice appear
14: * in supporting documentation.
15: *
16: * Permission to modify the software is granted, but not the right to
17: * distribute the complete modified source code. Modifications are to
18: * be distributed as patches to the released version. Permission to
19: * distribute binaries produced by compiling modified sources is granted,
20: * provided you
21: * 1. distribute the corresponding source modifications from the
22: * released version in the form of a patch file along with the binaries,
23: * 2. add special version identification to distinguish your version
24: * in addition to the base release version number,
25: * 3. provide your name and address as the primary contact for the
26: * support of your modified version, and
27: * 4. retain our contact information in regard to use of the base
28: * software.
29: * Permission to distribute the released version of the source code along
30: * with corresponding source modifications in the form of a patch file is
31: * granted with same provisions 2 through 4 for binary distributions.
32: *
33: * This software is provided "as is" without express or implied warranty
34: * to the extent permitted by applicable law.
35: ]*/
36:
37:
38: /* This module is responsible for looking after the terminal
39: * drivers at the lowest level. Only this module (should)
40: * know about all the various rules about interpreting
41: * the terminal capabilities exported by the terminal
42: * drivers in the table.
43: *
44: * Note that, as far as this module is concerned, a
45: * terminal session lasts only until _either_ terminal
46: * or output file changes. Before either is changed,
47: * the terminal is shut down.
48: *
49: * Entry points : (see also term/README)
50: *
51: * term_set_output() : called when set output invoked
52: *
53: * term_init() : optional. Prepare the terminal for first
54: * use. It protects itself against subsequent calls.
55: *
56: * term_start_plot() : called at start of graph output. Calls term_init
57: * if necessary
58: *
59: * term_apply_lp_properties() : apply linewidth settings
60: *
61: * term_end_plot() : called at the end of a plot
62: *
63: * term_reset() : called during int_error handling, to shut
64: * terminal down cleanly
65: *
66: * term_start_multiplot() : called by set multiplot
67: *
68: * term_end_multiplot() : called by set nomultiplot
69: *
70: * term_check_multiplot_okay() : called just before an interactive
71: * prompt is issued while in multiplot mode,
72: * to allow terminal to suspend if necessary,
73: * Raises an error if interactive multiplot
74: * is not supported.
75: */
76:
77: #include "plot.h"
78: #include "bitmap.h"
79: #include "setshow.h"
80: #include "driver.h"
81:
82: #ifdef _Windows
83: FILE *open_printer __PROTO((void)); /* in wprinter.c */
84: void close_printer __PROTO((FILE * outfile));
85: # ifdef __MSC__
86: # include <malloc.h>
87: # else
88: # include <alloc.h>
89: # endif /* MSC */
90: #endif /* _Windows */
91:
92:
93: /* true if terminal has been initialized */
94: static TBOOLEAN term_initialised;
95:
96: /* true if terminal is in graphics mode */
97: static TBOOLEAN term_graphics = FALSE;
98:
99: /* we have suspended the driver, in multiplot mode */
100: static TBOOLEAN term_suspended = FALSE;
101:
102: /* true if? */
103: static TBOOLEAN opened_binary = FALSE;
104:
105: /* true if require terminal to be initialized */
106: static TBOOLEAN term_force_init = FALSE;
107:
108: extern FILE *gpoutfile;
109: extern char *outstr;
110: extern float xsize, ysize;
111:
112: /* internal pointsize for do_point */
113: static double term_pointsize;
114:
1.1.1.3 ! ohara 115: int termcomp __PROTO((SORTFUNC_ARGS a, SORTFUNC_ARGS b));
1.1 maekawa 116: static void term_suspend __PROTO((void));
117: static void term_close_output __PROTO((void));
118: static void null_linewidth __PROTO((double));
119:
120: void do_point __PROTO((unsigned int x, unsigned int y, int number));
121: void do_pointsize __PROTO((double size));
122: void line_and_point __PROTO((unsigned int x, unsigned int y, int number));
123: void do_arrow __PROTO((unsigned int sx, unsigned int sy, unsigned int ex, unsigned int ey, int head));
124:
125:
126: #ifdef __ZTC__
127: char *ztc_init();
128: /* #undef TGIF */
129: #endif
130:
131: #ifdef VMS
132: char *vms_init();
133: void vms_reset();
134: void term_mode_tek();
135: void term_mode_native();
136: void term_pasthru();
137: void term_nopasthru();
138: void fflush_binary();
139: # define FOPEN_BINARY(file) fopen(file, "wb", "rfm=fix", "bls=512", "mrs=512")
140: #else /* !VMS */
141: # define FOPEN_BINARY(file) fopen(file, "wb")
142: #endif /* !VMS */
143:
144:
145: /* This is needed because the unixplot library only writes to stdout. */
146: #if defined(UNIXPLOT) || defined(GNUGRAPH)
147: static FILE save_stdout;
148: #endif
149: static int unixplot = 0;
150:
151: #if defined(MTOS) || defined(ATARI)
152: int aesid = -1;
153: #endif
154:
155: #define NICE_LINE 0
156: #define POINT_TYPES 6
157:
158: #ifndef DEFAULTTERM
159: # define DEFAULTTERM NULL
160: #endif
161:
162: /* interface to the rest of gnuplot - the rules are getting
163: * too complex for the rest of gnuplot to be allowed in
164: */
165:
166: #if defined(PIPES)
167: static TBOOLEAN pipe_open = FALSE;
168: #endif /* PIPES */
169:
170: static void term_close_output()
171: {
172: FPRINTF((stderr, "term_close_output\n"));
173:
174: opened_binary = FALSE;
175:
176: if (!outstr) /* ie using stdout */
177: return;
178:
179: #if defined(PIPES)
180: if (pipe_open) {
181: (void) pclose(gpoutfile);
182: pipe_open = FALSE;
183: } else
184: #endif /* PIPES */
185: #ifdef _Windows
186: if (stricmp(outstr, "PRN") == 0)
187: close_printer(gpoutfile);
188: else
189: #endif
190: (void) fclose(gpoutfile);
191:
192: gpoutfile = stdout; /* Don't dup... */
193: free(outstr);
194: outstr = NULL;
195: }
196:
197: #ifdef OS2
198: # define POPEN_MODE ("wb")
199: #else
200: # define POPEN_MODE ("w")
201: #endif
202:
203: /* assigns dest to outstr, so it must be allocated or NULL
204: * and it must not be outstr itself !
205: */
206: void term_set_output(dest)
207: char *dest;
208: {
209: FILE *f;
210:
211: FPRINTF((stderr, "term_set_output\n"));
212: assert(dest == NULL || dest != outstr);
213:
214: if (multiplot) {
215: fputs("In multiplotmode you can't change the output\n", stderr);
216: return;
217: }
218: if (term && term_initialised) {
219: (*term->reset) ();
220: term_initialised = FALSE;
221: }
222: if (dest == NULL) { /* stdout */
223: UP_redirect(4);
224: term_close_output();
225: } else {
226:
227: #if defined(PIPES)
228: if (*dest == '|') {
229: if ((f = popen(dest + 1, POPEN_MODE)) == (FILE *) NULL)
230: os_error("cannot create pipe; output not changed", c_token);
231: else
232: pipe_open = TRUE;
233: } else
234: #endif /* PIPES */
235:
236: #ifdef _Windows
237: if (outstr && stricmp(outstr, "PRN") == 0) {
238: /* we can't call open_printer() while printer is open, so */
239: close_printer(gpoutfile); /* close printer immediately if open */
240: gpoutfile = stdout; /* and reset output to stdout */
241: free(outstr);
242: outstr = NULL;
243: }
244: if (stricmp(dest, "PRN") == 0) {
245: if ((f = open_printer()) == (FILE *) NULL)
246: os_error("cannot open printer temporary file; output may have changed", c_token);
247: } else
248: #endif
249:
250: {
251: if (term && (term->flags & TERM_BINARY)) {
252: f = FOPEN_BINARY(dest);
253: } else
254: f = fopen(dest, "w");
255:
256: if (f == (FILE *) NULL)
257: os_error("cannot open file; output not changed", c_token);
258: }
259: term_close_output();
260: gpoutfile = f;
261: outstr = dest;
262: opened_binary = (term && (term->flags & TERM_BINARY));
263: UP_redirect(1);
264: }
265: }
266:
267: void term_init()
268: {
269: FPRINTF((stderr, "term_init()\n"));
270:
271: if (!term)
272: int_error("No terminal defined", NO_CARET);
273:
274: /* check if we have opened the output file in the wrong mode
275: * (text/binary), if set term comes after set output
276: * This was originally done in change_term, but that
277: * resulted in output files being truncated
278: */
279:
280: if (outstr &&
281: (((term->flags & TERM_BINARY) && !opened_binary) ||
282: ((!(term->flags & TERM_BINARY) && opened_binary)))) {
283: /* this is nasty - we cannot just term_set_output(outstr)
284: * since term_set_output will first free outstr and we
285: * end up with an invalid pointer. I think I would
286: * prefer to defer opening output file until first plot.
287: */
288: char *temp = gp_alloc(strlen(outstr) + 1, "temp file string");
289: if (temp) {
290: FPRINTF((stderr, "term_init : reopening \"%s\" as %s\n",
291: outstr, term->flags & TERM_BINARY ? "binary" : "text"));
292: strcpy(temp, outstr);
293: term_set_output(temp); /* will free outstr */
294: } else
295: fputs("Cannot reopen output file in binary", stderr);
296: /* and carry on, hoping for the best ! */
297: }
298: #ifdef OS2
299: else if (!outstr && !interactive && (term->flags & TERM_BINARY)) {
300: /* binary (eg gif) to stdout in a non-interactive session */
301: fflush(stdout); // _fsetmode requires an empty buffer
302:
303: _fsetmode(stdout, "b");
304: }
305: #endif
306:
307:
308: if (!term_initialised || term_force_init) {
309: FPRINTF((stderr, "- calling term->init()\n"));
310: (*term->init) ();
311: term_initialised = TRUE;
312: }
313: }
314:
315:
316: void term_start_plot()
317: {
318: FPRINTF((stderr, "term_start_plot()\n"));
319:
320: if (!term_initialised)
321: term_init();
322:
323: if (!term_graphics) {
324: FPRINTF((stderr, "- calling term->graphics()\n"));
325: (*term->graphics) ();
326: term_graphics = TRUE;
327: } else if (multiplot && term_suspended) {
328: if (term->resume) {
329: FPRINTF((stderr, "- calling term->resume()\n"));
330: (*term->resume) ();
331: }
332: term_suspended = FALSE;
333: }
334: }
335:
336: void term_end_plot()
337: {
338: FPRINTF((stderr, "term_end_plot()\n"));
339:
340: if (!term_initialised)
341: return;
342:
343: if (!multiplot) {
344: FPRINTF((stderr, "- calling term->text()\n"));
345: (*term->text) ();
346: term_graphics = FALSE;
347: }
348: #ifdef VMS
349: if (opened_binary)
350: fflush_binary();
351: else
352: #endif /* VMS */
353:
354: (void) fflush(gpoutfile);
355: }
356:
357: void term_start_multiplot()
358: {
359: FPRINTF((stderr, "term_start_multiplot()\n"));
360: if (multiplot)
361: term_end_multiplot();
362:
363: multiplot = TRUE;
364: term_start_plot();
365: }
366:
367: void term_end_multiplot()
368: {
369: FPRINTF((stderr, "term_end_multiplot()\n"));
370: if (!multiplot)
371: return;
372:
373: if (term_suspended) {
374: if (term->resume)
375: (*term->resume) ();
376: term_suspended = FALSE;
377: }
378: multiplot = FALSE;
379:
380: term_end_plot();
381: }
382:
383:
384:
385: static void term_suspend()
386: {
387: FPRINTF((stderr, "term_suspend()\n"));
388: if (term_initialised && !term_suspended && term->suspend) {
389: FPRINTF((stderr, "- calling term->suspend()\n"));
390: (*term->suspend) ();
391: term_suspended = TRUE;
392: }
393: }
394:
395: void term_reset()
396: {
397: FPRINTF((stderr, "term_reset()\n"));
398:
399: if (!term_initialised)
400: return;
401:
402: if (term_suspended) {
403: if (term->resume) {
404: FPRINTF((stderr, "- calling term->resume()\n"));
405: (*term->resume) ();
406: }
407: term_suspended = FALSE;
408: }
409: if (term_graphics) {
410: (*term->text) ();
411: term_graphics = FALSE;
412: }
413: if (term_initialised) {
414: (*term->reset) ();
415: term_initialised = FALSE;
416: }
417: }
418:
419: void term_apply_lp_properties(lp)
420: struct lp_style_type *lp;
421: {
422: /* This function passes all the line and point properties to the
423: * terminal driver and issues the corresponding commands.
424: *
425: * Alas, sometimes it might be necessary to give some help to
426: * this function by explicitly issuing additional '(*term)(...)'
427: * commands.
428: */
429:
430: if (lp->pointflag) {
431: /* change points, too
432: * Currently, there is no 'pointtype' function. For points
433: * there is a special function also dealing with (x,y) co-
434: * ordinates.
435: */
436: (*term->pointsize) (lp->p_size);
437: }
438: /* _first_ set the line width, _then_ set the line type !
439:
440: * The linetype might depend on the linewidth in some terminals.
441: */
442: (*term->linewidth) (lp->l_width);
443: (*term->linetype) (lp->l_type);
444: }
445:
446:
447:
448: void term_check_multiplot_okay(f_interactive)
449: TBOOLEAN f_interactive;
450: {
451: FPRINTF((stderr, "term_multiplot_okay(%d)\n", f_interactive));
452:
453: if (!term_initialised)
454: return; /* they've not started yet */
455:
456: /* make sure that it is safe to issue an interactive prompt
457: * it is safe if
458: * it is not an interactive read, or
459: * the terminal supports interactive multiplot, or
460: * we are not writing to stdout and terminal doesn't
461: * refuse multiplot outright
462: */
463: if (!f_interactive || (term->flags & TERM_CAN_MULTIPLOT) ||
464: ((gpoutfile != stdout) && !(term->flags & TERM_CANNOT_MULTIPLOT))
465: ) {
466: /* it's okay to use multiplot here, but suspend first */
467: term_suspend();
468: return;
469: }
470: /* uh oh : they're not allowed to be in multiplot here */
471:
472: term_end_multiplot();
473:
474: /* at this point we know that it is interactive and that the
475: * terminal can either only do multiplot when writing to
476: * to a file, or it does not do multiplot at all
477: */
478:
479: if (term->flags & TERM_CANNOT_MULTIPLOT)
480: int_error("This terminal does not support multiplot", NO_CARET);
481: else
482: int_error("Must set output to a file or put all multiplot commands on one input line", NO_CARET);
483: }
484:
485: void do_point(x, y, number)
486: unsigned int x, y;
487: int number;
488: {
489: register int htic, vtic;
490: register struct termentry *t = term;
491:
492: if (number < 0) { /* do dot */
493: (*t->move) (x, y);
494: (*t->vector) (x, y);
495: return;
496: }
497: number %= POINT_TYPES;
498: /* should be in term_tbl[] in later version */
499: htic = (term_pointsize * t->h_tic / 2);
500: vtic = (term_pointsize * t->v_tic / 2);
501:
502: switch (number) {
503: case 0: /* do diamond */
504: (*t->move) (x - htic, y);
505: (*t->vector) (x, y - vtic);
506: (*t->vector) (x + htic, y);
507: (*t->vector) (x, y + vtic);
508: (*t->vector) (x - htic, y);
509: (*t->move) (x, y);
510: (*t->vector) (x, y);
511: break;
512: case 1: /* do plus */
513: (*t->move) (x - htic, y);
514: (*t->vector) (x - htic, y);
515: (*t->vector) (x + htic, y);
516: (*t->move) (x, y - vtic);
517: (*t->vector) (x, y - vtic);
518: (*t->vector) (x, y + vtic);
519: break;
520: case 2: /* do box */
521: (*t->move) (x - htic, y - vtic);
522: (*t->vector) (x - htic, y - vtic);
523: (*t->vector) (x + htic, y - vtic);
524: (*t->vector) (x + htic, y + vtic);
525: (*t->vector) (x - htic, y + vtic);
526: (*t->vector) (x - htic, y - vtic);
527: (*t->move) (x, y);
528: (*t->vector) (x, y);
529: break;
530: case 3: /* do X */
531: (*t->move) (x - htic, y - vtic);
532: (*t->vector) (x - htic, y - vtic);
533: (*t->vector) (x + htic, y + vtic);
534: (*t->move) (x - htic, y + vtic);
535: (*t->vector) (x - htic, y + vtic);
536: (*t->vector) (x + htic, y - vtic);
537: break;
538: case 4: /* do triangle */
539: (*t->move) (x, y + (4 * vtic / 3));
540: (*t->vector) (x - (4 * htic / 3), y - (2 * vtic / 3));
541: (*t->vector) (x + (4 * htic / 3), y - (2 * vtic / 3));
542: (*t->vector) (x, y + (4 * vtic / 3));
543: (*t->move) (x, y);
544: (*t->vector) (x, y);
545: break;
546: case 5: /* do star */
547: (*t->move) (x - htic, y);
548: (*t->vector) (x - htic, y);
549: (*t->vector) (x + htic, y);
550: (*t->move) (x, y - vtic);
551: (*t->vector) (x, y - vtic);
552: (*t->vector) (x, y + vtic);
553: (*t->move) (x - htic, y - vtic);
554: (*t->vector) (x - htic, y - vtic);
555: (*t->vector) (x + htic, y + vtic);
556: (*t->move) (x - htic, y + vtic);
557: (*t->vector) (x - htic, y + vtic);
558: (*t->vector) (x + htic, y - vtic);
559: break;
560: }
561: }
562:
563: void do_pointsize(size)
564: double size;
565: {
566: term_pointsize = (size >= 0 ? size : 1);
567: }
568:
569:
570: /*
571: * general point routine
572: */
573: void line_and_point(x, y, number)
574: unsigned int x, y;
575: int number;
576: {
577: /* temporary(?) kludge to allow terminals with bad linetypes
578: to make nice marks */
579:
580: (*term->linetype) (NICE_LINE);
581: do_point(x, y, number);
582: }
583:
584: /*
585: * general arrow routine
586: *
587: * I set the angle between the arrowhead and the line 15 degree.
588: * The length of arrowhead varies depending on the line length
589: * within the the range [0.3*(the-tic-length), 2*(the-tic-length)].
590: * No head is printed if the arrow length is zero.
591: *
592: * Yasu-hiro Yamazaki(hiro@rainbow.physics.utoronto.ca)
593: * Jul 1, 1993
594: */
595:
596: #define COS15 (0.96593) /* cos of 15 degree */
597: #define SIN15 (0.25882) /* sin of 15 degree */
598:
599: #define HEAD_LONG_LIMIT (2.0) /* long limit of arrowhead length */
600: #define HEAD_SHORT_LIMIT (0.3) /* short limit of arrowhead length */
601: /* their units are the "tic" length */
602:
603: #define HEAD_COEFF (0.3) /* default value of head/line length ratio */
604:
605: void do_arrow(sx, sy, ex, ey, head)
606: unsigned int sx, sy; /* start point */
607: unsigned int ex, ey; /* end point (point of arrowhead) */
608: TBOOLEAN head;
609: {
610: register struct termentry *t = term;
611: float len_tic = ((double) (t->h_tic + t->v_tic)) / 2.0;
612: /* average of tic sizes */
613: /* (dx,dy) : vector from end to start */
614: double dx = (double) sx - (double) ex;
615: double dy = (double) sy - (double) ey;
616: double len_arrow = sqrt(dx * dx + dy * dy);
617:
618: /* draw the line for the arrow. That's easy. */
619: (*t->move) (sx, sy);
620: (*t->vector) (ex, ey);
621:
622: /* no head for arrows whih length = 0
623: * or, to be more specific, length < DBL_EPSILON,
624: * because len_arrow will almost always be != 0
625: */
626: if (head && fabs(len_arrow) >= DBL_EPSILON) {
627: /* now calc the head_coeff */
628: double coeff_shortest = len_tic * HEAD_SHORT_LIMIT / len_arrow;
629: double coeff_longest = len_tic * HEAD_LONG_LIMIT / len_arrow;
630: double head_coeff = GPMAX(coeff_shortest,
631: GPMIN(HEAD_COEFF, coeff_longest));
632: /* now draw the arrow head. */
633: /* we put the arrowhead marks at 15 degrees to line */
634: int x, y; /* one endpoint */
635:
636: x = (int) (ex + (COS15 * dx - SIN15 * dy) * head_coeff);
637: y = (int) (ey + (SIN15 * dx + COS15 * dy) * head_coeff);
638: (*t->move) (x, y);
639: (*t->vector) (ex, ey);
640:
641: x = (int) (ex + (COS15 * dx + SIN15 * dy) * head_coeff);
642: y = (int) (ey + (-SIN15 * dx + COS15 * dy) * head_coeff);
643: (*t->vector) (x, y);
644: }
645: }
646:
647: #if 0 /* oiginal routine */
648: #define ROOT2 (1.41421) /* sqrt of 2 */
649:
650: void org_do_arrow(sx, sy, ex, ey, head)
651: int sx, sy; /* start point */
652: int ex, ey; /* end point (point of arrowhead) */
653: TBOOLEAN head;
654: {
655: register struct termentry *t = term;
656: int len = (t->h_tic + t->v_tic) / 2; /* arrowhead size = avg of tic sizes */
657:
658: /* draw the line for the arrow. That's easy. */
659: (*t->move) (sx, sy);
660: (*t->vector) (ex, ey);
661:
662: if (head) {
663: /* now draw the arrow head. */
664: /* we put the arrowhead marks at 45 degrees to line */
665: if (sx == ex) {
666: /* vertical line, special case */
667: int delta = ((float) len / ROOT2 + 0.5);
668: if (sy < ey)
669: delta = -delta; /* up arrow goes the other way */
670: (*t->move) (ex - delta, ey + delta);
671: (*t->vector) (ex, ey);
672: (*t->vector) (ex + delta, ey + delta);
673: } else {
674: int dx = sx - ex;
675: int dy = sy - ey;
676: double coeff = len / sqrt(2.0 * ((double) dx * (double) dx
677: + (double) dy * (double) dy));
678: int x, y; /* one endpoint */
679:
680: x = (int) (ex + (dx + dy) * coeff);
681: y = (int) (ey + (dy - dx) * coeff);
682: (*t->move) (x, y);
683: (*t->vector) (ex, ey);
684:
685: x = (int) (ex + (dx - dy) * coeff);
686: y = (int) (ey + (dy + dx) * coeff);
687: (*t->vector) (x, y);
688: }
689: }
690: }
691:
692: #endif /* original routine */
693:
694:
695: #define TERM_PROTO
696: #define TERM_BODY
697: #define TERM_PUBLIC static
698:
699: #include "term.h"
700:
701: #undef TERM_PROTO
702: #undef TERM_BODY
703: #undef TERM_PUBLIC
704:
705:
706: /* Dummy functions for unavailable features */
707: /* return success if they asked for default - this simplifies code
708: * where param is passed as a param. Client can first pass it here,
709: * and only if it fails do they have to see what was trying to be done
710: */
711:
712: /* change angle of text. 0 is horizontal left to right.
713: * 1 is vertical bottom to top (90 deg rotate)
714: */
715: int null_text_angle(ang)
716: int ang;
717: {
718: return (ang == 0);
719: }
720:
721: /* change justification of text.
722: * modes are LEFT (flush left), CENTRE (centred), RIGHT (flush right)
723: */
724: int null_justify_text(just)
725: enum JUSTIFY just;
726: {
727: return (just == LEFT);
728: }
729:
730:
731: /* Change scale of plot.
732: * Parameters are x,y scaling factors for this plot.
733: * Some terminals (eg latex) need to do scaling themselves.
734: */
735: int null_scale(x, y)
736: double x;
737: double y;
738: {
739: return FALSE; /* can't be done */
740: }
741:
742: int do_scale(x, y)
743: double x;
744: double y;
745: {
746: return TRUE; /* can be done */
747: }
748:
749: void options_null()
750: {
751: term_options[0] = '\0'; /* we have no options */
752: }
753:
754: void UNKNOWN_null()
755: {
756: }
757:
758: void MOVE_null(x, y)
759: unsigned int x, y;
760: {
761: }
762:
763: void LINETYPE_null(t)
764: int t;
765: {
766: }
767:
768: void PUTTEXT_null(x, y, s)
769: unsigned int x, y;
770: char *s;
771: {
772: }
773:
774:
775: int set_font_null(s)
776: char *s;
777: {
778: return FALSE;
779: }
780:
781: static void null_linewidth(s)
782: double s;
783: {
784: }
785:
786:
787: /* cast to get rid of useless warnings about UNKNOWN_null */
788: typedef void (*void_fp) __PROTO((void));
789:
790:
791: /* setup the magic macros to compile in the right parts of the
792: * terminal drivers included by term.h
793: */
794:
795: #define TERM_TABLE
796: #define TERM_TABLE_START(x) ,{
797: #define TERM_TABLE_END(x) }
798:
799:
800: /*
801: * term_tbl[] contains an entry for each terminal. "unknown" must be the
802: * first, since term is initialized to 0.
803: */
804: struct termentry term_tbl[] =
805: {
806: {"unknown", "Unknown terminal type - not a plotting device",
807: 100, 100, 1, 1,
808: 1, 1, options_null, UNKNOWN_null, UNKNOWN_null,
809: UNKNOWN_null, null_scale, UNKNOWN_null, MOVE_null, MOVE_null,
810: LINETYPE_null, PUTTEXT_null}
811: ,
812: {"table", "Dump ASCII table of X Y [Z] values to output",
813: 100, 100, 1, 1,
814: 1, 1, options_null, UNKNOWN_null, UNKNOWN_null,
815: UNKNOWN_null, null_scale, UNKNOWN_null, MOVE_null, MOVE_null,
816: LINETYPE_null, PUTTEXT_null}
817: #include "term.h"
818:
819: };
820:
821: #define TERMCOUNT (sizeof(term_tbl)/sizeof(struct termentry))
822:
1.1.1.2 maekawa 823: /* mainly useful for external code */
824: GP_INLINE int
825: term_count()
826: {
827: return TERMCOUNT;
828: }
829:
1.1 maekawa 830: void list_terms()
831: {
832: register int i;
1.1.1.3 ! ohara 833: char *line_buffer = gp_alloc(BUFSIZ, "list_terms");
! 834: int sort_idxs[TERMCOUNT];
! 835:
! 836: /* sort terminal types alphabetically */
! 837: for( i = 0; i < TERMCOUNT; i++ )
! 838: sort_idxs[i] = i;
! 839: qsort( sort_idxs, TERMCOUNT, sizeof(int), termcomp );
! 840: /* now sort_idxs[] contains the sorted indices */
1.1 maekawa 841:
842: StartOutput();
1.1.1.3 ! ohara 843: strcpy(line_buffer, "\nAvailable terminal types:\n");
1.1 maekawa 844: OutLine(line_buffer);
845:
846: for (i = 0; i < TERMCOUNT; i++) {
1.1.1.3 ! ohara 847: sprintf(line_buffer, " %15s %s\n",
! 848: term_tbl[sort_idxs[i]].name,
! 849: term_tbl[sort_idxs[i]].description);
1.1 maekawa 850: OutLine(line_buffer);
851: }
852:
853: EndOutput();
1.1.1.3 ! ohara 854: free(line_buffer);
1.1 maekawa 855: }
856:
1.1.1.3 ! ohara 857: int
! 858: termcomp(arga, argb)
! 859: SORTFUNC_ARGS arga;
! 860: SORTFUNC_ARGS argb;
! 861: {
! 862: const int *a = arga;
! 863: const int *b = argb;
! 864:
! 865: return( strcasecmp( term_tbl[*a].name, term_tbl[*b].name ) );
! 866: }
1.1 maekawa 867:
868: /* set_term: get terminal number from name on command line
869: * will change 'term' variable if successful
870: */
871: struct termentry *
872: set_term(c_token_arg)
873: int c_token_arg;
874: {
875: register struct termentry *t = NULL;
876: char *input_name;
877:
878: if (!token[c_token_arg].is_token)
879: int_error("terminal name expected", c_token_arg);
880: input_name = input_line + token[c_token_arg].start_index;
881: t = change_term(input_name, token[c_token_arg].length);
882: if (!t)
883: int_error("unknown or ambiguous terminal type; type just 'set terminal' for a list",
884: c_token_arg);
885:
886: /* otherwise the type was changed */
887:
888: return (t);
889: }
890:
891: /* change_term: get terminal number from name and set terminal type
892: *
893: * returns NULL for unknown or ambiguous, otherwise is terminal
894: * driver pointer
895: */
896: struct termentry *
897: change_term(name, length)
898: char *name;
899: int length;
900: {
901: int i;
902: struct termentry *t = NULL;
903:
904: for (i = 0; i < TERMCOUNT; i++) {
905: if (!strncmp(name, term_tbl[i].name, length)) {
906: if (t)
907: return (NULL); /* ambiguous */
908: t = term_tbl + i;
909: }
910: }
911:
912: if (!t) /* unknown */
913: return (NULL);
914:
915: /* Success: set terminal type now */
916:
917: term = t;
918: term_initialised = FALSE;
919: name = term->name;
920:
921: if (term->scale != null_scale)
922: fputs("Warning : scale interface is not null_scale - may not work with multiplot\n", stderr);
923:
924: /* check that optional fields are initialised to something */
925: if (term->text_angle == 0)
926: term->text_angle = null_text_angle;
927: if (term->justify_text == 0)
928: term->justify_text = null_justify_text;
929: if (term->point == 0)
930: term->point = do_point;
931: if (term->arrow == 0)
932: term->arrow = do_arrow;
933: if (term->set_font == 0)
934: term->set_font = set_font_null;
935: if (term->pointsize == 0)
936: term->pointsize = do_pointsize;
937: if (term->linewidth == 0)
938: term->linewidth = null_linewidth;
939:
940: /* Special handling for unixplot term type */
941: if (!strncmp("unixplot", name, 8)) {
942: UP_redirect(2); /* Redirect actual stdout for unixplots */
943: } else if (unixplot) {
944: UP_redirect(3); /* Put stdout back together again. */
945: }
946: if (interactive)
947: fprintf(stderr, "Terminal type set to '%s'\n", name);
948:
949: return (t);
950: }
951:
952: /*
953: * Routine to detect what terminal is being used (or do anything else
954: * that would be nice). One anticipated (or allowed for) side effect
955: * is that the global ``term'' may be set.
956: * The environment variable GNUTERM is checked first; if that does
957: * not exist, then the terminal hardware is checked, if possible,
958: * and finally, we can check $TERM for some kinds of terminals.
959: * A default can be set with -DDEFAULTTERM=myterm in the Makefile
960: * or #define DEFAULTTERM myterm in term.h
961: */
962: /* thanks to osupyr!alden (Dave Alden) for the original GNUTERM code */
963: void init_terminal()
964: {
965: char *term_name = DEFAULTTERM;
966: #if (defined(__TURBOC__) && defined(MSDOS) && !defined(_Windows)) || defined(NEXT) || defined(SUN) || defined(X11)
967: char *env_term = NULL; /* from TERM environment var */
968: #endif
969: #ifdef X11
970: char *display = NULL;
971: #endif
972: char *gnuterm = NULL;
973:
974: /* GNUTERM environment variable is primary */
975: gnuterm = getenv("GNUTERM");
976: if (gnuterm != (char *) NULL) {
977: term_name = gnuterm;
978: } else {
979:
980: #ifdef __ZTC__
981: term_name = ztc_init();
982: #endif
983:
984: #ifdef VMS
985: term_name = vms_init();
986: #endif /* VMS */
987:
988: #ifdef NEXT
989: env_term = getenv("TERM");
990: if (term_name == (char *) NULL
1.1.1.2 maekawa 991: && env_term != (char *) NULL && strcmp(env_term, "next") == 0)
1.1 maekawa 992: term_name = "next";
993: #endif /* NeXT */
994:
995: #ifdef SUN
996: env_term = getenv("TERM"); /* try $TERM */
997: if (term_name == (char *) NULL
998: && env_term != (char *) NULL && strcmp(env_term, "sun") == 0)
999: term_name = "sun";
1000: #endif /* SUN */
1001:
1002: #ifdef _Windows
1003: term_name = "win";
1004: #endif /* _Windows */
1005:
1006: #ifdef GPR
1007: /* find out whether stdout is a DM pad. See term/gpr.trm */
1008: if (gpr_isa_pad())
1009: term_name = "gpr";
1010: #else
1011: # ifdef APOLLO
1012: /* find out whether stdout is a DM pad. See term/apollo.trm */
1013: if (apollo_isa_pad())
1014: term_name = "apollo";
1015: # endif /* APOLLO */
1016: #endif /* GPR */
1017:
1018: #ifdef X11
1019: env_term = getenv("TERM"); /* try $TERM */
1020: if (term_name == (char *) NULL
1021: && env_term != (char *) NULL && strcmp(env_term, "xterm") == 0)
1022: term_name = "x11";
1023: display = getenv("DISPLAY");
1024: if (term_name == (char *) NULL && display != (char *) NULL)
1025: term_name = "x11";
1026: if (X11_Display)
1027: term_name = "x11";
1028: #endif /* x11 */
1029:
1030: #ifdef AMIGA
1031: term_name = "amiga";
1032: #endif
1033:
1034: #if defined(ATARI) || defined(MTOS)
1035: term_name = "atari";
1036: #endif
1037:
1038: #ifdef UNIXPC
1039: if (iswind() == 0) {
1040: term_name = "unixpc";
1041: }
1042: #endif /* unixpc */
1043:
1044: #ifdef CGI
1045: if (getenv("CGIDISP") || getenv("CGIPRNT"))
1046: term_name = "cgi";
1047: #endif /*CGI */
1048:
1049: #ifdef DJGPP
1050: term_name = "svga";
1051: #endif
1052:
1053: #ifdef GRASS
1054: term_name = "grass";
1055: #endif
1056:
1057: #ifdef OS2
1058: /* if (_osmode==OS2_MODE) term_name = "pm" ; else term_name = "emxvga"; */
1059: # ifdef X11
1060: /* This catch is hopefully ok ... */
1061: env_term = getenv("WINDOWID");
1062: display = getenv("DISPLAY");
1063: if ((env_term != (char *) NULL) && (display != (char *) NULL))
1064: term_name = "x11";
1065: else
1066: # endif /* X11 */
1067: term_name = "pm";
1068: #endif /*OS2 */
1069:
1070: /* set linux terminal only if LINUX_setup was successfull, if we are on X11
1071: LINUX_setup has failed, also if we are logged in by network */
1072: #ifdef LINUXVGA
1073: if (LINUX_graphics_allowed)
1074: term_name = "linux";
1075: #endif /* LINUXVGA */
1076: }
1077:
1078: /* We have a name, try to set term type */
1079: if (term_name != NULL && *term_name != '\0') {
1080: if (change_term(term_name, (int) strlen(term_name)))
1081: return;
1082: fprintf(stderr, "Unknown or ambiguous terminal name '%s'\n", term_name);
1083: }
1084: change_term("unknown", 7);
1085: }
1086:
1087:
1088: #ifdef __ZTC__
1089: char *ztc_init()
1090: {
1091: int g_mode;
1092: char *term_name = NULL;
1093:
1094: g_mode = fg_init();
1095:
1096: switch (g_mode) {
1097: case FG_NULL:
1098: fputs("Graphics card not detected or not supported.\n", stderr);
1099: exit(1);
1100: case FG_HERCFULL:
1101: term_name = "hercules";
1102: break;
1103: case FG_EGAMONO:
1104: term_name = "egamono";
1105: break;
1106: case FG_EGAECD:
1107: term_name = "egalib";
1108: break;
1109: case FG_VGA11:
1110: term_name = "vgamono";
1111: break;
1112: case FG_VGA12:
1113: term_name = "vgalib";
1114: break;
1115: case FG_VESA6A:
1116: term_name = "svgalib";
1117: break;
1118: case FG_VESA5:
1119: term_name = "ssvgalib";
1120: break;
1121: }
1122: fg_term();
1123: return (term_name);
1124: }
1125: #endif /* __ZTC__ */
1126:
1127:
1128: /*
1129: This is always defined so we don't have to have command.c know if it
1130: is there or not.
1131: */
1132: #if !(defined(UNIXPLOT) || defined(GNUGRAPH))
1133: void UP_redirect(caller)
1134: int caller;
1135: {
1136: caller = caller; /* to stop Turbo C complaining
1137: * about caller not being used */
1138: }
1139:
1140: #else /* UNIXPLOT || GNUGRAPH */
1141: void UP_redirect(caller)
1142: int caller;
1143: /*
1144: Unixplot can't really write to gpoutfile--it wants to write to stdout.
1145: This is normally ok, but the original design of gnuplot gives us
1146: little choice. Originally users of unixplot had to anticipate
1147: their needs and redirect all I/O to a file... Not very gnuplot-like.
1148:
1149: caller: 1 - called from SET OUTPUT "FOO.OUT"
1150: 2 - called from SET TERM UNIXPLOT
1151: 3 - called from SET TERM other
1152: 4 - called from SET OUTPUT
1153: */
1154: {
1155: switch (caller) {
1156: case 1:
1157: /* Don't save, just replace stdout w/gpoutfile (save was already done). */
1158: if (unixplot)
1159: *(stdout) = *(gpoutfile); /* Copy FILE structure */
1160: break;
1161: case 2:
1162: if (!unixplot) {
1163: fflush(stdout);
1164: save_stdout = *(stdout);
1165: *(stdout) = *(gpoutfile); /* Copy FILE structure */
1166: unixplot = 1;
1167: }
1168: break;
1169: case 3:
1170: /* New terminal in use--put stdout back to original. */
1171: /* closepl(); *//* This is called by the term. */
1172: fflush(stdout);
1173: *(stdout) = save_stdout; /* Copy FILE structure */
1174: unixplot = 0;
1175: break;
1176: case 4:
1177: /* User really wants to go to normal output... */
1178: if (unixplot) {
1179: fflush(stdout);
1180: *(stdout) = save_stdout; /* Copy FILE structure */
1181: }
1182: break;
1183: }
1184: }
1185: #endif /* UNIXPLOT || GNUGRAPH */
1186:
1187:
1188: /* test terminal by drawing border and text */
1189: /* called from command test */
1190: void test_term()
1191: {
1192: register struct termentry *t = term;
1193: char *str;
1194: int x, y, xl, yl, i;
1195: unsigned int xmax_t, ymax_t;
1196: char label[MAX_ID_LEN];
1197: int key_entry_height;
1198: int p_width;
1199:
1200: term_start_plot();
1201: screen_ok = FALSE;
1202: xmax_t = (unsigned int) (t->xmax * xsize);
1203: ymax_t = (unsigned int) (t->ymax * ysize);
1204:
1205: p_width = pointsize * (t->h_tic);
1206: key_entry_height = pointsize * (t->v_tic) * 1.25;
1207: if (key_entry_height < (t->v_char))
1208: key_entry_height = (t->v_char);
1209:
1210: /* border linetype */
1.1.1.2 maekawa 1211: (*t->linewidth) (1.0);
1.1 maekawa 1212: (*t->linetype) (-2);
1213: (*t->move) (0, 0);
1214: (*t->vector) (xmax_t - 1, 0);
1215: (*t->vector) (xmax_t - 1, ymax_t - 1);
1216: (*t->vector) (0, ymax_t - 1);
1217: (*t->vector) (0, 0);
1218: (void) (*t->justify_text) (LEFT);
1219: (*t->put_text) (t->h_char * 5, ymax_t - t->v_char * 3, "Terminal Test");
1220: /* axis linetype */
1221: (*t->linetype) (-1);
1222: (*t->move) (xmax_t / 2, 0);
1223: (*t->vector) (xmax_t / 2, ymax_t - 1);
1224: (*t->move) (0, ymax_t / 2);
1225: (*t->vector) (xmax_t - 1, ymax_t / 2);
1226: /* test width and height of characters */
1227: (*t->linetype) (-2);
1228: (*t->move) (xmax_t / 2 - t->h_char * 10, ymax_t / 2 + t->v_char / 2);
1229: (*t->vector) (xmax_t / 2 + t->h_char * 10, ymax_t / 2 + t->v_char / 2);
1230: (*t->vector) (xmax_t / 2 + t->h_char * 10, ymax_t / 2 - t->v_char / 2);
1231: (*t->vector) (xmax_t / 2 - t->h_char * 10, ymax_t / 2 - t->v_char / 2);
1232: (*t->vector) (xmax_t / 2 - t->h_char * 10, ymax_t / 2 + t->v_char / 2);
1233: (*t->put_text) (xmax_t / 2 - t->h_char * 10, ymax_t / 2,
1234: "12345678901234567890");
1235: /* test justification */
1236: (void) (*t->justify_text) (LEFT);
1237: (*t->put_text) (xmax_t / 2, ymax_t / 2 + t->v_char * 6, "left justified");
1238: str = "centre+d text";
1239: if ((*t->justify_text) (CENTRE))
1240: (*t->put_text) (xmax_t / 2,
1241: ymax_t / 2 + t->v_char * 5, str);
1242: else
1243: (*t->put_text) (xmax_t / 2 - strlen(str) * t->h_char / 2,
1244: ymax_t / 2 + t->v_char * 5, str);
1245: str = "right justified";
1246: if ((*t->justify_text) (RIGHT))
1247: (*t->put_text) (xmax_t / 2,
1248: ymax_t / 2 + t->v_char * 4, str);
1249: else
1250: (*t->put_text) (xmax_t / 2 - strlen(str) * t->h_char,
1251: ymax_t / 2 + t->v_char * 4, str);
1252: /* test text angle */
1253: str = "rotated ce+ntred text";
1254: if ((*t->text_angle) (1)) {
1255: if ((*t->justify_text) (CENTRE))
1256: (*t->put_text) (t->v_char,
1257: ymax_t / 2, str);
1258: else
1259: (*t->put_text) (t->v_char,
1260: ymax_t / 2 - strlen(str) * t->h_char / 2, str);
1261: } else {
1262: (void) (*t->justify_text) (LEFT);
1263: (*t->put_text) (t->h_char * 2, ymax_t / 2 - t->v_char * 2, "Can't rotate text");
1264: }
1265: (void) (*t->justify_text) (LEFT);
1266: (void) (*t->text_angle) (0);
1267: /* test tic size */
1268: (*t->move) ((unsigned int) (xmax_t / 2 + t->h_tic * (1 + ticscale)), (unsigned) 0);
1269: (*t->vector) ((unsigned int) (xmax_t / 2 + t->h_tic * (1 + ticscale)), (unsigned int)
1270: (ticscale * t->v_tic));
1271: (*t->move) ((unsigned int) (xmax_t / 2), (unsigned int) (t->v_tic * (1 + ticscale)));
1272: (*t->vector) ((unsigned int) (xmax_t / 2 + ticscale * t->h_tic), (unsigned int) (t->v_tic * (1
1273: + ticscale)));
1274: (*t->put_text) ((unsigned int) (xmax_t / 2 - 10 * t->h_char), (unsigned int) (t->v_tic * 2 +
1275: t->v_char / 2),
1276: "test tics");
1277:
1278: /* test line and point types */
1279: x = xmax_t - t->h_char * 6 - p_width;
1280: y = ymax_t - key_entry_height;
1281: (*t->pointsize) (pointsize);
1282: for (i = -2; y > key_entry_height; i++) {
1283: (*t->linetype) (i);
1284: /* (void) sprintf(label,"%d",i); Jorgen Lippert
1285: lippert@risoe.dk */
1286: (void) sprintf(label, "%d", i + 1);
1287: if ((*t->justify_text) (RIGHT))
1288: (*t->put_text) (x, y, label);
1289: else
1290: (*t->put_text) (x - strlen(label) * t->h_char, y, label);
1291: (*t->move) (x + t->h_char, y);
1292: (*t->vector) (x + t->h_char * 4, y);
1293: if (i >= -1)
1294: (*t->point) (x + t->h_char * 5 + p_width / 2, y, i);
1295: y -= key_entry_height;
1296: }
1297: /* test some arrows */
1298: (*t->linewidth) (1.0);
1299: (*t->linetype) (0);
1300: x = xmax_t / 4;
1301: y = ymax_t / 4;
1302: xl = t->h_tic * 5;
1303: yl = t->v_tic * 5;
1304: (*t->arrow) (x, y, x + xl, y, TRUE);
1305: (*t->arrow) (x, y, x + xl / 2, y + yl, TRUE);
1306: (*t->arrow) (x, y, x, y + yl, TRUE);
1307: (*t->arrow) (x, y, x - xl / 2, y + yl, FALSE);
1308: (*t->arrow) (x, y, x - xl, y, TRUE);
1309: (*t->arrow) (x, y, x - xl, y - yl, TRUE);
1310: (*t->arrow) (x, y, x, y - yl, TRUE);
1311: (*t->arrow) (x, y, x + xl, y - yl, TRUE);
1312:
1313: term_end_plot();
1314: }
1315:
1316: #if 0
1317: # if defined(MSDOS)||defined(g)||defined(MTOS)||defined(OS2)||defined(_Windows)||defined(DOS386)
1318: /* output for some terminal types must be binary to stop non Unix computers
1319: changing \n to \r\n.
1320: If the output is not STDOUT, the following code reopens gpoutfile
1321: with binary mode. */
1322: void reopen_binary()
1323: {
1324: if (outstr) {
1325: (void) fclose(gpoutfile);
1326: # ifdef _Windows
1327: if (!stricmp(outstr, "PRN")) {
1328: /* use temp file for windows */
1329: (void) strcpy(filename, win_prntmp);
1330: }
1331: # endif
1332: if ((gpoutfile = fopen(filename, "wb")) == (FILE *) NULL) {
1333: if ((gpoutfile = fopen(filename, "w")) == (FILE *) NULL) {
1334: os_error("cannot reopen file with binary type; output unknown",
1335: NO_CARET);
1336: } else {
1337: os_error("cannot reopen file with binary type; output reset to ascii",
1338: NO_CARET);
1339: }
1340: }
1341: # if defined(__TURBOC__) && defined(MSDOS)
1342: # ifndef _Windows
1343: if (!stricmp(outstr, "PRN")) {
1344: /* Put the printer into binary mode. */
1345: union REGS regs;
1346: regs.h.ah = 0x44; /* ioctl */
1347: regs.h.al = 0; /* get device info */
1348: regs.x.bx = fileno(gpoutfile);
1349: intdos(®s, ®s);
1350: regs.h.dl |= 0x20; /* binary (no ^Z intervention) */
1351: regs.h.dh = 0;
1352: regs.h.ah = 0x44; /* ioctl */
1353: regs.h.al = 1; /* set device info */
1354: intdos(®s, ®s);
1355: }
1356: # endif /* !_Windows */
1357: # endif /* TURBOC && MSDOS */
1358: }
1359: }
1360:
1361: # endif /* MSDOS || g || MTOS || ... */
1362: #endif /* 0 */
1363:
1364: #ifdef VMS
1365: /* these are needed to modify terminal characteristics */
1366: # ifndef VWS_XMAX
1367: /* avoid duplicate warning; VWS includes these */
1368: # include <descrip.h>
1369: # include <ssdef.h>
1370: # endif /* !VWS_MAX */
1371: # include <iodef.h>
1372: # include <ttdef.h>
1373: # include <tt2def.h>
1374: # include <dcdef.h>
1375: # include <stat.h>
1376: # include <fab.h>
1377: /* If you use WATCOM C or a very strict ANSI compiler, you may have to
1378: * delete or comment out the following 3 lines: */
1379: # ifndef TT2$M_DECCRT3 /* VT300 not defined as of VAXC v2.4 */
1380: # define TT2$M_DECCRT3 0X80000000
1381: # endif
1382: static unsigned short chan;
1383: static int old_char_buf[3], cur_char_buf[3];
1384: $DESCRIPTOR(sysoutput_desc, "SYS$OUTPUT");
1385:
1386: char *vms_init()
1387: /*
1388: * Look first for decw$display (decterms do regis)
1389: * Determine if we have a regis terminal
1390: * and save terminal characteristics
1391: */
1392: {
1393: /* Save terminal characteristics in old_char_buf and
1394: initialise cur_char_buf to current settings. */
1395: int i;
1396: if (getenv("DECW$DISPLAY"))
1397: return ("x11");
1398: atexit(vms_reset);
1399: sys$assign(&sysoutput_desc, &chan, 0, 0);
1400: sys$qiow(0, chan, IO$_SENSEMODE, 0, 0, 0, old_char_buf, 12, 0, 0, 0, 0);
1401: for (i = 0; i < 3; ++i)
1402: cur_char_buf[i] = old_char_buf[i];
1403: sys$dassgn(chan);
1404:
1405: /* Test if terminal is regis */
1406: if ((cur_char_buf[2] & TT2$M_REGIS) == TT2$M_REGIS)
1407: return ("regis");
1408: return (NULL);
1409: }
1410:
1411: void vms_reset()
1412: /* set terminal to original state */
1413: {
1414: int i;
1415: sys$assign(&sysoutput_desc, &chan, 0, 0);
1416: sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, old_char_buf, 12, 0, 0, 0, 0);
1417: for (i = 0; i < 3; ++i)
1418: cur_char_buf[i] = old_char_buf[i];
1419: sys$dassgn(chan);
1420: }
1421:
1422: void term_mode_tek()
1423: /* set terminal mode to tektronix */
1424: {
1425: long status;
1426: if (gpoutfile != stdout)
1427: return; /* don't modify if not stdout */
1428: sys$assign(&sysoutput_desc, &chan, 0, 0);
1429: cur_char_buf[0] = 0x004A0000 | DC$_TERM | (TT$_TEK401X << 8);
1430: cur_char_buf[1] = (cur_char_buf[1] & 0x00FFFFFF) | 0x18000000;
1431:
1432: cur_char_buf[1] &= ~TT$M_CRFILL;
1433: cur_char_buf[1] &= ~TT$M_ESCAPE;
1434: cur_char_buf[1] &= ~TT$M_HALFDUP;
1435: cur_char_buf[1] &= ~TT$M_LFFILL;
1436: cur_char_buf[1] &= ~TT$M_MECHFORM;
1437: cur_char_buf[1] &= ~TT$M_NOBRDCST;
1438: cur_char_buf[1] &= ~TT$M_NOECHO;
1439: cur_char_buf[1] &= ~TT$M_READSYNC;
1440: cur_char_buf[1] &= ~TT$M_REMOTE;
1441: cur_char_buf[1] |= TT$M_LOWER;
1442: cur_char_buf[1] |= TT$M_TTSYNC;
1443: cur_char_buf[1] |= TT$M_WRAP;
1444: cur_char_buf[1] &= ~TT$M_EIGHTBIT;
1445: cur_char_buf[1] &= ~TT$M_MECHTAB;
1446: cur_char_buf[1] &= ~TT$M_SCOPE;
1447: cur_char_buf[1] |= TT$M_HOSTSYNC;
1448:
1449: cur_char_buf[2] &= ~TT2$M_APP_KEYPAD;
1450: cur_char_buf[2] &= ~TT2$M_BLOCK;
1451: cur_char_buf[2] &= ~TT2$M_DECCRT3;
1452: cur_char_buf[2] &= ~TT2$M_LOCALECHO;
1453: cur_char_buf[2] &= ~TT2$M_PASTHRU;
1454: cur_char_buf[2] &= ~TT2$M_REGIS;
1455: cur_char_buf[2] &= ~TT2$M_SIXEL;
1456: cur_char_buf[2] |= TT2$M_BRDCSTMBX;
1457: cur_char_buf[2] |= TT2$M_EDITING;
1458: cur_char_buf[2] |= TT2$M_INSERT;
1459: cur_char_buf[2] |= TT2$M_PRINTER;
1460: cur_char_buf[2] &= ~TT2$M_ANSICRT;
1461: cur_char_buf[2] &= ~TT2$M_AVO;
1462: cur_char_buf[2] &= ~TT2$M_DECCRT;
1463: cur_char_buf[2] &= ~TT2$M_DECCRT2;
1464: cur_char_buf[2] &= ~TT2$M_DRCS;
1465: cur_char_buf[2] &= ~TT2$M_EDIT;
1466: cur_char_buf[2] |= TT2$M_FALLBACK;
1467:
1468: status = sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, cur_char_buf, 12, 0, 0, 0, 0);
1469: if (status == SS$_BADPARAM) {
1470: /* terminal fallback utility not installed on system */
1471: cur_char_buf[2] &= ~TT2$M_FALLBACK;
1472: sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, cur_char_buf, 12, 0, 0, 0, 0);
1473: } else {
1474: if (status != SS$_NORMAL)
1475: lib$signal(status, 0, 0);
1476: }
1477: sys$dassgn(chan);
1478: }
1479:
1480: void term_mode_native()
1481: /* set terminal mode back to native */
1482: {
1483: int i;
1484: if (gpoutfile != stdout)
1485: return; /* don't modify if not stdout */
1486: sys$assign(&sysoutput_desc, &chan, 0, 0);
1487: sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, old_char_buf, 12, 0, 0, 0, 0);
1488: for (i = 0; i < 3; ++i)
1489: cur_char_buf[i] = old_char_buf[i];
1490: sys$dassgn(chan);
1491: }
1492:
1493: void term_pasthru()
1494: /* set terminal mode pasthru */
1495: {
1496: if (gpoutfile != stdout)
1497: return; /* don't modify if not stdout */
1498: sys$assign(&sysoutput_desc, &chan, 0, 0);
1499: cur_char_buf[2] |= TT2$M_PASTHRU;
1500: sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, cur_char_buf, 12, 0, 0, 0, 0);
1501: sys$dassgn(chan);
1502: }
1503:
1504: void term_nopasthru()
1505: /* set terminal mode nopasthru */
1506: {
1507: if (gpoutfile != stdout)
1508: return; /* don't modify if not stdout */
1509: sys$assign(&sysoutput_desc, &chan, 0, 0);
1510: cur_char_buf[2] &= ~TT2$M_PASTHRU;
1511: sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, cur_char_buf, 12, 0, 0, 0, 0);
1512: sys$dassgn(chan);
1513: }
1514:
1515: void fflush_binary()
1516: {
1517: typedef short int INT16; /* signed 16-bit integers */
1518: register INT16 k; /* loop index */
1519: if (gpoutfile != stdout) {
1520: /* Stupid VMS fflush() raises error and loses last data block
1521: unless it is full for a fixed-length record binary file.
1522: Pad it here with NULL characters. */
1523: for (k = (INT16) ((*gpoutfile)->_cnt); k > 0; --k)
1524: putc('\0', gpoutfile);
1525: fflush(gpoutfile);
1526: }
1527: }
1528: #endif /* VMS */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>