/* * $Id: $ */ /* GNUPLOT - pm.trm */ /*[ * Copyright 1992, 1993, 1998 * * Permission to use, copy, and distribute this software and its * documentation for any purpose with or without fee is hereby granted, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. * * Permission to modify the software is granted, but not the right to * distribute the complete modified source code. Modifications are to * be distributed as patches to the released version. Permission to * distribute binaries produced by compiling modified sources is granted, * provided you * 1. distribute the corresponding source modifications from the * released version in the form of a patch file along with the binaries, * 2. add special version identification to distinguish your version * in addition to the base release version number, * 3. provide your name and address as the primary contact for the * support of your modified version, and * 4. retain our contact information in regard to use of the base * software. * Permission to distribute the released version of the source code along * with corresponding source modifications in the form of a patch file is * granted with same provisions 2 through 4 for binary distributions. * * This software is provided "as is" without express or implied warranty * to the extent permitted by applicable law. ]*/ /* * pm.trm --- inboard terminal driver for Presentation Manager * --- after X-11 driver, by R.W.Fearick 31/1/92. * v1.1 11/8/92 -- speed things up */ #include "driver.h" #ifdef TERM_REGISTER register_term(pm) #endif #ifdef TERM_PROTO TERM_PUBLIC void PM_init __PROTO((void)); TERM_PUBLIC void PM_options __PROTO((void)); TERM_PUBLIC void PM_reset __PROTO((void)); TERM_PUBLIC void PM_text __PROTO((void)); TERM_PUBLIC void PM_graphics __PROTO((void)); TERM_PUBLIC void PM_linetype __PROTO((int lt)); TERM_PUBLIC void PM_move __PROTO((unsigned int x, unsigned int y)); TERM_PUBLIC void PM_vector __PROTO((unsigned int x, unsigned int y)); TERM_PUBLIC int PM_text_angle __PROTO((int ang)); TERM_PUBLIC void PM_put_text __PROTO((unsigned int x, unsigned int y, char *str)); TERM_PUBLIC int PM_justify_text __PROTO((enum JUSTIFY mode)); TERM_PUBLIC void PM_point __PROTO((unsigned int x, unsigned int y, int number)); TERM_PUBLIC void PM_suspend __PROTO((void)); TERM_PUBLIC void PM_resume __PROTO((void)); TERM_PUBLIC void PM_linewidth __PROTO((double linewidth)); /* define PM world coordinate limits */ #define PM_XMAX 19500 #define PM_YMAX 12500 /* approximations for typical font/screen sizes */ #define PM_VCHAR (550) #define PM_HCHAR (220) #define PM_VTIC (200) #define PM_HTIC (200) #endif #ifdef TERM_BODY #include #include #include #define INCL_DOSPROCESS #define INCL_DOSSEMAPHORES #define INCL_DOSMISC #define INCL_DOSMODULEMGR #include /* graphics commands */ #define SET_GRAPHICS 'G' #define SET_TEXT 'E' #define SET_LINE 'L' #define SET_LINEWIDTH 'W' #define SET_ANGLE 'A' #define SET_JUSTIFY 'J' #define SET_POINTMODE 'D' #define SET_FONT 'F' #define SET_OPTIONS 'O' #define GR_QUERY 'Q' #define GR_SUSPEND 'E' /*'s' */ #define GR_RESUME 'r' #define GR_MOVE 'M' #define GR_DRAW 'V' #define GR_RESET 'R' #define GR_TEXT 'T' #define GR_PAUSE 'P' #define GR_HELP 'H' #define PM_nopts 1 /* path for pm program */ static char PM_path[256] = ""; /* track mode to avoid redraw after hitting break */ static int PM_mode = 0; static HEV hev; static int PM_termmode = 0; static int PM_must_reset_opts = FALSE; static int PM_must_abort = 0; static char PM_opts[256] = ""; static int PM_optargs = 0; static int PM_plot_number = 0; static char PM_term_title[128] = ""; FILE *fopen(); static FILE *PM_pipe = NULL; static FILE *PM_savepipe = NULL; int PM_pause __PROTO((char *str)); void PM_setup(void); static void PM_reset_opts(void); static void PM_query(void); static void PM_make_servername(char *); static void PM_abortplot(); TERM_PUBLIC void PM_init() { static char buffer[1024]; int pid; int rc; int spawnmode; PPIB pib; PTIB tib; char semname[32]; char pipename[32]; char tempname[32]; term_force_init = TRUE; if (PM_savepipe != NULL && PM_termmode == 0) { PM_pipe = PM_savepipe; } if ((PM_pipe == NULL) && (PM_termmode & 2)) { /* check if term is running */ PM_make_servername(tempname); strcpy(pipename, "\\pipe\\"); strcat(pipename, tempname); // sprintf( pipename, "\\pipe\\gpServ%d", PM_plot_number ) ; DosGetInfoBlocks(&tib, &pib); PM_pipe = fopen(pipename, "r+b"); if (PM_pipe != NULL) { setvbuf(PM_pipe, buffer, _IOFBF, 1024); pid = pib->pib_ulpid; fwrite(&pid, 1, 4, PM_pipe); fflush(PM_pipe); /* set new options */ // PM_reset_opts() ; } } /* else we start up term here */ if (PM_pipe == NULL) { if (PM_termmode & 2) { PM_make_servername(tempname); // sprintf( tempname, "gpServ%d", PM_plot_number ) ; } else { static int gpid = 0; gpid++; sprintf(tempname, "gp%X%d", getpid(), gpid); } strcpy(semname, "\\sem32\\"); strcpy(pipename, "\\pipe\\"); strcat(semname, tempname); strcat(pipename, tempname); strcat(PM_path, "\\gnupmdrv.exe"); rc = access(PM_path, 0); /* find exe file */ if (rc != 0) rc = DosSearchPath(0x0002, /* search GNUPLOT environment */ "GNUPLOT", "gnupmdrv.exe", PM_path, 256); if (rc != 0) rc = DosSearchPath(0x0003, /* then try current directory & path */ "PATH", "gnupmdrv.exe", PM_path, 256); if (rc != 0) { fputs("Cannot find gnupmdrv.exe !\n", stderr); exit(3); } rc = DosCreateEventSem(semname, &hev, 1, 0); if (rc != 0) { fputs("Cannot create semaphore !\n", stderr); exit(3); } spawnmode = P_SESSION | P_DEFAULT; if (PM_optargs != 0) spawnmode |= P_UNRELATED; pid = spawnl(spawnmode, PM_path, "GnuplotPM", tempname, PM_opts, NULL); if (pid == -1) { fputs("Cannot spawn gnupmdrv.exe !\n", stderr); exit(3); } DosGetInfoBlocks(&tib, &pib); DosWaitEventSem(hev, 10000); DosCloseEventSem(hev); PM_pipe = fopen(pipename, "r+b"); if (PM_pipe == NULL) { fputs("Cannot open pipe to gnupmdrv.exe !\n", stderr); exit(3); } else if (PM_termmode == 0) PM_savepipe = PM_pipe; setvbuf(PM_pipe, buffer, _IOFBF, 1024); pid = pib->pib_ulpid; fwrite(&pid, 1, 4, PM_pipe); fflush(PM_pipe); } else { if (PM_must_reset_opts) PM_reset_opts(); } PM_query(); } static void PM_make_servername(char *str) { if (PM_term_title[0]) { int hash = 0; char *p = PM_term_title + 1; int match = PM_term_title[0]; while (*p != match) { hash = (hash << 1) + hash + *p++; } hash %= (256 * 256 * 256 - 1); sprintf(str, "gp%x", hash); } else sprintf(str, "gpServ%d", PM_plot_number); } TERM_PUBLIC void PM_options() { int old_termmode = PM_termmode; PM_termmode = 0; term_options[0] = NUL; PM_term_title[0] = NUL; PM_opts[0] = NUL; PM_optargs = 0; while (!END_OF_COMMAND) { if (almost_equals(c_token, "pe$rsist")) { strcat(PM_opts, "-p "); strcat(term_options, "persist "); PM_termmode |= 1; PM_optargs = 1; if (!(old_termmode & 1)) PM_pipe = NULL; } else if (almost_equals(c_token, "s$erver")) { strcat(PM_opts, "-s "); strcat(term_options, "server "); PM_termmode |= 2; PM_optargs = 1; if (!(old_termmode & 2)) PM_pipe = NULL; if (isanumber(c_token + 1)) { struct value t; char *p = PM_opts + strlen(PM_opts); c_token++; PM_plot_number = (int) real(const_express(&t)); sprintf(p, "%d", PM_plot_number); sprintf(term_options + strlen(term_options), "%d", PM_plot_number); } } else if (almost_equals(c_token, "w$idelines")) { strcat(PM_opts, "-w "); strcat(term_options, "widelines "); PM_optargs = 1; } else if (almost_equals(c_token, "e$nhanced")) { strcat(PM_opts, "-e "); strcat(term_options, "enhanced "); PM_optargs = 1; } else if (isstring(c_token)) { copy_str(PM_term_title, c_token, 127); } #if 0 else if (almost_equals(c_token, "po$rtrait")) { strcat(PM_opts, "-l "); strcat(term_options, "portrait "); PM_optargs = 1; } #endif c_token++; } if (PM_term_title[0]) { strcat(PM_opts, " "); strcat(term_options, " "); strcat(PM_opts, PM_term_title); strcat(term_options, PM_term_title); } PM_must_reset_opts = TRUE; } static void PM_reset_opts() { int len; putc(SET_OPTIONS, PM_pipe); len = strlen(PM_opts) + 1; fwrite(&len, sizeof(int), 1, PM_pipe); fwrite(PM_opts, 1, len, PM_pipe); for (len = sizeof(int) - len % sizeof(int); len > 0; len--) { /* pad rest of int with zeros */ putc(NUL, PM_pipe); } fflush(PM_pipe); PM_must_reset_opts = FALSE; } static void PM_query() { int rc; ULONG cbR; putc(GR_QUERY, PM_pipe); fflush(PM_pipe); rc = DosRead(fileno(PM_pipe), &term->h_char, sizeof(int), &cbR); rc = DosRead(fileno(PM_pipe), &term->v_char, sizeof(int), &cbR); } TERM_PUBLIC void PM_reset() { putc(GR_RESET, PM_pipe); fflush(PM_pipe); term_force_init = FALSE; if (PM_termmode > 0) { fclose(PM_pipe); PM_pipe = NULL; } } TERM_PUBLIC void PM_suspend() { putc(GR_SUSPEND, PM_pipe); fflush(PM_pipe); } TERM_PUBLIC void PM_resume() { putc(GR_RESUME, PM_pipe); fflush(PM_pipe); } TERM_PUBLIC void PM_text() { fflush(PM_pipe); if (PM_mode != SET_TEXT) { putc(SET_TEXT, PM_pipe); fflush(PM_pipe); // keep_term_initialised = term_initialised ; // term_initialised = FALSE ; /* need to force init */ } PM_mode = SET_TEXT; } TERM_PUBLIC void PM_graphics() { putc(SET_GRAPHICS, PM_pipe); fflush(PM_pipe); PM_mode = SET_GRAPHICS; } TERM_PUBLIC void PM_move(unsigned int x, unsigned int y) { if (PM_must_abort) PM_abortplot(); putc(GR_MOVE, PM_pipe); fwrite(&x, sizeof(int), 1, PM_pipe); fwrite(&y, sizeof(int), 1, PM_pipe); } TERM_PUBLIC void PM_vector(unsigned int x, unsigned int y) { if (PM_must_abort) PM_abortplot(); putc(GR_DRAW, PM_pipe); fwrite(&x, sizeof(int), 1, PM_pipe); fwrite(&y, sizeof(int), 1, PM_pipe); } TERM_PUBLIC void PM_linetype(int lt) { putc(SET_LINE, PM_pipe); fwrite(<, sizeof(int), 1, PM_pipe); } TERM_PUBLIC int PM_text_angle(int ang) { putc(SET_ANGLE, PM_pipe); fwrite(&ang, sizeof(int), 1, PM_pipe); return (TRUE); } TERM_PUBLIC void PM_put_text(unsigned int x, unsigned int y, char *str) { int len; if (PM_must_abort) PM_abortplot(); putc(GR_TEXT, PM_pipe); fwrite(&x, sizeof(int), 1, PM_pipe); fwrite(&y, sizeof(int), 1, PM_pipe); len = strlen(str) + 1; fwrite(&len, sizeof(int), 1, PM_pipe); fwrite(str, 1, len, PM_pipe); for (len = sizeof(int) - len % sizeof(int); len > 0; len--) { /* pad rest of int with zeros */ putc(NUL, PM_pipe); } } TERM_PUBLIC int PM_justify_text(enum JUSTIFY mode) { putc(SET_JUSTIFY, PM_pipe); fwrite(&mode, sizeof(int), 1, PM_pipe); return (TRUE); } TERM_PUBLIC int PM_set_font(font) /* Entry font added by DJL */ char *font; { int len, fontsize; char *p; p = strchr(font, ','); if (p == NULL || *p == NUL) fontsize = 14; else fontsize = strtol(p + 1, NULL, 10); if (fontsize <= 0) fontsize = 14; putc(SET_FONT, PM_pipe); len = strlen(font) + 1; fwrite(&len, sizeof(int), 1, PM_pipe); fwrite(font, 1, len, PM_pipe); for (len = sizeof(int) - len % sizeof(int); len > 0; len--) { /* pad rest of int with zeros */ putc(NUL, PM_pipe); } return TRUE; } TERM_PUBLIC void PM_point(unsigned int x, unsigned int y, int number) /* ** tell the driver we are plotting a point so it can decide whether to ** use colour or not */ { int mode; mode = 1; putc(SET_POINTMODE, PM_pipe); fwrite(&mode, sizeof(int), 1, PM_pipe); do_point(x, y, number); mode = 0; putc(SET_POINTMODE, PM_pipe); fwrite(&mode, sizeof(int), 1, PM_pipe); } void PM_abortplot() { PM_must_abort = 0; term_reset(); (void) putc('\n', stderr); bail_to_command_line(); } void PM_intc_cleanup() { if (PM_pipe == NULL || PM_mode == SET_TEXT) PM_abortplot(); PM_must_abort = 1; } void PM_setup(void) /* ** Initial terminal setup */ { char *envpath; PPIB pib; PTIB tib; char path[256], *p; DosGetInfoBlocks(&tib, &pib); DosQueryModuleName(pib->pib_hmte, 256, path); if (PM_path[0] == NUL) { strcpy(PM_path, path); p = strrchr(PM_path, '\\'); if (p != NULL) *p = NUL; else { p = strrchr(PM_path, ':'); if (p != NULL) *(p + 1) = NUL; } if (p == NULL) _getcwd2(PM_path, 256); } if (getenv("GNUHELP") == NULL) { int n = strlen("GNUHELP") + strlen(PM_path) + strlen("gnuplot.gih") + 3; envpath = (char *) malloc(n); if (envpath != NULL) { strcpy(envpath, "GNUHELP"); strcat(envpath, "="); strcat(envpath, PM_path); strcat(envpath, "/"); strcat(envpath, "gnuplot.gih"); putenv(envpath); } } if (getenv("GNUPLOT") == NULL) { int n = strlen("GNUPLOT") + strlen(PM_path) + 2; envpath = (char *) malloc(n); if (envpath != NULL) { strcpy(envpath, "GNUPLOT"); strcat(envpath, "="); strcat(envpath, PM_path); putenv(envpath); } } } int PM_pause(char *str) /* ** pause - using message box on PM screen */ { int len, rc; ULONG cbR; char buf[256]; char *bp; if (PM_pipe == NULL) return 2; bp = buf; putc(GR_PAUSE, PM_pipe); len = strlen(str) + 1; fwrite(&len, sizeof(int), 1, PM_pipe); fwrite(str, 1, len, PM_pipe); for (rc = sizeof(int) - len % sizeof(int); rc > 0; rc--) { /* pad rest of int with zeros */ putc(NUL, PM_pipe); } fflush(PM_pipe); rc = DosRead(fileno(PM_pipe), &len, sizeof(int), &cbR); return len; } TERM_PUBLIC void PM_linewidth(double linewidth) { int lw; lw = linewidth * 100; putc(SET_LINEWIDTH, PM_pipe); fwrite(&lw, sizeof(int), 1, PM_pipe); } #endif #ifdef TERM_TABLE TERM_TABLE_START(PM_driver) "pm", "OS/2 Presentation Manager", PM_XMAX, PM_YMAX, PM_VCHAR, PM_HCHAR, PM_VTIC, PM_HTIC, PM_options, PM_init, PM_reset, PM_text, null_scale, PM_graphics, PM_move, PM_vector, PM_linetype, PM_put_text, PM_text_angle, PM_justify_text, PM_point, do_arrow, PM_set_font, 0 /*pointsize */ , TERM_CAN_MULTIPLOT, PM_suspend, PM_resume, 0 /*fillbox */ , PM_linewidth TERM_TABLE_END(PM_driver) #undef LAST_TERM #define LAST_TERM PM_driver #endif /* TERM_TABLE */ #ifdef TERM_HELP START_HELP(pm) "1 pm", "?commands set terminal pm", "?set terminal pm", "?set term pm", "?terminal pm", "?term pm", "?pm", " The `pm` terminal driver provides an OS/2 Presentation Manager window in", " which the graph is plotted. The window is opened when the first graph is", " plotted. This window has its own online help as well as facilities for", " printing, copying to the clipboard and some line type and color adjustments.", " The `multiplot` option is supported.", "", " Syntax:", " set terminal pm {server {n}} {persist} {widelines} {enhanced} {\"title\"}", "", " If `persist` is specified, each graph appears in its own window and all", " windows remain open after `gnuplot` exits. If `server` is specified, all", " graphs appear in the same window, which remains open when `gnuplot` exits.", " This option takes an optional numerical argument which specifies an instance", " of the server process. Thus multiple server windows can be in use at the", " same time.", "", " If `widelines` is specified, all plots will be drawn with wide lines. If", " `enhanced` is specified, sub- and superscripts and multiple fonts are", " enabled using the same syntax as the `enhanced postscript` option (see", " `set terminal postscript enhanced` for details). Font names for the basic", " PostScript fonts may be abbreviated to single letters.", "", " If `title` is specified, it will be used as the title of the plot window.", " It will also be used as the name of the server instance, and will override", " the optional numerical argument.", "", " Linewidths may be changed with `set linestyle`." END_HELP(pm) #endif /* TERM_HELP */