Annotation of OpenXM_contrib/gnuplot/term/pm.trm, Revision 1.1.1.2
1.1 maekawa 1: /*
1.1.1.2 ! maekawa 2: * $Id: pm.trm,v 1.13 1998/12/23 21:53:26 lhecking Exp $
1.1 maekawa 3: */
4:
5: /* GNUPLOT - pm.trm */
6:
7: /*[
8: * Copyright 1992, 1993, 1998
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: * pm.trm --- inboard terminal driver for Presentation Manager
39: * --- after X-11 driver, by R.W.Fearick 31/1/92.
40: * v1.1 11/8/92 -- speed things up
41: */
42:
43: #include "driver.h"
44:
45: #ifdef TERM_REGISTER
46: register_term(pm)
47: #endif
48:
49: #ifdef TERM_PROTO
50: TERM_PUBLIC void PM_init __PROTO((void));
51: TERM_PUBLIC void PM_options __PROTO((void));
52: TERM_PUBLIC void PM_reset __PROTO((void));
53: TERM_PUBLIC void PM_text __PROTO((void));
54: TERM_PUBLIC void PM_graphics __PROTO((void));
55: TERM_PUBLIC void PM_linetype __PROTO((int lt));
56: TERM_PUBLIC void PM_move __PROTO((unsigned int x, unsigned int y));
57: TERM_PUBLIC void PM_vector __PROTO((unsigned int x, unsigned int y));
58: TERM_PUBLIC int PM_text_angle __PROTO((int ang));
59: TERM_PUBLIC void PM_put_text __PROTO((unsigned int x, unsigned int y, char *str));
60: TERM_PUBLIC int PM_justify_text __PROTO((enum JUSTIFY mode));
61: TERM_PUBLIC void PM_point __PROTO((unsigned int x, unsigned int y, int number));
62: TERM_PUBLIC void PM_suspend __PROTO((void));
63: TERM_PUBLIC void PM_resume __PROTO((void));
64: TERM_PUBLIC void PM_linewidth __PROTO((double linewidth));
65:
66: /* define PM world coordinate limits */
67:
68: #define PM_XMAX 19500
69: #define PM_YMAX 12500
70:
71: /* approximations for typical font/screen sizes */
72: #define PM_VCHAR (550)
73: #define PM_HCHAR (220)
74: #define PM_VTIC (200)
75: #define PM_HTIC (200)
76: #endif
77:
78: #ifdef TERM_BODY
79:
80: #include <stdio.h>
81: #include <process.h>
82: #include <io.h>
83: #define INCL_DOSPROCESS
84: #define INCL_DOSSEMAPHORES
85: #define INCL_DOSMISC
86: #define INCL_DOSMODULEMGR
87: #include <os2.h>
88:
89:
90: /* graphics commands */
91: #define SET_GRAPHICS 'G'
92: #define SET_TEXT 'E'
93: #define SET_LINE 'L'
94: #define SET_LINEWIDTH 'W'
95: #define SET_ANGLE 'A'
96: #define SET_JUSTIFY 'J'
97: #define SET_POINTMODE 'D'
98: #define SET_FONT 'F'
99: #define SET_OPTIONS 'O'
100: #define GR_QUERY 'Q'
101: #define GR_SUSPEND 'E' /*'s' */
102: #define GR_RESUME 'r'
103: #define GR_MOVE 'M'
104: #define GR_DRAW 'V'
105: #define GR_RESET 'R'
106: #define GR_TEXT 'T'
107: #define GR_PAUSE 'P'
108: #define GR_HELP 'H'
109: #define PM_nopts 1
110:
111: /* path for pm program */
112: static char PM_path[256] = "";
113: /* track mode to avoid redraw after hitting break */
114: static int PM_mode = 0;
115: static HEV hev;
116: static int PM_termmode = 0;
117: static int PM_must_reset_opts = FALSE;
118: static int PM_must_abort = 0;
119:
120: static char PM_opts[256] = "";
121: static int PM_optargs = 0;
122: static int PM_plot_number = 0;
123: static char PM_term_title[128] = "";
124:
125: FILE *fopen();
126: static FILE *PM_pipe = NULL;
127: static FILE *PM_savepipe = NULL;
128:
129: int PM_pause __PROTO((char *str));
130: void PM_setup(void);
131: static void PM_reset_opts(void);
132: static void PM_query(void);
133: static void PM_make_servername(char *);
134: static void PM_abortplot();
135:
136: TERM_PUBLIC void PM_init()
137: {
138: static char buffer[1024];
139: int pid;
140: int rc;
141: int spawnmode;
142: PPIB pib;
143: PTIB tib;
144: char semname[32];
145: char pipename[32];
146: char tempname[32];
147:
148: term_force_init = TRUE;
149: if (PM_savepipe != NULL && PM_termmode == 0) {
150: PM_pipe = PM_savepipe;
151: }
152: if ((PM_pipe == NULL) && (PM_termmode & 2)) {
153: /* check if term is running */
154: PM_make_servername(tempname);
155: strcpy(pipename, "\\pipe\\");
156: strcat(pipename, tempname);
157: // sprintf( pipename, "\\pipe\\gpServ%d", PM_plot_number ) ;
158: DosGetInfoBlocks(&tib, &pib);
159: PM_pipe = fopen(pipename, "r+b");
160: if (PM_pipe != NULL) {
161: setvbuf(PM_pipe, buffer, _IOFBF, 1024);
162: pid = pib->pib_ulpid;
163: fwrite(&pid, 1, 4, PM_pipe);
164: fflush(PM_pipe);
165: /* set new options */
166: // PM_reset_opts() ;
167: }
168: }
169: /* else we start up term here */
170: if (PM_pipe == NULL) {
171: if (PM_termmode & 2) {
172: PM_make_servername(tempname);
173: // sprintf( tempname, "gpServ%d", PM_plot_number ) ;
174: } else {
175: static int gpid = 0;
176: gpid++;
177: sprintf(tempname, "gp%X%d", getpid(), gpid);
178: }
179: strcpy(semname, "\\sem32\\");
180: strcpy(pipename, "\\pipe\\");
181: strcat(semname, tempname);
182: strcat(pipename, tempname);
183: strcat(PM_path, "\\gnupmdrv.exe");
184: rc = access(PM_path, 0);
185: /* find exe file */
186: if (rc != 0)
187: rc = DosSearchPath(0x0002, /* search GNUPLOT environment */
188: "GNUPLOT",
189: "gnupmdrv.exe",
190: PM_path,
191: 256);
192:
193: if (rc != 0)
194: rc = DosSearchPath(0x0003, /* then try current directory & path */
195: "PATH",
196: "gnupmdrv.exe",
197: PM_path,
198: 256);
199: if (rc != 0) {
200: fputs("Cannot find gnupmdrv.exe !\n", stderr);
201: exit(3);
202: }
203: rc = DosCreateEventSem(semname, &hev, 1, 0);
204: if (rc != 0) {
205: fputs("Cannot create semaphore !\n", stderr);
206: exit(3);
207: }
208: spawnmode = P_SESSION | P_DEFAULT;
209: if (PM_optargs != 0)
210: spawnmode |= P_UNRELATED;
211: pid = spawnl(spawnmode, PM_path, "GnuplotPM", tempname, PM_opts, NULL);
212: if (pid == -1) {
213: fputs("Cannot spawn gnupmdrv.exe !\n", stderr);
214: exit(3);
215: }
216: DosGetInfoBlocks(&tib, &pib);
217: DosWaitEventSem(hev, 10000);
218: DosCloseEventSem(hev);
219: PM_pipe = fopen(pipename, "r+b");
220: if (PM_pipe == NULL) {
221: fputs("Cannot open pipe to gnupmdrv.exe !\n", stderr);
222: exit(3);
223: } else if (PM_termmode == 0)
224: PM_savepipe = PM_pipe;
225: setvbuf(PM_pipe, buffer, _IOFBF, 1024);
226: pid = pib->pib_ulpid;
227: fwrite(&pid, 1, 4, PM_pipe);
228: fflush(PM_pipe);
229: } else {
230: if (PM_must_reset_opts)
231: PM_reset_opts();
232: }
233: PM_query();
234: }
235:
236: static void PM_make_servername(char *str)
237: {
238: if (PM_term_title[0]) {
239: int hash = 0;
240: char *p = PM_term_title + 1;
241: int match = PM_term_title[0];
242: while (*p != match) {
243: hash = (hash << 1) + hash + *p++;
244: }
245: hash %= (256 * 256 * 256 - 1);
246: sprintf(str, "gp%x", hash);
247: } else
248: sprintf(str, "gpServ%d", PM_plot_number);
249: }
250:
251:
252: TERM_PUBLIC void PM_options()
253: {
254: int old_termmode = PM_termmode;
255: PM_termmode = 0;
256: term_options[0] = NUL;
257: PM_term_title[0] = NUL;
258: PM_opts[0] = NUL;
259: PM_optargs = 0;
260: while (!END_OF_COMMAND) {
261: if (almost_equals(c_token, "pe$rsist")) {
262: strcat(PM_opts, "-p ");
263: strcat(term_options, "persist ");
264: PM_termmode |= 1;
265: PM_optargs = 1;
266: if (!(old_termmode & 1))
267: PM_pipe = NULL;
268: } else if (almost_equals(c_token, "s$erver")) {
269: strcat(PM_opts, "-s ");
270: strcat(term_options, "server ");
271: PM_termmode |= 2;
272: PM_optargs = 1;
273: if (!(old_termmode & 2))
274: PM_pipe = NULL;
275: if (isanumber(c_token + 1)) {
276: struct value t;
277: char *p = PM_opts + strlen(PM_opts);
278: c_token++;
279: PM_plot_number = (int) real(const_express(&t));
280: sprintf(p, "%d", PM_plot_number);
281: sprintf(term_options + strlen(term_options), "%d", PM_plot_number);
282: }
283: } else if (almost_equals(c_token, "w$idelines")) {
284: strcat(PM_opts, "-w ");
285: strcat(term_options, "widelines ");
286: PM_optargs = 1;
287: } else if (almost_equals(c_token, "e$nhanced")) {
288: strcat(PM_opts, "-e ");
289: strcat(term_options, "enhanced ");
290: PM_optargs = 1;
291: } else if (isstring(c_token)) {
292: copy_str(PM_term_title, c_token, 127);
293: }
294: #if 0
295: else if (almost_equals(c_token, "po$rtrait")) {
296: strcat(PM_opts, "-l ");
297: strcat(term_options, "portrait ");
298: PM_optargs = 1;
299: }
300: #endif
301: c_token++;
302: }
303: if (PM_term_title[0]) {
304: strcat(PM_opts, " ");
305: strcat(term_options, " ");
306: strcat(PM_opts, PM_term_title);
307: strcat(term_options, PM_term_title);
308: }
309: PM_must_reset_opts = TRUE;
310: }
311:
312: static void PM_reset_opts()
313: {
314: int len;
315: putc(SET_OPTIONS, PM_pipe);
316: len = strlen(PM_opts) + 1;
317: fwrite(&len, sizeof(int), 1, PM_pipe);
318: fwrite(PM_opts, 1, len, PM_pipe);
319: for (len = sizeof(int) - len % sizeof(int); len > 0; len--) {
320: /* pad rest of int with zeros */
321: putc(NUL, PM_pipe);
322: }
323: fflush(PM_pipe);
324: PM_must_reset_opts = FALSE;
325: }
326:
327: static void PM_query()
328: {
329: int rc;
330: ULONG cbR;
331: putc(GR_QUERY, PM_pipe);
332: fflush(PM_pipe);
333: rc = DosRead(fileno(PM_pipe), &term->h_char, sizeof(int), &cbR);
334: rc = DosRead(fileno(PM_pipe), &term->v_char, sizeof(int), &cbR);
335: }
336:
337: TERM_PUBLIC void PM_reset()
338: {
339: putc(GR_RESET, PM_pipe);
340: fflush(PM_pipe);
341: term_force_init = FALSE;
342: if (PM_termmode > 0) {
343: fclose(PM_pipe);
344: PM_pipe = NULL;
345: }
346: }
347:
348: TERM_PUBLIC void PM_suspend()
349: {
350: putc(GR_SUSPEND, PM_pipe);
351: fflush(PM_pipe);
352: }
353:
354: TERM_PUBLIC void PM_resume()
355: {
356: putc(GR_RESUME, PM_pipe);
357: fflush(PM_pipe);
358: }
359:
360: TERM_PUBLIC void PM_text()
361: {
362: fflush(PM_pipe);
363: if (PM_mode != SET_TEXT) {
364: putc(SET_TEXT, PM_pipe);
365: fflush(PM_pipe);
366: // keep_term_initialised = term_initialised ;
367: // term_initialised = FALSE ; /* need to force init */
368: }
369: PM_mode = SET_TEXT;
370: }
371:
372: TERM_PUBLIC void PM_graphics()
373: {
374: putc(SET_GRAPHICS, PM_pipe);
375: fflush(PM_pipe);
376: PM_mode = SET_GRAPHICS;
377: }
378:
379: TERM_PUBLIC void PM_move(unsigned int x, unsigned int y)
380: {
381: if (PM_must_abort)
382: PM_abortplot();
383: putc(GR_MOVE, PM_pipe);
384: fwrite(&x, sizeof(int), 1, PM_pipe);
385: fwrite(&y, sizeof(int), 1, PM_pipe);
386: }
387:
388: TERM_PUBLIC void PM_vector(unsigned int x, unsigned int y)
389: {
390: if (PM_must_abort)
391: PM_abortplot();
392: putc(GR_DRAW, PM_pipe);
393: fwrite(&x, sizeof(int), 1, PM_pipe);
394: fwrite(&y, sizeof(int), 1, PM_pipe);
395: }
396:
397: TERM_PUBLIC void PM_linetype(int lt)
398: {
399: putc(SET_LINE, PM_pipe);
400: fwrite(<, sizeof(int), 1, PM_pipe);
401: }
402:
403: TERM_PUBLIC int PM_text_angle(int ang)
404: {
405: putc(SET_ANGLE, PM_pipe);
406: fwrite(&ang, sizeof(int), 1, PM_pipe);
407: return (TRUE);
408: }
409:
410: TERM_PUBLIC void PM_put_text(unsigned int x, unsigned int y, char *str)
411: {
412: int len;
413: if (PM_must_abort)
414: PM_abortplot();
415: putc(GR_TEXT, PM_pipe);
416: fwrite(&x, sizeof(int), 1, PM_pipe);
417: fwrite(&y, sizeof(int), 1, PM_pipe);
418: len = strlen(str) + 1;
419: fwrite(&len, sizeof(int), 1, PM_pipe);
420: fwrite(str, 1, len, PM_pipe);
421: for (len = sizeof(int) - len % sizeof(int); len > 0; len--) {
422: /* pad rest of int with zeros */
423: putc(NUL, PM_pipe);
424: }
425: }
426:
427: TERM_PUBLIC int PM_justify_text(enum JUSTIFY mode)
428: {
429: putc(SET_JUSTIFY, PM_pipe);
430: fwrite(&mode, sizeof(int), 1, PM_pipe);
431: return (TRUE);
432: }
433:
434: TERM_PUBLIC int PM_set_font(font) /* Entry font added by DJL */
435: char *font;
436: {
437: int len, fontsize;
438: char *p;
439: p = strchr(font, ',');
440: if (p == NULL || *p == NUL)
441: fontsize = 14;
442: else
443: fontsize = strtol(p + 1, NULL, 10);
444: if (fontsize <= 0)
445: fontsize = 14;
446: putc(SET_FONT, PM_pipe);
447: len = strlen(font) + 1;
448: fwrite(&len, sizeof(int), 1, PM_pipe);
449: fwrite(font, 1, len, PM_pipe);
450: for (len = sizeof(int) - len % sizeof(int); len > 0; len--) {
451: /* pad rest of int with zeros */
452: putc(NUL, PM_pipe);
453: }
454: return TRUE;
455: }
456:
457:
458: TERM_PUBLIC void PM_point(unsigned int x, unsigned int y, int number)
459: /*
460: ** tell the driver we are plotting a point so it can decide whether to
461: ** use colour or not
462: */
463: {
464: int mode;
465: mode = 1;
466: putc(SET_POINTMODE, PM_pipe);
467: fwrite(&mode, sizeof(int), 1, PM_pipe);
468: do_point(x, y, number);
469: mode = 0;
470: putc(SET_POINTMODE, PM_pipe);
471: fwrite(&mode, sizeof(int), 1, PM_pipe);
472: }
473:
474: void PM_abortplot()
475: {
476: PM_must_abort = 0;
477: term_reset();
478: (void) putc('\n', stderr);
479: bail_to_command_line();
480: }
481:
482: void PM_intc_cleanup()
483: {
484: if (PM_pipe == NULL || PM_mode == SET_TEXT)
485: PM_abortplot();
486: PM_must_abort = 1;
487: }
488:
489: void PM_setup(void)
490: /*
491: ** Initial terminal setup
492: */
493: {
494: char *envpath;
495: PPIB pib;
496: PTIB tib;
497: char path[256], *p;
498: DosGetInfoBlocks(&tib, &pib);
499: DosQueryModuleName(pib->pib_hmte, 256, path);
500: if (PM_path[0] == NUL) {
501: strcpy(PM_path, path);
502: p = strrchr(PM_path, '\\');
503: if (p != NULL)
504: *p = NUL;
505: else {
506: p = strrchr(PM_path, ':');
507: if (p != NULL)
508: *(p + 1) = NUL;
509: }
510: if (p == NULL)
511: _getcwd2(PM_path, 256);
512: }
513: if (getenv("GNUHELP") == NULL) {
514: int n = strlen("GNUHELP") + strlen(PM_path) + strlen("gnuplot.gih") + 3;
515: envpath = (char *) malloc(n);
516: if (envpath != NULL) {
517: strcpy(envpath, "GNUHELP");
518: strcat(envpath, "=");
519: strcat(envpath, PM_path);
520: strcat(envpath, "/");
521: strcat(envpath, "gnuplot.gih");
522: putenv(envpath);
523: }
524: }
525: if (getenv("GNUPLOT") == NULL) {
526: int n = strlen("GNUPLOT") + strlen(PM_path) + 2;
527: envpath = (char *) malloc(n);
528: if (envpath != NULL) {
529: strcpy(envpath, "GNUPLOT");
530: strcat(envpath, "=");
531: strcat(envpath, PM_path);
532: putenv(envpath);
533: }
534: }
535: }
536:
537: int PM_pause(char *str)
538: /*
539: ** pause - using message box on PM screen
540: */
541: {
542: int len, rc;
543: ULONG cbR;
544: char buf[256];
545: char *bp;
546:
547: if (PM_pipe == NULL)
548: return 2;
549: bp = buf;
550: putc(GR_PAUSE, PM_pipe);
551: len = strlen(str) + 1;
552: fwrite(&len, sizeof(int), 1, PM_pipe);
553: fwrite(str, 1, len, PM_pipe);
554: for (rc = sizeof(int) - len % sizeof(int); rc > 0; rc--) {
555: /* pad rest of int with zeros */
556: putc(NUL, PM_pipe);
557: }
558: fflush(PM_pipe);
559: rc = DosRead(fileno(PM_pipe), &len, sizeof(int), &cbR);
560: return len;
561: }
562:
563: TERM_PUBLIC void PM_linewidth(double linewidth)
564: {
565: int lw;
566: lw = linewidth * 100;
567: putc(SET_LINEWIDTH, PM_pipe);
568: fwrite(&lw, sizeof(int), 1, PM_pipe);
569: }
570:
571: #endif
572:
573: #ifdef TERM_TABLE
574: TERM_TABLE_START(PM_driver)
575: "pm", "OS/2 Presentation Manager",
576: PM_XMAX, PM_YMAX, PM_VCHAR, PM_HCHAR,
577: PM_VTIC, PM_HTIC, PM_options, PM_init, PM_reset,
578: PM_text, null_scale, PM_graphics, PM_move, PM_vector,
579: PM_linetype, PM_put_text, PM_text_angle,
580: PM_justify_text, PM_point, do_arrow, PM_set_font,
581: 0 /*pointsize */ , TERM_CAN_MULTIPLOT, PM_suspend, PM_resume,
582: 0 /*fillbox */ , PM_linewidth
583: TERM_TABLE_END(PM_driver)
584:
585: #undef LAST_TERM
586: #define LAST_TERM PM_driver
587:
588: #endif /* TERM_TABLE */
589:
590: #ifdef TERM_HELP
591: START_HELP(pm)
592: "1 pm",
593: "?commands set terminal pm",
594: "?set terminal pm",
595: "?set term pm",
596: "?terminal pm",
597: "?term pm",
598: "?pm",
599: " The `pm` terminal driver provides an OS/2 Presentation Manager window in",
600: " which the graph is plotted. The window is opened when the first graph is",
601: " plotted. This window has its own online help as well as facilities for",
602: " printing, copying to the clipboard and some line type and color adjustments.",
603: " The `multiplot` option is supported.",
604: "",
605: " Syntax:",
606: " set terminal pm {server {n}} {persist} {widelines} {enhanced} {\"title\"}",
607: "",
608: " If `persist` is specified, each graph appears in its own window and all",
609: " windows remain open after `gnuplot` exits. If `server` is specified, all",
610: " graphs appear in the same window, which remains open when `gnuplot` exits.",
611: " This option takes an optional numerical argument which specifies an instance",
612: " of the server process. Thus multiple server windows can be in use at the",
613: " same time.",
614: "",
615: " If `widelines` is specified, all plots will be drawn with wide lines. If",
616: " `enhanced` is specified, sub- and superscripts and multiple fonts are",
617: " enabled using the same syntax as the `enhanced postscript` option (see",
618: " `set terminal postscript enhanced` for details). Font names for the basic",
619: " PostScript fonts may be abbreviated to single letters.",
620: "",
621: " If `title` is specified, it will be used as the title of the plot window.",
622: " It will also be used as the name of the server instance, and will override",
623: " the optional numerical argument.",
624: "",
625: " Linewidths may be changed with `set linestyle`."
626: END_HELP(pm)
627: #endif /* TERM_HELP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>