--- /dev/null
+/* Hello, Emacs, this is -*-C-*-
+ * $Id: x11.trm,v 1.160.2.14 2009/05/29 03:25:29 sfeam Exp $
+ *
+ */
+
+/* GNUPLOT - x11.trm */
+
+/*[
+ * Copyright 1986 - 1993, 1998, 2004 Thomas Williams, Colin Kelley
+ *
+ * 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.
+]*/
+
+/*
+ * x11.trm --- inboard terminal driver for X11
+ */
+
+/* Petr Mikulik and Johannes Zellner: added mouse support (October 1999)
+ * Implementation and functionality is based on pm.trm
+ */
+
+/* X11 support for Petr Mikulik's pm3d
+ * by Johannes Zellner <johannes@zellner.org>
+ * (November 1999 - January 2000)
+ */
+
+/* Dynamic font support, enhanced text mode support,
+ * additional feedback from outboard driver
+ * Ethan A Merritt <merritt@u.washington.edu>
+ * 2003
+ */
+
+/* Daniel Sebald: added X11 support for images. (27 February 2003)
+ */
+
+#include "driver.h"
+
+#ifdef TERM_REGISTER
+register_term(x11)
+#endif
+
+#ifdef TERM_PROTO
+int X11_args __PROTO((int argc, char *argv[]));
+
+TERM_PUBLIC void X11_options __PROTO((void));
+TERM_PUBLIC void X11_init __PROTO((void));
+TERM_PUBLIC void X11_graphics __PROTO((void));
+TERM_PUBLIC void X11_text __PROTO((void));
+TERM_PUBLIC int X11_set_font __PROTO((const char * fontname));
+TERM_PUBLIC void X11_reset __PROTO((void));
+TERM_PUBLIC void X11_move __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void X11_vector __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void X11_linewidth __PROTO((double lw));
+TERM_PUBLIC void X11_pointsize __PROTO((double ps));
+TERM_PUBLIC void X11_linetype __PROTO((int lt));
+TERM_PUBLIC void X11_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
+TERM_PUBLIC int X11_text_angle __PROTO((int i));
+TERM_PUBLIC int X11_justify_text __PROTO((enum JUSTIFY mode));
+TERM_PUBLIC void X11_point __PROTO((unsigned int x, unsigned int y, int number));
+TERM_PUBLIC void X11_fillbox __PROTO((int style, unsigned int x, unsigned y, unsigned int width, unsigned int height));
+
+#if defined(WITH_IMAGE) || defined(BINARY_X11_POLYGON)
+TERM_PUBLIC void X11_send_endianess __PROTO((void));
+#endif
+
+# ifdef USE_MOUSE
+TERM_PUBLIC int X11_waitforinput __PROTO((void));
+TERM_PUBLIC void X11_set_ruler __PROTO((int, int));
+TERM_PUBLIC void X11_set_cursor __PROTO((int, int, int));
+TERM_PUBLIC void X11_put_tmptext __PROTO((int, const char str[]));
+TERM_PUBLIC void X11_set_clipboard __PROTO((const char[]));
+# endif
+
+TERM_PUBLIC void X11_update_opts __PROTO((void));
+TERM_PUBLIC int X11_make_palette __PROTO((t_sm_palette *));
+TERM_PUBLIC void X11_set_color __PROTO((t_colorspec *));
+TERM_PUBLIC void X11_filled_polygon __PROTO((int, gpiPoint *));
+
+# ifdef WITH_IMAGE
+TERM_PUBLIC void X11_image __PROTO((unsigned, unsigned, coordval *, gpiPoint *, t_imagecolor));
+# endif
+
+/* To support "set term x11 enhanced" */
+TERM_PUBLIC void ENHX11_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
+TERM_PUBLIC void ENHX11_OPEN __PROTO((char * fontname, double fontsize,
+ double base, TBOOLEAN widthflag, TBOOLEAN showflag,
+ int overprint));
+TERM_PUBLIC void ENHX11_FLUSH __PROTO((void));
+
+# define X11_XMAX 4096
+# define X11_YMAX 4096
+
+static int X11_SIZE_X = 640;
+static int X11_SIZE_Y = 450;
+static int X11_POSITION_X = 0;
+static int X11_POSITION_Y = 0;
+
+/* approximations for typical font/screen sizes */
+# define X11_VCHAR (X11_YMAX/25)
+# define X11_HCHAR (X11_XMAX/100)
+# define X11_VTIC (X11_YMAX/100)
+# define X11_HTIC (X11_XMAX/150)
+#endif /* TERM_PROTO */
+
+
+#ifndef TERM_PROTO_ONLY
+
+#ifdef TERM_BODY
+
+#include "gplt_x11.h"
+
+/* non-zero if '-display' found on command line */
+static int X11_Display = 0;
+
+/* Fonts can have very long names */
+/* EAM FIXME - these should be dynamically allocated */
+#define X11_MAX_FONTNAME_LENGTH 255
+static char X11_default_font[X11_MAX_FONTNAME_LENGTH+1] = {'\0'};
+static int X11_default_fontsize = 12;
+static char X11_last_font_used[X11_MAX_FONTNAME_LENGTH+1] = {'\01','\0'};
+static char X11_next_font_used[X11_MAX_FONTNAME_LENGTH+1] = {'\0'};
+static enum JUSTIFY X11_last_justification = LEFT;
+
+static void X11_atexit __PROTO((void));
+static void X11_set_default_font __PROTO((void));
+
+static void transmit_gradient __PROTO((gradient_struct *gradient, int cnt));
+
+/* Merged the old char X11_opts[] and int X11_optarg[]
+ * into one array of structs.
+ * Loosely based on XrmOptionDescRec, the use of which
+ * would probably be overkill here. */
+typedef enum { hasNoArg, hasArg } OptionArg;
+
+static struct x11opt {
+ const char *option; /* Name of option */
+ OptionArg arg; /* Whether option has argument */
+} X11_cmdopts[] = {
+ { "-mono", hasNoArg}, { "-gray", hasNoArg}, { "-clear", hasNoArg},
+ { "-tvtwm", hasNoArg}, { "-pointsize", hasArg},
+ { "-iconic", hasNoArg}, { "-rv", hasNoArg},
+ { "-reverse", hasNoArg}, { "+rv", hasNoArg},
+ { "-synchronous", hasNoArg},
+ { "-display", hasArg}, { "-geometry", hasArg}, { "-bg", hasArg},
+ { "-background", hasArg}, { "-bd", hasArg},
+ { "-bordercolor", hasArg}, { "-bw", hasArg},
+ { "-borderwidth", hasArg}, { "-fg", hasArg},
+ { "-foreground", hasArg}, { "-fn", hasArg}, { "-font", hasArg},
+ { "-name", hasArg},
+ { "-selectionTimeout", hasArg}, { "-title", hasArg},
+ { "-xnllanguage", hasArg}, { "-xrm", hasArg},
+ { "-raise", hasNoArg}, { "-noraise", hasNoArg},
+ { "-solid", hasNoArg}, { "-dashed", hasNoArg},
+ { "-persist", hasNoArg}
+#ifdef USE_MOUSE
+ , { "-nofeedback", hasNoArg}
+ , { "-noevents", hasNoArg}
+ , { "-ctrlq", hasNoArg}
+#endif
+};
+
+#define X11_nopts (sizeof(X11_cmdopts) / sizeof(X11_cmdopts[0]))
+
+static FILE *X11_ipc = (FILE *) 0;
+#ifdef PIPE_IPC
+#define X11_ipc_back_fd ipc_back_fd
+#endif
+
+static char **xargv = (char **) NULL;
+/* reserve a minimum 10 driver opts */
+static char *optvec[2 * X11_nopts + 1 + 10];
+
+/* gnuplot_x11 has extension .exe on OS/2 and Windows (and on RSX/VMS, but
+ these construct their own full path GNUPLOT_X11 in their build script).
+*/
+# if defined(OS2) || defined(_Windows)
+# ifndef GNUPLOT_X11
+static char X11_default_command[] = "gnuplot_x11.exe";
+# else
+static char X11_default_command[] = GNUPLOT_X11 ".exe";
+# endif
+# else /* thus !OS/2 && !Windows */
+# ifndef GNUPLOT_X11
+static char X11_default_command[] = "gnuplot_x11";
+# else
+static char X11_default_command[] = GNUPLOT_X11;
+# endif
+# endif /* OS/2 || Windows */
+
+static char *X11_command = X11_default_command;
+static char *X11_command_parsed = NULL;
+static char *X11_full_command_path = NULL;
+
+/* must match the definition in src/gplt_x11.c: */
+static int persist = UNSET;
+static int do_raise = UNSET;
+static int dashedlines = UNSET;
+static int ctrlq = UNSET;
+static int set_size = UNSET;
+static int set_position = UNSET;
+
+/* driver properties managed by x11.trm rather than gnuplot_x11 */
+static double X11_linewidth_multiplier = 1.0;
+
+#ifdef USE_MOUSE
+/* Interlock to prevent the mouse channel from being coopted more than
+ * once per plot by the gnuplot_x11<->x11.trm font information query.
+ */
+static TBOOLEAN default_font_size_known = FALSE;
+static TBOOLEAN X11_MOUSE_FEEDBACK = TRUE;
+#endif
+#ifdef PIPE_IPC
+static TBOOLEAN IPC_LOCK = FALSE;
+#endif
+
+static int parse_driver __PROTO((const char *));
+
+static int
+parse_driver(const char *cmd)
+{
+ int nr = 0;
+ char *ptr;
+
+ /* make a copy of cmd, as parsing will modify the string */
+ X11_command_parsed = gp_realloc(X11_command_parsed,
+ strlen(cmd) + 1, "x11->parse_driver");
+ strcpy(X11_command_parsed, X11_command);
+ ptr = X11_command_parsed;
+
+ while (*ptr != '\0' && nr < sizeof(optvec) / sizeof(char)) {
+
+ /* Strip whitespace. Use nulls, so that
+ * the previous argument is terminated
+ * automatically.
+ */
+ while (isspace((unsigned char)*ptr))
+ *ptr++ = '\0';
+
+ if (!(*ptr)) /* don't count the terminating NULL */
+ break;
+
+ /* Save the argument. */
+ optvec[nr++] = ptr;
+
+ /* Skip over the argument. */
+ while ('\0' != *ptr && !isspace((unsigned char)*ptr)) {
+ ptr++;
+ }
+ }
+
+ /* HBB 20020214: new code to prepend the environment X11_DRIVER_DIR
+ * to the command name, if it doesn't contain any slashes yet */
+ if (!strchr(optvec[0],'/')) {
+ char *dir = getenv("GNUPLOT_DRIVER_DIR");
+
+ if (!dir)
+ dir = X11_DRIVER_DIR;
+#ifndef OS2
+ if (dir[0] != '/' && dir[0] != '.') {
+ /* Can't call int_error because longjump has not been set up yet */
+ int_warn(NO_CARET, "Illegal X11 driver directory name! Using default");
+ dir = "";
+ }
+#endif
+ X11_full_command_path = gp_realloc(X11_full_command_path,
+ strlen(dir) + strlen(optvec[0]) + 2,
+ "x11 driver pathname");
+ /* optvec[0] = X11_full_command_path; */
+ if (*dir)
+ sprintf(X11_full_command_path, "%s/%s", dir, optvec[0]);
+ else
+ sprintf(X11_full_command_path, "%s", optvec[0]);
+ }
+
+ return nr;
+}
+
+/* X11_args - scan gnuplot command line for standard X Toolkit options
+ * called from plot.c so must not be TERM_PUBLIC (which may be static)
+ */
+
+int
+X11_args(int argc, char *argv[])
+{
+ int nx11 = 0, i, n;
+
+ xargv = (char **) gp_alloc(argc * sizeof(char *), "<xargv>");
+
+ if (!xargv) {
+ fputs("not enough memory to copy argv - quitting\n", stderr);
+ exit(EXIT_FAILURE);
+ }
+
+ /* We make a copy of the argument vector because
+ * argv is modified later. */
+ memcpy(xargv, argv, argc * sizeof(char *));
+ i = parse_driver(X11_command);
+
+ while (++argv, ++xargv, --argc > 0) {
+ for (n = 0; n < X11_nopts; n++) {
+ if (strcmp(*argv, X11_cmdopts[n].option) == 0) {
+ optvec[i++] = *xargv;
+#ifdef USE_MOUSE
+ if (strcmp(*argv, "-nofeedback") == 0)
+ X11_MOUSE_FEEDBACK = FALSE;
+#endif
+ if (strcmp(*argv, "-display") == 0)
+ X11_Display++;
+ if (X11_cmdopts[n].arg == hasArg) {
+ if (--argc <= 0)
+ return nx11;
+ optvec[i++] = *++xargv, ++argv;
+ nx11++;
+ }
+ if (i >= (sizeof(optvec) / sizeof(char))) {
+ fprintf(stderr, "warning: X11 options will be truncated\n");
+ return nx11; /* optvec is full */
+ }
+ nx11++;
+ break;
+ }
+ }
+ if (n == X11_nopts)
+ break;
+ }
+
+ return (nx11);
+}
+
+
+static unsigned int X11_plot_number;
+
+enum X11_id {
+ X11_RESET,
+ X11_CLOSE,
+ X11_PERSIST,
+ X11_NOPERSIST,
+ X11_RAISE,
+ X11_NORAISE,
+ X11_FONT,
+ X11_TITLE,
+ X11_ENHANCED,
+ X11_NOENHANCED,
+ X11_SOLID,
+ X11_DASHED,
+ X11_LINEWIDTH,
+ X11_CTRLQ,
+ X11_NOCTRLQ,
+ X11_SIZE,
+ X11_POSITION,
+ X11_OTHER
+};
+
+static struct gen_table X11_opts[] = {
+ {"res$et", X11_RESET},
+ {"cl$ose", X11_CLOSE},
+ {"per$sist", X11_PERSIST},
+ {"noper$sist", X11_NOPERSIST},
+ {"rai$se", X11_RAISE},
+ {"norai$se", X11_NORAISE},
+ {"font", X11_FONT},
+ {"fn$ame", X11_FONT},
+ {"ti$tle", X11_TITLE},
+ {"enh$anced", X11_ENHANCED},
+ {"noenh$anced", X11_NOENHANCED},
+ {"solid", X11_SOLID},
+ {"dash$ed", X11_DASHED},
+ {"linew$idth", X11_LINEWIDTH},
+ {"lw", X11_LINEWIDTH},
+ {"ctrl$q", X11_CTRLQ},
+ {"noctrl$q", X11_NOCTRLQ},
+ {"si$ze", X11_SIZE},
+ {"pos$ition", X11_POSITION},
+ {NULL, X11_OTHER}
+};
+
+
+TERM_PUBLIC void
+X11_options()
+{
+
+#define NOT_PROCESS_IF_DUPLICATION 1
+
+ struct value a;
+ int c_title_token = 0;
+ int new_term_number = 0;
+ TBOOLEAN duplication = FALSE;
+ TBOOLEAN set_reset = FALSE, set_persist = FALSE, set_raise = FALSE, set_font = FALSE;
+ TBOOLEAN set_ctrlq = FALSE;
+ TBOOLEAN set_title = FALSE, set_number = FALSE, set_close = FALSE, set_solid = FALSE;
+
+ persist = do_raise = dashedlines = ctrlq = UNSET;
+ set_size = set_position = UNSET;
+
+ while (!END_OF_COMMAND) {
+ switch (lookup_table(&X11_opts[0], c_token)) {
+ case X11_RESET:
+ c_token++;
+ if (set_reset) duplication=TRUE;
+ set_reset = TRUE;
+ break;
+ case X11_CLOSE:
+ c_token++;
+ if (set_close) duplication=TRUE;
+ set_close = TRUE;
+ break;
+ case X11_PERSIST:
+ persist = yes;
+ c_token++;
+ if (set_persist) duplication=TRUE;
+ set_persist = TRUE;
+ break;
+ case X11_NOPERSIST:
+ persist = no;
+ c_token++;
+ if (set_persist) duplication=TRUE;
+ set_persist = TRUE;
+ break;
+ case X11_CTRLQ:
+ ctrlq = yes;
+ c_token++;
+ if (set_ctrlq) duplication=TRUE;
+ set_ctrlq = TRUE;
+ break;
+ case X11_NOCTRLQ:
+ ctrlq = no;
+ c_token++;
+ if (set_ctrlq) duplication=TRUE;
+ set_ctrlq = TRUE;
+ break;
+ case X11_SOLID:
+ dashedlines = FALSE;
+ c_token++;
+ if (set_solid) duplication=TRUE;
+ set_solid = TRUE;
+ break;
+ case X11_DASHED:
+ dashedlines = TRUE;
+ c_token++;
+ if (set_solid) duplication=TRUE;
+ set_solid = TRUE;
+ break;
+ case X11_LINEWIDTH:
+ c_token++;
+ X11_linewidth_multiplier = real(const_express(&a));
+ if (X11_linewidth_multiplier <= 0)
+ X11_linewidth_multiplier = 1.0;
+ break;
+ case X11_RAISE:
+ do_raise = yes;
+ c_token++;
+ if (set_raise) duplication=TRUE;
+ set_raise = TRUE;
+ break;
+ case X11_NORAISE:
+ do_raise = no;
+ c_token++;
+ if (set_raise) duplication=TRUE;
+ set_raise = TRUE;
+ break;
+ case X11_FONT:
+ c_token++;
+ if (END_OF_COMMAND)
+ int_error(c_token, "expecting font name");
+ if (isstringvalue(c_token)) {
+ char *s = try_to_get_string();
+ strncpy(X11_default_font, s, sizeof(X11_default_font));
+ free(s);
+ } else {
+ copy_str(X11_default_font, c_token, sizeof(X11_default_font));
+ c_token++;
+ }
+ if (strchr(X11_default_font,','))
+ sscanf(strchr(X11_default_font,',')+1, "%d",
+ &X11_default_fontsize);
+ if (set_font) duplication=TRUE;
+ set_font = TRUE;
+ break;
+ case X11_TITLE:
+ c_token++;
+ if (END_OF_COMMAND)
+ int_error(c_token, "expecting title text");
+ c_title_token = c_token;
+ c_token++;
+ if (set_title) duplication=TRUE;
+ set_title = TRUE;
+ break;
+ case X11_ENHANCED:
+ term->put_text = ENHX11_put_text;
+ term->flags |= TERM_ENHANCED_TEXT;
+ c_token++;
+ break;
+ case X11_NOENHANCED:
+ term->put_text = X11_put_text;
+ term->flags &= ~TERM_ENHANCED_TEXT;
+ c_token++;
+ break;
+ case X11_SIZE:
+ c_token++;
+ if (END_OF_COMMAND) {
+ int_error(c_token, "expecting X[,Y]");
+ } else {
+ int x_in, y_in;
+ x_in = (int) real(const_express(&a));
+ if (x_in > 0)
+ X11_SIZE_X = x_in;
+ else
+ int_error(c_token, "X size must be > 0");
+ if (equals(c_token, ",")) {
+ c_token++;
+ y_in = (int) real(const_express(&a));
+ if (y_in > 0)
+ X11_SIZE_Y = y_in;
+ else
+ int_error(c_token, "Y size must be > 0");
+ }
+ set_size = yes;
+ }
+ break;
+ case X11_POSITION:
+ c_token++;
+ if (END_OF_COMMAND) {
+ int_error(c_token, "expecting X[,Y]");
+ } else {
+ X11_POSITION_X = (int) real(const_express(&a));
+ if (equals(c_token, ",")) {
+ c_token++;
+ X11_POSITION_Y = (int) real(const_express(&a));
+ }
+ set_position = yes;
+ }
+ break;
+
+ case X11_OTHER:
+ default:
+ /* let gnuplot_x11 check range */
+ new_term_number = (int) real(const_express(&a));
+ if (set_number) duplication=TRUE;
+ set_number = TRUE;
+ break;
+ }
+
+ if (duplication) {
+ int_error(c_token-1, "duplicated or contradicting arguments in X11 term options");
+ }
+
+ }
+
+
+ /* Call own init routine; this might be xlib rather than x11 */
+ term->init();
+
+ if (set_reset)
+ X11_atexit(); /* tell gnuplot_x11 to shut down */
+
+ /* Leave the current window unchanged when closing an old window */
+ if (set_close) {
+ if (X11_ipc) {
+ fprintf(X11_ipc, (set_number ? "C%d\n" : "C\n"), new_term_number);
+ fflush(X11_ipc);
+ }
+ } else if (set_number) {
+ X11_plot_number = new_term_number;
+ if (X11_ipc) {
+ fprintf(X11_ipc, "N%d\n", X11_plot_number);
+ fflush(X11_ipc);
+ }
+ }
+
+ sprintf(term_options, "%d", X11_plot_number);
+ if (UNSET != do_raise) {
+ strcat(term_options, (yes == do_raise ? " raise" : " noraise"));
+ }
+ if (UNSET != persist) {
+ strcat(term_options, (yes == persist ? " persist" : " nopersist"));
+ }
+ if (UNSET != ctrlq) {
+ strcat(term_options, (yes == ctrlq ? " ctrlq" : " noctrlq"));
+ }
+ if (UNSET != dashedlines) {
+ strcat(term_options, (yes == dashedlines ? " dashed" : " solid"));
+ }
+ if (term->put_text == ENHX11_put_text) {
+ strcat(term_options, " enhanced");
+ }
+ if (X11_linewidth_multiplier != 1.0) {
+ sprintf(term_options + strlen(term_options),
+ " linewidth %.2g", X11_linewidth_multiplier);
+ }
+ if (*X11_default_font) {
+ strcat(term_options, " font \"");
+ strcat(term_options, X11_default_font);
+ strcat(term_options, "\"");
+ }
+ if (set_title) {
+ char *title;
+ int save_token = c_token;
+ c_token = c_title_token;
+ strncat(term_options, " title \"", MAX_LINE_LEN-strlen(term_options));
+ title = term_options + strlen(term_options);
+ if (isstringvalue(c_title_token)) {
+ char *s = try_to_get_string();
+ strncat(term_options, s, MAX_LINE_LEN-strlen(term_options));
+ free(s);
+ } else
+ copy_str(term_options+strlen(term_options), c_title_token, MAX_LINE_LEN-strlen(term_options));
+ if (X11_ipc) {
+ /* Send up to maximum buffer length minus three characters of
+ * title string to account for required 'n', '\0', '\n'.
+ */
+ int i;
+ fputc('n', X11_ipc);
+ for (i=0; i < X11_COMMAND_BUFFER_LENGTH-3 && title[i] != '\0'; i++)
+ fputc(title[i], X11_ipc);
+ fputc('\0', X11_ipc);
+ fputc('\n', X11_ipc);
+ fflush(X11_ipc);
+ }
+ strncat(term_options, "\"", MAX_LINE_LEN-strlen(term_options));
+ c_token = save_token;
+ }
+ if (set_size != UNSET)
+ sprintf(term_options + strlen(term_options),
+ " size %d,%d ", X11_SIZE_X,X11_SIZE_Y);
+
+ if (set_position != UNSET)
+ sprintf(term_options + strlen(term_options),
+ " position %d,%d ", X11_POSITION_X,X11_POSITION_Y);
+
+ X11_update_opts();
+}
+
+
+void
+x11_raise_terminal_window(int number)
+{
+ /* Send the raise character and a number. */
+ if (X11_ipc) {
+ fprintf(X11_ipc, "^%d\n", number);
+ fflush(X11_ipc);
+ }
+}
+
+void
+x11_raise_terminal_group(void)
+{
+ /* Send just the raise character. */
+ if (X11_ipc) {
+ fprintf(X11_ipc, "^\n");
+ fflush(X11_ipc);
+ }
+}
+
+void
+x11_lower_terminal_window(int number)
+{
+ /* Send the raise character and a number. */
+ if (X11_ipc) {
+ fprintf(X11_ipc, "v%d\n", number);
+ fflush(X11_ipc);
+ }
+}
+
+void
+x11_lower_terminal_group(void)
+{
+ /* Send just the raise character. */
+ if (X11_ipc) {
+ fprintf(X11_ipc, "v\n");
+ fflush(X11_ipc);
+ }
+}
+
+
+TERM_PUBLIC void
+X11_update_opts()
+{
+ if (!X11_ipc)
+ return;
+
+ if (UNSET != do_raise || UNSET != persist || UNSET != dashedlines || UNSET != ctrlq) {
+ fprintf(X11_ipc, "X %d %d %d %d\n",
+ do_raise, persist, dashedlines, ctrlq);
+ fflush(X11_ipc);
+ }
+
+ /* pass size as a valid X11 geometry string WIDTHxHEIGHT[+XPOS+YPOS] */
+ if (set_size != UNSET || set_position != UNSET) {
+ if (set_size != UNSET && set_position == UNSET)
+ fprintf(X11_ipc, "s %dx%d\n", X11_SIZE_X, X11_SIZE_Y);
+ else if (set_size == UNSET && set_position != UNSET)
+ fprintf(X11_ipc, "s %+d%+d\n", X11_POSITION_X, X11_POSITION_Y);
+ else if (set_size != UNSET && set_position != UNSET)
+ fprintf(X11_ipc, "s %dx%d%+d%+d\n", X11_SIZE_X, X11_SIZE_Y,
+ X11_POSITION_X, X11_POSITION_Y);
+ fflush(X11_ipc);
+ }
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Three different versions of the remainder of the X11 terminal driver
+ * are provided to support three different types of IPC with the
+ * gnuplot_x11 outboard terminal driver:
+ *
+ * DEFAULT_X11: popen() pipe for most un*x platforms
+ *
+ * CRIPPLED_SELECT : file IPC for un*x platforms with incomplete or faulty
+ * implementation of BSD select()
+ *
+ * VMS : mailbox/spawn IPC
+ *---------------------------------------------------------------------------*/
+
+#define DEFAULT_X11
+#if defined(VMS) || defined(CRIPPLED_SELECT)
+# undef DEFAULT_X11
+#endif
+#if defined(VMS) && defined(CRIPPLED_SELECT)
+Error.Incompatible options.
+#endif
+/* we do not want to have to duplicate all the code, so we
+ * do most of it with macros.
+ * PRINT0(format), PRINT1(format, p1), PRINT2(format, p1, p2) etc
+ * also FLUSH0(format), etc, which do an additional flush
+ */
+#ifdef DEFAULT_X11
+/*-----------------------------------------------------------------------------
+ * DEFAULT_X11 popen() pipe IPC
+ *---------------------------------------------------------------------------*/
+static void
+X11_atexit()
+{
+ if (X11_ipc) {
+ fputs("R\n", X11_ipc);
+ fclose(X11_ipc);
+ /* dont wait(), since they might be -persist */
+ X11_ipc = NULL;
+#ifdef PIPE_IPC
+ close(ipc_back_fd);
+ ipc_back_fd = -1;
+#endif
+ }
+}
+
+#ifdef USE_MOUSE
+
+TERM_PUBLIC int
+X11_waitforinput()
+{
+#ifdef PIPE_IPC
+ fd_set fds;
+ static struct gp_event_t ge;
+ static int l = 0;
+ int n;
+ int fd = fileno(stdin);
+ int repeat_count = 0;
+
+AGAIN:
+ /* XXX: if the input device it not a tty (e.g. /dev/null)
+ * mouse events are not processed. This is necessary
+ * as on some systems /dev/null is not selectable.
+ * TODO: should we close the ipc_back_fd in this case ? */
+ if (ipc_back_fd >= 0)
+ do {
+ int ierr;
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ FD_SET(ipc_back_fd, &fds);
+ ierr = select(ipc_back_fd + 1, SELECT_TYPE_ARG234 &fds, 0, 0, NULL);
+ if (ierr < 0 && errno == EINTR) {
+ FD_ZERO(&fds);
+ continue;
+ }
+ if (FD_ISSET(ipc_back_fd, &fds)) {
+ n = read(ipc_back_fd, (void *) (l + (char *) &ge), sizeof(ge) - l);
+ if (n == 0) {
+ close(ipc_back_fd);
+ ipc_back_fd = -1;
+ /* don't close X11_ipc, otherwise later writes
+ * to it will cause a segfault */
+ IPC_LOCK = FALSE;
+ break; /* outboard driver has stopped */
+ }
+ l += n;
+ if (l == sizeof(ge)) {
+ /* note: do_event() may not return (if an
+ * error occurs), so need to reset l first */
+ l = 0;
+ do_event(&ge);
+ if (ge.type == GE_fontprops) {
+ if (repeat_count > 0) {
+ FPRINTF((stderr,
+ "X11_waitforinput: caught GE_fontprops after %d tries\n",
+ repeat_count));
+ }
+ return(GE_fontprops);
+ }
+ if (ge.type == GE_buttonrelease && (paused_for_mouse & PAUSE_CLICK)) {
+ int button = ge.par1;
+ if (button == 1 && (paused_for_mouse & PAUSE_BUTTON1))
+ paused_for_mouse = 0;
+ if (button == 2 && (paused_for_mouse & PAUSE_BUTTON2))
+ paused_for_mouse = 0;
+ if (button == 3 && (paused_for_mouse & PAUSE_BUTTON3))
+ paused_for_mouse = 0;
+ if (paused_for_mouse == 0)
+ return '\0';
+ }
+ if (ge.type == GE_keypress && (paused_for_mouse & PAUSE_KEYSTROKE)) {
+ /* Ignore NULL keycode */
+ if (ge.par1 > '\0') {
+ paused_for_mouse = 0;
+ return '\0';
+ }
+ }
+ }
+ }
+ } while (!FD_ISSET(fd, &fds));
+
+ /* If ipc_back_fd is not open, we will never see any mouse events! */
+ else if (paused_for_mouse) {
+ paused_for_mouse = 0;
+ int_error(NO_CARET,"Mousing not active");
+ }
+
+ /* IPC_LOCK indicates that we are specifically waiting for a reply on */
+ /* the mousing channel. If stdin unblocks first, defer reading it, */
+ /* wait a few microseconds, and try again. */
+ /* FIXME EAM - Give up after a few seconds. This will drop input chars*/
+ /* but at least it won't hang forever if the X11 connection goes bad. */
+ if (IPC_LOCK) {
+#ifdef HAVE_USLEEP
+ usleep(100);
+#endif
+ if (repeat_count++ < 10000)
+ goto AGAIN;
+ }
+
+ /* Same sort of thing if we are specifically waiting for mouse input. */
+ if (paused_for_mouse) {
+#ifdef HAVE_USLEEP
+ usleep(10);
+#endif
+ goto AGAIN;
+ }
+
+#endif /* PIPE_IPC */
+
+# if 0
+/* HBB 20010620: switching back and forth between X11 and a non-GUI
+ * terminal, while stdin is redirected, causes gnuplot to terminate
+ * right after it re-enters the X11 terminal --- read() returns a '\0'
+ * character once, and then EOF. Switching to <stdio.h>'s getc() fixed
+ * that, for me. */
+ if (read(0, &c, 1) != 1)
+ return EOF;
+ else
+ return c;
+# else
+ return getc(stdin);
+# endif /* 0/1 */
+}
+#endif /* USE_MOUSE */
+
+
+TERM_PUBLIC void
+X11_init()
+{
+ static int been_here = 0;
+
+ if (!X11_ipc) {
+ /* first time through or after a reset */
+#if defined(OSK)
+ /* OS-9 popen() does not block on close for child to end, so
+ * we can safely use it here
+ */
+ /* FIXME HBB 20020214: This doesn't understand X11_DRIVER_DIR
+ * or $GNUPLOT_DRIVER_DIR yet. This may break execution of
+ * freshly built gnuplot until 'make install' */
+
+ X11_ipc = popen(X11_command, "w");
+#else
+#if defined(OS2)
+ /* FIXME amai 20020219: nice try...
+ * But popen() does return a non-NULL handle to almost command,
+ * it's just a new session which will stop if the command does
+ * not exist... We should stat() for the argument?! */
+ /* X11_ipc = popen(X11_full_command_path, "w");
+ if (X11_ipc==NULL) */
+ {
+ X11_ipc = popen(X11_command, "w");
+ }
+#else /* !(OSK || OS/2) */
+ int fdes[2];
+# ifdef PIPE_IPC
+ int fdes_back[2];
+
+#define X11_ALLOW_EVENTS (mouse_setting.on)
+ if (X11_ALLOW_EVENTS) {
+ if (pipe(fdes_back))
+ perror("pipe() failed:");
+ }
+# endif /* PIPE_IPC */
+ if (pipe(fdes))
+ perror("pipe() failed:");
+
+ if (fork() == 0) {
+ /* child */
+# ifdef PIPE_IPC
+ char noevents[] = "-noevents";
+ if (X11_ALLOW_EVENTS) {
+ dup2(fdes_back[1], 1); /* stdout to pipe */
+ close(fdes_back[0]);
+ } else {
+ char **ptr;
+ for (ptr = optvec; ptr && *ptr; ptr++)
+ ; /* do nothing: skip over set arguments */
+ /* tell the driver not to supply any events by
+ * appending "-noevents" to the optvec list. */
+ *ptr = noevents;
+ *++ptr = (char *) 0; /* terminate */
+ }
+# endif /* PIPE_IPC */
+ /* close the write side of the child's forward fd */
+ close(fdes[1]);
+
+ dup2(fdes[0], 0); /* stdin from pipe */
+ execvp(X11_full_command_path, optvec);
+ /* if we get here, something went wrong */
+ fprintf(stderr,"Expected X11 driver: %s\n",X11_full_command_path);
+ perror("Exec failed");
+ fprintf(stderr,"See 'help x11' for more details\n");
+ exit(EXIT_FAILURE);
+ }
+ /* parent */
+# ifdef PIPE_IPC
+ /* X11_ipc_out = fdopen(fdes[0], "r"); */
+ if (ipc_back_fd > 0) {
+ fprintf(stderr, "(X11_init) warning: unclosed ipc_back_fd.\n");
+ fprintf(stderr, " this is probably a program error.\n");
+ close(ipc_back_fd);
+ }
+ if (X11_ALLOW_EVENTS) {
+ ipc_back_fd = fdes_back[0];
+ close(fdes_back[1]); /* the parent doesn't need this */
+ } else {
+ /* we do not open a bidirectional communication
+ * for non-tty's by default. If this is desired,
+ * the mouse must be turned on explicitely *before*
+ * starting the x11 driver.
+ * So: if we're here, we close the ipc-back-channel
+ * which will cause a SIGPIPE in the driver. This
+ * is *ugly* but it works. (joze) */
+ /* close(fdes_back[0]); */
+ /* mark ipc_back_fd as unusable */
+ ipc_back_fd = IPC_BACK_UNUSABLE;
+ }
+# endif /* PIPE_IPC */
+ /* close the read side of the parent's forward fd */
+ close(fdes[0]);
+ X11_ipc = fdopen(fdes[1], "w");
+#endif /* !OSK */
+#endif /* !OS/2 */
+ }
+
+ if (!been_here) {
+ GP_ATEXIT(X11_atexit);
+ been_here++;
+ }
+#if defined(WITH_IMAGE) || defined(BINARY_X11_POLYGON)
+ X11_send_endianess();
+#endif
+#ifdef USE_MOUSE
+ default_font_size_known = FALSE;
+#endif
+ X11_update_opts();
+}
+
+TERM_PUBLIC void
+X11_reset()
+{
+ /* Leave the pipe alone, until exit or set term x11 reset */
+ /* but make sure that all locks are cleared. */
+#ifdef PIPE_IPC
+ IPC_LOCK = FALSE;
+#endif
+#ifdef USE_MOUSE
+ paused_for_mouse = 0;
+#endif
+}
+
+#define PRINT0(fmt) fprintf(X11_ipc, fmt)
+#define PRINT1(fmt,p1) fprintf(X11_ipc, fmt,p1)
+#define PRINT2(fmt,p1,p2) fprintf(X11_ipc, fmt,p1,p2)
+#define PRINT3(fmt,p1,p2,p3) fprintf(X11_ipc, fmt,p1,p2,p3)
+#define PRINT4(fmt,p1,p2,p3,p4) fprintf(X11_ipc, fmt,p1,p2,p3,p4)
+#define PRINT5(fmt,p1,p2,p3,p4,p5) fprintf(X11_ipc, fmt,p1,p2,p3,p4,p5)
+
+#define FFLUSH() fflush(X11_ipc)
+
+#define BEFORE_GRAPHICS /* nowt */
+#define AFTER_TEXT /* nowt */
+
+
+#elif defined(CRIPPLED_SELECT)
+/* PLEASE CAN SOMEONE CHECK THAT THIS STILL WORKS !!! */
+/*-----------------------------------------------------------------------------
+ * CRIPPLED_SELECT file IPC
+ *---------------------------------------------------------------------------*/
+static char X11_tmp[32], X11_tmp0[32], X11_shutdown[32];
+static int X11_pid;
+
+TERM_PUBLIC void
+X11_init()
+{
+ if (!(X11_pid = fork())) {
+ execvp(X11_full_command_path, optvec);
+ _exit(1);
+ }
+ sprintf(X11_tmp, "/tmp/Gnuplot_%d", X11_pid);
+ sprintf(X11_tmp0, "%s-", X11_tmp);
+ sprintf(X11_shutdown, "echo R >%s", X11_tmp);
+}
+
+TERM_PUBLIC void
+X11_reset()
+{
+ system(X11_shutdown);
+}
+
+#define BEFORE_GRAPHICS \
+ if (!(X11_ipc = fopen(X11_tmp0, "w"))) { \
+ perror(X11_tmp0); system(X11_shutdown); exit(1); \
+ }
+
+#define AFTER_TEXT \
+ { fclose(X11_ipc); rename(X11_tmp0, X11_tmp); }
+
+#define PRINT0(fmt) fprintf(X11_ipc, fmt)
+#define PRINT1(fmt,p1) fprintf(X11_ipc, fmt,p1)
+#define PRINT2(fmt,p1,p2) fprintf(X11_ipc, fmt,p1,p2)
+#define PRINT3(fmt,p1,p2,p3) fprintf(X11_ipc, fmt,p1,p2,p3)
+#define PRINT4(fmt,p1,p2,p3,p4) fprintf(X11_ipc, fmt,p1,p2,p3,p4)
+#define PRINT5(fmt,p1,p2,p3,p4,p5) fprintf(X11_ipc, fmt,p1,p2,p3,p4,p5)
+#define FFLUSH() fflush(X11_ipc)
+
+static void
+X11_atexit()
+{
+ /* WHAT SHOULD I DO ? */
+}
+#elif defined(VMS)
+/*-----------------------------------------------------------------------------
+ * VMS mailbox/spawn IPC - Yehavi Bourvine - YEHAVI@VMS.HUJI.AC.IL
+ *---------------------------------------------------------------------------*/
+#include <iodef.h>
+#include <descrip.h>
+#include <dvidef.h>
+#ifdef __DECC
+#include <lib$routines.h>
+#include <starlet.h>
+#endif
+#ifdef __GNUC__
+#include <errno.h>
+#else
+int vaxc$errno;
+#endif
+
+#define SS$_NORMAL 1 /* or include <ssdef.h> for all SS$_ def's */
+
+#define MBXMXMSG 128 /* DEFMBXMXMSG is set by SYSGEN */
+
+static short X11_channel;
+
+struct iosb {
+ unsigned short stat;
+ unsigned short count;
+ unsigned long info;
+};
+
+
+
+TERM_PUBLIC void
+X11_init()
+{
+
+ struct iosb iosb;
+
+ static char devnam_string[64];
+ static $DESCRIPTOR(devnam, devnam_string);
+
+ struct {
+ short int buf_len;
+ short int item;
+ char *buf_addr;
+ unsigned short int *ret_len;
+ int end;
+ } item_list = {
+ devnam.dsc$w_length, DVI$_DEVNAM, devnam.dsc$a_pointer, &devnam.dsc$w_length, 0};
+#define CMDLEN 1024
+ char cmdline[CMDLEN], *cmdp;
+ int optindex;
+
+ if (!X11_channel) {
+ int one = 1;
+
+ /* Create a descriptor for the command line that starts
+ GNUPLOT_X11. $DESCRIP doesn't work in this context... */
+
+ /* FIXME!
+ * This does not work anymore since X11 option passing has been
+ * changed to use execvp() in the DEFAULT_X11 case
+ */
+ struct dsc$descriptor_s pgmdsc = { 0, DSC$K_DTYPE_T,
+ DSC$K_CLASS_S, 0
+ };
+ optindex = 0;
+ strcpy(cmdline, optvec[optindex]);
+ cmdp = cmdline + strlen(optvec[optindex]);
+ while (optvec[++optindex] != NULL) {
+ *cmdp++ = ' ';
+ *cmdp++ = '\"';
+ strcpy(cmdp, optvec[optindex]);
+ cmdp += strlen(optvec[optindex]);
+ *cmdp++ = '\"';
+ }
+ pgmdsc.dsc$w_length = cmdp - cmdline;
+ pgmdsc.dsc$a_pointer = cmdline;
+
+ /* Create a mailbox which will be used as a pipe for commands to the
+ * subprocess. What we'll write to it will be read by the subprocess
+ * as its STDIN. Use an unnamed mailbox and refer to it by its device
+ * number */
+
+ vaxc$errno = sys$crembx(0, &X11_channel, MBXMXMSG, MBXMXMSG, 0, 0, 0, 0);
+ if ((vaxc$errno & SS$_NORMAL) != SS$_NORMAL) {
+ printf("SYS$CreMbx failed with status=%d\r\n", vaxc$errno);
+ os_error(NO_CARET, "sys$crembx failed");
+ }
+ vaxc$errno = sys$getdviw(0, X11_channel, 0, &item_list, &iosb, 0, 0, 0);
+ if ((vaxc$errno & SS$_NORMAL) == SS$_NORMAL)
+ vaxc$errno = iosb.stat;
+ if ((vaxc$errno & SS$_NORMAL) != SS$_NORMAL) {
+ printf("SYS$Getdviw failed with status=%d\r\n", vaxc$errno);
+ sys$dassgn(X11_channel);
+ X11_channel = 0;
+ os_error(NO_CARET, "sys$getdviw failed");
+ }
+ /* Create a subprocess whose input is this mailbox. */
+ vaxc$errno = lib$spawn(&pgmdsc, &devnam, 0, &one, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ if ((vaxc$errno & SS$_NORMAL) != SS$_NORMAL) {
+ printf("LIB$SPAWN failed with status=%d\r\n", vaxc$errno);
+ sys$dassgn(X11_channel);
+ X11_channel = 0;
+ os_error(NO_CARET, "lib$spawn failed");
+ }
+ }
+ {
+ static int been_here = 0;
+ if (!been_here) {
+ GP_ATEXIT(X11_atexit);
+ been_here = 1;
+ }
+ }
+}
+
+
+/* We use $QIO in order to avoid buffering problems, although it might
+ * work as well with simple Fprintf calls.
+ */
+
+#define GO(x) \
+do { \
+ char buffer[512]; int status; struct iosb iosb;\
+ sprintf x; \
+ if (strlen(buffer) >= MBXMXMSG) { \
+ printf("buffer contents (%d char) catenated to mailbox size (%d bytes)\n", \
+ strlen(buffer), MBXMXMSG); \
+ buffer[MBXMXMSG-1] = '\0';\
+ printf("%s\n", buffer); \
+ } \
+ status = sys$qiow(0, X11_channel, IO$_WRITEVBLK, &iosb, 0, 0, buffer, strlen(buffer), 0, 0, 0, 0); \
+ if ((status & SS$_NORMAL) == SS$_NORMAL) status = iosb.stat; \
+ if((status & SS$_NORMAL) != SS$_NORMAL) exit(status); \
+ } while (0)
+
+#define PRINT0(fmt) GO((buffer, fmt))
+#define PRINT1(fmt,p1) GO((buffer, fmt,p1))
+#define PRINT2(fmt,p1,p2) GO((buffer, fmt,p1,p2))
+#define PRINT3(fmt,p1,p2,p3) GO((buffer, fmt,p1,p2,p3))
+#define PRINT4(fmt,p1,p2,p3,p4) GO((buffer, fmt,p1,p2,p3,p4))
+#define PRINT5(fmt,p1,p2,p3,p4,p5) GO((buffer, fmt,p1,p2,p3,p4,p5))
+
+#define FFLUSH() /* nowt */
+#define BEFORE_GRAPHICS /* nowt */
+#define AFTER_TEXT /* nowt */
+
+static void
+X11_atexit()
+{
+ if (X11_channel) {
+ PRINT0("R\n");
+ sleep(2); /* Wait for subprocess to finish */
+ sys$dassgn(X11_channel);
+ X11_channel = 0;
+ }
+}
+
+TERM_PUBLIC void
+X11_reset()
+{
+ /* do nothing until exit */
+}
+
+#else /* !VMS */
+ You lose.
+#endif /* !VMS */
+
+/* common stuff, using macros defined above */
+
+TERM_PUBLIC void
+X11_graphics()
+{
+#ifdef USE_MOUSE
+ static unsigned long windowid = 0;
+#endif
+ static enum set_encoding_id last_encoding = S_ENC_DEFAULT;
+
+ BEFORE_GRAPHICS; /* kludge for crippled select */
+
+#ifndef USE_MOUSE
+ /* for VMS sake, keep as separate prints */
+ PRINT1("G%d\n", X11_plot_number);
+#else
+#ifdef PIPE_IPC
+ /* if we know the outboard driver has stopped, restart it */
+ if (ipc_back_fd == IPC_BACK_CLOSED) {
+ fclose(X11_ipc);
+ X11_ipc = NULL;
+ X11_init();
+ }
+#endif
+ /* send also XID of gnuplot window (<space> then raises it up) */
+ if (!windowid) {
+ char *window_env = getenv("WINDOWID");
+ if (window_env)
+ sscanf(window_env, "%lu", &windowid);
+ }
+#ifndef OS2
+ PRINT2("G%d %lu\n", X11_plot_number, windowid);
+#else
+ PRINT3("G%d %lu %i\n", X11_plot_number, windowid, getpid());
+#endif
+#endif /* USE_MOUSE */
+
+#ifdef ULTRIX_KLUDGE
+ fflush(X11_ipc);
+#endif
+
+ if (encoding != last_encoding) {
+ PRINT1("QE%d\n",encoding);
+ last_encoding = encoding;
+ }
+
+#if defined(USE_MOUSE) && defined(PIPE_IPC)
+ /* EAM June 2003 - Flush the set font command through the pipe */
+ /* to gnuplot_x11, then wait for it to return the resulting */
+ /* font size information (v_char and h_char). The feedback is */
+ /* caught by do_event() as an event of type GE_fontprops. */
+ if (ipc_back_fd >= 0 && X11_MOUSE_FEEDBACK) {
+ if (!default_font_size_known) {
+ IPC_LOCK = TRUE;
+ PRINT1("QG%s\n",X11_default_font);
+ FFLUSH();
+ X11_waitforinput();
+ default_font_size_known = TRUE;
+ IPC_LOCK = FALSE;
+ }
+ }
+#endif
+ /* Force default font at start of plot */
+ *X11_last_font_used = '\01';
+ X11_set_default_font();
+ X11_set_font("");
+}
+
+TERM_PUBLIC void
+X11_text()
+{
+ if (!X11_ipc)
+ return;
+
+#ifdef USE_MOUSE
+ /* EAM July 2003: send over a snapshot of the final axis scaling
+ * so that subsequent mouse events can be transformed into plot
+ * coordinates even though the plot is no longer active.
+ */
+#ifdef PIPE_IPC
+ if (ipc_back_fd >= 0)
+#endif
+ {
+ /* Construct a mask showing which axes are active */
+ int axis_mask = 0;
+ int i;
+
+ for (i = FIRST_AXES; i < 2*SECOND_AXES; i++) {
+ if (axis_array[i].ticmode != NO_TICS)
+ axis_mask |= (1 << i);
+ }
+ PRINT2("S %d %d\n", -2, ALMOST2D);
+ PRINT2("S %2d %d\n", -1, axis_mask);
+ PRINT5("S %2d %14.3g %14d %14.3g %14.3g\n", FIRST_X_AXIS,
+ axis_array[FIRST_X_AXIS].min,
+ axis_array[FIRST_X_AXIS].term_lower,
+ axis_array[FIRST_X_AXIS].term_scale,
+ axis_array[FIRST_X_AXIS].log ? axis_array[FIRST_X_AXIS].log_base : 0);
+ PRINT5("S %2d %14.3g %14d %14.3g %14.3g\n", FIRST_Y_AXIS,
+ axis_array[FIRST_Y_AXIS].min,
+ axis_array[FIRST_Y_AXIS].term_lower,
+ axis_array[FIRST_Y_AXIS].term_scale,
+ axis_array[FIRST_Y_AXIS].log ? axis_array[FIRST_Y_AXIS].log_base : 0);
+ PRINT5("S %2d %14.3g %14d %14.3g %14.3g\n", SECOND_X_AXIS,
+ axis_array[SECOND_X_AXIS].min,
+ axis_array[SECOND_X_AXIS].term_lower,
+ axis_array[SECOND_X_AXIS].term_scale,
+ axis_array[SECOND_X_AXIS].log ? axis_array[SECOND_X_AXIS].log_base : 0);
+ PRINT5("S %2d %14.3g %14d %14.3g %14.3g\n", SECOND_Y_AXIS,
+ axis_array[SECOND_Y_AXIS].min,
+ axis_array[SECOND_Y_AXIS].term_lower,
+ axis_array[SECOND_Y_AXIS].term_scale,
+ axis_array[SECOND_Y_AXIS].log ? axis_array[SECOND_Y_AXIS].log_base : 0);
+ }
+#endif
+
+ PRINT0("E\n");
+ FFLUSH();
+#ifdef ULTRIX_KLUDGE
+ PRINT0("E\n");
+ FFLUSH();
+#endif
+
+ AFTER_TEXT; /* kludge for crippled select */
+}
+
+TERM_PUBLIC void
+X11_move(unsigned int x, unsigned int y)
+{
+ PRINT2("M%04d%04d\n", x, y);
+}
+
+TERM_PUBLIC void
+X11_vector(unsigned int x, unsigned int y)
+{
+ PRINT2("V%04d%04d\n", x, y);
+}
+
+TERM_PUBLIC void
+X11_pointsize(double ps)
+{
+ if (ps < 0)
+ ps = 1;
+ PRINT2("P-2 %d %d\n", /* size of point symbols */
+ (int) (term->h_tic * ps * 0.5), (int) (term->v_tic * ps * 0.5));
+}
+
+TERM_PUBLIC void
+X11_linewidth(double lw)
+{
+ PRINT1("W%04d\n", (int) (lw * X11_linewidth_multiplier + 0.5));
+}
+
+TERM_PUBLIC void
+X11_linetype(int lt)
+{
+ PRINT1("L%04d\n", lt);
+}
+
+TERM_PUBLIC void
+X11_put_text(unsigned int x, unsigned int y, const char str[])
+{
+ /* Only send the font change request to X11 if it really is a change */
+ if (strcmp(X11_last_font_used,X11_next_font_used)) {
+ strcpy(X11_last_font_used,X11_next_font_used);
+ PRINT1("QF%s\n", X11_next_font_used);
+ }
+
+ /* badly outrange labels can overflow into text field */
+ if (x < 10000 && y < 10000) {
+ PRINT3("T%04d%04d%s\n", x, y, str);
+ }
+}
+
+TERM_PUBLIC int
+X11_text_angle(int ang)
+{
+ PRINT1("A%d\n", ang);
+ return TRUE;
+}
+
+TERM_PUBLIC int
+X11_justify_text(enum JUSTIFY mode)
+{
+ PRINT1("J%04d\n", mode);
+ X11_last_justification = mode;
+ return (TRUE);
+}
+
+TERM_PUBLIC void
+X11_point(unsigned int x, unsigned int y, int number)
+{
+ PRINT3("P%d %d %d\n", number, x, y);
+}
+
+TERM_PUBLIC int
+X11_set_font(const char *fontname)
+{
+ PRINT1("QF%s\n", fontname?fontname:"");
+ strncpy(X11_next_font_used,fontname?fontname:"",sizeof(X11_next_font_used)-1);
+ return(TRUE);
+}
+
+static void
+X11_set_default_font()
+{
+ PRINT1("QD%s\n",X11_default_font);
+}
+
+TERM_PUBLIC void
+X11_fillbox(int style, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
+{
+ if (X11_ipc) {
+ PRINT5("F%04d%04u%04u%04u%04u\n", style, x, y, w, h);
+ }
+}
+
+#ifdef USE_MOUSE
+TERM_PUBLIC void
+X11_put_tmptext(int i, const char str[])
+{
+ if (X11_ipc) {
+ PRINT2("t%04d%s\n", i, str);
+ FFLUSH();
+ }
+}
+
+TERM_PUBLIC void
+X11_set_ruler(int x, int y)
+{
+ if (X11_ipc) {
+ PRINT2("r%04d%04d\n", x < 9999 ? x : 9999, y < 9999 ? y : 9999);
+ FFLUSH();
+ }
+}
+
+TERM_PUBLIC void
+X11_set_cursor(int c, int x, int y)
+{
+ if (X11_ipc) {
+ PRINT3("u%04d%04d%04d\n", c, x, y);
+ FFLUSH();
+ }
+}
+
+TERM_PUBLIC void
+X11_set_clipboard(const char s[])
+{
+ if (X11_ipc) {
+ PRINT1("z%s\n", s);
+ FFLUSH();
+ }
+}
+
+#endif /* USE_MOUSE */
+
+
+static void
+transmit_gradient(gradient_struct *gradient, int cnt)
+{
+ int i = 0;
+
+ fprintf(X11_ipc, "%d", cnt);
+ for(i=0; i<cnt; i++) {
+ /* this %50 *must* match the corresponding %50 in gplt_x11.c */
+ if(i%50 == 0) {
+ fputs("\n", X11_ipc);
+ fflush(X11_ipc);
+ }
+ fprintf(X11_ipc, "%s", gradient_entry_to_str(&(gradient[i])));
+ }
+ fputs("\n", X11_ipc);
+}
+
+
+TERM_PUBLIC int
+X11_make_palette(t_sm_palette *palette)
+{
+ if(!palette) {
+ return 0;
+ }
+
+ if(!X11_ipc) {
+ fprintf(stderr, "(X11_make_palette) 0 == X11_ipc\n");
+ return -1;
+ }
+
+ fprintf(X11_ipc, "%c %c %c %c %d\n",
+ X11_GR_MAKE_PALETTE, (char)(palette->colorMode),
+ (char)(palette->positive), (char)(palette->cmodel),
+ palette->use_maxcolors);
+
+ switch(palette->colorMode) {
+ case SMPAL_COLOR_MODE_GRAY:
+ fprintf(X11_ipc,"%g\n", palette->gamma);
+ break;
+ case SMPAL_COLOR_MODE_RGB:
+ fprintf(X11_ipc, "%d %d %d\n", palette->formulaR,
+ palette->formulaG, palette->formulaB);
+ break;
+ case SMPAL_COLOR_MODE_GRADIENT:
+ transmit_gradient(palette->gradient, palette->gradient_num);
+ break;
+ case SMPAL_COLOR_MODE_FUNCTIONS: {
+ int cnt=0;
+ gradient_struct *gradient;
+ gradient = approximate_palette(palette, -1, 0.01, &cnt);
+ transmit_gradient(gradient, cnt);
+ free(gradient);
+ break;
+ }
+ default:
+ fprintf(stderr, "%s:%d ooops: Unknown colorMode '%c'.\n",
+ __FILE__, __LINE__, (char)(palette->colorMode));
+ }
+ fflush(X11_ipc);
+ return 0;
+}
+
+
+#if 0
+/* The following are some handy little routines to keep around
+ * in case one wants to do statistics on the binary data being
+ * passed to a terminal function.
+ */
+
+int char_count[256];
+
+void histogram(unsigned char c) {
+ char_count[c] += 1;
+}
+
+void dump_histogram(void) {
+ int i, sum;
+ fprintf(stderr,"\n\n");
+ for (i=0,sum=0; i<256; i++) {
+ fprintf(stderr," %3.3d:%7.7d ", i, char_count[i]);
+ sum += char_count[i];
+ }
+ fprintf(stderr,"\n\ntotal: %d\n\n",sum);
+}
+#endif
+
+TERM_PUBLIC void
+X11_set_color(t_colorspec *colorspec)
+{
+ if (colorspec->type == TC_RGB) {
+ fputc(X11_GR_SET_RGBCOLOR, X11_ipc);
+ PRINT1("%6.6x\n", colorspec->lt);
+ FFLUSH();
+ return;
+ }
+
+ if (colorspec->type == TC_LT) {
+ fputc(X11_GR_SET_LINECOLOR, X11_ipc);
+ PRINT1("%4d\n", colorspec->lt);
+ FFLUSH();
+ return;
+ }
+
+ if (colorspec->type != TC_FRAC)
+ return;
+
+#ifndef BINARY_X11_POLYGON
+ fputc(X11_GR_SET_COLOR, X11_ipc);
+ PRINT1("%f\n", colorspec->value);
+ FFLUSH();
+ return;
+#else
+ {
+ char *c_ptr;
+ unsigned short byte_remaining;
+ float fgray = colorspec->value;
+
+ fputc(X11_GR_SET_COLOR, X11_ipc);
+ byte_remaining = sizeof(fgray);
+ c_ptr = (char *) &fgray;
+
+ while (byte_remaining) {
+
+ char c_tmp = *c_ptr++ - SET_COLOR_TRANSLATION_CHAR;
+
+ byte_remaining--;
+
+ if ( (c_tmp == '\n') || (c_tmp == SET_COLOR_CODE_CHAR) || (c_tmp == '\0') ) {
+ fputc(SET_COLOR_CODE_CHAR, X11_ipc);
+ c_tmp += 1;
+ }
+ fputc(c_tmp, X11_ipc);
+
+ }
+
+ fputc('\n', X11_ipc);
+ FFLUSH();
+ }
+#endif /* BINARY_X11_POLYGON */
+
+}
+
+TERM_PUBLIC void
+X11_filled_polygon(int points, gpiPoint *corners)
+{
+
+#ifndef BINARY_X11_POLYGON
+
+ int i;
+
+ fputc(X11_GR_FILLED_POLYGON, X11_ipc);
+ /* FIXME HBB 20010919: this %04d format somewhat arbitrarily
+ * limits us to 10000 vertices in the polygon */
+ PRINT2("%04d%04d", points, corners->style);
+ for (i = 0; i < points; i++) {
+ PRINT2("%04d%04d", corners[i].x, corners[i].y);
+ /* HBB 20010919: fix for buffer overflow problem: start
+ * another line every 100 points, to avoid overflowing
+ * fixed-size buffer in gplt_x11. Number of points == -1
+ * signals continuation line */
+ if ((i % 100) == 99) {
+ PRINT1("xxxx\n%c-001", X11_GR_FILLED_POLYGON);
+ FFLUSH();
+ }
+ }
+ fputc('\n', X11_ipc);
+ FFLUSH();
+ return;
+
+#else
+
+ int int_cache[2];
+ int i_corner;
+ unsigned short i_buffer;
+ unsigned short byte_remaining;
+ unsigned point_remaining;
+
+ /* Encode and transfer data to the pipe, one character at a time. */
+
+ if (!points) return;
+
+ fputc(X11_GR_FILLED_POLYGON, X11_ipc);
+ i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
+
+ /* First put number of points into the buffer. Initialize the "cache"
+ * to the number of points and the number of bytes to transfer to the
+ * size of an int. This will be the first transfer, so increase the
+ * number of points by one.
+ */
+ int_cache[0] = points;
+ int_cache[1] = corners->style;
+ byte_remaining = 2*sizeof(int_cache[0]);
+ point_remaining = points + 1;
+ i_corner = 0;
+
+ while (point_remaining) {
+
+ unsigned char *uc_ptr = (unsigned char *) int_cache;
+
+ while (byte_remaining) {
+
+ int sent_val;
+
+ unsigned char uc_tmp = *uc_ptr++ - FILLED_POLYGON_TRANSLATION_CHAR;
+ byte_remaining--;
+
+ if ( (uc_tmp == '\n') || (uc_tmp == FILLED_POLYGON_CODE_CHAR) || (uc_tmp == '\0') ) {
+ uc_tmp += 1;
+ sent_val = fputc(FILLED_POLYGON_CODE_CHAR, X11_ipc);
+ if (sent_val != (int)FILLED_POLYGON_CODE_CHAR)
+ fprintf(stderr, "Bad character mapping %d -> %d\n", (int)FILLED_POLYGON_CODE_CHAR, sent_val);
+ i_buffer--;
+ if (!i_buffer) {
+ fputc('\n', X11_ipc); FFLUSH(); /* End of chunk. */
+ i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
+ fputc(X11_GR_FILLED_POLYGON, X11_ipc); /* Will be another chunk. */
+ }
+ }
+
+ sent_val = fputc(uc_tmp, X11_ipc);
+ if (sent_val != (int)uc_tmp)
+ fprintf(stderr, "Bad character mapping %d -> %d\n", (int)uc_tmp, sent_val);
+ i_buffer--;
+ if (!i_buffer) {
+ fputc('\n', X11_ipc); FFLUSH(); /* End of chunk. */
+ i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
+ if (point_remaining || byte_remaining)
+ fputc(X11_GR_FILLED_POLYGON, X11_ipc); /* Will be another chunk. */
+ }
+
+ }
+
+ byte_remaining = 2*sizeof(int);
+ if (--point_remaining) {
+ int_cache[0] = corners[i_corner].x;
+ int_cache[1] = corners[i_corner].y;
+ i_corner++;
+ }
+ }
+
+ /* Check if some characters were put in the buffer that need to be flushed. */
+ if (i_buffer != BINARY_MAX_CHAR_PER_TRANSFER) {
+ fputc('\n', X11_ipc);
+ FFLUSH();
+ }
+
+ return;
+#endif
+
+}
+
+
+/*
+ * Ethan A Merritt November 2003
+ * - Support for enhanced text mode
+ *
+ * PROBLEMS:
+ * - The default font must be scalable
+ * - Without more feedback from the outboard driver (gnuplot_x11) it is
+ * hard to set up proper text rotation. The current approximation is so-so.
+ * - Right- and Center- justified text is problematic for the same reason.
+ * - The default font size is not really known, and font scaling
+ * in general could be improved
+ */
+
+static TBOOLEAN ENHx11_opened_string;
+static TBOOLEAN ENHx11_sizeonly = FALSE;
+static TBOOLEAN ENHx11_show = TRUE;
+static int ENHx11_overprint = 0;
+static TBOOLEAN ENHx11_widthflag = TRUE;
+static double ENHx11_base;
+static double ENHx11_fontsize;
+static char *ENHx11_font;
+
+TERM_PUBLIC void
+ENHX11_OPEN(
+ char *fontname,
+ double fontsize, double base,
+ TBOOLEAN widthflag, TBOOLEAN showflag,
+ int overprint)
+{
+ /* If the overprint code requests a save or request, that's all we do */
+ if (overprint == 3) {
+ PRINT2("Tp%04d%04d\n", 0, 0);
+ return;
+ } else if (overprint == 4) {
+ PRINT2("Tr%04d%04d\n", 0, 0);
+ return;
+ }
+
+ if (!ENHx11_opened_string) {
+ ENHx11_opened_string = TRUE;
+ enhanced_cur_text = &enhanced_text[0];
+ ENHx11_font = fontname;
+ ENHx11_fontsize = fontsize;
+ ENHx11_base = base * 10; /* FIXME - should this be v_char? v_tic? */
+ ENHx11_show = showflag;
+ ENHx11_overprint = overprint;
+ ENHx11_widthflag = widthflag;
+ }
+}
+
+/*
+ * Write a string fragment and update current position.
+ * We leave the real work up to gnuplot_x11!
+ */
+TERM_PUBLIC void
+ENHX11_FLUSH()
+{
+ /* Send a command to print this string at current position */
+ if (ENHx11_opened_string) {
+
+ char tmpfont[128]; /* FIXME - there must be a better way! */
+ *enhanced_cur_text = '\0';
+ sprintf(tmpfont,"%s,%.1f", ENHx11_font, ENHx11_fontsize);
+ PRINT1("QF%s\n", tmpfont);
+ *X11_last_font_used = '\01';
+
+ if (!ENHx11_show || ENHx11_sizeonly)
+ PRINT3("Ts%04d%04d%s\n", 0, (int)ENHx11_base, enhanced_text);
+ else if (ENHx11_overprint == 1)
+ PRINT3("Tc%04d%04d%s\n", 0, (int)ENHx11_base, enhanced_text);
+ else if (!ENHx11_widthflag && ENHx11_overprint != 0)
+ PRINT3("To%04d%04d%s\n", 0, (int)ENHx11_base, enhanced_text);
+ else
+ PRINT3("Tu%04d%04d%s\n", 0, (int)ENHx11_base, enhanced_text);
+
+ ENHx11_opened_string = FALSE;
+ }
+}
+
+TERM_PUBLIC void
+ENHX11_put_text(unsigned int x, unsigned int y, const char *str)
+{
+ char *original_string = (char *)str;
+ static char *initial_font = NULL;
+ int pass = 1;
+
+ if (ignore_enhanced_text) {
+ X11_put_text(x,y,str);
+ return;
+ }
+
+ if (!strlen(str))
+ return;
+
+ /* if there are no magic characters, we should just be able
+ * punt the string to X11_put_text()
+ */
+ if (!strpbrk(str, "{}^_@&~")) {
+ X11_put_text(x,y,str);
+ return;
+ }
+
+ /* set up the global variables needed by enhanced_recursion() */
+ enhanced_fontscale = 1.25;
+ ENHx11_opened_string = FALSE;
+ strncpy(enhanced_escape_format,"%c",sizeof(enhanced_escape_format));
+
+
+ /* Tell gnuplot_x11 to set the current position to (x,y) */
+ PRINT2("Tl%04d%04d\n", x, y);
+
+ /* Text justification requires two passes. During the first pass we */
+ /* don't draw anything, we just measure the space it will take. */
+ if (X11_last_justification != LEFT) {
+ PRINT1("J%04d\n", LEFT);
+ ENHx11_sizeonly = TRUE;
+ }
+PASS2:
+
+ /* Make sure that we start out using the intended font. */
+ ENHx11_font = "DEFAULT";
+ ENHx11_fontsize = X11_default_fontsize;
+ if (*X11_next_font_used) {
+ int sep = strcspn(X11_next_font_used,",");
+ free(initial_font);
+ initial_font = gp_strdup(X11_next_font_used);
+ initial_font[sep] = '\0';
+ sscanf(&(X11_next_font_used[sep+1]),"%lf",&ENHx11_fontsize);
+ ENHx11_font = initial_font;
+ FPRINTF((stderr,"setting font to %s,%g\n",ENHx11_font,ENHx11_fontsize));
+ }
+
+ /* Set the recursion going. We say to keep going until a
+ * closing brace, but we don't really expect to find one.
+ * If the return value is not the nul-terminator of the
+ * string, that can only mean that we did find an unmatched
+ * closing brace in the string. We increment past it (else
+ * we get stuck in an infinite loop) and try again.
+ */
+ while (*(str = enhanced_recursion((char *)str, TRUE,
+ ENHx11_font, ENHx11_fontsize,
+ 0.0, TRUE, TRUE, 0))) {
+ (term->enhanced_flush)();
+
+ /* I think we can only get here if *str == '}' */
+ enh_err_check(str);
+
+ if (!*++str)
+ break; /* end of string */
+
+ /* else carry on and process the rest of the string */
+ }
+
+ /* Restore text justification flag after 2nd pass */
+ if (pass > 1) {
+ PRINT1("J%04d\n", X11_last_justification);
+ return;
+ }
+
+ /* In order to do text justification we need to do a second pass that */
+ /* uses information stored by gnuplot_x11 during the first pass. */
+ if (X11_last_justification != LEFT) {
+ ENHx11_sizeonly = FALSE;
+
+ if (X11_last_justification == RIGHT) {
+ PRINT2("Tj%04d%04d\n", x, y);
+ } else if (X11_last_justification == CENTRE) {
+ PRINT2("Tk%04d%04d\n", x, y);
+ }
+ str = original_string;
+ pass = 2;
+ goto PASS2;
+
+ }
+
+}
+
+
+#if defined(WITH_IMAGE) || defined(BINARY_X11_POLYGON)
+TERM_PUBLIC void
+X11_send_endianess(void)
+{
+ /* Place an integer 1 in the pipe and see if the byte order agrees
+ * with program on the other side. Information used for routines
+ * having encoded binary data.
+ */
+ unsigned short tmp = (unsigned short) ENDIAN_VALUE;
+ fputc(X11_GR_CHECK_ENDIANESS, X11_ipc);
+ fputc(((char *)&tmp)[0], X11_ipc);
+ fputc(((char *)&tmp)[1], X11_ipc);
+ fputc('\n', X11_ipc);
+ fflush(X11_ipc);
+}
+#endif
+
+#ifdef WITH_IMAGE
+
+TERM_PUBLIC void
+X11_image(unsigned M, unsigned N, coordval *image, gpiPoint *corner, t_imagecolor color_mode)
+{
+
+ /* Avoid using floats or formatted I/O. That's too slow for image data.
+ *
+ * To avoid using floats, we assume that the maximum resolution of the
+ * color plane of the x11 device is 16 bits. (Not an unreasonable
+ * assumption.) So we convert coordval to unsigned short and then
+ * send those. The driver then shifts these unsigned short values to
+ * the right to match the size of its palette.
+ *
+ * The driver uses the '\n' character to mean end of command. When the
+ * core routine sees the '\n', it stops copying the remaining characters
+ * that are in the buffer. Therefore, we need to hide the '\n' character
+ * from the data stream. We also need to hide the '\0' because the core
+ * routine also does an 'strcpy'. So the scheme is as follows:
+ *
+ * On the driver side, if the char CODE_WORD is found it
+ * should be ignored and replaced with the char that
+ * follows it, but subtract one from that value.
+ *
+ * This means that there exists the chance of the data stream enlarging
+ * by a factor of two. So the algorithm must make sure to keep the
+ * number of bytes transfered less than the buffer length.
+ *
+ * Also note that the '\0' character is often prevalent in 16 bit image
+ * data where the palette may be 8 bits or less. For this reason, a
+ * translation is first done on the character to make the '\0' occur less
+ * often. In this way, less amount of data is sent and fewer command
+ * lines are used to store an image.
+ */
+
+ unsigned short i_buffer;
+ unsigned coord_remaining;
+ coordval *coord_ptr;
+
+ /* Use formatted I/O to transfer image information. Hexadecimal uses less characters.
+ *
+ * Note that X11 has different frame of reference (top left origin) than does Gnuplot
+ * (bottom left origin)
+ */
+ fputc(X11_GR_IMAGE, X11_ipc);
+ fprintf(X11_ipc,"%x %x %x %x %x %x %x %x %x %x %x\n", M, N, corner[0].x, corner[0].y, corner[1].x,
+ corner[1].y, corner[2].x, corner[2].y, corner[3].x, corner[3].y, color_mode);
+ FFLUSH();
+
+ /* Encode and transfer data to the pipe, one character at a time. */
+
+ coord_remaining = M*N;
+ if (color_mode == IC_RGB) coord_remaining *= 3;
+
+ if (!coord_remaining) return;
+
+ fputc(X11_GR_IMAGE, X11_ipc);
+ i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
+ coord_ptr = image;
+
+ while (coord_remaining) {
+
+ unsigned short us_tmp;
+ unsigned short byte_remaining;
+ unsigned char *uc_ptr;
+
+ /* Convert coordinate value to an unsigned short. Note that there
+ * is no need for a range check because we are already using the
+ * full range of the unsigned short value. It is the C casting
+ * routine that should do the range check.
+ */
+ us_tmp = (unsigned short) ((*coord_ptr++)*IMAGE_PALETTE_VALUE_MAX + 0.5);
+ coord_remaining--;
+
+ byte_remaining = sizeof(us_tmp);
+ uc_ptr = (unsigned char *) &us_tmp;
+
+ while (byte_remaining) {
+
+ int sent_val;
+
+ unsigned char uc_tmp = *uc_ptr++ - IMAGE_TRANSLATION_CHAR;
+ byte_remaining--;
+
+ if ((uc_tmp == '\n') || (uc_tmp == IMAGE_CODE_CHAR) || (uc_tmp == '\0') ) {
+ uc_tmp += 1;
+ sent_val = fputc(IMAGE_CODE_CHAR, X11_ipc);
+ if (sent_val != (int)IMAGE_CODE_CHAR)
+ fprintf(stderr, "Bad character mapping %d -> %d\n", (int)IMAGE_CODE_CHAR, sent_val);
+ i_buffer--;
+ if (!i_buffer) {
+ fputc('\n', X11_ipc); FFLUSH(); /* End of chunk. */
+ i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
+ fputc(X11_GR_IMAGE, X11_ipc); /* Will be another chunk. */
+ }
+ }
+
+ sent_val = fputc(uc_tmp, X11_ipc);
+ if (sent_val != (int)uc_tmp)
+ fprintf(stderr, "Bad character mapping %d -> %d\n", (int)uc_tmp, sent_val);
+ i_buffer--;
+ if (!i_buffer) {
+ fputc('\n', X11_ipc); FFLUSH(); /* End of chunk. */
+ i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
+ if (coord_remaining || byte_remaining)
+ fputc(X11_GR_IMAGE, X11_ipc); /* Will be another chunk. */
+ }
+
+ }
+
+ }
+
+ /* Check if some characters were put in the buffer that need to be flushed. */
+ if (i_buffer != BINARY_MAX_CHAR_PER_TRANSFER) {fputc('\n', X11_ipc); FFLUSH();}
+
+ return;
+}
+
+#endif /* WITH_IMAGE */
+
+#endif /* TERM_BODY */
+
+#ifdef TERM_TABLE
+
+TERM_TABLE_START(x11_driver)
+ "x11", "X11 Window System",
+ X11_XMAX, X11_YMAX, X11_VCHAR, X11_HCHAR,
+ X11_VTIC, X11_HTIC, X11_options, X11_init, X11_reset,
+ X11_text, null_scale, X11_graphics, X11_move, X11_vector,
+ X11_linetype, X11_put_text, X11_text_angle,
+ X11_justify_text, X11_point, do_arrow, X11_set_font,
+ X11_pointsize, TERM_CAN_MULTIPLOT|TERM_INIT_ON_REPLOT|TERM_NO_OUTPUTFILE,
+ X11_text /* suspend can use same routine */ , 0 /* resume */ ,
+ X11_fillbox, X11_linewidth
+#ifdef USE_MOUSE
+ , X11_waitforinput, X11_put_tmptext, X11_set_ruler, X11_set_cursor, X11_set_clipboard
+#endif
+ , X11_make_palette, 0 /* X11_previous_palette */ ,
+ X11_set_color, X11_filled_polygon
+#ifdef WITH_IMAGE
+ , X11_image
+#endif
+ , ENHX11_OPEN, ENHX11_FLUSH, do_enh_writec
+TERM_TABLE_END(x11_driver)
+
+#undef LAST_TERM
+#define LAST_TERM x11_driver
+
+#endif /* TERM_TABLE */
+#endif /* TERM_PROTO_ONLY */
+
+
+#ifdef TERM_HELP
+START_HELP(x11)
+"1 x11",
+"?commands set terminal x11",
+"?set terminal x11",
+"?set term x11",
+"?terminal x11",
+"?term x11",
+"?x11",
+"?X11",
+" `gnuplot` provides the `x11` terminal type for use with X servers. This",
+" terminal type is set automatically at startup if the `DISPLAY` environment",
+" variable is set, if the `TERM` environment variable is set to `xterm`, or",
+" if the `-display` command line option is used.",
+"",
+" Syntax:",
+" set terminal x11 {<n>}",
+" {title \"<string>\"}",
+" {{no}enhanced} {font <fontspec>}",
+" {linewidth LW} {solid|dashed}",
+" {{no}persist} {{no}raise} {{no}ctrlq}",
+" {close}",
+" {size XX,YY} {position XX,YY}",
+" set terminal x11 {reset}",
+"",
+" Multiple plot windows are supported: `set terminal x11 <n>` directs the",
+" output to plot window number n. If n is not 0, the terminal number will be",
+" appended to the window title (unless a title has been supplied manually)",
+" and the icon will be labeled `Gnuplot <n>`. The active window may be",
+" distinguished by a change in cursor (from default to crosshair).",
+"",
+" The x11 terminal support enhanced text mode (see `enhanced`), subject",
+" to the available fonts. In order for font size commands embedded in text",
+" to have any effect, the default x11 font must be scalable. Thus the first",
+" example below will work as expected, but the second will not.",
+"",
+" set term x11 enhanced font \"arial,15\" ",
+" set title '{/=20 Big} Medium {/=5 Small}' ",
+"",
+" set term x11 enhanced font \"terminal-14\" ",
+" set title '{/=20 Big} Medium {/=5 Small}' ",
+"",
+" Plot windows remain open even when the `gnuplot` driver is changed to a",
+" different device. A plot window can be closed by pressing the letter q",
+" while that window has input focus, or by choosing `close` from a window",
+" manager menu. All plot windows can be closed by specifying `reset`, which",
+" actually terminates the subprocess which maintains the windows (unless",
+" `-persist` was specified). The `close` command can be used to close",
+" individual plot windows by number. However, after a `reset`, those plot",
+" windows left due to persist cannot be closed with the command `close`.",
+" A `close` without a number closes the current active plot window.",
+"",
+" The gnuplot outboard driver, gnuplot_x11, is searched in a default place",
+" chosen when the program is compiled. You can override that by defining",
+" the environment variable GNUPLOT_DRIVER_DIR to point to a different",
+" location.",
+"",
+" Plot windows will automatically be closed at the end of the session",
+" unless the `-persist` option was given.",
+"",
+" The options `persist` and `raise` are unset by default, which means that",
+" the defaults (persist == no and raise == yes) or the command line options",
+" -persist / -raise or the Xresources are taken. If [no]persist or",
+" [no]raise are specified, they will override command line options and",
+" Xresources. Setting one of these options takes place immediately, so",
+" the behaviour of an already running driver can be modified. If the window",
+" does not get raised, see discussion in `raise`.",
+"",
+" The option `title \"<title name>\"` will supply the title name of the window",
+" for the current plot window or plot window <n> if a number is given.",
+" Where (or if) this title is shown depends on your X window manager.",
+"",
+" The size option can be used to set the size of the plot window. The",
+" size option will only apply to newly created windows.",
+"",
+" The position option can be used to set the position of the plot window. The",
+" position option will only apply to newly created windows.",
+"",
+" The size or aspect ratio of a plot may be changed by resizing the `gnuplot`",
+" window.",
+"",
+" Linewidths and pointsizes may be changed from within `gnuplot` with",
+" `set linestyle`.",
+"",
+" For terminal type `x11`, `gnuplot` accepts (when initialized) the standard",
+" X Toolkit options and resources such as geometry, font, and name from the",
+" command line arguments or a configuration file. See the X(1) man page",
+" (or its equivalent) for a description of such options.",
+"",
+"=X resources",
+" A number of other `gnuplot` options are available for the `x11` terminal.",
+" These may be specified either as command-line options when `gnuplot` is",
+" invoked or as resources in the configuration file \".Xdefaults\". They are",
+" set upon initialization and cannot be altered during a `gnuplot` session.",
+" (except `persist` and `raise`)",
+"2 x11_fonts",
+"?commands set terminal x11 x11_fonts",
+"?set terminal x11 x11_fonts",
+"?set term x11 x11_fonts",
+"?x11 x11_fonts",
+"?x11_fonts",
+"=fonts",
+" Upon initial startup, the default font is taken from the X11 resources",
+" as set in the system or user .Xdefaults file or on the command line.",
+"",
+" Example:",
+" gnuplot*font: lucidasans-bold-12",
+" A new default font may be specified to the x11 driver from inside",
+" gnuplot using",
+" `set term x11 font \"<fontspec>\"`",
+" The driver first queries the X-server for a font of the exact name given.",
+" If this query fails, then it tries to interpret <fontspec> as",
+" \"<font>,<size>,<slant>,<weight>\" and to construct a full X11 font name",
+" of the form",
+" -*-<font>-<weight>-<s>-*-*-<size>-*-*-*-*-*-<encoding>",
+"",
+" <font> is the base name of the font (e.g. Times or Symbol)",
+" <size> is the point size (defaults to 12 if not specified)",
+" <s> is `i` if <slant>==\"italic\" `o` if <slant>==\"oblique\" `r` otherwise",
+" <weight> is `medium` or `bold` if explicitly requested, otherwise `*`",
+" <encoding> is set based on the current character set (see `set encoding`).",
+" So `set term x11 font \"arial,15,italic\"` will be translated to",
+" -*-arial-*-i-*-*-15-*-*-*-*-*-iso8859-1 (assuming default encoding).",
+" The <size>, <slant>, and <weight> specifications are all optional.",
+" If you do not specify <slant> or <weight> then you will get whatever font ",
+" variant the font server offers first.",
+" You may set a default enconding via the corresponding X11 resource. E.g.",
+" gnuplot*encoding: iso8859-15",
+" The driver also recognizes some common PostScript font names and",
+" replaces them with possible X11 or TrueType equivalents.",
+" This same sequence is used to process font requests from `set label`.",
+"",
+" If your gnuplot was built with configuration option --enable-x11-mbfonts,",
+" you can specify multi-byte fonts by using the prefix \"mbfont:\" on the font",
+" name. An additional font may be given, separated by a semicolon.",
+" Since multi-byte font encodings are interpreted according to the locale",
+" setting, you must make sure that the environmental variable LC_CTYPE is set",
+" to some appropriate locale value such as ja_JP.eucJP, ko_KR.EUC, or zh_CN.EUC.",
+"",
+" Example:",
+" set term x11 font 'mbfont:kana14;k14'",
+" # 'kana14' and 'k14' are Japanese X11 font aliases, and ';'",
+" # is the separator of font names.",
+" set term x11 font 'mbfont:fixed,16,r,medium'",
+" # <font>,<size>,<slant>,<weight> form is also usable.",
+" set title '(mb strings)' font 'mbfont:*-fixed-medium-r-normal--14-*'",
+"",
+" The same syntax applies to the default font in Xresources settings,",
+" for example,",
+" gnuplot*font: \\",
+" mbfont:-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0",
+"",
+" If gnuplot is built with --enable-x11-mbfonts, you can use two special",
+" PostScript font names 'Ryumin-Light-*' and 'GothicBBB-Medium-*' (standard",
+" Japanese PS fonts) without the prefix \"mbfont:\".",
+"",
+"2 command-line_options",
+"?commands set terminal x11 command-line-options",
+"?set terminal x11 command-line-options",
+"?set term x11 command-line-options",
+"?x11 command-line-options",
+"?command-line-options",
+" In addition to the X Toolkit options, the following options may be specified",
+" on the command line when starting `gnuplot` or as resources in your",
+" \".Xdefaults\" file (note that `raise` and `persist` can be overridden",
+" later by `set term x11 [no]raise [no]persist)`:",
+"@start table - first is interactive cleartext form",
+" `-mono` forces monochrome rendering on color displays.",
+" `-gray` requests grayscale rendering on grayscale or color displays.",
+" (Grayscale displays receive monochrome rendering by default.)",
+" `-clear` requests that the window be cleared momentarily before a",
+" new plot is displayed.",
+" `-tvtwm` requests that geometry specifications for position of the",
+" window be made relative to the currently displayed portion",
+" of the virtual root.",
+" `-raise` raises plot window after each plot",
+" `-noraise` does not raise plot window after each plot",
+#ifdef USE_MOUSE
+" `-noevents` does not process mouse and key events",
+" `-ctrlq ` closes window on ctrl-q rather than q",
+#endif
+" `-persist` plot windows survive after main gnuplot program exits",
+"#\\begin{tabular}{|cl|} \\hline",
+"#`-mono` & forces monochrome rendering on color displays.\\\\",
+"#`-gray` & requests grayscale rendering on grayscale or color displays.\\\\",
+"# & (Grayscale displays receive monochrome rendering by default.) \\\\",
+"#`-clear` & requests that the window be cleared momentarily before a\\\\",
+"# & new plot is displayed. \\\\",
+"#`-tvtwm` & requests that geometry specifications for position of the\\\\",
+"# & window be made relative to the currently displayed portion\\\\",
+"# & of the virtual root. \\\\",
+"#`-raise` & raises plot window after each plot. \\\\",
+"#`-noraise` & does not raise plot window after each plot. \\\\",
+#ifdef USE_MOUSE
+"#`-noevents` & does not process mouse and key events. \\\\",
+#endif
+"#`-persist` & plot windows survive after main gnuplot program exits. \\\\",
+"%c l .",
+"%`-mono`@forces monochrome rendering on color displays.",
+"%`-gray`@requests grayscale rendering on grayscale or color displays.",
+"% @(Grayscale displays receive monochrome rendering by default.)",
+"%`-clear`@requests that the window be cleared momentarily before a",
+"% @new plot is displayed.",
+"%`-tvtwm`@requests that geometry specifications for position of the",
+"% @window be made relative to the currently displayed portion",
+"% @of the virtual root.",
+"%`-raise`@raises plot window after each plot",
+"%`-noraise`@does not raise plot window after each plot",
+#ifdef USE_MOUSE
+"%`-novevents`@does not process mouse and key events",
+"%`-ctrlq`@closes window on ctrl-q rather than q",
+#endif
+"%`-persist`@plot windows survive after main gnuplot program exits",
+"@end table",
+"=X resources",
+" The options are shown above in their command-line syntax. When entered as",
+" resources in \".Xdefaults\", they require a different syntax.",
+"",
+" Example:",
+" gnuplot*gray: on",
+" gnuplot*ctrlq: on",
+"",
+" `gnuplot` also provides a command line option (`-pointsize <v>`) and a",
+" resource, `gnuplot*pointsize: <v>`, to control the size of points plotted",
+" with the `points` plotting style. The value `v` is a real number (greater",
+" than 0 and less than or equal to ten) used as a scaling factor for point",
+" sizes. For example, `-pointsize 2` uses points twice the default size, and",
+" `-pointsize 0.5` uses points half the normal size.",
+"",
+" The `-noevents` switch disables all mouse and key event processing (except",
+" for `q` and `<space>` for closing the window). This is useful for programs",
+" which use the x11 driver independent of the gnuplot main program.",
+"",
+" The `-ctrlq` switch changes the hot-key that closes a plot window from `q`",
+" to `<ctrl>q`. This is useful is you are using the keystroke-capture feature",
+" `pause mouse keystroke`, since it allows the character `q` to be captured",
+" just as all other alphanumeric characters. The `-ctrlq` switch similarly",
+" replaces the <space> hot-key with <ctrl><space> for the same reason.",
+"",
+"2 monochrome_options",
+"?commands set terminal x11 monochrome_options",
+"?set terminal x11 monochrome_options",
+"?set term x11 monochrome_options",
+"?x11 monochrome_options",
+"?monochrome_options",
+"=X resources",
+" For monochrome displays, `gnuplot` does not honor foreground or background",
+" colors. The default is black-on-white. `-rv` or `gnuplot*reverseVideo: on`",
+" requests white-on-black.",
+"",
+"2 color_resources",
+"?commands set terminal x11 color_resources",
+"?set terminal x11 color_resources",
+"?set term x11 color_resources",
+"?x11 color_resources",
+"?color_resources",
+"=X resources",
+" For color displays, `gnuplot` honors the following resources (shown here",
+" with their default values) or the greyscale resources. The values may be",
+" color names as listed in the X11 rgb.txt file on your system, hexadecimal",
+" RGB color specifications (see X11 documentation), or a color name followed",
+" by a comma and an `intensity` value from 0 to 1. For example, `blue, 0.5`",
+" means a half intensity blue.",
+"@start table - first is interactive cleartext form",
+" gnuplot*background: white",
+" gnuplot*textColor: black",
+" gnuplot*borderColor: black",
+" gnuplot*axisColor: black",
+" gnuplot*line1Color: red",
+" gnuplot*line2Color: green",
+" gnuplot*line3Color: blue",
+" gnuplot*line4Color: magenta",
+" gnuplot*line5Color: cyan",
+" gnuplot*line6Color: sienna",
+" gnuplot*line7Color: orange",
+" gnuplot*line8Color: coral",
+"#\\begin{tabular}{|cl|} \\hline",
+"#&gnuplot*background: white\\\\",
+"#&gnuplot*textColor: black\\\\",
+"#&gnuplot*borderColor: black\\\\",
+"#&gnuplot*axisColor: black\\\\",
+"#&gnuplot*line1Color: red\\\\",
+"#&gnuplot*line2Color: green\\\\",
+"#&gnuplot*line3Color: blue\\\\",
+"#&gnuplot*line4Color: magenta\\\\",
+"#&gnuplot*line5Color: cyan\\\\",
+"#&gnuplot*line6Color: sienna\\\\",
+"#&gnuplot*line7Color: orange\\\\",
+"#&gnuplot*line8Color: coral\\\\",
+"%c l .",
+"%@gnuplot*background: white",
+"%@gnuplot*textColor: black",
+"%@gnuplot*borderColor: black",
+"%@gnuplot*axisColor: black",
+"%@gnuplot*line1Color: red",
+"%@gnuplot*line2Color: green",
+"%@gnuplot*line3Color: blue",
+"%@gnuplot*line4Color: magenta",
+"%@gnuplot*line5Color: cyan",
+"%@gnuplot*line6Color: sienna",
+"%@gnuplot*line7Color: orange",
+"%@gnuplot*line8Color: coral",
+"@end table",
+"",
+" The command-line syntax for these is simple only for background,",
+" which maps directly to the usual X11 toolkit option \"-bg\". All",
+" others can only be set on the command line by use of the generic",
+" \"-xrm\" resource override option",
+"",
+" Examples:",
+"",
+" gnuplot -background coral",
+" to change the background color.",
+"",
+" gnuplot -xrm 'gnuplot*line1Color:blue'",
+" to override the first linetype color.",
+"",
+"2 grayscale_resources",
+"?commands set terminal x11 grayscale_resources",
+"?set terminal x11 grayscale_resources",
+"?set term x11 grayscale_resources",
+"?x11 grayscale_resources",
+"?grayscale_resources",
+"=X resources",
+" When `-gray` is selected, `gnuplot` honors the following resources for",
+" grayscale or color displays (shown here with their default values). Note",
+" that the default background is black.",
+"@start table - first is interactive cleartext form",
+" gnuplot*background: black",
+" gnuplot*textGray: white",
+" gnuplot*borderGray: gray50",
+" gnuplot*axisGray: gray50",
+" gnuplot*line1Gray: gray100",
+" gnuplot*line2Gray: gray60",
+" gnuplot*line3Gray: gray80",
+" gnuplot*line4Gray: gray40",
+" gnuplot*line5Gray: gray90",
+" gnuplot*line6Gray: gray50",
+" gnuplot*line7Gray: gray70",
+" gnuplot*line8Gray: gray30",
+"#\\begin{tabular}{|cl|} \\hline",
+"#&gnuplot*background: black\\\\",
+"#&gnuplot*textGray: white\\\\",
+"#&gnuplot*borderGray: gray50\\\\",
+"#&gnuplot*axisGray: gray50\\\\",
+"#&gnuplot*line1Gray: gray100\\\\",
+"#&gnuplot*line2Gray: gray60\\\\",
+"#&gnuplot*line3Gray: gray80\\\\",
+"#&gnuplot*line4Gray: gray40\\\\",
+"#&gnuplot*line5Gray: gray90\\\\",
+"#&gnuplot*line6Gray: gray50\\\\",
+"#&gnuplot*line7Gray: gray70\\\\",
+"#&gnuplot*line8Gray: gray30\\\\",
+"%c l .",
+"%@gnuplot*background: black",
+"%@gnuplot*textGray: white",
+"%@gnuplot*borderGray: gray50",
+"%@gnuplot*axisGray: gray50",
+"%@gnuplot*line1Gray: gray100",
+"%@gnuplot*line2Gray: gray60",
+"%@gnuplot*line3Gray: gray80",
+"%@gnuplot*line4Gray: gray40",
+"%@gnuplot*line5Gray: gray90",
+"%@gnuplot*line6Gray: gray50",
+"%@gnuplot*line7Gray: gray70",
+"%@gnuplot*line8Gray: gray30",
+"@end table",
+"",
+"2 line_resources",
+"?commands set terminal x11 line_resources",
+"?set terminal x11 line_resources",
+"?set term x11 line_resources",
+"?x11 line_resources",
+"?line_resources",
+"=X resources",
+" `gnuplot` honors the following resources for setting the width (in pixels) of",
+" plot lines (shown here with their default values.) 0 or 1 means a minimal",
+" width line of 1 pixel width. A value of 2 or 3 may improve the appearance of",
+" some plots.",
+"@start table - first is interactive cleartext form",
+" gnuplot*borderWidth: 2",
+" gnuplot*axisWidth: 0",
+" gnuplot*line1Width: 0",
+" gnuplot*line2Width: 0",
+" gnuplot*line3Width: 0",
+" gnuplot*line4Width: 0",
+" gnuplot*line5Width: 0",
+" gnuplot*line6Width: 0",
+" gnuplot*line7Width: 0",
+" gnuplot*line8Width: 0",
+"#\\begin{tabular}{|cl|} \\hline",
+"#&gnuplot*borderWidth: 2\\\\",
+"#&gnuplot*axisWidth: 0\\\\",
+"#&gnuplot*line1Width: 0\\\\",
+"#&gnuplot*line2Width: 0\\\\",
+"#&gnuplot*line3Width: 0\\\\",
+"#&gnuplot*line4Width: 0\\\\",
+"#&gnuplot*line5Width: 0\\\\",
+"#&gnuplot*line6Width: 0\\\\",
+"#&gnuplot*line7Width: 0\\\\",
+"#&gnuplot*line8Width: 0\\\\",
+"%c l .",
+"%@gnuplot*borderWidth: 2",
+"%@gnuplot*axisWidth: 0",
+"%@gnuplot*line1Width: 0",
+"%@gnuplot*line2Width: 0",
+"%@gnuplot*line3Width: 0",
+"%@gnuplot*line4Width: 0",
+"%@gnuplot*line5Width: 0",
+"%@gnuplot*line6Width: 0",
+"%@gnuplot*line7Width: 0",
+"%@gnuplot*line8Width: 0",
+"@end table",
+"",
+" `gnuplot` honors the following resources for setting the dash style used for",
+" plotting lines. 0 means a solid line. A two-digit number `jk` (`j` and `k`",
+" are >= 1 and <= 9) means a dashed line with a repeated pattern of `j` pixels",
+" on followed by `k` pixels off. For example, '16' is a dotted line with one",
+" pixel on followed by six pixels off. More elaborate on/off patterns can be",
+" specified with a four-digit value. For example, '4441' is four on, four off,",
+" four on, one off. The default values shown below are for monochrome displays",
+" or monochrome rendering on color or grayscale displays.",
+" Color displays default to dashed:off ",
+"@start table - first is interactive cleartext form",
+" gnuplot*dashed: off",
+" gnuplot*borderDashes: 0",
+" gnuplot*axisDashes: 16",
+" gnuplot*line1Dashes: 0",
+" gnuplot*line2Dashes: 42",
+" gnuplot*line3Dashes: 13",
+" gnuplot*line4Dashes: 44",
+" gnuplot*line5Dashes: 15",
+" gnuplot*line6Dashes: 4441",
+" gnuplot*line7Dashes: 42",
+" gnuplot*line8Dashes: 13",
+"#\\begin{tabular}{|cl|} \\hline",
+"#&gnuplot*dashed: off\\\\",
+"#&gnuplot*borderDashes: 0\\\\",
+"#&gnuplot*axisDashes: 16\\\\",
+"#&gnuplot*line1Dashes: 0\\\\",
+"#&gnuplot*line2Dashes: 42\\\\",
+"#&gnuplot*line3Dashes: 13\\\\",
+"#&gnuplot*line4Dashes: 44\\\\",
+"#&gnuplot*line5Dashes: 15\\\\",
+"#&gnuplot*line6Dashes: 4441\\\\",
+"#&gnuplot*line7Dashes: 42\\\\",
+"#&gnuplot*line8Dashes: 13\\\\",
+"%c l .",
+"%@gnuplot*dashed: off",
+"%@gnuplot*borderDashes: 0",
+"%@gnuplot*axisDashes: 16",
+"%@gnuplot*line1Dashes: 0",
+"%@gnuplot*line2Dashes: 42",
+"%@gnuplot*line3Dashes: 13",
+"%@gnuplot*line4Dashes: 44",
+"%@gnuplot*line5Dashes: 15",
+"%@gnuplot*line6Dashes: 4441",
+"%@gnuplot*line7Dashes: 42",
+"%@gnuplot*line8Dashes: 13",
+"@end table"
+, "",
+"2 x11 pm3d_resources",
+"?commands set terminal x11 pm3d_resources",
+"?set terminal x11 pm3d_resources",
+"?set term x11 pm3d_resources",
+"?x11 pm3d_resources",
+"?pm3d_resources",
+"?x11 pm3d",
+"=X resources",
+" Choosing the appropriate visual class and number of colors is a crucial",
+" point in X11 applications and a bit awkward, since X11 supports six visual",
+" types in different depths.",
+"",
+" By default `gnuplot` uses the default visual of the screen. The number of",
+" colors which can be allocated depends on the visual class chosen. On a",
+" visual class with a depth > 12bit, gnuplot starts with a maximal number",
+" of 0x200 colors. On a visual class with a depth > 8bit (but <= 12 bit)",
+" the maximal number of colors is 0x100, on <= 8bit displays the maximum",
+" number of colors is 240 (16 are left for line colors).",
+"",
+" Gnuplot first starts to allocate the maximal number of colors as stated",
+" above. If this fails, the number of colors is reduced by the factor 2",
+" until gnuplot gets all colors which are requested. If dividing `maxcolors`",
+" by 2 repeatedly results in a number which is smaller than `mincolors`",
+" `gnuplot` tries to install a private colormap. In this case the window",
+" manager is responsible for swapping colormaps when the pointer is moved",
+" in and out the x11 driver's window.",
+"",
+" The default for `mincolors` is maxcolors / (num_colormaps > 1 ? 2 : 8),",
+" where num_colormaps is the number of colormaps which are currently used",
+" by gnuplot (usually 1, if only one x11 window is open).",
+"",
+" Some systems support multiple (different) visual classes together on one",
+" screen. On these systems it might be necessary to force gnuplot to use a",
+" specific visual class, e.g. the default visual might be 8bit PseudoColor",
+" but the screen would also support 24bit TrueColor which would be the",
+" preferred choice.",
+"",
+" The information about an Xserver's capabilities can be obtained with the",
+" program `xdpyinfo`. For the visual names below you can choose one of",
+" StaticGray, GrayScale, StaticColor, PseudoColor, TrueColor, DirectColor.",
+" If an Xserver supports a requested visual type at different depths,",
+" `gnuplot` chooses the visual class with the highest depth (deepest).",
+" If the requested visual class matches the default visual and multiple",
+" classes of this type are supported, the default visual is preferred.",
+"",
+" Example: on an 8bit PseudoColor visual you can force a private color map",
+" by specifying `gnuplot*maxcolors: 240` and `gnuplot*mincolors: 240`.",
+"",
+"@start table - first is interactive cleartext form",
+" gnuplot*maxcolors: <integer>",
+" gnuplot*mincolors: <integer>",
+" gnuplot*visual: <visual name>",
+"#\\begin{tabular}{|cl|} \\hline",
+"#&gnuplot*maxcolors: integer\\\\",
+"#&gnuplot*mincolors: integer\\\\",
+"#&gnuplot*visual: visual name\\\\",
+"%c l .",
+"%@gnuplot*maxcolors: <integer number>",
+"%@gnuplot*mincolors: <integer number>",
+"%@gnuplot*visual: <visual name>",
+"@end table"
+, "",
+"2 x11 other_resources",
+"?commands set terminal x11 other_resources",
+"?set terminal x11 other_resources",
+"?set term x11 other_resources",
+"?x11 other_resources",
+"=X resources",
+" By default the contents of the current plot window are exported to the X11",
+" clipboard in response to X events in the window. Setting the resource",
+" 'gnuplot*exportselection' to 'off' or 'false' will disable this.",
+"",
+" By default text rotation is done using a method that is fast, but can",
+" corrupt nearby colors depending on the background. If this is a problem,",
+" you can set the resource 'gnuplot.fastrotate' to 'off'",
+"",
+"@start table - other x11 resources",
+" gnuplot*exportselection: off",
+" gnuplot*fastrotate: on",
+" gnuplot*ctrlq: off",
+"#\\begin{tabular}{|cl|} \\hline",
+"#&gnuplot*exportselection: off\\\\",
+"#&gnuplot*fastrotate: on\\\\",
+"#&gnuplot*ctrlq: off\\\\",
+"%c l .",
+"%@gnuplot*exportselection: off",
+"%@gnuplot*fastrotate: on",
+"%@gnuplot*ctrlq: off",
+"@end table"
+
+END_HELP(x11)
+#endif /* TERM_HELP */