Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / x11.trm
1 /* Hello, Emacs, this is -*-C-*-
2  * $Id: x11.trm,v 1.160.2.14 2009/05/29 03:25:29 sfeam Exp $
3  *
4  */
5
6 /* GNUPLOT - x11.trm */
7
8 /*[
9  * Copyright 1986 - 1993, 1998, 2004   Thomas Williams, Colin Kelley
10  *
11  * Permission to use, copy, and distribute this software and its
12  * documentation for any purpose with or without fee is hereby granted,
13  * provided that the above copyright notice appear in all copies and
14  * that both that copyright notice and this permission notice appear
15  * in supporting documentation.
16  *
17  * Permission to modify the software is granted, but not the right to
18  * distribute the complete modified source code.  Modifications are to
19  * be distributed as patches to the released version.  Permission to
20  * distribute binaries produced by compiling modified sources is granted,
21  * provided you
22  *   1. distribute the corresponding source modifications from the
23  *    released version in the form of a patch file along with the binaries,
24  *   2. add special version identification to distinguish your version
25  *    in addition to the base release version number,
26  *   3. provide your name and address as the primary contact for the
27  *    support of your modified version, and
28  *   4. retain our contact information in regard to use of the base
29  *    software.
30  * Permission to distribute the released version of the source code along
31  * with corresponding source modifications in the form of a patch file is
32  * granted with same provisions 2 through 4 for binary distributions.
33  *
34  * This software is provided "as is" without express or implied warranty
35  * to the extent permitted by applicable law.
36 ]*/
37
38 /*
39  *    x11.trm  --- inboard terminal driver for X11
40  */
41
42 /* Petr Mikulik and Johannes Zellner: added mouse support (October 1999)
43  * Implementation and functionality is based on pm.trm
44  */
45
46 /* X11 support for Petr Mikulik's pm3d
47  * by Johannes Zellner <johannes@zellner.org>
48  * (November 1999 - January 2000)
49  */
50
51 /* Dynamic font support, enhanced text mode support,
52  * additional feedback from outboard driver
53  * Ethan A Merritt <merritt@u.washington.edu>
54  * 2003
55  */
56
57 /* Daniel Sebald: added X11 support for images. (27 February 2003)
58  */
59
60 #include "driver.h"
61
62 #ifdef TERM_REGISTER
63 register_term(x11)
64 #endif
65
66 #ifdef TERM_PROTO
67 int X11_args __PROTO((int argc, char *argv[]));
68
69 TERM_PUBLIC void X11_options __PROTO((void));
70 TERM_PUBLIC void X11_init __PROTO((void));
71 TERM_PUBLIC void X11_graphics __PROTO((void));
72 TERM_PUBLIC void X11_text __PROTO((void));
73 TERM_PUBLIC int  X11_set_font __PROTO((const char * fontname));
74 TERM_PUBLIC void X11_reset __PROTO((void));
75 TERM_PUBLIC void X11_move __PROTO((unsigned int x, unsigned int y));
76 TERM_PUBLIC void X11_vector __PROTO((unsigned int x, unsigned int y));
77 TERM_PUBLIC void X11_linewidth __PROTO((double lw));
78 TERM_PUBLIC void X11_pointsize __PROTO((double ps));
79 TERM_PUBLIC void X11_linetype __PROTO((int lt));
80 TERM_PUBLIC void X11_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
81 TERM_PUBLIC int X11_text_angle __PROTO((int i));
82 TERM_PUBLIC int X11_justify_text __PROTO((enum JUSTIFY mode));
83 TERM_PUBLIC void X11_point __PROTO((unsigned int x, unsigned int y, int number));
84 TERM_PUBLIC void X11_fillbox __PROTO((int style, unsigned int x, unsigned y, unsigned int width, unsigned int height));
85
86 #if defined(WITH_IMAGE) || defined(BINARY_X11_POLYGON)
87 TERM_PUBLIC void X11_send_endianess __PROTO((void));
88 #endif
89
90 # ifdef USE_MOUSE
91 TERM_PUBLIC int X11_waitforinput __PROTO((void));
92 TERM_PUBLIC void X11_set_ruler __PROTO((int, int));
93 TERM_PUBLIC void X11_set_cursor __PROTO((int, int, int));
94 TERM_PUBLIC void X11_put_tmptext __PROTO((int, const char str[]));
95 TERM_PUBLIC void X11_set_clipboard __PROTO((const char[]));
96 # endif
97
98 TERM_PUBLIC void X11_update_opts __PROTO((void));
99 TERM_PUBLIC int X11_make_palette __PROTO((t_sm_palette *));
100 TERM_PUBLIC void X11_set_color __PROTO((t_colorspec *));
101 TERM_PUBLIC void X11_filled_polygon __PROTO((int, gpiPoint *));
102
103 # ifdef WITH_IMAGE
104 TERM_PUBLIC void X11_image __PROTO((unsigned, unsigned, coordval *, gpiPoint *, t_imagecolor));
105 # endif
106
107 /* To support "set term x11 enhanced" */
108 TERM_PUBLIC void ENHX11_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
109 TERM_PUBLIC void ENHX11_OPEN __PROTO((char * fontname, double fontsize,
110                                 double base, TBOOLEAN widthflag, TBOOLEAN showflag,
111                                 int overprint));
112 TERM_PUBLIC void ENHX11_FLUSH __PROTO((void));
113
114 # define X11_XMAX 4096
115 # define X11_YMAX 4096
116
117 static int X11_SIZE_X = 640;
118 static int X11_SIZE_Y = 450;
119 static int X11_POSITION_X = 0;
120 static int X11_POSITION_Y = 0;
121
122 /* approximations for typical font/screen sizes */
123 # define X11_VCHAR (X11_YMAX/25)
124 # define X11_HCHAR (X11_XMAX/100)
125 # define X11_VTIC (X11_YMAX/100)
126 # define X11_HTIC (X11_XMAX/150)
127 #endif  /* TERM_PROTO */
128
129
130 #ifndef TERM_PROTO_ONLY
131
132 #ifdef TERM_BODY
133
134 #include "gplt_x11.h"
135
136 /* non-zero if '-display' found on command line */
137 static int X11_Display = 0;
138
139 /* Fonts can have very long names */
140 /* EAM FIXME - these should be dynamically allocated */
141 #define X11_MAX_FONTNAME_LENGTH 255
142 static char X11_default_font[X11_MAX_FONTNAME_LENGTH+1] = {'\0'};
143 static int  X11_default_fontsize = 12;
144 static char X11_last_font_used[X11_MAX_FONTNAME_LENGTH+1] = {'\01','\0'};
145 static char X11_next_font_used[X11_MAX_FONTNAME_LENGTH+1] = {'\0'};
146 static enum JUSTIFY X11_last_justification = LEFT;
147
148 static void X11_atexit __PROTO((void));
149 static void X11_set_default_font __PROTO((void));
150
151 static void transmit_gradient __PROTO((gradient_struct *gradient, int cnt));
152
153 /* Merged the old char X11_opts[] and int X11_optarg[]
154  * into one array of structs.
155  * Loosely based on XrmOptionDescRec, the use of which
156  * would probably be overkill here. */
157 typedef enum { hasNoArg, hasArg } OptionArg;
158
159 static struct x11opt {
160     const char *option;         /* Name of option */
161     OptionArg arg;              /* Whether option has argument */
162 } X11_cmdopts[] = {
163     { "-mono", hasNoArg}, { "-gray", hasNoArg}, { "-clear", hasNoArg},
164     { "-tvtwm", hasNoArg}, { "-pointsize", hasArg},
165     { "-iconic", hasNoArg}, { "-rv", hasNoArg},
166     { "-reverse", hasNoArg}, { "+rv", hasNoArg},
167     { "-synchronous", hasNoArg},
168     { "-display", hasArg}, { "-geometry", hasArg}, { "-bg", hasArg},
169     { "-background", hasArg}, { "-bd", hasArg},
170     { "-bordercolor", hasArg}, { "-bw", hasArg},
171     { "-borderwidth", hasArg}, { "-fg", hasArg},
172     { "-foreground", hasArg}, { "-fn", hasArg}, { "-font", hasArg},
173     { "-name", hasArg},
174     { "-selectionTimeout", hasArg}, { "-title", hasArg},
175     { "-xnllanguage", hasArg}, { "-xrm", hasArg},
176     { "-raise", hasNoArg}, { "-noraise", hasNoArg},
177     { "-solid", hasNoArg}, { "-dashed", hasNoArg},
178     { "-persist", hasNoArg}
179 #ifdef USE_MOUSE
180     , { "-nofeedback", hasNoArg}
181     , { "-noevents", hasNoArg}
182     , { "-ctrlq", hasNoArg}
183 #endif
184 };
185
186 #define X11_nopts (sizeof(X11_cmdopts) / sizeof(X11_cmdopts[0]))
187
188 static FILE *X11_ipc = (FILE *) 0;
189 #ifdef PIPE_IPC
190 #define X11_ipc_back_fd ipc_back_fd
191 #endif
192
193 static char **xargv = (char **) NULL;
194 /* reserve a minimum 10 driver opts */
195 static char *optvec[2 * X11_nopts + 1 + 10];
196
197 /* gnuplot_x11 has extension .exe on OS/2 and Windows (and on RSX/VMS, but
198    these construct their own full path GNUPLOT_X11 in their build script).
199 */
200 # if defined(OS2) || defined(_Windows)
201 #   ifndef GNUPLOT_X11
202 static char X11_default_command[] = "gnuplot_x11.exe";
203 #   else
204 static char X11_default_command[] = GNUPLOT_X11 ".exe";
205 #   endif
206 # else  /* thus !OS/2 && !Windows */
207 #   ifndef GNUPLOT_X11
208 static char X11_default_command[] = "gnuplot_x11";
209 #   else
210 static char X11_default_command[] = GNUPLOT_X11;
211 #   endif
212 # endif /* OS/2 || Windows */
213
214 static char *X11_command = X11_default_command;
215 static char *X11_command_parsed = NULL;
216 static char *X11_full_command_path = NULL;
217
218 /* must match the definition in src/gplt_x11.c: */
219 static int persist = UNSET;
220 static int do_raise = UNSET;
221 static int dashedlines = UNSET;
222 static int ctrlq = UNSET;
223 static int set_size = UNSET;
224 static int set_position = UNSET;
225
226 /* driver properties managed by x11.trm rather than gnuplot_x11 */
227 static double X11_linewidth_multiplier = 1.0;
228
229 #ifdef USE_MOUSE
230 /* Interlock to prevent the mouse channel from being coopted more than
231  * once per plot by the gnuplot_x11<->x11.trm font information query.
232  */
233 static TBOOLEAN default_font_size_known = FALSE;
234 static TBOOLEAN X11_MOUSE_FEEDBACK = TRUE;
235 #endif
236 #ifdef PIPE_IPC
237 static TBOOLEAN IPC_LOCK = FALSE;
238 #endif
239
240 static int parse_driver __PROTO((const char *));
241
242 static int
243 parse_driver(const char *cmd)
244 {
245     int nr = 0;
246     char *ptr;
247
248     /* make a copy of cmd, as parsing will modify the string */
249     X11_command_parsed = gp_realloc(X11_command_parsed,
250                                     strlen(cmd) + 1, "x11->parse_driver");
251     strcpy(X11_command_parsed, X11_command);
252     ptr = X11_command_parsed;
253
254     while (*ptr != '\0' && nr < sizeof(optvec) / sizeof(char)) {
255
256         /* Strip whitespace.  Use nulls, so that
257          * the previous argument is terminated
258          * automatically.
259          */
260         while (isspace((unsigned char)*ptr))
261             *ptr++ = '\0';
262
263         if (!(*ptr))            /* don't count the terminating NULL */
264             break;
265
266         /* Save the argument. */
267         optvec[nr++] = ptr;
268
269         /* Skip over the argument. */
270         while ('\0' != *ptr && !isspace((unsigned char)*ptr)) {
271             ptr++;
272         }
273     }
274
275     /* HBB 20020214: new code to prepend the environment X11_DRIVER_DIR
276      * to the command name, if it doesn't contain any slashes yet */
277     if (!strchr(optvec[0],'/')) {
278         char *dir = getenv("GNUPLOT_DRIVER_DIR");
279
280         if (!dir)
281             dir = X11_DRIVER_DIR;
282 #ifndef OS2
283         if (dir[0] != '/' && dir[0] != '.') {
284             /* Can't call int_error because longjump has not been set up yet */
285             int_warn(NO_CARET, "Illegal X11 driver directory name! Using default");
286             dir = "";
287         }
288 #endif
289         X11_full_command_path = gp_realloc(X11_full_command_path,
290                                            strlen(dir) + strlen(optvec[0]) + 2,
291                                            "x11 driver pathname");
292         /* optvec[0] = X11_full_command_path; */
293         if (*dir)
294             sprintf(X11_full_command_path, "%s/%s", dir, optvec[0]);
295         else
296             sprintf(X11_full_command_path, "%s", optvec[0]);
297     }
298
299     return nr;
300 }
301
302 /*   X11_args - scan gnuplot command line for standard X Toolkit options
303  * called from plot.c so must not be TERM_PUBLIC (which may be static)
304  */
305
306 int
307 X11_args(int argc, char *argv[])
308 {
309     int nx11 = 0, i, n;
310
311     xargv = (char **) gp_alloc(argc * sizeof(char *), "<xargv>");
312
313     if (!xargv) {
314         fputs("not enough memory to copy argv - quitting\n", stderr);
315         exit(EXIT_FAILURE);
316     }
317
318     /* We make a copy of the argument vector because
319      * argv is modified later. */
320     memcpy(xargv, argv, argc * sizeof(char *));
321     i = parse_driver(X11_command);
322
323     while (++argv, ++xargv, --argc > 0) {
324         for (n = 0; n < X11_nopts; n++) {
325             if (strcmp(*argv, X11_cmdopts[n].option) == 0) {
326                 optvec[i++] = *xargv;
327 #ifdef USE_MOUSE
328                 if (strcmp(*argv, "-nofeedback") == 0)
329                     X11_MOUSE_FEEDBACK = FALSE;
330 #endif
331                 if (strcmp(*argv, "-display") == 0)
332                     X11_Display++;
333                 if (X11_cmdopts[n].arg == hasArg) {
334                     if (--argc <= 0)
335                         return nx11;
336                     optvec[i++] = *++xargv, ++argv;
337                     nx11++;
338                 }
339                 if (i >= (sizeof(optvec) / sizeof(char))) {
340                     fprintf(stderr, "warning: X11 options will be truncated\n");
341                     return nx11;        /* optvec is full */
342                 }
343                 nx11++;
344                 break;
345             }
346         }
347         if (n == X11_nopts)
348             break;
349     }
350
351     return (nx11);
352 }
353
354
355 static unsigned int X11_plot_number;
356
357 enum X11_id {
358     X11_RESET,
359     X11_CLOSE,
360     X11_PERSIST,
361     X11_NOPERSIST,
362     X11_RAISE,
363     X11_NORAISE,
364     X11_FONT,
365     X11_TITLE,
366     X11_ENHANCED,
367     X11_NOENHANCED,
368     X11_SOLID,
369     X11_DASHED,
370     X11_LINEWIDTH,
371     X11_CTRLQ,
372     X11_NOCTRLQ,
373     X11_SIZE,
374     X11_POSITION,
375     X11_OTHER
376 };
377
378 static struct gen_table X11_opts[] = {
379     {"res$et", X11_RESET},
380     {"cl$ose", X11_CLOSE},
381     {"per$sist", X11_PERSIST},
382     {"noper$sist", X11_NOPERSIST},
383     {"rai$se", X11_RAISE},
384     {"norai$se", X11_NORAISE},
385     {"font",   X11_FONT},
386     {"fn$ame", X11_FONT},
387     {"ti$tle", X11_TITLE},
388     {"enh$anced", X11_ENHANCED},
389     {"noenh$anced", X11_NOENHANCED},
390     {"solid", X11_SOLID},
391     {"dash$ed", X11_DASHED},
392     {"linew$idth", X11_LINEWIDTH},
393     {"lw", X11_LINEWIDTH},
394     {"ctrl$q", X11_CTRLQ},
395     {"noctrl$q", X11_NOCTRLQ},
396     {"si$ze", X11_SIZE},
397     {"pos$ition", X11_POSITION},
398     {NULL, X11_OTHER}
399 };
400
401
402 TERM_PUBLIC void
403 X11_options()
404 {
405
406 #define NOT_PROCESS_IF_DUPLICATION 1
407
408     struct value a;
409     int c_title_token = 0;
410     int new_term_number = 0;
411     TBOOLEAN duplication = FALSE;
412     TBOOLEAN set_reset = FALSE, set_persist = FALSE, set_raise = FALSE, set_font = FALSE;
413     TBOOLEAN set_ctrlq = FALSE;
414     TBOOLEAN set_title = FALSE, set_number = FALSE, set_close = FALSE, set_solid = FALSE;
415
416     persist = do_raise = dashedlines = ctrlq = UNSET;
417     set_size = set_position = UNSET;
418
419     while (!END_OF_COMMAND) {
420         switch (lookup_table(&X11_opts[0], c_token)) {
421         case X11_RESET:
422             c_token++;
423             if (set_reset) duplication=TRUE;
424             set_reset = TRUE;
425             break;
426         case X11_CLOSE:
427             c_token++;
428             if (set_close) duplication=TRUE;
429             set_close = TRUE;
430             break;
431         case X11_PERSIST:
432             persist = yes;
433             c_token++;
434             if (set_persist) duplication=TRUE;
435             set_persist = TRUE;
436             break;
437         case X11_NOPERSIST:
438             persist = no;
439             c_token++;
440             if (set_persist) duplication=TRUE;
441             set_persist = TRUE;
442             break;
443         case X11_CTRLQ:
444             ctrlq = yes;
445             c_token++;
446             if (set_ctrlq) duplication=TRUE;
447             set_ctrlq = TRUE;
448             break;
449         case X11_NOCTRLQ:
450             ctrlq = no;
451             c_token++;
452             if (set_ctrlq) duplication=TRUE;
453             set_ctrlq = TRUE;
454             break;
455         case X11_SOLID:
456             dashedlines = FALSE;
457             c_token++;
458             if (set_solid) duplication=TRUE;
459             set_solid = TRUE;
460             break;
461         case X11_DASHED:
462             dashedlines = TRUE;
463             c_token++;
464             if (set_solid) duplication=TRUE;
465             set_solid = TRUE;
466             break;
467         case X11_LINEWIDTH:
468             c_token++;
469             X11_linewidth_multiplier = real(const_express(&a));
470             if (X11_linewidth_multiplier <= 0)
471                 X11_linewidth_multiplier = 1.0;
472             break;
473         case X11_RAISE:
474             do_raise = yes;
475             c_token++;
476             if (set_raise) duplication=TRUE;
477             set_raise = TRUE;
478             break;
479         case X11_NORAISE:
480             do_raise = no;
481             c_token++;
482             if (set_raise) duplication=TRUE;
483             set_raise = TRUE;
484             break;
485         case X11_FONT:
486             c_token++;
487             if (END_OF_COMMAND)
488                 int_error(c_token, "expecting font name");
489             if (isstringvalue(c_token)) {
490                 char *s = try_to_get_string();
491                 strncpy(X11_default_font, s, sizeof(X11_default_font));
492                 free(s);
493             } else {
494                 copy_str(X11_default_font, c_token, sizeof(X11_default_font));
495                 c_token++;
496             }
497             if (strchr(X11_default_font,','))
498                 sscanf(strchr(X11_default_font,',')+1, "%d",
499                         &X11_default_fontsize);
500             if (set_font) duplication=TRUE;
501             set_font = TRUE;
502             break;
503         case X11_TITLE:
504             c_token++;
505             if (END_OF_COMMAND)
506                 int_error(c_token, "expecting title text");
507             c_title_token = c_token;
508             c_token++;
509             if (set_title) duplication=TRUE;
510             set_title = TRUE;
511             break;
512         case X11_ENHANCED:
513             term->put_text = ENHX11_put_text;
514             term->flags |= TERM_ENHANCED_TEXT;
515             c_token++;
516             break;
517         case X11_NOENHANCED:
518             term->put_text = X11_put_text;
519             term->flags &= ~TERM_ENHANCED_TEXT;
520             c_token++;
521             break;
522         case X11_SIZE:
523             c_token++;
524             if (END_OF_COMMAND) {
525                 int_error(c_token, "expecting X[,Y]");
526             } else {
527                 int x_in, y_in;
528                 x_in = (int) real(const_express(&a));
529                 if (x_in > 0)
530                     X11_SIZE_X = x_in;
531                 else
532                     int_error(c_token, "X size must be > 0");
533                 if (equals(c_token, ",")) {
534                     c_token++;
535                     y_in = (int) real(const_express(&a));
536                     if (y_in > 0)
537                         X11_SIZE_Y = y_in;
538                     else
539                         int_error(c_token, "Y size must be > 0");
540                 }
541                 set_size = yes;
542             }
543             break;
544         case X11_POSITION:
545             c_token++;
546             if (END_OF_COMMAND) {
547                 int_error(c_token, "expecting X[,Y]");
548             } else {
549                 X11_POSITION_X = (int) real(const_express(&a));
550                 if (equals(c_token, ",")) {
551                     c_token++;
552                     X11_POSITION_Y = (int) real(const_express(&a));
553                 }
554                 set_position = yes;
555             }
556             break;
557
558         case X11_OTHER:
559         default:
560             /* let gnuplot_x11 check range */
561             new_term_number = (int) real(const_express(&a));
562             if (set_number) duplication=TRUE;
563             set_number = TRUE;
564             break;
565         }
566
567         if (duplication) {
568             int_error(c_token-1, "duplicated or contradicting arguments in X11 term options");
569         }
570
571     }
572
573
574     /* Call own init routine; this might be xlib rather than x11 */
575     term->init();
576
577     if (set_reset)
578         X11_atexit();   /* tell gnuplot_x11 to shut down */
579
580     /* Leave the current window unchanged when closing an old window */
581     if (set_close) {
582         if (X11_ipc) {
583             fprintf(X11_ipc, (set_number ? "C%d\n" : "C\n"), new_term_number);
584             fflush(X11_ipc);
585         }
586     } else if (set_number) {
587         X11_plot_number = new_term_number;
588         if (X11_ipc) {
589             fprintf(X11_ipc, "N%d\n", X11_plot_number);
590             fflush(X11_ipc);
591         }
592     }
593
594     sprintf(term_options, "%d", X11_plot_number);
595     if (UNSET != do_raise) {
596         strcat(term_options, (yes == do_raise ? " raise" : " noraise"));
597     }
598     if (UNSET != persist) {
599         strcat(term_options, (yes == persist ? " persist" : " nopersist"));
600     }
601     if (UNSET != ctrlq) {
602         strcat(term_options, (yes == ctrlq ? " ctrlq" : " noctrlq"));
603     }
604     if (UNSET != dashedlines) {
605         strcat(term_options, (yes == dashedlines ? " dashed" : " solid"));
606     }
607     if (term->put_text == ENHX11_put_text) {
608         strcat(term_options, " enhanced");
609     }
610     if (X11_linewidth_multiplier != 1.0) {
611         sprintf(term_options + strlen(term_options),
612                 " linewidth %.2g", X11_linewidth_multiplier);
613     }
614     if (*X11_default_font) {
615         strcat(term_options, " font \"");
616         strcat(term_options, X11_default_font);
617         strcat(term_options, "\"");
618     }
619     if (set_title) {
620         char *title;
621         int save_token = c_token;
622         c_token = c_title_token;
623         strncat(term_options, " title \"", MAX_LINE_LEN-strlen(term_options));
624         title = term_options + strlen(term_options);
625         if (isstringvalue(c_title_token)) {
626             char *s = try_to_get_string();
627             strncat(term_options, s, MAX_LINE_LEN-strlen(term_options));
628             free(s);
629         } else
630             copy_str(term_options+strlen(term_options), c_title_token, MAX_LINE_LEN-strlen(term_options));
631         if (X11_ipc) {
632             /* Send up to maximum buffer length minus three characters of
633              * title string to account for required 'n', '\0', '\n'.
634              */
635             int i;
636             fputc('n', X11_ipc);
637             for (i=0; i < X11_COMMAND_BUFFER_LENGTH-3 && title[i] != '\0'; i++)
638                 fputc(title[i], X11_ipc);
639             fputc('\0', X11_ipc);
640             fputc('\n', X11_ipc);
641             fflush(X11_ipc);
642         }
643         strncat(term_options, "\"", MAX_LINE_LEN-strlen(term_options));
644         c_token = save_token;
645     }
646     if (set_size != UNSET)
647         sprintf(term_options + strlen(term_options),
648               " size %d,%d ", X11_SIZE_X,X11_SIZE_Y);
649
650     if (set_position != UNSET)
651         sprintf(term_options + strlen(term_options),
652               " position %d,%d ", X11_POSITION_X,X11_POSITION_Y);
653
654     X11_update_opts();
655 }
656
657
658 void
659 x11_raise_terminal_window(int number)
660 {
661     /* Send the raise character and a number. */
662     if (X11_ipc) {
663         fprintf(X11_ipc, "^%d\n", number);
664         fflush(X11_ipc);
665     }
666 }
667
668 void
669 x11_raise_terminal_group(void)
670 {
671     /* Send just the raise character. */
672     if (X11_ipc) {
673         fprintf(X11_ipc, "^\n");
674         fflush(X11_ipc);
675     }
676 }
677
678 void
679 x11_lower_terminal_window(int number)
680 {
681     /* Send the raise character and a number. */
682     if (X11_ipc) {
683         fprintf(X11_ipc, "v%d\n", number);
684         fflush(X11_ipc);
685     }
686 }
687
688 void
689 x11_lower_terminal_group(void)
690 {
691     /* Send just the raise character. */
692     if (X11_ipc) {
693         fprintf(X11_ipc, "v\n");
694         fflush(X11_ipc);
695     }
696 }
697
698
699 TERM_PUBLIC void
700 X11_update_opts()
701 {
702     if (!X11_ipc)
703         return;
704
705     if (UNSET != do_raise || UNSET != persist || UNSET != dashedlines || UNSET != ctrlq) {
706         fprintf(X11_ipc, "X %d %d %d %d\n", 
707                 do_raise, persist, dashedlines, ctrlq);
708         fflush(X11_ipc);
709     }
710
711     /* pass size as a valid X11 geometry string WIDTHxHEIGHT[+XPOS+YPOS] */
712     if (set_size != UNSET || set_position != UNSET) {
713         if (set_size != UNSET && set_position == UNSET)
714             fprintf(X11_ipc, "s %dx%d\n", X11_SIZE_X, X11_SIZE_Y);
715         else if (set_size == UNSET && set_position != UNSET)
716             fprintf(X11_ipc, "s %+d%+d\n", X11_POSITION_X, X11_POSITION_Y);
717         else if (set_size != UNSET && set_position != UNSET)
718             fprintf(X11_ipc, "s %dx%d%+d%+d\n", X11_SIZE_X, X11_SIZE_Y,
719                 X11_POSITION_X, X11_POSITION_Y);
720         fflush(X11_ipc);
721     }
722 }
723
724
725 /*-----------------------------------------------------------------------------
726  *   Three different versions of the remainder of the X11 terminal driver
727  *   are provided to support three different types of IPC with the
728  *   gnuplot_x11 outboard terminal driver:
729  *
730  *   DEFAULT_X11:      popen() pipe for most un*x platforms
731  *
732  *   CRIPPLED_SELECT : file IPC for un*x platforms with incomplete or faulty
733  *                     implementation of BSD select()
734  *
735  *   VMS :             mailbox/spawn IPC
736  *---------------------------------------------------------------------------*/
737
738 #define DEFAULT_X11
739 #if defined(VMS) || defined(CRIPPLED_SELECT)
740 # undef DEFAULT_X11
741 #endif
742 #if defined(VMS) && defined(CRIPPLED_SELECT)
743 Error.Incompatible options.
744 #endif
745 /* we do not want to have to duplicate all the code, so we
746  * do most of it with macros.
747  * PRINT0(format), PRINT1(format, p1), PRINT2(format, p1, p2) etc
748  * also  FLUSH0(format), etc, which do an additional flush
749  */
750 #ifdef DEFAULT_X11
751 /*-----------------------------------------------------------------------------
752  *   DEFAULT_X11 popen() pipe IPC
753  *---------------------------------------------------------------------------*/
754 static void
755 X11_atexit()
756 {
757     if (X11_ipc) {
758         fputs("R\n", X11_ipc);
759         fclose(X11_ipc);
760         /* dont wait(), since they might be -persist */
761         X11_ipc = NULL;
762 #ifdef PIPE_IPC
763         close(ipc_back_fd);
764         ipc_back_fd = -1;
765 #endif
766     }
767 }
768
769 #ifdef USE_MOUSE
770
771 TERM_PUBLIC int
772 X11_waitforinput()
773 {
774 #ifdef PIPE_IPC
775     fd_set fds;
776     static struct gp_event_t ge;
777     static int l = 0;
778     int n;
779     int fd = fileno(stdin);
780     int repeat_count = 0;
781
782 AGAIN:
783     /* XXX:  if the input device it not a tty (e.g. /dev/null)
784      *       mouse events are not processed. This is necessary
785      *       as on some systems /dev/null is not selectable.
786      * TODO: should we close the ipc_back_fd in this case ? */
787     if (ipc_back_fd >= 0)
788         do {
789             int ierr;
790             FD_ZERO(&fds);
791             FD_SET(fd, &fds);
792             FD_SET(ipc_back_fd, &fds);
793             ierr = select(ipc_back_fd + 1, SELECT_TYPE_ARG234 &fds, 0, 0, NULL);
794             if (ierr < 0 && errno == EINTR) {
795                 FD_ZERO(&fds);
796                 continue;
797             }
798             if (FD_ISSET(ipc_back_fd, &fds)) {
799                 n = read(ipc_back_fd, (void *) (l + (char *) &ge), sizeof(ge) - l);
800                 if (n == 0) {
801                     close(ipc_back_fd);
802                     ipc_back_fd = -1;
803                     /* don't close X11_ipc, otherwise later writes
804                      * to it will cause a segfault */
805                     IPC_LOCK = FALSE;
806                     break;      /* outboard driver has stopped */
807                 }
808                 l += n;
809                 if (l == sizeof(ge)) {
810                     /* note: do_event() may not return (if an
811                      * error occurs), so need to reset l first */
812                     l = 0;
813                     do_event(&ge);
814                     if (ge.type == GE_fontprops) {
815                         if (repeat_count > 0) {
816                             FPRINTF((stderr,
817                                 "X11_waitforinput: caught GE_fontprops after %d tries\n",
818                                 repeat_count));
819                         }
820                         return(GE_fontprops);
821                     }
822                     if (ge.type == GE_buttonrelease && (paused_for_mouse & PAUSE_CLICK)) {
823                         int button = ge.par1;
824                         if (button == 1 && (paused_for_mouse & PAUSE_BUTTON1))
825                             paused_for_mouse = 0;
826                         if (button == 2 && (paused_for_mouse & PAUSE_BUTTON2))
827                             paused_for_mouse = 0;
828                         if (button == 3 && (paused_for_mouse & PAUSE_BUTTON3))
829                             paused_for_mouse = 0;
830                         if (paused_for_mouse == 0)
831                             return '\0';
832                     }
833                     if (ge.type == GE_keypress && (paused_for_mouse & PAUSE_KEYSTROKE)) {
834                         /* Ignore NULL keycode */
835                         if (ge.par1 > '\0') {
836                             paused_for_mouse = 0;
837                             return '\0';
838                         }
839                     }
840                 }
841             }
842         } while (!FD_ISSET(fd, &fds));
843
844     /* If ipc_back_fd is not open, we will never see any mouse events! */
845     else if (paused_for_mouse) {
846         paused_for_mouse = 0;
847         int_error(NO_CARET,"Mousing not active");
848     }
849
850     /* IPC_LOCK indicates that we are specifically waiting for a reply on */
851     /* the mousing channel.  If stdin unblocks first, defer reading it,   */
852     /* wait a few microseconds, and try again.                            */
853     /* FIXME EAM - Give up after a few seconds. This will drop input chars*/
854     /* but at least it won't hang forever if the X11 connection goes bad. */
855     if (IPC_LOCK) {
856 #ifdef HAVE_USLEEP
857         usleep(100);
858 #endif
859         if (repeat_count++ < 10000)
860             goto AGAIN;
861     }
862
863     /* Same sort of thing if we are specifically waiting for mouse input. */
864     if (paused_for_mouse) {
865 #ifdef HAVE_USLEEP
866         usleep(10);
867 #endif
868         goto AGAIN;
869     }
870
871 #endif /* PIPE_IPC */
872
873 # if 0
874 /* HBB 20010620: switching back and forth between X11 and a non-GUI
875  * terminal, while stdin is redirected, causes gnuplot to terminate
876  * right after it re-enters the X11 terminal --- read() returns a '\0'
877  * character once, and then EOF. Switching to <stdio.h>'s getc() fixed
878  * that, for me. */
879     if (read(0, &c, 1) != 1)
880         return EOF;
881     else
882         return c;
883 # else
884     return getc(stdin);
885 # endif /* 0/1 */
886 }
887 #endif /* USE_MOUSE */
888
889
890 TERM_PUBLIC void
891 X11_init()
892 {
893     static int been_here = 0;
894
895     if (!X11_ipc) {
896         /* first time through or after a reset */
897 #if defined(OSK)
898         /* OS-9 popen() does not block on close for child to end, so
899          * we can safely use it here
900          */
901         /* FIXME HBB 20020214: This doesn't understand X11_DRIVER_DIR
902          * or $GNUPLOT_DRIVER_DIR yet. This may break execution of
903          * freshly built gnuplot until 'make install' */
904
905            X11_ipc = popen(X11_command, "w");
906 #else
907 #if defined(OS2)
908       /* FIXME amai 20020219: nice try...
909        * But popen() does return a non-NULL handle to almost command,
910        * it's just a new session which will stop if the command does
911        * not exist... We should stat() for the argument?! */
912       /* X11_ipc = popen(X11_full_command_path, "w");
913       if (X11_ipc==NULL) */
914       {
915            X11_ipc = popen(X11_command, "w");
916       }
917 #else /* !(OSK || OS/2) */
918         int fdes[2];
919 # ifdef PIPE_IPC
920         int fdes_back[2];
921
922 #define X11_ALLOW_EVENTS (mouse_setting.on)
923         if (X11_ALLOW_EVENTS) {
924             if (pipe(fdes_back))
925                 perror("pipe() failed:");
926         }
927 # endif /* PIPE_IPC */
928         if (pipe(fdes))
929             perror("pipe() failed:");
930
931         if (fork() == 0) {
932             /* child */
933 # ifdef PIPE_IPC
934             char noevents[] = "-noevents";
935             if (X11_ALLOW_EVENTS) {
936                 dup2(fdes_back[1], 1);  /* stdout to pipe */
937                 close(fdes_back[0]);
938             } else {
939                 char **ptr;
940                 for (ptr = optvec; ptr && *ptr; ptr++)
941                     ;           /* do nothing: skip over set arguments */
942                 /* tell the driver not to supply any events by
943                  * appending "-noevents" to the optvec list. */
944                 *ptr = noevents;
945                 *++ptr = (char *) 0;    /* terminate */
946             }
947 # endif /* PIPE_IPC */
948             /* close the write side of the child's forward fd */
949             close(fdes[1]);
950
951             dup2(fdes[0], 0);   /* stdin from pipe */
952             execvp(X11_full_command_path, optvec);
953             /* if we get here, something went wrong */
954             fprintf(stderr,"Expected X11 driver: %s\n",X11_full_command_path);
955             perror("Exec failed");
956             fprintf(stderr,"See 'help x11' for more details\n");
957             exit(EXIT_FAILURE);
958         }
959         /* parent */
960 # ifdef PIPE_IPC
961         /* X11_ipc_out = fdopen(fdes[0], "r"); */
962         if (ipc_back_fd > 0) {
963             fprintf(stderr, "(X11_init) warning: unclosed ipc_back_fd.\n");
964             fprintf(stderr, "           this is probably a program error.\n");
965             close(ipc_back_fd);
966         }
967         if (X11_ALLOW_EVENTS) {
968             ipc_back_fd = fdes_back[0];
969             close(fdes_back[1]);        /* the parent doesn't need this */
970         } else {
971             /* we do not open a bidirectional communication
972              * for non-tty's by default. If this is desired,
973              * the mouse must be turned on explicitely *before*
974              * starting the x11 driver.
975              * So: if we're here, we close the ipc-back-channel
976              * which will cause a SIGPIPE in the driver. This
977              * is *ugly* but it works. (joze) */
978             /* close(fdes_back[0]); */
979             /* mark ipc_back_fd as unusable */
980             ipc_back_fd = IPC_BACK_UNUSABLE;
981         }
982 # endif /* PIPE_IPC */
983         /* close the read side of the parent's forward fd */
984         close(fdes[0]);
985         X11_ipc = fdopen(fdes[1], "w");
986 #endif /* !OSK  */
987 #endif /* !OS/2 */
988     }
989
990     if (!been_here) {
991         GP_ATEXIT(X11_atexit);
992         been_here++;
993     }
994 #if defined(WITH_IMAGE) || defined(BINARY_X11_POLYGON)
995     X11_send_endianess();
996 #endif
997 #ifdef USE_MOUSE
998     default_font_size_known = FALSE;
999 #endif
1000     X11_update_opts();
1001 }
1002
1003 TERM_PUBLIC void
1004 X11_reset()
1005 {
1006     /* Leave the pipe alone, until exit or  set term x11 reset */
1007     /* but make sure that all locks are cleared.               */
1008 #ifdef PIPE_IPC
1009     IPC_LOCK = FALSE;
1010 #endif
1011 #ifdef USE_MOUSE
1012     paused_for_mouse = 0;
1013 #endif
1014 }
1015
1016 #define PRINT0(fmt)          fprintf(X11_ipc, fmt)
1017 #define PRINT1(fmt,p1)       fprintf(X11_ipc, fmt,p1)
1018 #define PRINT2(fmt,p1,p2)    fprintf(X11_ipc, fmt,p1,p2)
1019 #define PRINT3(fmt,p1,p2,p3) fprintf(X11_ipc, fmt,p1,p2,p3)
1020 #define PRINT4(fmt,p1,p2,p3,p4) fprintf(X11_ipc, fmt,p1,p2,p3,p4)
1021 #define PRINT5(fmt,p1,p2,p3,p4,p5) fprintf(X11_ipc, fmt,p1,p2,p3,p4,p5)
1022
1023 #define FFLUSH()             fflush(X11_ipc)
1024
1025 #define BEFORE_GRAPHICS         /* nowt */
1026 #define AFTER_TEXT              /* nowt */
1027
1028
1029 #elif defined(CRIPPLED_SELECT)
1030 /* PLEASE CAN SOMEONE CHECK THAT THIS STILL WORKS !!! */
1031 /*-----------------------------------------------------------------------------
1032  *   CRIPPLED_SELECT file IPC
1033  *---------------------------------------------------------------------------*/
1034 static char X11_tmp[32], X11_tmp0[32], X11_shutdown[32];
1035 static int X11_pid;
1036
1037 TERM_PUBLIC void
1038 X11_init()
1039 {
1040     if (!(X11_pid = fork())) {
1041         execvp(X11_full_command_path, optvec);
1042         _exit(1);
1043     }
1044     sprintf(X11_tmp, "/tmp/Gnuplot_%d", X11_pid);
1045     sprintf(X11_tmp0, "%s-", X11_tmp);
1046     sprintf(X11_shutdown, "echo R >%s", X11_tmp);
1047 }
1048
1049 TERM_PUBLIC void
1050 X11_reset()
1051 {
1052     system(X11_shutdown);
1053 }
1054
1055 #define BEFORE_GRAPHICS \
1056  if (!(X11_ipc = fopen(X11_tmp0, "w"))) { \
1057    perror(X11_tmp0); system(X11_shutdown); exit(1); \
1058  }
1059
1060 #define AFTER_TEXT \
1061  { fclose(X11_ipc); rename(X11_tmp0, X11_tmp); }
1062
1063 #define PRINT0(fmt)          fprintf(X11_ipc, fmt)
1064 #define PRINT1(fmt,p1)       fprintf(X11_ipc, fmt,p1)
1065 #define PRINT2(fmt,p1,p2)    fprintf(X11_ipc, fmt,p1,p2)
1066 #define PRINT3(fmt,p1,p2,p3) fprintf(X11_ipc, fmt,p1,p2,p3)
1067 #define PRINT4(fmt,p1,p2,p3,p4) fprintf(X11_ipc, fmt,p1,p2,p3,p4)
1068 #define PRINT5(fmt,p1,p2,p3,p4,p5) fprintf(X11_ipc, fmt,p1,p2,p3,p4,p5)
1069 #define FFLUSH()             fflush(X11_ipc)
1070
1071 static void
1072 X11_atexit()
1073 {
1074     /* WHAT SHOULD I DO ? */
1075 }
1076 #elif defined(VMS)
1077 /*-----------------------------------------------------------------------------
1078  *   VMS mailbox/spawn IPC - Yehavi Bourvine - YEHAVI@VMS.HUJI.AC.IL
1079  *---------------------------------------------------------------------------*/
1080 #include <iodef.h>
1081 #include <descrip.h>
1082 #include <dvidef.h>
1083 #ifdef __DECC
1084 #include <lib$routines.h>
1085 #include <starlet.h>
1086 #endif
1087 #ifdef __GNUC__
1088 #include <errno.h>
1089 #else
1090 int vaxc$errno;
1091 #endif
1092
1093 #define SS$_NORMAL 1            /* or include <ssdef.h> for all SS$_ def's */
1094
1095 #define MBXMXMSG 128            /* DEFMBXMXMSG is set by SYSGEN */
1096
1097 static short X11_channel;
1098
1099 struct iosb {
1100     unsigned short stat;
1101     unsigned short count;
1102     unsigned long info;
1103 };
1104
1105
1106
1107 TERM_PUBLIC void
1108 X11_init()
1109 {
1110
1111     struct iosb iosb;
1112
1113     static char devnam_string[64];
1114     static $DESCRIPTOR(devnam, devnam_string);
1115
1116     struct {
1117         short int buf_len;
1118         short int item;
1119         char *buf_addr;
1120         unsigned short int *ret_len;
1121         int end;
1122     } item_list = {
1123     devnam.dsc$w_length, DVI$_DEVNAM, devnam.dsc$a_pointer, &devnam.dsc$w_length, 0};
1124 #define CMDLEN 1024
1125     char cmdline[CMDLEN], *cmdp;
1126     int optindex;
1127
1128     if (!X11_channel) {
1129         int one = 1;
1130
1131         /* Create a descriptor for the command line that starts
1132            GNUPLOT_X11. $DESCRIP doesn't work in this context... */
1133
1134         /* FIXME!
1135          * This does not work anymore since X11 option passing has been
1136          * changed to use execvp() in the DEFAULT_X11 case
1137          */
1138         struct dsc$descriptor_s pgmdsc = { 0, DSC$K_DTYPE_T,
1139             DSC$K_CLASS_S, 0
1140         };
1141         optindex = 0;
1142         strcpy(cmdline, optvec[optindex]);
1143         cmdp = cmdline + strlen(optvec[optindex]);
1144         while (optvec[++optindex] != NULL) {
1145             *cmdp++ = ' ';
1146             *cmdp++ = '\"';
1147             strcpy(cmdp, optvec[optindex]);
1148             cmdp += strlen(optvec[optindex]);
1149             *cmdp++ = '\"';
1150         }
1151         pgmdsc.dsc$w_length = cmdp - cmdline;
1152         pgmdsc.dsc$a_pointer = cmdline;
1153
1154         /* Create a mailbox which will be used as a pipe for commands to the
1155          * subprocess.  What we'll write to it will be read by the subprocess
1156          * as its STDIN.  Use an unnamed mailbox and refer to it by its device
1157          * number */
1158
1159         vaxc$errno = sys$crembx(0, &X11_channel, MBXMXMSG, MBXMXMSG, 0, 0, 0, 0);
1160         if ((vaxc$errno & SS$_NORMAL) != SS$_NORMAL) {
1161             printf("SYS$CreMbx failed with status=%d\r\n", vaxc$errno);
1162             os_error(NO_CARET, "sys$crembx failed");
1163         }
1164         vaxc$errno = sys$getdviw(0, X11_channel, 0, &item_list, &iosb, 0, 0, 0);
1165         if ((vaxc$errno & SS$_NORMAL) == SS$_NORMAL)
1166             vaxc$errno = iosb.stat;
1167         if ((vaxc$errno & SS$_NORMAL) != SS$_NORMAL) {
1168             printf("SYS$Getdviw failed with status=%d\r\n", vaxc$errno);
1169             sys$dassgn(X11_channel);
1170             X11_channel = 0;
1171             os_error(NO_CARET, "sys$getdviw failed");
1172         }
1173         /* Create a subprocess whose input is this mailbox. */
1174         vaxc$errno = lib$spawn(&pgmdsc, &devnam, 0, &one, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1175         if ((vaxc$errno & SS$_NORMAL) != SS$_NORMAL) {
1176             printf("LIB$SPAWN failed with status=%d\r\n", vaxc$errno);
1177             sys$dassgn(X11_channel);
1178             X11_channel = 0;
1179             os_error(NO_CARET, "lib$spawn failed");
1180         }
1181     }
1182     {
1183         static int been_here = 0;
1184         if (!been_here) {
1185             GP_ATEXIT(X11_atexit);
1186             been_here = 1;
1187         }
1188     }
1189 }
1190
1191
1192 /*   We use $QIO in order to avoid buffering problems, although it might
1193  *   work  as well with simple Fprintf calls.
1194  */
1195
1196 #define GO(x) \
1197 do { \
1198    char buffer[512]; int status; struct iosb iosb;\
1199    sprintf x; \
1200    if (strlen(buffer) >= MBXMXMSG)  { \
1201      printf("buffer contents (%d char) catenated to mailbox size (%d bytes)\n", \
1202      strlen(buffer), MBXMXMSG); \
1203      buffer[MBXMXMSG-1] = '\0';\
1204      printf("%s\n", buffer); \
1205    } \
1206    status = sys$qiow(0, X11_channel, IO$_WRITEVBLK, &iosb, 0, 0, buffer, strlen(buffer), 0, 0, 0, 0); \
1207    if ((status & SS$_NORMAL) == SS$_NORMAL) status = iosb.stat; \
1208    if((status & SS$_NORMAL) != SS$_NORMAL) exit(status); \
1209  } while (0)
1210
1211 #define PRINT0(fmt)          GO((buffer, fmt))
1212 #define PRINT1(fmt,p1)       GO((buffer, fmt,p1))
1213 #define PRINT2(fmt,p1,p2)    GO((buffer, fmt,p1,p2))
1214 #define PRINT3(fmt,p1,p2,p3) GO((buffer, fmt,p1,p2,p3))
1215 #define PRINT4(fmt,p1,p2,p3,p4) GO((buffer, fmt,p1,p2,p3,p4))
1216 #define PRINT5(fmt,p1,p2,p3,p4,p5) GO((buffer, fmt,p1,p2,p3,p4,p5))
1217
1218 #define FFLUSH()                /* nowt */
1219 #define BEFORE_GRAPHICS         /* nowt */
1220 #define AFTER_TEXT              /* nowt */
1221
1222 static void
1223 X11_atexit()
1224 {
1225     if (X11_channel) {
1226         PRINT0("R\n");
1227         sleep(2);               /* Wait for subprocess to finish */
1228         sys$dassgn(X11_channel);
1229         X11_channel = 0;
1230     }
1231 }
1232
1233 TERM_PUBLIC void
1234 X11_reset()
1235 {
1236     /* do nothing until exit */
1237 }
1238
1239 #else /* !VMS */
1240     You lose.
1241 #endif /* !VMS */
1242
1243 /* common stuff, using macros defined above */
1244
1245 TERM_PUBLIC void
1246 X11_graphics()
1247 {
1248 #ifdef USE_MOUSE
1249     static unsigned long windowid = 0;
1250 #endif
1251     static enum set_encoding_id last_encoding = S_ENC_DEFAULT;
1252
1253     BEFORE_GRAPHICS;            /* kludge for crippled select */
1254
1255 #ifndef USE_MOUSE
1256     /* for VMS sake, keep as separate prints */
1257     PRINT1("G%d\n", X11_plot_number);
1258 #else
1259 #ifdef PIPE_IPC
1260     /* if we know the outboard driver has stopped, restart it */
1261     if (ipc_back_fd == IPC_BACK_CLOSED) {
1262         fclose(X11_ipc);
1263         X11_ipc = NULL;
1264         X11_init();
1265     }
1266 #endif
1267     /* send also XID of gnuplot window (<space> then raises it up) */
1268     if (!windowid) {
1269         char *window_env = getenv("WINDOWID");
1270         if (window_env)
1271             sscanf(window_env, "%lu", &windowid);
1272     }
1273 #ifndef OS2
1274     PRINT2("G%d %lu\n", X11_plot_number, windowid);
1275 #else
1276     PRINT3("G%d %lu %i\n", X11_plot_number, windowid, getpid());
1277 #endif
1278 #endif /* USE_MOUSE */
1279
1280 #ifdef ULTRIX_KLUDGE
1281     fflush(X11_ipc);
1282 #endif
1283
1284     if (encoding != last_encoding) {
1285         PRINT1("QE%d\n",encoding);
1286         last_encoding = encoding;
1287     }
1288
1289 #if defined(USE_MOUSE) && defined(PIPE_IPC)
1290     /* EAM June 2003 - Flush the set font command through the pipe */
1291     /* to gnuplot_x11, then wait for it to return the resulting    */
1292     /* font size information (v_char and h_char). The feedback is  */
1293     /* caught by do_event() as an event of type GE_fontprops.      */
1294     if (ipc_back_fd >= 0 && X11_MOUSE_FEEDBACK) {
1295         if (!default_font_size_known) {
1296             IPC_LOCK = TRUE;
1297             PRINT1("QG%s\n",X11_default_font);
1298             FFLUSH();
1299             X11_waitforinput();
1300             default_font_size_known = TRUE;
1301             IPC_LOCK = FALSE;
1302         }
1303     }
1304 #endif
1305     /* Force default font at start of plot */
1306     *X11_last_font_used = '\01';
1307     X11_set_default_font();
1308     X11_set_font("");
1309 }
1310
1311 TERM_PUBLIC void
1312 X11_text()
1313 {
1314     if (!X11_ipc)
1315         return;
1316
1317 #ifdef USE_MOUSE
1318     /* EAM July 2003:  send over a snapshot of the final axis scaling
1319      * so that subsequent mouse events can be transformed into plot
1320      * coordinates even though the plot is no longer active.
1321      */
1322 #ifdef PIPE_IPC
1323     if (ipc_back_fd >= 0)
1324 #endif
1325         {
1326         /* Construct a mask showing which axes are active */
1327         int axis_mask = 0;
1328         int i;
1329
1330         for (i = FIRST_AXES; i < 2*SECOND_AXES; i++) {
1331             if (axis_array[i].ticmode != NO_TICS)
1332                 axis_mask |= (1 << i);
1333         }
1334         PRINT2("S %d %d\n", -2, ALMOST2D);
1335         PRINT2("S %2d %d\n", -1, axis_mask);
1336         PRINT5("S %2d %14.3g %14d %14.3g %14.3g\n", FIRST_X_AXIS,
1337                 axis_array[FIRST_X_AXIS].min,
1338                 axis_array[FIRST_X_AXIS].term_lower,
1339                 axis_array[FIRST_X_AXIS].term_scale,
1340                 axis_array[FIRST_X_AXIS].log ? axis_array[FIRST_X_AXIS].log_base : 0);
1341         PRINT5("S %2d %14.3g %14d %14.3g %14.3g\n", FIRST_Y_AXIS,
1342                 axis_array[FIRST_Y_AXIS].min,
1343                 axis_array[FIRST_Y_AXIS].term_lower,
1344                 axis_array[FIRST_Y_AXIS].term_scale,
1345                 axis_array[FIRST_Y_AXIS].log ? axis_array[FIRST_Y_AXIS].log_base : 0);
1346         PRINT5("S %2d %14.3g %14d %14.3g %14.3g\n", SECOND_X_AXIS,
1347                 axis_array[SECOND_X_AXIS].min,
1348                 axis_array[SECOND_X_AXIS].term_lower,
1349                 axis_array[SECOND_X_AXIS].term_scale,
1350                 axis_array[SECOND_X_AXIS].log ? axis_array[SECOND_X_AXIS].log_base : 0);
1351         PRINT5("S %2d %14.3g %14d %14.3g %14.3g\n", SECOND_Y_AXIS,
1352                 axis_array[SECOND_Y_AXIS].min,
1353                 axis_array[SECOND_Y_AXIS].term_lower,
1354                 axis_array[SECOND_Y_AXIS].term_scale,
1355                 axis_array[SECOND_Y_AXIS].log ? axis_array[SECOND_Y_AXIS].log_base : 0);
1356     }
1357 #endif
1358
1359     PRINT0("E\n");
1360     FFLUSH();
1361 #ifdef ULTRIX_KLUDGE
1362     PRINT0("E\n");
1363     FFLUSH();
1364 #endif
1365
1366     AFTER_TEXT;                 /* kludge for crippled select */
1367 }
1368
1369 TERM_PUBLIC void
1370 X11_move(unsigned int x, unsigned int y)
1371 {
1372     PRINT2("M%04d%04d\n", x, y);
1373 }
1374
1375 TERM_PUBLIC void
1376 X11_vector(unsigned int x, unsigned int y)
1377 {
1378     PRINT2("V%04d%04d\n", x, y);
1379 }
1380
1381 TERM_PUBLIC void
1382 X11_pointsize(double ps)
1383 {
1384     if (ps < 0)
1385         ps = 1;
1386     PRINT2("P-2 %d %d\n",       /* size of point symbols */
1387            (int) (term->h_tic * ps * 0.5), (int) (term->v_tic * ps * 0.5));
1388 }
1389
1390 TERM_PUBLIC void
1391 X11_linewidth(double lw)
1392 {
1393     PRINT1("W%04d\n", (int) (lw * X11_linewidth_multiplier + 0.5));
1394 }
1395
1396 TERM_PUBLIC void
1397 X11_linetype(int lt)
1398 {
1399     PRINT1("L%04d\n", lt);
1400 }
1401
1402 TERM_PUBLIC void
1403 X11_put_text(unsigned int x, unsigned int y, const char str[])
1404 {
1405     /* Only send the font change request to X11 if it really is a change */
1406     if (strcmp(X11_last_font_used,X11_next_font_used)) {
1407         strcpy(X11_last_font_used,X11_next_font_used);
1408         PRINT1("QF%s\n", X11_next_font_used);
1409     }
1410
1411     /* badly outrange labels can overflow into text field */
1412     if (x < 10000 && y < 10000) {
1413         PRINT3("T%04d%04d%s\n", x, y, str);
1414     }
1415 }
1416
1417 TERM_PUBLIC int
1418 X11_text_angle(int ang)
1419 {
1420     PRINT1("A%d\n", ang);
1421     return TRUE;
1422 }
1423
1424 TERM_PUBLIC int
1425 X11_justify_text(enum JUSTIFY mode)
1426 {
1427     PRINT1("J%04d\n", mode);
1428     X11_last_justification = mode;
1429     return (TRUE);
1430 }
1431
1432 TERM_PUBLIC void
1433 X11_point(unsigned int x, unsigned int y, int number)
1434 {
1435     PRINT3("P%d %d %d\n", number, x, y);
1436 }
1437
1438 TERM_PUBLIC int
1439 X11_set_font(const char *fontname)
1440 {
1441     PRINT1("QF%s\n", fontname?fontname:"");
1442     strncpy(X11_next_font_used,fontname?fontname:"",sizeof(X11_next_font_used)-1);
1443     return(TRUE);
1444 }
1445
1446 static void
1447 X11_set_default_font()
1448 {
1449     PRINT1("QD%s\n",X11_default_font);
1450 }
1451
1452 TERM_PUBLIC void
1453 X11_fillbox(int style, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
1454 {
1455     if (X11_ipc) {
1456         PRINT5("F%04d%04u%04u%04u%04u\n", style, x, y, w, h);
1457     }
1458 }
1459
1460 #ifdef USE_MOUSE
1461 TERM_PUBLIC void
1462 X11_put_tmptext(int i, const char str[])
1463 {
1464     if (X11_ipc) {
1465         PRINT2("t%04d%s\n", i, str);
1466         FFLUSH();
1467     }
1468 }
1469
1470 TERM_PUBLIC void
1471 X11_set_ruler(int x, int y)
1472 {
1473     if (X11_ipc) {
1474         PRINT2("r%04d%04d\n", x < 9999 ? x : 9999, y < 9999 ? y : 9999);
1475         FFLUSH();
1476     }
1477 }
1478
1479 TERM_PUBLIC void
1480 X11_set_cursor(int c, int x, int y)
1481 {
1482     if (X11_ipc) {
1483         PRINT3("u%04d%04d%04d\n", c, x, y);
1484         FFLUSH();
1485     }
1486 }
1487
1488 TERM_PUBLIC void
1489 X11_set_clipboard(const char s[])
1490 {
1491     if (X11_ipc) {
1492         PRINT1("z%s\n", s);
1493         FFLUSH();
1494     }
1495 }
1496
1497 #endif /* USE_MOUSE */
1498
1499
1500 static void
1501 transmit_gradient(gradient_struct *gradient, int cnt)
1502 {
1503     int i = 0;
1504
1505     fprintf(X11_ipc, "%d", cnt);
1506     for(i=0; i<cnt; i++) {
1507         /* this %50 *must* match the corresponding %50 in gplt_x11.c  */
1508         if(i%50 == 0) {
1509             fputs("\n", X11_ipc);
1510             fflush(X11_ipc);
1511         }
1512         fprintf(X11_ipc, "%s", gradient_entry_to_str(&(gradient[i])));
1513     }
1514     fputs("\n", X11_ipc);
1515 }
1516
1517
1518 TERM_PUBLIC int
1519 X11_make_palette(t_sm_palette *palette)
1520 {
1521     if(!palette) {
1522         return 0;
1523     }
1524
1525     if(!X11_ipc) {
1526             fprintf(stderr, "(X11_make_palette) 0 == X11_ipc\n");
1527             return -1;
1528         }
1529
1530     fprintf(X11_ipc, "%c %c %c %c %d\n",
1531              X11_GR_MAKE_PALETTE, (char)(palette->colorMode),
1532              (char)(palette->positive), (char)(palette->cmodel),
1533              palette->use_maxcolors);
1534
1535     switch(palette->colorMode) {
1536     case SMPAL_COLOR_MODE_GRAY:
1537         fprintf(X11_ipc,"%g\n", palette->gamma);
1538         break;
1539     case SMPAL_COLOR_MODE_RGB:
1540         fprintf(X11_ipc, "%d %d %d\n", palette->formulaR,
1541                  palette->formulaG, palette->formulaB);
1542         break;
1543     case SMPAL_COLOR_MODE_GRADIENT:
1544         transmit_gradient(palette->gradient, palette->gradient_num);
1545         break;
1546     case SMPAL_COLOR_MODE_FUNCTIONS: {
1547         int cnt=0;
1548         gradient_struct *gradient;
1549         gradient = approximate_palette(palette, -1, 0.01, &cnt);
1550         transmit_gradient(gradient, cnt);
1551         free(gradient);
1552         break;
1553     }
1554     default:
1555         fprintf(stderr, "%s:%d ooops: Unknown colorMode '%c'.\n",
1556                  __FILE__, __LINE__, (char)(palette->colorMode));
1557     }
1558     fflush(X11_ipc);
1559     return 0;
1560 }
1561
1562
1563 #if 0
1564 /* The following are some handy little routines to keep around
1565  * in case one wants to do statistics on the binary data being
1566  * passed to a terminal function.
1567  */
1568
1569 int char_count[256];
1570
1571 void histogram(unsigned char c) {
1572     char_count[c] += 1;
1573 }
1574
1575 void dump_histogram(void) {
1576   int i, sum;
1577   fprintf(stderr,"\n\n");
1578   for (i=0,sum=0; i<256; i++) {
1579     fprintf(stderr," %3.3d:%7.7d ", i, char_count[i]);
1580     sum += char_count[i];
1581   }
1582   fprintf(stderr,"\n\ntotal: %d\n\n",sum);
1583 }
1584 #endif
1585
1586 TERM_PUBLIC void
1587 X11_set_color(t_colorspec *colorspec)
1588 {
1589     if (colorspec->type == TC_RGB) {
1590         fputc(X11_GR_SET_RGBCOLOR, X11_ipc);
1591         PRINT1("%6.6x\n", colorspec->lt);
1592         FFLUSH();
1593         return;
1594     }
1595
1596     if (colorspec->type == TC_LT) {
1597         fputc(X11_GR_SET_LINECOLOR, X11_ipc);
1598         PRINT1("%4d\n", colorspec->lt);
1599         FFLUSH();
1600         return;
1601     }
1602
1603     if (colorspec->type != TC_FRAC)
1604         return;
1605
1606 #ifndef BINARY_X11_POLYGON
1607     fputc(X11_GR_SET_COLOR, X11_ipc);
1608     PRINT1("%f\n", colorspec->value);
1609     FFLUSH();
1610     return;
1611 #else
1612     {
1613     char *c_ptr;
1614     unsigned short byte_remaining;
1615     float fgray = colorspec->value;
1616
1617     fputc(X11_GR_SET_COLOR, X11_ipc);
1618     byte_remaining = sizeof(fgray);
1619     c_ptr = (char *) &fgray;
1620
1621     while (byte_remaining) {
1622
1623         char c_tmp = *c_ptr++ - SET_COLOR_TRANSLATION_CHAR;
1624
1625         byte_remaining--;
1626
1627         if ( (c_tmp == '\n') || (c_tmp == SET_COLOR_CODE_CHAR) || (c_tmp == '\0') ) {
1628             fputc(SET_COLOR_CODE_CHAR, X11_ipc);
1629             c_tmp += 1;
1630         }
1631         fputc(c_tmp, X11_ipc);
1632
1633     }
1634
1635     fputc('\n', X11_ipc);
1636     FFLUSH();
1637     }
1638 #endif /* BINARY_X11_POLYGON */
1639
1640 }
1641
1642 TERM_PUBLIC void
1643 X11_filled_polygon(int points, gpiPoint *corners)
1644 {
1645
1646 #ifndef BINARY_X11_POLYGON
1647
1648     int i;
1649
1650     fputc(X11_GR_FILLED_POLYGON, X11_ipc);
1651     /* FIXME HBB 20010919: this %04d format somewhat arbitrarily
1652      * limits us to 10000 vertices in the polygon */
1653     PRINT2("%04d%04d", points, corners->style);
1654     for (i = 0; i < points; i++) {
1655         PRINT2("%04d%04d", corners[i].x, corners[i].y);
1656         /* HBB 20010919: fix for buffer overflow problem: start
1657          * another line every 100 points, to avoid overflowing
1658          * fixed-size buffer in gplt_x11.  Number of points == -1
1659          * signals continuation line */
1660         if ((i % 100) == 99) {
1661             PRINT1("xxxx\n%c-001", X11_GR_FILLED_POLYGON);
1662             FFLUSH();
1663         }
1664     }
1665     fputc('\n', X11_ipc);
1666     FFLUSH();
1667     return;
1668
1669 #else
1670
1671     int int_cache[2];
1672     int i_corner;
1673     unsigned short i_buffer;
1674     unsigned short byte_remaining;
1675     unsigned point_remaining;
1676
1677     /* Encode and transfer data to the pipe, one character at a time. */
1678
1679     if (!points) return;
1680
1681     fputc(X11_GR_FILLED_POLYGON, X11_ipc);
1682     i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
1683
1684     /* First put number of points into the buffer.  Initialize the "cache"
1685      * to the number of points and the number of bytes to transfer to the
1686      * size of an int.  This will be the first transfer, so increase the
1687      * number of points by one.
1688      */
1689     int_cache[0] = points;
1690     int_cache[1] = corners->style;
1691     byte_remaining = 2*sizeof(int_cache[0]);
1692     point_remaining = points + 1;
1693     i_corner = 0;
1694
1695     while (point_remaining) {
1696
1697         unsigned char *uc_ptr = (unsigned char *) int_cache;
1698
1699         while (byte_remaining) {
1700
1701             int sent_val;
1702
1703             unsigned char uc_tmp = *uc_ptr++ - FILLED_POLYGON_TRANSLATION_CHAR;
1704             byte_remaining--;
1705
1706             if ( (uc_tmp == '\n') || (uc_tmp == FILLED_POLYGON_CODE_CHAR) || (uc_tmp == '\0') ) {
1707                 uc_tmp += 1;
1708                 sent_val = fputc(FILLED_POLYGON_CODE_CHAR, X11_ipc);
1709                 if (sent_val != (int)FILLED_POLYGON_CODE_CHAR)
1710                     fprintf(stderr, "Bad character mapping %d -> %d\n", (int)FILLED_POLYGON_CODE_CHAR, sent_val);
1711                 i_buffer--;
1712                 if (!i_buffer) {
1713                     fputc('\n', X11_ipc);  FFLUSH();               /* End of chunk. */
1714                     i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
1715                     fputc(X11_GR_FILLED_POLYGON, X11_ipc);         /* Will be another chunk. */
1716                 }
1717             }
1718
1719             sent_val = fputc(uc_tmp, X11_ipc);
1720             if (sent_val != (int)uc_tmp)
1721                 fprintf(stderr, "Bad character mapping %d -> %d\n", (int)uc_tmp, sent_val);
1722             i_buffer--;
1723             if (!i_buffer) {
1724                 fputc('\n', X11_ipc);  FFLUSH();                   /* End of chunk. */
1725                 i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
1726                 if (point_remaining || byte_remaining)
1727                     fputc(X11_GR_FILLED_POLYGON, X11_ipc);         /* Will be another chunk. */
1728             }
1729
1730         }
1731
1732         byte_remaining = 2*sizeof(int);
1733         if (--point_remaining) {
1734             int_cache[0] = corners[i_corner].x;
1735             int_cache[1] = corners[i_corner].y;
1736             i_corner++;
1737         }
1738     }
1739
1740     /* Check if some characters were put in the buffer that need to be flushed. */
1741     if (i_buffer != BINARY_MAX_CHAR_PER_TRANSFER) {
1742         fputc('\n', X11_ipc);
1743         FFLUSH();
1744     }
1745
1746     return;
1747 #endif
1748
1749 }
1750
1751
1752 /*
1753  * Ethan A Merritt November 2003
1754  *      - Support for enhanced text mode
1755  *
1756  * PROBLEMS:
1757  *      - The default font must be scalable
1758  *      - Without more feedback from the outboard driver (gnuplot_x11) it is
1759  *        hard to set up proper text rotation. The current approximation is so-so.
1760  *      - Right- and Center- justified text is problematic for the same reason.
1761  *      - The default font size is not really known, and font scaling
1762  *        in general could be improved
1763  */
1764
1765 static TBOOLEAN ENHx11_opened_string;
1766 static TBOOLEAN ENHx11_sizeonly = FALSE;
1767 static TBOOLEAN ENHx11_show = TRUE;
1768 static int ENHx11_overprint = 0;
1769 static TBOOLEAN ENHx11_widthflag = TRUE;
1770 static double ENHx11_base;
1771 static double ENHx11_fontsize;
1772 static char  *ENHx11_font;
1773
1774 TERM_PUBLIC void
1775 ENHX11_OPEN(
1776     char *fontname,
1777     double fontsize, double base,
1778     TBOOLEAN widthflag, TBOOLEAN showflag,
1779     int overprint)
1780 {
1781     /* If the overprint code requests a save or request, that's all we do */
1782     if (overprint == 3) {
1783         PRINT2("Tp%04d%04d\n", 0, 0);
1784         return;
1785     } else if (overprint == 4) {
1786         PRINT2("Tr%04d%04d\n", 0, 0);
1787         return;
1788     }
1789
1790     if (!ENHx11_opened_string) {
1791         ENHx11_opened_string = TRUE;
1792         enhanced_cur_text = &enhanced_text[0];
1793         ENHx11_font = fontname;
1794         ENHx11_fontsize = fontsize;
1795         ENHx11_base = base * 10;        /* FIXME - should this be v_char? v_tic? */
1796         ENHx11_show = showflag;
1797         ENHx11_overprint = overprint;
1798         ENHx11_widthflag = widthflag;
1799     }
1800 }
1801
1802 /*
1803  * Write a string fragment and update current position.
1804  * We leave the real work up to gnuplot_x11!
1805  */
1806 TERM_PUBLIC void
1807 ENHX11_FLUSH()
1808 {
1809     /* Send a command to print this string at current position */
1810     if (ENHx11_opened_string) {
1811
1812         char tmpfont[128];      /* FIXME - there must be a better way! */
1813         *enhanced_cur_text = '\0';
1814         sprintf(tmpfont,"%s,%.1f", ENHx11_font, ENHx11_fontsize);
1815         PRINT1("QF%s\n", tmpfont);
1816         *X11_last_font_used = '\01';
1817
1818         if (!ENHx11_show || ENHx11_sizeonly)
1819             PRINT3("Ts%04d%04d%s\n", 0, (int)ENHx11_base, enhanced_text);
1820         else if (ENHx11_overprint == 1)
1821             PRINT3("Tc%04d%04d%s\n", 0, (int)ENHx11_base, enhanced_text);
1822         else if (!ENHx11_widthflag && ENHx11_overprint != 0)
1823             PRINT3("To%04d%04d%s\n", 0, (int)ENHx11_base, enhanced_text);
1824         else
1825             PRINT3("Tu%04d%04d%s\n", 0, (int)ENHx11_base, enhanced_text);
1826
1827         ENHx11_opened_string = FALSE;
1828     }
1829 }
1830
1831 TERM_PUBLIC void
1832 ENHX11_put_text(unsigned int x, unsigned int y, const char *str)
1833 {
1834     char *original_string = (char *)str;
1835     static char *initial_font = NULL;
1836     int pass = 1;
1837
1838     if (ignore_enhanced_text) {
1839         X11_put_text(x,y,str);
1840         return;
1841     }
1842
1843     if (!strlen(str))
1844         return;
1845
1846     /* if there are no magic characters, we should just be able
1847      * punt the string to X11_put_text()
1848      */
1849     if (!strpbrk(str, "{}^_@&~")) {
1850         X11_put_text(x,y,str);
1851         return;
1852     }
1853
1854     /* set up the global variables needed by enhanced_recursion() */
1855     enhanced_fontscale = 1.25;
1856     ENHx11_opened_string = FALSE;
1857     strncpy(enhanced_escape_format,"%c",sizeof(enhanced_escape_format));
1858
1859
1860     /* Tell gnuplot_x11 to set the current position to (x,y) */
1861         PRINT2("Tl%04d%04d\n", x, y);
1862
1863     /* Text justification requires two passes. During the first pass we */
1864     /* don't draw anything, we just measure the space it will take.     */
1865     if (X11_last_justification != LEFT) {
1866         PRINT1("J%04d\n", LEFT);
1867         ENHx11_sizeonly = TRUE;
1868     }
1869 PASS2:
1870
1871     /* Make sure that we start out using the intended font.  */
1872         ENHx11_font = "DEFAULT";
1873         ENHx11_fontsize = X11_default_fontsize;
1874         if (*X11_next_font_used) {
1875             int sep = strcspn(X11_next_font_used,",");
1876             free(initial_font);
1877             initial_font = gp_strdup(X11_next_font_used);
1878             initial_font[sep] = '\0';
1879             sscanf(&(X11_next_font_used[sep+1]),"%lf",&ENHx11_fontsize);
1880             ENHx11_font = initial_font;
1881             FPRINTF((stderr,"setting font to %s,%g\n",ENHx11_font,ENHx11_fontsize));
1882         }
1883
1884     /* Set the recursion going. We say to keep going until a
1885      * closing brace, but we don't really expect to find one.
1886      * If the return value is not the nul-terminator of the
1887      * string, that can only mean that we did find an unmatched
1888      * closing brace in the string. We increment past it (else
1889      * we get stuck in an infinite loop) and try again.
1890      */
1891     while (*(str = enhanced_recursion((char *)str, TRUE,
1892                         ENHx11_font, ENHx11_fontsize,
1893                         0.0, TRUE, TRUE, 0))) {
1894         (term->enhanced_flush)();
1895
1896         /* I think we can only get here if *str == '}' */
1897             enh_err_check(str);
1898
1899         if (!*++str)
1900             break; /* end of string */
1901
1902         /* else carry on and process the rest of the string */
1903     }
1904
1905     /* Restore text justification flag after 2nd pass */
1906     if (pass > 1) {
1907         PRINT1("J%04d\n", X11_last_justification);
1908         return;
1909     }
1910
1911     /* In order to do text justification we need to do a second pass that */
1912     /* uses information stored by gnuplot_x11 during the first pass.      */
1913     if (X11_last_justification != LEFT) {
1914         ENHx11_sizeonly = FALSE;
1915
1916         if (X11_last_justification == RIGHT) {
1917                 PRINT2("Tj%04d%04d\n", x, y);
1918         } else if (X11_last_justification == CENTRE) {
1919                 PRINT2("Tk%04d%04d\n", x, y);
1920         }
1921         str = original_string;
1922         pass = 2;
1923         goto PASS2;
1924
1925     }
1926
1927 }
1928
1929
1930 #if defined(WITH_IMAGE) || defined(BINARY_X11_POLYGON)
1931 TERM_PUBLIC void
1932 X11_send_endianess(void)
1933 {
1934     /* Place an integer 1 in the pipe and see if the byte order agrees
1935      * with program on the other side.  Information used for routines
1936      * having encoded binary data.
1937      */
1938     unsigned short tmp = (unsigned short) ENDIAN_VALUE;
1939     fputc(X11_GR_CHECK_ENDIANESS, X11_ipc);
1940     fputc(((char *)&tmp)[0], X11_ipc);
1941     fputc(((char *)&tmp)[1], X11_ipc);
1942     fputc('\n', X11_ipc);
1943     fflush(X11_ipc);
1944 }
1945 #endif
1946
1947 #ifdef WITH_IMAGE
1948
1949 TERM_PUBLIC void
1950 X11_image(unsigned M, unsigned N, coordval *image, gpiPoint *corner, t_imagecolor color_mode)
1951 {
1952
1953     /* Avoid using floats or formatted I/O.  That's too slow for image data.
1954      *
1955      * To avoid using floats, we assume that the maximum resolution of the
1956      * color plane of the x11 device is 16 bits.  (Not an unreasonable
1957      * assumption.)  So we convert coordval to unsigned short and then
1958      * send those.  The driver then shifts these unsigned short values to
1959      * the right to match the size of its palette.
1960      *
1961      * The driver uses the '\n' character to mean end of command.  When the
1962      * core routine sees the '\n', it stops copying the remaining characters
1963      * that are in the buffer.  Therefore, we need to hide the '\n' character
1964      * from the data stream.  We also need to hide the '\0' because the core
1965      * routine also does an 'strcpy'.  So the scheme is as follows:
1966      *
1967      *   On the driver side, if the char CODE_WORD is found it
1968      *   should be ignored and replaced with the char that
1969      *   follows it, but subtract one from that value.
1970      *
1971      * This means that there exists the chance of the data stream enlarging
1972      * by a factor of two.  So the algorithm must make sure to keep the
1973      * number of bytes transfered less than the buffer length.
1974      *
1975      * Also note that the '\0' character is often prevalent in 16 bit image
1976      * data where the palette may be 8 bits or less.  For this reason, a
1977      * translation is first done on the character to make the '\0' occur less
1978      * often.  In this way, less amount of data is sent and fewer command
1979      * lines are used to store an image.
1980      */
1981
1982     unsigned short i_buffer;
1983     unsigned coord_remaining;
1984     coordval *coord_ptr;
1985
1986     /* Use formatted I/O to transfer image information.  Hexadecimal uses less characters.
1987      *
1988      * Note that X11 has different frame of reference (top left origin) than does Gnuplot
1989      * (bottom left origin)
1990      */
1991     fputc(X11_GR_IMAGE, X11_ipc);
1992     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,
1993       corner[1].y, corner[2].x, corner[2].y, corner[3].x, corner[3].y, color_mode);
1994     FFLUSH();
1995
1996     /* Encode and transfer data to the pipe, one character at a time. */
1997
1998     coord_remaining = M*N;
1999     if (color_mode == IC_RGB) coord_remaining *= 3;
2000
2001     if (!coord_remaining) return;
2002
2003     fputc(X11_GR_IMAGE, X11_ipc);
2004     i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
2005     coord_ptr = image;
2006
2007     while (coord_remaining) {
2008
2009         unsigned short us_tmp;
2010         unsigned short byte_remaining;
2011         unsigned char *uc_ptr;
2012
2013         /* Convert coordinate value to an unsigned short.  Note that there
2014          * is no need for a range check because we are already using the
2015          * full range of the unsigned short value.  It is the C casting
2016          * routine that should do the range check.
2017          */
2018         us_tmp = (unsigned short) ((*coord_ptr++)*IMAGE_PALETTE_VALUE_MAX + 0.5);
2019         coord_remaining--;
2020
2021         byte_remaining = sizeof(us_tmp);
2022         uc_ptr = (unsigned char *) &us_tmp;
2023
2024         while (byte_remaining) {
2025
2026             int sent_val;
2027
2028             unsigned char uc_tmp = *uc_ptr++ - IMAGE_TRANSLATION_CHAR;
2029             byte_remaining--;
2030
2031             if ((uc_tmp == '\n') || (uc_tmp == IMAGE_CODE_CHAR) || (uc_tmp == '\0') ) {
2032                 uc_tmp += 1;
2033                 sent_val = fputc(IMAGE_CODE_CHAR, X11_ipc);
2034                 if (sent_val != (int)IMAGE_CODE_CHAR)
2035                     fprintf(stderr, "Bad character mapping %d -> %d\n", (int)IMAGE_CODE_CHAR, sent_val);
2036                 i_buffer--;
2037                 if (!i_buffer) {
2038                     fputc('\n', X11_ipc);  FFLUSH();               /* End of chunk. */
2039                     i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
2040                     fputc(X11_GR_IMAGE, X11_ipc);                  /* Will be another chunk. */
2041                 }
2042             }
2043
2044             sent_val = fputc(uc_tmp, X11_ipc);
2045             if (sent_val != (int)uc_tmp)
2046                 fprintf(stderr, "Bad character mapping %d -> %d\n", (int)uc_tmp, sent_val);
2047             i_buffer--;
2048             if (!i_buffer) {
2049                 fputc('\n', X11_ipc);  FFLUSH();                   /* End of chunk. */
2050                 i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
2051                 if (coord_remaining || byte_remaining)
2052                     fputc(X11_GR_IMAGE, X11_ipc);                  /* Will be another chunk. */
2053             }
2054
2055         }
2056
2057     }
2058
2059     /* Check if some characters were put in the buffer that need to be flushed. */
2060     if (i_buffer != BINARY_MAX_CHAR_PER_TRANSFER) {fputc('\n', X11_ipc);  FFLUSH();}
2061
2062     return;
2063 }
2064
2065 #endif /* WITH_IMAGE */
2066
2067 #endif /* TERM_BODY */
2068
2069 #ifdef TERM_TABLE
2070
2071 TERM_TABLE_START(x11_driver)
2072     "x11", "X11 Window System",
2073     X11_XMAX, X11_YMAX, X11_VCHAR, X11_HCHAR,
2074     X11_VTIC, X11_HTIC, X11_options, X11_init, X11_reset,
2075     X11_text, null_scale, X11_graphics, X11_move, X11_vector,
2076     X11_linetype, X11_put_text, X11_text_angle,
2077     X11_justify_text, X11_point, do_arrow, X11_set_font,
2078     X11_pointsize, TERM_CAN_MULTIPLOT|TERM_INIT_ON_REPLOT|TERM_NO_OUTPUTFILE,
2079     X11_text /* suspend can use same routine */ , 0 /* resume */ ,
2080     X11_fillbox, X11_linewidth
2081 #ifdef USE_MOUSE
2082     , X11_waitforinput, X11_put_tmptext, X11_set_ruler, X11_set_cursor, X11_set_clipboard
2083 #endif
2084     , X11_make_palette, 0 /* X11_previous_palette */ ,
2085     X11_set_color, X11_filled_polygon
2086 #ifdef WITH_IMAGE
2087     , X11_image
2088 #endif
2089     , ENHX11_OPEN, ENHX11_FLUSH, do_enh_writec
2090 TERM_TABLE_END(x11_driver)
2091
2092 #undef LAST_TERM
2093 #define LAST_TERM x11_driver
2094
2095 #endif                          /* TERM_TABLE */
2096 #endif                          /* TERM_PROTO_ONLY */
2097
2098
2099 #ifdef TERM_HELP
2100 START_HELP(x11)
2101 "1 x11",
2102 "?commands set terminal x11",
2103 "?set terminal x11",
2104 "?set term x11",
2105 "?terminal x11",
2106 "?term x11",
2107 "?x11",
2108 "?X11",
2109 " `gnuplot` provides the `x11` terminal type for use with X servers.  This",
2110 " terminal type is set automatically at startup if the `DISPLAY` environment",
2111 " variable is set, if the `TERM` environment variable is set to `xterm`, or",
2112 " if the `-display` command line option is used.",
2113 "",
2114 " Syntax:",
2115 "    set terminal x11 {<n>}",
2116 "                     {title \"<string>\"}",
2117 "                     {{no}enhanced} {font <fontspec>}",
2118 "                     {linewidth LW} {solid|dashed}",
2119 "                     {{no}persist} {{no}raise} {{no}ctrlq}",
2120 "                     {close}",
2121 "                     {size XX,YY} {position XX,YY}",
2122 "    set terminal x11 {reset}",
2123 "",
2124 " Multiple plot windows are supported: `set terminal x11 <n>` directs the",
2125 " output to plot window number n.  If n is not 0, the terminal number will be",
2126 " appended to the window title (unless a title has been supplied manually)",
2127 " and the icon will be labeled `Gnuplot <n>`.  The active window may be",
2128 " distinguished by a change in cursor (from default to crosshair).",
2129 "",
2130 " The x11 terminal support enhanced text mode (see `enhanced`), subject",
2131 " to the available fonts. In order for font size commands embedded in text",
2132 " to have any effect, the default x11 font must be scalable. Thus the first",
2133 " example below will work as expected, but the second will not.",
2134 "",
2135 "    set term x11 enhanced font \"arial,15\" ",
2136 "    set title '{/=20 Big} Medium {/=5 Small}' ",
2137 "",
2138 "    set term x11 enhanced font \"terminal-14\" ",
2139 "    set title '{/=20 Big} Medium {/=5 Small}' ",
2140 "",
2141 " Plot windows remain open even when the `gnuplot` driver is changed to a",
2142 " different device.  A plot window can be closed by pressing the letter q",
2143 " while that window has input focus, or by choosing `close` from a window",
2144 " manager menu.  All plot windows can be closed by specifying `reset`, which",
2145 " actually terminates the subprocess which maintains the windows (unless",
2146 " `-persist` was specified).  The `close` command can be used to close",
2147 " individual plot windows by number.  However, after a `reset`, those plot",
2148 " windows left due to persist cannot be closed with the command `close`.",
2149 " A `close` without a number closes the current active plot window.",
2150 "",
2151 " The gnuplot outboard driver, gnuplot_x11, is searched in a default place",
2152 " chosen when the program is compiled.  You can override that by defining",
2153 " the environment variable GNUPLOT_DRIVER_DIR to point to a different",
2154 " location.",
2155 "",
2156 " Plot windows will automatically be closed at the end of the session",
2157 " unless the `-persist` option was given.",
2158 "",
2159 " The options `persist` and `raise` are unset by default, which means that",
2160 " the defaults (persist == no and raise == yes) or the command line options",
2161 " -persist / -raise or the Xresources are taken.  If [no]persist or",
2162 " [no]raise are specified, they will override command line options and",
2163 " Xresources.  Setting one of these options takes place immediately, so",
2164 " the behaviour of an already running driver can be modified.  If the window",
2165 " does not get raised, see discussion in `raise`.",
2166 "",
2167 " The option `title \"<title name>\"` will supply the title name of the window",
2168 " for the current plot window or plot window <n> if a number is given.",
2169 " Where (or if) this title is shown depends on your X window manager.",
2170 "",
2171 " The size option can be used to set the size of the plot window.  The",
2172 " size option will only apply to newly created windows.",
2173 "",
2174 " The position option can be used to set the position of the plot window.  The",
2175 " position option will only apply to newly created windows.",
2176 "",
2177 " The size or aspect ratio of a plot may be changed by resizing the `gnuplot`",
2178 " window.",
2179 "",
2180 " Linewidths and pointsizes may be changed from within `gnuplot` with",
2181 " `set linestyle`.",
2182 "",
2183 " For terminal type `x11`, `gnuplot` accepts (when initialized) the standard",
2184 " X Toolkit options and resources such as geometry, font, and name from the",
2185 " command line arguments or a configuration file.  See the X(1) man page",
2186 " (or its equivalent) for a description of such options.",
2187 "",
2188 "=X resources",
2189 " A number of other `gnuplot` options are available for the `x11` terminal.",
2190 " These may be specified either as command-line options when `gnuplot` is",
2191 " invoked or as resources in the configuration file \".Xdefaults\".  They are",
2192 " set upon initialization and cannot be altered during a `gnuplot` session.",
2193 " (except `persist` and `raise`)",
2194 "2 x11_fonts",
2195 "?commands set terminal x11 x11_fonts",
2196 "?set terminal x11 x11_fonts",
2197 "?set term x11 x11_fonts",
2198 "?x11 x11_fonts",
2199 "?x11_fonts",
2200 "=fonts",
2201 " Upon initial startup, the default font is taken from the X11 resources",
2202 " as set in the system or user .Xdefaults file or on the command line.",
2203 "",
2204 " Example:",
2205 "       gnuplot*font: lucidasans-bold-12",
2206 " A new default font may be specified to the x11 driver from inside",
2207 " gnuplot using",
2208 "      `set term x11 font \"<fontspec>\"`",
2209 " The driver first queries the X-server for a font of the exact name given.",
2210 " If this query fails, then it tries to interpret <fontspec> as",
2211 " \"<font>,<size>,<slant>,<weight>\" and to construct a full X11 font name",
2212 " of the form",
2213 "       -*-<font>-<weight>-<s>-*-*-<size>-*-*-*-*-*-<encoding>",
2214 "",
2215 "  <font> is the base name of the font (e.g. Times or Symbol)",
2216 "  <size> is the point size (defaults to 12 if not specified)",
2217 "  <s> is `i` if <slant>==\"italic\" `o` if <slant>==\"oblique\" `r` otherwise",
2218 "  <weight> is `medium` or `bold` if explicitly requested, otherwise `*`",
2219 "  <encoding> is set based on the current character set (see `set encoding`).",
2220 " So `set term x11 font \"arial,15,italic\"` will be translated to",
2221 " -*-arial-*-i-*-*-15-*-*-*-*-*-iso8859-1 (assuming default encoding).",
2222 " The <size>, <slant>, and <weight> specifications are all optional.",
2223 " If you do not specify <slant> or <weight> then you will get whatever font ",
2224 " variant the font server offers first.",
2225 " You may set a default enconding via the corresponding X11 resource. E.g.",
2226 "       gnuplot*encoding: iso8859-15",
2227 " The driver also recognizes some common PostScript font names and",
2228 " replaces them with possible X11 or TrueType equivalents.",
2229 " This same sequence is used to process font requests from `set label`.",
2230 "",
2231 " If your gnuplot was built with configuration option --enable-x11-mbfonts,",
2232 " you can specify multi-byte fonts by using the prefix \"mbfont:\" on the font",
2233 " name. An additional font may be given, separated by a semicolon.",
2234 " Since multi-byte font encodings are interpreted according to the locale",
2235 " setting, you must make sure that the environmental variable LC_CTYPE is set",
2236 " to some appropriate locale value such as ja_JP.eucJP, ko_KR.EUC, or zh_CN.EUC.",
2237 "",
2238 " Example:",
2239 "       set term x11 font 'mbfont:kana14;k14'",
2240 "             # 'kana14' and 'k14' are Japanese X11 font aliases, and ';'",
2241 "             # is the separator of font names.",
2242 "       set term x11 font 'mbfont:fixed,16,r,medium'",
2243 "             # <font>,<size>,<slant>,<weight> form is also usable.",
2244 "       set title '(mb strings)' font 'mbfont:*-fixed-medium-r-normal--14-*'",
2245 "",
2246 " The same syntax applies to the default font in Xresources settings,",
2247 " for example,", 
2248 "       gnuplot*font: \\",
2249 "           mbfont:-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0",
2250 "",
2251 " If gnuplot is built with --enable-x11-mbfonts, you can use two special",
2252 " PostScript font names 'Ryumin-Light-*' and 'GothicBBB-Medium-*' (standard",
2253 " Japanese PS fonts) without the prefix \"mbfont:\".",
2254 "", 
2255 "2 command-line_options",
2256 "?commands set terminal x11 command-line-options",
2257 "?set terminal x11 command-line-options",
2258 "?set term x11 command-line-options",
2259 "?x11 command-line-options",
2260 "?command-line-options",
2261 " In addition to the X Toolkit options, the following options may be specified",
2262 " on the command line when starting `gnuplot` or as resources in your",
2263 " \".Xdefaults\" file (note that `raise` and `persist` can be overridden",
2264 " later by `set term x11 [no]raise [no]persist)`:",
2265 "@start table - first is interactive cleartext form",
2266 "  `-mono`     forces monochrome rendering on color displays.",
2267 "  `-gray`     requests grayscale rendering on grayscale or color displays.",
2268 "              (Grayscale displays receive monochrome rendering by default.)",
2269 "  `-clear`    requests that the window be cleared momentarily before a",
2270 "              new plot is displayed.",
2271 "  `-tvtwm`    requests that geometry specifications for position of the",
2272 "              window be made relative to the currently displayed portion",
2273 "              of the virtual root.",
2274 "  `-raise`    raises plot window after each plot",
2275 "  `-noraise`  does not raise plot window after each plot",
2276 #ifdef USE_MOUSE
2277 "  `-noevents` does not process mouse and key events",
2278 "  `-ctrlq   ` closes window on ctrl-q rather than q",
2279 #endif
2280 "  `-persist`  plot windows survive after main gnuplot program exits",
2281 "#\\begin{tabular}{|cl|} \\hline",
2282 "#`-mono`     & forces monochrome rendering on color displays.\\\\",
2283 "#`-gray`     & requests grayscale rendering on grayscale or color displays.\\\\",
2284 "#            & (Grayscale displays receive monochrome rendering by default.) \\\\",
2285 "#`-clear`    & requests that the window be cleared momentarily before a\\\\",
2286 "#            & new plot is displayed. \\\\",
2287 "#`-tvtwm`    & requests that geometry specifications for position of the\\\\",
2288 "#            & window be made relative to the currently displayed portion\\\\",
2289 "#            & of the virtual root. \\\\",
2290 "#`-raise`    & raises plot window after each plot. \\\\",
2291 "#`-noraise`  & does not raise plot window after each plot. \\\\",
2292 #ifdef USE_MOUSE
2293 "#`-noevents` & does not process mouse and key events. \\\\",
2294 #endif
2295 "#`-persist`  & plot windows survive after main gnuplot program exits. \\\\",
2296 "%c l .",
2297 "%`-mono`@forces monochrome rendering on color displays.",
2298 "%`-gray`@requests grayscale rendering on grayscale or color displays.",
2299 "%       @(Grayscale displays receive monochrome rendering by default.)",
2300 "%`-clear`@requests that the window be cleared momentarily before a",
2301 "%        @new plot is displayed.",
2302 "%`-tvtwm`@requests that geometry specifications for position of the",
2303 "%        @window be made relative to the currently displayed portion",
2304 "%        @of the virtual root.",
2305 "%`-raise`@raises plot window after each plot",
2306 "%`-noraise`@does not raise plot window after each plot",
2307 #ifdef USE_MOUSE
2308 "%`-novevents`@does not process mouse and key events",
2309 "%`-ctrlq`@closes window on ctrl-q rather than q",
2310 #endif
2311 "%`-persist`@plot windows survive after main gnuplot program exits",
2312 "@end table",
2313 "=X resources",
2314 " The options are shown above in their command-line syntax.  When entered as",
2315 " resources in \".Xdefaults\", they require a different syntax.",
2316 "",
2317 " Example:",
2318 "       gnuplot*gray:  on",
2319 "       gnuplot*ctrlq: on",
2320 "",
2321 " `gnuplot` also provides a command line option (`-pointsize <v>`) and a",
2322 " resource, `gnuplot*pointsize: <v>`, to control the size of points plotted",
2323 " with the `points` plotting style.  The value `v` is a real number (greater",
2324 " than 0 and less than or equal to ten) used as a scaling factor for point",
2325 " sizes.  For example, `-pointsize 2` uses points twice the default size, and",
2326 " `-pointsize 0.5` uses points half the normal size.",
2327 "",
2328 " The `-noevents` switch disables all mouse and key event processing (except",
2329 " for `q` and `<space>` for closing the window). This is useful for programs",
2330 " which use the x11 driver independent of the gnuplot main program.",
2331 "",
2332 " The `-ctrlq` switch changes the hot-key that closes a plot window from `q`",
2333 " to `<ctrl>q`. This is useful is you are using the keystroke-capture feature",
2334 " `pause mouse keystroke`, since it allows the character `q` to be captured",
2335 " just as all other alphanumeric characters. The `-ctrlq` switch similarly",
2336 " replaces the <space> hot-key with <ctrl><space> for the same reason.",
2337 "",
2338 "2 monochrome_options",
2339 "?commands set terminal x11 monochrome_options",
2340 "?set terminal x11 monochrome_options",
2341 "?set term x11 monochrome_options",
2342 "?x11 monochrome_options",
2343 "?monochrome_options",
2344 "=X resources",
2345 " For monochrome displays, `gnuplot` does not honor foreground or background",
2346 " colors.  The default is black-on-white.  `-rv` or `gnuplot*reverseVideo: on`",
2347 " requests white-on-black.",
2348 "",
2349 "2 color_resources",
2350 "?commands set terminal x11 color_resources",
2351 "?set terminal x11 color_resources",
2352 "?set term x11 color_resources",
2353 "?x11 color_resources",
2354 "?color_resources",
2355 "=X resources",
2356 " For color displays, `gnuplot` honors the following resources (shown here",
2357 " with their default values) or the greyscale resources.  The values may be",
2358 " color names as listed in the X11 rgb.txt file on your system, hexadecimal",
2359 " RGB color specifications (see X11 documentation), or a color name followed",
2360 " by a comma and an `intensity` value from 0 to 1.  For example, `blue, 0.5`",
2361 " means a half intensity blue.",
2362 "@start table - first is interactive cleartext form",
2363 "  gnuplot*background:  white",
2364 "  gnuplot*textColor:   black",
2365 "  gnuplot*borderColor: black",
2366 "  gnuplot*axisColor:   black",
2367 "  gnuplot*line1Color:  red",
2368 "  gnuplot*line2Color:  green",
2369 "  gnuplot*line3Color:  blue",
2370 "  gnuplot*line4Color:  magenta",
2371 "  gnuplot*line5Color:  cyan",
2372 "  gnuplot*line6Color:  sienna",
2373 "  gnuplot*line7Color:  orange",
2374 "  gnuplot*line8Color:  coral",
2375 "#\\begin{tabular}{|cl|} \\hline",
2376 "#&gnuplot*background: white\\\\",
2377 "#&gnuplot*textColor: black\\\\",
2378 "#&gnuplot*borderColor: black\\\\",
2379 "#&gnuplot*axisColor: black\\\\",
2380 "#&gnuplot*line1Color: red\\\\",
2381 "#&gnuplot*line2Color: green\\\\",
2382 "#&gnuplot*line3Color: blue\\\\",
2383 "#&gnuplot*line4Color: magenta\\\\",
2384 "#&gnuplot*line5Color: cyan\\\\",
2385 "#&gnuplot*line6Color: sienna\\\\",
2386 "#&gnuplot*line7Color: orange\\\\",
2387 "#&gnuplot*line8Color: coral\\\\",
2388 "%c l .",
2389 "%@gnuplot*background: white",
2390 "%@gnuplot*textColor: black",
2391 "%@gnuplot*borderColor: black",
2392 "%@gnuplot*axisColor: black",
2393 "%@gnuplot*line1Color: red",
2394 "%@gnuplot*line2Color: green",
2395 "%@gnuplot*line3Color: blue",
2396 "%@gnuplot*line4Color: magenta",
2397 "%@gnuplot*line5Color: cyan",
2398 "%@gnuplot*line6Color: sienna",
2399 "%@gnuplot*line7Color: orange",
2400 "%@gnuplot*line8Color: coral",
2401 "@end table",
2402 "",
2403 " The command-line syntax for these is simple only for background,",
2404 " which maps directly to the usual X11 toolkit option \"-bg\".  All",
2405 " others can only be set on the command line by use of the generic",
2406 " \"-xrm\" resource override option",
2407 "",
2408 " Examples:",
2409 "",
2410 "       gnuplot -background coral",
2411 " to change the background color.",
2412 "",
2413 "       gnuplot -xrm 'gnuplot*line1Color:blue'",
2414 " to override the first linetype color.",
2415 "",
2416 "2 grayscale_resources",
2417 "?commands set terminal x11 grayscale_resources",
2418 "?set terminal x11 grayscale_resources",
2419 "?set term x11 grayscale_resources",
2420 "?x11 grayscale_resources",
2421 "?grayscale_resources",
2422 "=X resources",
2423 " When `-gray` is selected, `gnuplot` honors the following resources for",
2424 " grayscale or color displays (shown here with their default values).  Note",
2425 " that the default background is black.",
2426 "@start table - first is interactive cleartext form",
2427 "  gnuplot*background: black",
2428 "  gnuplot*textGray:   white",
2429 "  gnuplot*borderGray: gray50",
2430 "  gnuplot*axisGray:   gray50",
2431 "  gnuplot*line1Gray:  gray100",
2432 "  gnuplot*line2Gray:  gray60",
2433 "  gnuplot*line3Gray:  gray80",
2434 "  gnuplot*line4Gray:  gray40",
2435 "  gnuplot*line5Gray:  gray90",
2436 "  gnuplot*line6Gray:  gray50",
2437 "  gnuplot*line7Gray:  gray70",
2438 "  gnuplot*line8Gray:  gray30",
2439 "#\\begin{tabular}{|cl|} \\hline",
2440 "#&gnuplot*background: black\\\\",
2441 "#&gnuplot*textGray: white\\\\",
2442 "#&gnuplot*borderGray: gray50\\\\",
2443 "#&gnuplot*axisGray: gray50\\\\",
2444 "#&gnuplot*line1Gray: gray100\\\\",
2445 "#&gnuplot*line2Gray: gray60\\\\",
2446 "#&gnuplot*line3Gray: gray80\\\\",
2447 "#&gnuplot*line4Gray: gray40\\\\",
2448 "#&gnuplot*line5Gray: gray90\\\\",
2449 "#&gnuplot*line6Gray: gray50\\\\",
2450 "#&gnuplot*line7Gray: gray70\\\\",
2451 "#&gnuplot*line8Gray: gray30\\\\",
2452 "%c l .",
2453 "%@gnuplot*background: black",
2454 "%@gnuplot*textGray: white",
2455 "%@gnuplot*borderGray: gray50",
2456 "%@gnuplot*axisGray: gray50",
2457 "%@gnuplot*line1Gray: gray100",
2458 "%@gnuplot*line2Gray: gray60",
2459 "%@gnuplot*line3Gray: gray80",
2460 "%@gnuplot*line4Gray: gray40",
2461 "%@gnuplot*line5Gray: gray90",
2462 "%@gnuplot*line6Gray: gray50",
2463 "%@gnuplot*line7Gray: gray70",
2464 "%@gnuplot*line8Gray: gray30",
2465 "@end table",
2466 "",
2467 "2 line_resources",
2468 "?commands set terminal x11 line_resources",
2469 "?set terminal x11 line_resources",
2470 "?set term x11 line_resources",
2471 "?x11 line_resources",
2472 "?line_resources",
2473 "=X resources",
2474 " `gnuplot` honors the following resources for setting the width (in pixels) of",
2475 " plot lines (shown here with their default values.)  0 or 1 means a minimal",
2476 " width line of 1 pixel width.  A value of 2 or 3 may improve the appearance of",
2477 " some plots.",
2478 "@start table - first is interactive cleartext form",
2479 "  gnuplot*borderWidth: 2",
2480 "  gnuplot*axisWidth:   0",
2481 "  gnuplot*line1Width:  0",
2482 "  gnuplot*line2Width:  0",
2483 "  gnuplot*line3Width:  0",
2484 "  gnuplot*line4Width:  0",
2485 "  gnuplot*line5Width:  0",
2486 "  gnuplot*line6Width:  0",
2487 "  gnuplot*line7Width:  0",
2488 "  gnuplot*line8Width:  0",
2489 "#\\begin{tabular}{|cl|} \\hline",
2490 "#&gnuplot*borderWidth: 2\\\\",
2491 "#&gnuplot*axisWidth: 0\\\\",
2492 "#&gnuplot*line1Width: 0\\\\",
2493 "#&gnuplot*line2Width: 0\\\\",
2494 "#&gnuplot*line3Width: 0\\\\",
2495 "#&gnuplot*line4Width: 0\\\\",
2496 "#&gnuplot*line5Width: 0\\\\",
2497 "#&gnuplot*line6Width: 0\\\\",
2498 "#&gnuplot*line7Width: 0\\\\",
2499 "#&gnuplot*line8Width: 0\\\\",
2500 "%c l .",
2501 "%@gnuplot*borderWidth: 2",
2502 "%@gnuplot*axisWidth: 0",
2503 "%@gnuplot*line1Width: 0",
2504 "%@gnuplot*line2Width: 0",
2505 "%@gnuplot*line3Width: 0",
2506 "%@gnuplot*line4Width: 0",
2507 "%@gnuplot*line5Width: 0",
2508 "%@gnuplot*line6Width: 0",
2509 "%@gnuplot*line7Width: 0",
2510 "%@gnuplot*line8Width: 0",
2511 "@end table",
2512 "",
2513 " `gnuplot` honors the following resources for setting the dash style used for",
2514 " plotting lines.  0 means a solid line.  A two-digit number `jk` (`j` and `k`",
2515 " are >= 1 and <= 9) means a dashed line with a repeated pattern of `j` pixels",
2516 " on followed by `k` pixels off.  For example, '16' is a dotted line with one",
2517 " pixel on followed by six pixels off.  More elaborate on/off patterns can be",
2518 " specified with a four-digit value.  For example, '4441' is four on, four off,",
2519 " four on, one off.  The default values shown below are for monochrome displays",
2520 " or monochrome rendering on color or grayscale displays.",
2521 " Color displays default to dashed:off ",
2522 "@start table - first is interactive cleartext form",
2523 "  gnuplot*dashed:       off",
2524 "  gnuplot*borderDashes:   0",
2525 "  gnuplot*axisDashes:    16",
2526 "  gnuplot*line1Dashes:    0",
2527 "  gnuplot*line2Dashes:   42",
2528 "  gnuplot*line3Dashes:   13",
2529 "  gnuplot*line4Dashes:   44",
2530 "  gnuplot*line5Dashes:   15",
2531 "  gnuplot*line6Dashes: 4441",
2532 "  gnuplot*line7Dashes:   42",
2533 "  gnuplot*line8Dashes:   13",
2534 "#\\begin{tabular}{|cl|} \\hline",
2535 "#&gnuplot*dashed: off\\\\",
2536 "#&gnuplot*borderDashes: 0\\\\",
2537 "#&gnuplot*axisDashes: 16\\\\",
2538 "#&gnuplot*line1Dashes: 0\\\\",
2539 "#&gnuplot*line2Dashes: 42\\\\",
2540 "#&gnuplot*line3Dashes: 13\\\\",
2541 "#&gnuplot*line4Dashes: 44\\\\",
2542 "#&gnuplot*line5Dashes: 15\\\\",
2543 "#&gnuplot*line6Dashes: 4441\\\\",
2544 "#&gnuplot*line7Dashes: 42\\\\",
2545 "#&gnuplot*line8Dashes: 13\\\\",
2546 "%c l .",
2547 "%@gnuplot*dashed: off",
2548 "%@gnuplot*borderDashes: 0",
2549 "%@gnuplot*axisDashes: 16",
2550 "%@gnuplot*line1Dashes: 0",
2551 "%@gnuplot*line2Dashes: 42",
2552 "%@gnuplot*line3Dashes: 13",
2553 "%@gnuplot*line4Dashes: 44",
2554 "%@gnuplot*line5Dashes: 15",
2555 "%@gnuplot*line6Dashes: 4441",
2556 "%@gnuplot*line7Dashes: 42",
2557 "%@gnuplot*line8Dashes: 13",
2558 "@end table"
2559 , "",
2560 "2 x11 pm3d_resources",
2561 "?commands set terminal x11 pm3d_resources",
2562 "?set terminal x11 pm3d_resources",
2563 "?set term x11 pm3d_resources",
2564 "?x11 pm3d_resources",
2565 "?pm3d_resources",
2566 "?x11 pm3d",
2567 "=X resources",
2568 " Choosing the appropriate visual class and number of colors is a crucial",
2569 " point in X11 applications and a bit awkward, since X11 supports six visual",
2570 " types in different depths.",
2571 "",
2572 " By default `gnuplot` uses the default visual of the screen. The number of",
2573 " colors which can be allocated depends on the visual class chosen. On a",
2574 " visual class with a depth > 12bit, gnuplot starts with a maximal number",
2575 " of 0x200 colors.  On a visual class with a depth > 8bit (but <= 12 bit)",
2576 " the maximal number of colors is 0x100, on <= 8bit displays the maximum",
2577 " number of colors is 240 (16 are left for line colors).",
2578 "",
2579 " Gnuplot first starts to allocate the maximal number of colors as stated",
2580 " above.  If this fails, the number of colors is reduced by the factor 2",
2581 " until gnuplot gets all colors which are requested. If dividing `maxcolors`",
2582 " by 2 repeatedly results in a number which is smaller than `mincolors`",
2583 " `gnuplot` tries to install a private colormap. In this case the window",
2584 " manager is responsible for swapping colormaps when the pointer is moved",
2585 " in and out the x11 driver's window.",
2586 "",
2587 " The default for `mincolors` is maxcolors / (num_colormaps > 1 ? 2 : 8),",
2588 " where num_colormaps is the number of colormaps which are currently used",
2589 " by gnuplot (usually 1, if only one x11 window is open).",
2590 "",
2591 " Some systems support multiple (different) visual classes together on one",
2592 " screen. On these systems it might be necessary to force gnuplot to use a",
2593 " specific visual class, e.g. the default visual might be 8bit PseudoColor",
2594 " but the screen would also support 24bit TrueColor which would be the",
2595 " preferred choice.",
2596 "",
2597 " The information about an Xserver's capabilities can be obtained with the",
2598 " program `xdpyinfo`.  For the visual names below you can choose one of",
2599 " StaticGray, GrayScale, StaticColor, PseudoColor, TrueColor, DirectColor.",
2600 " If an Xserver supports a requested visual type at different depths,",
2601 " `gnuplot` chooses the visual class with the highest depth (deepest).",
2602 " If the requested visual class matches the default visual and multiple",
2603 " classes of this type are supported, the default visual is preferred.",
2604 "",
2605 " Example: on an 8bit PseudoColor visual you can force a private color map",
2606 " by specifying `gnuplot*maxcolors: 240` and `gnuplot*mincolors: 240`.",
2607 "",
2608 "@start table - first is interactive cleartext form",
2609 "  gnuplot*maxcolors:  <integer>",
2610 "  gnuplot*mincolors:  <integer>",
2611 "  gnuplot*visual:     <visual name>",
2612 "#\\begin{tabular}{|cl|} \\hline",
2613 "#&gnuplot*maxcolors:  integer\\\\",
2614 "#&gnuplot*mincolors:  integer\\\\",
2615 "#&gnuplot*visual:     visual name\\\\",
2616 "%c l .",
2617 "%@gnuplot*maxcolors:  <integer number>",
2618 "%@gnuplot*mincolors:  <integer number>",
2619 "%@gnuplot*visual:     <visual name>",
2620 "@end table"
2621 , "",
2622 "2 x11 other_resources",
2623 "?commands set terminal x11 other_resources",
2624 "?set terminal x11 other_resources",
2625 "?set term x11 other_resources",
2626 "?x11 other_resources",
2627 "=X resources",
2628 " By default the contents of the current plot window are exported to the X11",
2629 " clipboard in response to X events in the window. Setting the resource",
2630 " 'gnuplot*exportselection' to 'off' or 'false' will disable this.",
2631 "",
2632 " By default text rotation is done using a method that is fast, but can",
2633 " corrupt nearby colors depending on the background.  If this is a problem,",
2634 " you can set the resource 'gnuplot.fastrotate' to 'off'",
2635 "",
2636 "@start table - other x11 resources",
2637 "  gnuplot*exportselection:  off",
2638 "  gnuplot*fastrotate:  on",
2639 "  gnuplot*ctrlq:  off",
2640 "#\\begin{tabular}{|cl|} \\hline",
2641 "#&gnuplot*exportselection:  off\\\\",
2642 "#&gnuplot*fastrotate:  on\\\\",
2643 "#&gnuplot*ctrlq:  off\\\\",
2644 "%c l .",
2645 "%@gnuplot*exportselection:  off",
2646 "%@gnuplot*fastrotate:  on",
2647 "%@gnuplot*ctrlq:  off",
2648 "@end table"
2649
2650 END_HELP(x11)
2651 #endif                          /* TERM_HELP */