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