Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / x11.trm
diff --git a/term/x11.trm b/term/x11.trm
new file mode 100644 (file)
index 0000000..c043f6a
--- /dev/null
@@ -0,0 +1,2651 @@
+/* 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 */