1 /* Hello, Emacs, this is -*-C-*-
2 * $Id: x11.trm,v 1.160.2.14 2009/05/29 03:25:29 sfeam Exp $
6 /* GNUPLOT - x11.trm */
9 * Copyright 1986 - 1993, 1998, 2004 Thomas Williams, Colin Kelley
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.
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,
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
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.
34 * This software is provided "as is" without express or implied warranty
35 * to the extent permitted by applicable law.
39 * x11.trm --- inboard terminal driver for X11
42 /* Petr Mikulik and Johannes Zellner: added mouse support (October 1999)
43 * Implementation and functionality is based on pm.trm
46 /* X11 support for Petr Mikulik's pm3d
47 * by Johannes Zellner <johannes@zellner.org>
48 * (November 1999 - January 2000)
51 /* Dynamic font support, enhanced text mode support,
52 * additional feedback from outboard driver
53 * Ethan A Merritt <merritt@u.washington.edu>
57 /* Daniel Sebald: added X11 support for images. (27 February 2003)
67 int X11_args __PROTO((int argc, char *argv[]));
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));
86 #if defined(WITH_IMAGE) || defined(BINARY_X11_POLYGON)
87 TERM_PUBLIC void X11_send_endianess __PROTO((void));
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[]));
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 *));
104 TERM_PUBLIC void X11_image __PROTO((unsigned, unsigned, coordval *, gpiPoint *, t_imagecolor));
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,
112 TERM_PUBLIC void ENHX11_FLUSH __PROTO((void));
114 # define X11_XMAX 4096
115 # define X11_YMAX 4096
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;
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 */
130 #ifndef TERM_PROTO_ONLY
134 #include "gplt_x11.h"
136 /* non-zero if '-display' found on command line */
137 static int X11_Display = 0;
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;
148 static void X11_atexit __PROTO((void));
149 static void X11_set_default_font __PROTO((void));
151 static void transmit_gradient __PROTO((gradient_struct *gradient, int cnt));
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;
159 static struct x11opt {
160 const char *option; /* Name of option */
161 OptionArg arg; /* Whether option has argument */
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},
174 { "-selectionTimeout", hasArg}, { "-title", hasArg},
175 { "-xnllanguage", hasArg}, { "-xrm", hasArg},
176 { "-raise", hasNoArg}, { "-noraise", hasNoArg},
177 { "-solid", hasNoArg}, { "-dashed", hasNoArg},
178 { "-persist", hasNoArg}
180 , { "-nofeedback", hasNoArg}
181 , { "-noevents", hasNoArg}
182 , { "-ctrlq", hasNoArg}
186 #define X11_nopts (sizeof(X11_cmdopts) / sizeof(X11_cmdopts[0]))
188 static FILE *X11_ipc = (FILE *) 0;
190 #define X11_ipc_back_fd ipc_back_fd
193 static char **xargv = (char **) NULL;
194 /* reserve a minimum 10 driver opts */
195 static char *optvec[2 * X11_nopts + 1 + 10];
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).
200 # if defined(OS2) || defined(_Windows)
202 static char X11_default_command[] = "gnuplot_x11.exe";
204 static char X11_default_command[] = GNUPLOT_X11 ".exe";
206 # else /* thus !OS/2 && !Windows */
208 static char X11_default_command[] = "gnuplot_x11";
210 static char X11_default_command[] = GNUPLOT_X11;
212 # endif /* OS/2 || Windows */
214 static char *X11_command = X11_default_command;
215 static char *X11_command_parsed = NULL;
216 static char *X11_full_command_path = NULL;
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;
226 /* driver properties managed by x11.trm rather than gnuplot_x11 */
227 static double X11_linewidth_multiplier = 1.0;
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.
233 static TBOOLEAN default_font_size_known = FALSE;
234 static TBOOLEAN X11_MOUSE_FEEDBACK = TRUE;
237 static TBOOLEAN IPC_LOCK = FALSE;
240 static int parse_driver __PROTO((const char *));
243 parse_driver(const char *cmd)
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;
254 while (*ptr != '\0' && nr < sizeof(optvec) / sizeof(char)) {
256 /* Strip whitespace. Use nulls, so that
257 * the previous argument is terminated
260 while (isspace((unsigned char)*ptr))
263 if (!(*ptr)) /* don't count the terminating NULL */
266 /* Save the argument. */
269 /* Skip over the argument. */
270 while ('\0' != *ptr && !isspace((unsigned char)*ptr)) {
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");
281 dir = X11_DRIVER_DIR;
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");
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; */
294 sprintf(X11_full_command_path, "%s/%s", dir, optvec[0]);
296 sprintf(X11_full_command_path, "%s", optvec[0]);
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)
307 X11_args(int argc, char *argv[])
311 xargv = (char **) gp_alloc(argc * sizeof(char *), "<xargv>");
314 fputs("not enough memory to copy argv - quitting\n", stderr);
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);
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;
328 if (strcmp(*argv, "-nofeedback") == 0)
329 X11_MOUSE_FEEDBACK = FALSE;
331 if (strcmp(*argv, "-display") == 0)
333 if (X11_cmdopts[n].arg == hasArg) {
336 optvec[i++] = *++xargv, ++argv;
339 if (i >= (sizeof(optvec) / sizeof(char))) {
340 fprintf(stderr, "warning: X11 options will be truncated\n");
341 return nx11; /* optvec is full */
355 static unsigned int X11_plot_number;
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},
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},
397 {"pos$ition", X11_POSITION},
406 #define NOT_PROCESS_IF_DUPLICATION 1
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;
416 persist = do_raise = dashedlines = ctrlq = UNSET;
417 set_size = set_position = UNSET;
419 while (!END_OF_COMMAND) {
420 switch (lookup_table(&X11_opts[0], c_token)) {
423 if (set_reset) duplication=TRUE;
428 if (set_close) duplication=TRUE;
434 if (set_persist) duplication=TRUE;
440 if (set_persist) duplication=TRUE;
446 if (set_ctrlq) duplication=TRUE;
452 if (set_ctrlq) duplication=TRUE;
458 if (set_solid) duplication=TRUE;
464 if (set_solid) duplication=TRUE;
469 X11_linewidth_multiplier = real(const_express(&a));
470 if (X11_linewidth_multiplier <= 0)
471 X11_linewidth_multiplier = 1.0;
476 if (set_raise) duplication=TRUE;
482 if (set_raise) duplication=TRUE;
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));
494 copy_str(X11_default_font, c_token, sizeof(X11_default_font));
497 if (strchr(X11_default_font,','))
498 sscanf(strchr(X11_default_font,',')+1, "%d",
499 &X11_default_fontsize);
500 if (set_font) duplication=TRUE;
506 int_error(c_token, "expecting title text");
507 c_title_token = c_token;
509 if (set_title) duplication=TRUE;
513 term->put_text = ENHX11_put_text;
514 term->flags |= TERM_ENHANCED_TEXT;
518 term->put_text = X11_put_text;
519 term->flags &= ~TERM_ENHANCED_TEXT;
524 if (END_OF_COMMAND) {
525 int_error(c_token, "expecting X[,Y]");
528 x_in = (int) real(const_express(&a));
532 int_error(c_token, "X size must be > 0");
533 if (equals(c_token, ",")) {
535 y_in = (int) real(const_express(&a));
539 int_error(c_token, "Y size must be > 0");
546 if (END_OF_COMMAND) {
547 int_error(c_token, "expecting X[,Y]");
549 X11_POSITION_X = (int) real(const_express(&a));
550 if (equals(c_token, ",")) {
552 X11_POSITION_Y = (int) real(const_express(&a));
560 /* let gnuplot_x11 check range */
561 new_term_number = (int) real(const_express(&a));
562 if (set_number) duplication=TRUE;
568 int_error(c_token-1, "duplicated or contradicting arguments in X11 term options");
574 /* Call own init routine; this might be xlib rather than x11 */
578 X11_atexit(); /* tell gnuplot_x11 to shut down */
580 /* Leave the current window unchanged when closing an old window */
583 fprintf(X11_ipc, (set_number ? "C%d\n" : "C\n"), new_term_number);
586 } else if (set_number) {
587 X11_plot_number = new_term_number;
589 fprintf(X11_ipc, "N%d\n", X11_plot_number);
594 sprintf(term_options, "%d", X11_plot_number);
595 if (UNSET != do_raise) {
596 strcat(term_options, (yes == do_raise ? " raise" : " noraise"));
598 if (UNSET != persist) {
599 strcat(term_options, (yes == persist ? " persist" : " nopersist"));
601 if (UNSET != ctrlq) {
602 strcat(term_options, (yes == ctrlq ? " ctrlq" : " noctrlq"));
604 if (UNSET != dashedlines) {
605 strcat(term_options, (yes == dashedlines ? " dashed" : " solid"));
607 if (term->put_text == ENHX11_put_text) {
608 strcat(term_options, " enhanced");
610 if (X11_linewidth_multiplier != 1.0) {
611 sprintf(term_options + strlen(term_options),
612 " linewidth %.2g", X11_linewidth_multiplier);
614 if (*X11_default_font) {
615 strcat(term_options, " font \"");
616 strcat(term_options, X11_default_font);
617 strcat(term_options, "\"");
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));
630 copy_str(term_options+strlen(term_options), c_title_token, MAX_LINE_LEN-strlen(term_options));
632 /* Send up to maximum buffer length minus three characters of
633 * title string to account for required 'n', '\0', '\n'.
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);
643 strncat(term_options, "\"", MAX_LINE_LEN-strlen(term_options));
644 c_token = save_token;
646 if (set_size != UNSET)
647 sprintf(term_options + strlen(term_options),
648 " size %d,%d ", X11_SIZE_X,X11_SIZE_Y);
650 if (set_position != UNSET)
651 sprintf(term_options + strlen(term_options),
652 " position %d,%d ", X11_POSITION_X,X11_POSITION_Y);
659 x11_raise_terminal_window(int number)
661 /* Send the raise character and a number. */
663 fprintf(X11_ipc, "^%d\n", number);
669 x11_raise_terminal_group(void)
671 /* Send just the raise character. */
673 fprintf(X11_ipc, "^\n");
679 x11_lower_terminal_window(int number)
681 /* Send the raise character and a number. */
683 fprintf(X11_ipc, "v%d\n", number);
689 x11_lower_terminal_group(void)
691 /* Send just the raise character. */
693 fprintf(X11_ipc, "v\n");
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);
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);
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:
730 * DEFAULT_X11: popen() pipe for most un*x platforms
732 * CRIPPLED_SELECT : file IPC for un*x platforms with incomplete or faulty
733 * implementation of BSD select()
735 * VMS : mailbox/spawn IPC
736 *---------------------------------------------------------------------------*/
739 #if defined(VMS) || defined(CRIPPLED_SELECT)
742 #if defined(VMS) && defined(CRIPPLED_SELECT)
743 Error.Incompatible options.
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
751 /*-----------------------------------------------------------------------------
752 * DEFAULT_X11 popen() pipe IPC
753 *---------------------------------------------------------------------------*/
758 fputs("R\n", X11_ipc);
760 /* dont wait(), since they might be -persist */
776 static struct gp_event_t ge;
779 int fd = fileno(stdin);
780 int repeat_count = 0;
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)
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) {
798 if (FD_ISSET(ipc_back_fd, &fds)) {
799 n = read(ipc_back_fd, (void *) (l + (char *) &ge), sizeof(ge) - l);
803 /* don't close X11_ipc, otherwise later writes
804 * to it will cause a segfault */
806 break; /* outboard driver has stopped */
809 if (l == sizeof(ge)) {
810 /* note: do_event() may not return (if an
811 * error occurs), so need to reset l first */
814 if (ge.type == GE_fontprops) {
815 if (repeat_count > 0) {
817 "X11_waitforinput: caught GE_fontprops after %d tries\n",
820 return(GE_fontprops);
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)
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;
842 } while (!FD_ISSET(fd, &fds));
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");
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. */
859 if (repeat_count++ < 10000)
863 /* Same sort of thing if we are specifically waiting for mouse input. */
864 if (paused_for_mouse) {
871 #endif /* PIPE_IPC */
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
879 if (read(0, &c, 1) != 1)
887 #endif /* USE_MOUSE */
893 static int been_here = 0;
896 /* first time through or after a reset */
898 /* OS-9 popen() does not block on close for child to end, so
899 * we can safely use it here
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' */
905 X11_ipc = popen(X11_command, "w");
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) */
915 X11_ipc = popen(X11_command, "w");
917 #else /* !(OSK || OS/2) */
922 #define X11_ALLOW_EVENTS (mouse_setting.on)
923 if (X11_ALLOW_EVENTS) {
925 perror("pipe() failed:");
927 # endif /* PIPE_IPC */
929 perror("pipe() failed:");
934 char noevents[] = "-noevents";
935 if (X11_ALLOW_EVENTS) {
936 dup2(fdes_back[1], 1); /* stdout to pipe */
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. */
945 *++ptr = (char *) 0; /* terminate */
947 # endif /* PIPE_IPC */
948 /* close the write side of the child's forward fd */
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");
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");
967 if (X11_ALLOW_EVENTS) {
968 ipc_back_fd = fdes_back[0];
969 close(fdes_back[1]); /* the parent doesn't need this */
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;
982 # endif /* PIPE_IPC */
983 /* close the read side of the parent's forward fd */
985 X11_ipc = fdopen(fdes[1], "w");
991 GP_ATEXIT(X11_atexit);
994 #if defined(WITH_IMAGE) || defined(BINARY_X11_POLYGON)
995 X11_send_endianess();
998 default_font_size_known = FALSE;
1006 /* Leave the pipe alone, until exit or set term x11 reset */
1007 /* but make sure that all locks are cleared. */
1012 paused_for_mouse = 0;
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)
1023 #define FFLUSH() fflush(X11_ipc)
1025 #define BEFORE_GRAPHICS /* nowt */
1026 #define AFTER_TEXT /* nowt */
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];
1040 if (!(X11_pid = fork())) {
1041 execvp(X11_full_command_path, optvec);
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);
1052 system(X11_shutdown);
1055 #define BEFORE_GRAPHICS \
1056 if (!(X11_ipc = fopen(X11_tmp0, "w"))) { \
1057 perror(X11_tmp0); system(X11_shutdown); exit(1); \
1060 #define AFTER_TEXT \
1061 { fclose(X11_ipc); rename(X11_tmp0, X11_tmp); }
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)
1074 /* WHAT SHOULD I DO ? */
1077 /*-----------------------------------------------------------------------------
1078 * VMS mailbox/spawn IPC - Yehavi Bourvine - YEHAVI@VMS.HUJI.AC.IL
1079 *---------------------------------------------------------------------------*/
1081 #include <descrip.h>
1084 #include <lib$routines.h>
1085 #include <starlet.h>
1093 #define SS$_NORMAL 1 /* or include <ssdef.h> for all SS$_ def's */
1095 #define MBXMXMSG 128 /* DEFMBXMXMSG is set by SYSGEN */
1097 static short X11_channel;
1100 unsigned short stat;
1101 unsigned short count;
1113 static char devnam_string[64];
1114 static $DESCRIPTOR(devnam, devnam_string);
1120 unsigned short int *ret_len;
1123 devnam.dsc$w_length, DVI$_DEVNAM, devnam.dsc$a_pointer, &devnam.dsc$w_length, 0};
1125 char cmdline[CMDLEN], *cmdp;
1131 /* Create a descriptor for the command line that starts
1132 GNUPLOT_X11. $DESCRIP doesn't work in this context... */
1135 * This does not work anymore since X11 option passing has been
1136 * changed to use execvp() in the DEFAULT_X11 case
1138 struct dsc$descriptor_s pgmdsc = { 0, DSC$K_DTYPE_T,
1142 strcpy(cmdline, optvec[optindex]);
1143 cmdp = cmdline + strlen(optvec[optindex]);
1144 while (optvec[++optindex] != NULL) {
1147 strcpy(cmdp, optvec[optindex]);
1148 cmdp += strlen(optvec[optindex]);
1151 pgmdsc.dsc$w_length = cmdp - cmdline;
1152 pgmdsc.dsc$a_pointer = cmdline;
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
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");
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);
1171 os_error(NO_CARET, "sys$getdviw failed");
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);
1179 os_error(NO_CARET, "lib$spawn failed");
1183 static int been_here = 0;
1185 GP_ATEXIT(X11_atexit);
1192 /* We use $QIO in order to avoid buffering problems, although it might
1193 * work as well with simple Fprintf calls.
1198 char buffer[512]; int status; struct iosb iosb;\
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); \
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); \
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))
1218 #define FFLUSH() /* nowt */
1219 #define BEFORE_GRAPHICS /* nowt */
1220 #define AFTER_TEXT /* nowt */
1227 sleep(2); /* Wait for subprocess to finish */
1228 sys$dassgn(X11_channel);
1236 /* do nothing until exit */
1243 /* common stuff, using macros defined above */
1249 static unsigned long windowid = 0;
1251 static enum set_encoding_id last_encoding = S_ENC_DEFAULT;
1253 BEFORE_GRAPHICS; /* kludge for crippled select */
1256 /* for VMS sake, keep as separate prints */
1257 PRINT1("G%d\n", X11_plot_number);
1260 /* if we know the outboard driver has stopped, restart it */
1261 if (ipc_back_fd == IPC_BACK_CLOSED) {
1267 /* send also XID of gnuplot window (<space> then raises it up) */
1269 char *window_env = getenv("WINDOWID");
1271 sscanf(window_env, "%lu", &windowid);
1274 PRINT2("G%d %lu\n", X11_plot_number, windowid);
1276 PRINT3("G%d %lu %i\n", X11_plot_number, windowid, getpid());
1278 #endif /* USE_MOUSE */
1280 #ifdef ULTRIX_KLUDGE
1284 if (encoding != last_encoding) {
1285 PRINT1("QE%d\n",encoding);
1286 last_encoding = encoding;
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) {
1297 PRINT1("QG%s\n",X11_default_font);
1300 default_font_size_known = TRUE;
1305 /* Force default font at start of plot */
1306 *X11_last_font_used = '\01';
1307 X11_set_default_font();
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.
1323 if (ipc_back_fd >= 0)
1326 /* Construct a mask showing which axes are active */
1330 for (i = FIRST_AXES; i < 2*SECOND_AXES; i++) {
1331 if (axis_array[i].ticmode != NO_TICS)
1332 axis_mask |= (1 << i);
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);
1361 #ifdef ULTRIX_KLUDGE
1366 AFTER_TEXT; /* kludge for crippled select */
1370 X11_move(unsigned int x, unsigned int y)
1372 PRINT2("M%04d%04d\n", x, y);
1376 X11_vector(unsigned int x, unsigned int y)
1378 PRINT2("V%04d%04d\n", x, y);
1382 X11_pointsize(double ps)
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));
1391 X11_linewidth(double lw)
1393 PRINT1("W%04d\n", (int) (lw * X11_linewidth_multiplier + 0.5));
1397 X11_linetype(int lt)
1399 PRINT1("L%04d\n", lt);
1403 X11_put_text(unsigned int x, unsigned int y, const char str[])
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);
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);
1418 X11_text_angle(int ang)
1420 PRINT1("A%d\n", ang);
1425 X11_justify_text(enum JUSTIFY mode)
1427 PRINT1("J%04d\n", mode);
1428 X11_last_justification = mode;
1433 X11_point(unsigned int x, unsigned int y, int number)
1435 PRINT3("P%d %d %d\n", number, x, y);
1439 X11_set_font(const char *fontname)
1441 PRINT1("QF%s\n", fontname?fontname:"");
1442 strncpy(X11_next_font_used,fontname?fontname:"",sizeof(X11_next_font_used)-1);
1447 X11_set_default_font()
1449 PRINT1("QD%s\n",X11_default_font);
1453 X11_fillbox(int style, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
1456 PRINT5("F%04d%04u%04u%04u%04u\n", style, x, y, w, h);
1462 X11_put_tmptext(int i, const char str[])
1465 PRINT2("t%04d%s\n", i, str);
1471 X11_set_ruler(int x, int y)
1474 PRINT2("r%04d%04d\n", x < 9999 ? x : 9999, y < 9999 ? y : 9999);
1480 X11_set_cursor(int c, int x, int y)
1483 PRINT3("u%04d%04d%04d\n", c, x, y);
1489 X11_set_clipboard(const char s[])
1497 #endif /* USE_MOUSE */
1501 transmit_gradient(gradient_struct *gradient, int cnt)
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 */
1509 fputs("\n", X11_ipc);
1512 fprintf(X11_ipc, "%s", gradient_entry_to_str(&(gradient[i])));
1514 fputs("\n", X11_ipc);
1519 X11_make_palette(t_sm_palette *palette)
1526 fprintf(stderr, "(X11_make_palette) 0 == X11_ipc\n");
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);
1535 switch(palette->colorMode) {
1536 case SMPAL_COLOR_MODE_GRAY:
1537 fprintf(X11_ipc,"%g\n", palette->gamma);
1539 case SMPAL_COLOR_MODE_RGB:
1540 fprintf(X11_ipc, "%d %d %d\n", palette->formulaR,
1541 palette->formulaG, palette->formulaB);
1543 case SMPAL_COLOR_MODE_GRADIENT:
1544 transmit_gradient(palette->gradient, palette->gradient_num);
1546 case SMPAL_COLOR_MODE_FUNCTIONS: {
1548 gradient_struct *gradient;
1549 gradient = approximate_palette(palette, -1, 0.01, &cnt);
1550 transmit_gradient(gradient, cnt);
1555 fprintf(stderr, "%s:%d ooops: Unknown colorMode '%c'.\n",
1556 __FILE__, __LINE__, (char)(palette->colorMode));
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.
1569 int char_count[256];
1571 void histogram(unsigned char c) {
1575 void dump_histogram(void) {
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];
1582 fprintf(stderr,"\n\ntotal: %d\n\n",sum);
1587 X11_set_color(t_colorspec *colorspec)
1589 if (colorspec->type == TC_RGB) {
1590 fputc(X11_GR_SET_RGBCOLOR, X11_ipc);
1591 PRINT1("%6.6x\n", colorspec->lt);
1596 if (colorspec->type == TC_LT) {
1597 fputc(X11_GR_SET_LINECOLOR, X11_ipc);
1598 PRINT1("%4d\n", colorspec->lt);
1603 if (colorspec->type != TC_FRAC)
1606 #ifndef BINARY_X11_POLYGON
1607 fputc(X11_GR_SET_COLOR, X11_ipc);
1608 PRINT1("%f\n", colorspec->value);
1614 unsigned short byte_remaining;
1615 float fgray = colorspec->value;
1617 fputc(X11_GR_SET_COLOR, X11_ipc);
1618 byte_remaining = sizeof(fgray);
1619 c_ptr = (char *) &fgray;
1621 while (byte_remaining) {
1623 char c_tmp = *c_ptr++ - SET_COLOR_TRANSLATION_CHAR;
1627 if ( (c_tmp == '\n') || (c_tmp == SET_COLOR_CODE_CHAR) || (c_tmp == '\0') ) {
1628 fputc(SET_COLOR_CODE_CHAR, X11_ipc);
1631 fputc(c_tmp, X11_ipc);
1635 fputc('\n', X11_ipc);
1638 #endif /* BINARY_X11_POLYGON */
1643 X11_filled_polygon(int points, gpiPoint *corners)
1646 #ifndef BINARY_X11_POLYGON
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);
1665 fputc('\n', X11_ipc);
1673 unsigned short i_buffer;
1674 unsigned short byte_remaining;
1675 unsigned point_remaining;
1677 /* Encode and transfer data to the pipe, one character at a time. */
1679 if (!points) return;
1681 fputc(X11_GR_FILLED_POLYGON, X11_ipc);
1682 i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
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.
1689 int_cache[0] = points;
1690 int_cache[1] = corners->style;
1691 byte_remaining = 2*sizeof(int_cache[0]);
1692 point_remaining = points + 1;
1695 while (point_remaining) {
1697 unsigned char *uc_ptr = (unsigned char *) int_cache;
1699 while (byte_remaining) {
1703 unsigned char uc_tmp = *uc_ptr++ - FILLED_POLYGON_TRANSLATION_CHAR;
1706 if ( (uc_tmp == '\n') || (uc_tmp == FILLED_POLYGON_CODE_CHAR) || (uc_tmp == '\0') ) {
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);
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. */
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);
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. */
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;
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);
1753 * Ethan A Merritt November 2003
1754 * - Support for enhanced text mode
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
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;
1777 double fontsize, double base,
1778 TBOOLEAN widthflag, TBOOLEAN showflag,
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);
1785 } else if (overprint == 4) {
1786 PRINT2("Tr%04d%04d\n", 0, 0);
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;
1803 * Write a string fragment and update current position.
1804 * We leave the real work up to gnuplot_x11!
1809 /* Send a command to print this string at current position */
1810 if (ENHx11_opened_string) {
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';
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);
1825 PRINT3("Tu%04d%04d%s\n", 0, (int)ENHx11_base, enhanced_text);
1827 ENHx11_opened_string = FALSE;
1832 ENHX11_put_text(unsigned int x, unsigned int y, const char *str)
1834 char *original_string = (char *)str;
1835 static char *initial_font = NULL;
1838 if (ignore_enhanced_text) {
1839 X11_put_text(x,y,str);
1846 /* if there are no magic characters, we should just be able
1847 * punt the string to X11_put_text()
1849 if (!strpbrk(str, "{}^_@&~")) {
1850 X11_put_text(x,y,str);
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));
1860 /* Tell gnuplot_x11 to set the current position to (x,y) */
1861 PRINT2("Tl%04d%04d\n", x, y);
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;
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,",");
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));
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.
1891 while (*(str = enhanced_recursion((char *)str, TRUE,
1892 ENHx11_font, ENHx11_fontsize,
1893 0.0, TRUE, TRUE, 0))) {
1894 (term->enhanced_flush)();
1896 /* I think we can only get here if *str == '}' */
1900 break; /* end of string */
1902 /* else carry on and process the rest of the string */
1905 /* Restore text justification flag after 2nd pass */
1907 PRINT1("J%04d\n", X11_last_justification);
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;
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);
1921 str = original_string;
1930 #if defined(WITH_IMAGE) || defined(BINARY_X11_POLYGON)
1932 X11_send_endianess(void)
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.
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);
1950 X11_image(unsigned M, unsigned N, coordval *image, gpiPoint *corner, t_imagecolor color_mode)
1953 /* Avoid using floats or formatted I/O. That's too slow for image data.
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.
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:
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.
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.
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.
1982 unsigned short i_buffer;
1983 unsigned coord_remaining;
1984 coordval *coord_ptr;
1986 /* Use formatted I/O to transfer image information. Hexadecimal uses less characters.
1988 * Note that X11 has different frame of reference (top left origin) than does Gnuplot
1989 * (bottom left origin)
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);
1996 /* Encode and transfer data to the pipe, one character at a time. */
1998 coord_remaining = M*N;
1999 if (color_mode == IC_RGB) coord_remaining *= 3;
2001 if (!coord_remaining) return;
2003 fputc(X11_GR_IMAGE, X11_ipc);
2004 i_buffer = BINARY_MAX_CHAR_PER_TRANSFER;
2007 while (coord_remaining) {
2009 unsigned short us_tmp;
2010 unsigned short byte_remaining;
2011 unsigned char *uc_ptr;
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.
2018 us_tmp = (unsigned short) ((*coord_ptr++)*IMAGE_PALETTE_VALUE_MAX + 0.5);
2021 byte_remaining = sizeof(us_tmp);
2022 uc_ptr = (unsigned char *) &us_tmp;
2024 while (byte_remaining) {
2028 unsigned char uc_tmp = *uc_ptr++ - IMAGE_TRANSLATION_CHAR;
2031 if ((uc_tmp == '\n') || (uc_tmp == IMAGE_CODE_CHAR) || (uc_tmp == '\0') ) {
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);
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. */
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);
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. */
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();}
2065 #endif /* WITH_IMAGE */
2067 #endif /* TERM_BODY */
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
2082 , X11_waitforinput, X11_put_tmptext, X11_set_ruler, X11_set_cursor, X11_set_clipboard
2084 , X11_make_palette, 0 /* X11_previous_palette */ ,
2085 X11_set_color, X11_filled_polygon
2089 , ENHX11_OPEN, ENHX11_FLUSH, do_enh_writec
2090 TERM_TABLE_END(x11_driver)
2093 #define LAST_TERM x11_driver
2095 #endif /* TERM_TABLE */
2096 #endif /* TERM_PROTO_ONLY */
2102 "?commands set terminal x11",
2103 "?set terminal 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.",
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}",
2121 " {size XX,YY} {position XX,YY}",
2122 " set terminal x11 {reset}",
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).",
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.",
2135 " set term x11 enhanced font \"arial,15\" ",
2136 " set title '{/=20 Big} Medium {/=5 Small}' ",
2138 " set term x11 enhanced font \"terminal-14\" ",
2139 " set title '{/=20 Big} Medium {/=5 Small}' ",
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.",
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",
2156 " Plot windows will automatically be closed at the end of the session",
2157 " unless the `-persist` option was given.",
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`.",
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.",
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.",
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.",
2177 " The size or aspect ratio of a plot may be changed by resizing the `gnuplot`",
2180 " Linewidths and pointsizes may be changed from within `gnuplot` with",
2181 " `set linestyle`.",
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.",
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`)",
2195 "?commands set terminal x11 x11_fonts",
2196 "?set terminal x11 x11_fonts",
2197 "?set term x11 x11_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.",
2205 " gnuplot*font: lucidasans-bold-12",
2206 " A new default font may be specified to the x11 driver from inside",
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",
2213 " -*-<font>-<weight>-<s>-*-*-<size>-*-*-*-*-*-<encoding>",
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`.",
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.",
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-*'",
2246 " The same syntax applies to the default font in Xresources settings,",
2248 " gnuplot*font: \\",
2249 " mbfont:-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0",
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:\".",
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",
2277 " `-noevents` does not process mouse and key events",
2278 " `-ctrlq ` closes window on ctrl-q rather than q",
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. \\\\",
2293 "#`-noevents` & does not process mouse and key events. \\\\",
2295 "#`-persist` & plot windows survive after main gnuplot program exits. \\\\",
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",
2308 "%`-novevents`@does not process mouse and key events",
2309 "%`-ctrlq`@closes window on ctrl-q rather than q",
2311 "%`-persist`@plot windows survive after main gnuplot program exits",
2314 " The options are shown above in their command-line syntax. When entered as",
2315 " resources in \".Xdefaults\", they require a different syntax.",
2318 " gnuplot*gray: on",
2319 " gnuplot*ctrlq: on",
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.",
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.",
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.",
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",
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.",
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",
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\\\\",
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",
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",
2410 " gnuplot -background coral",
2411 " to change the background color.",
2413 " gnuplot -xrm 'gnuplot*line1Color:blue'",
2414 " to override the first linetype color.",
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",
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\\\\",
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",
2468 "?commands set terminal x11 line_resources",
2469 "?set terminal x11 line_resources",
2470 "?set term x11 line_resources",
2471 "?x11 line_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",
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\\\\",
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",
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\\\\",
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",
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",
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.",
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).",
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.",
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).",
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.",
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.",
2605 " Example: on an 8bit PseudoColor visual you can force a private color map",
2606 " by specifying `gnuplot*maxcolors: 240` and `gnuplot*mincolors: 240`.",
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\\\\",
2617 "%@gnuplot*maxcolors: <integer number>",
2618 "%@gnuplot*mincolors: <integer number>",
2619 "%@gnuplot*visual: <visual name>",
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",
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.",
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'",
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\\\\",
2645 "%@gnuplot*exportselection: off",
2646 "%@gnuplot*fastrotate: on",
2647 "%@gnuplot*ctrlq: off",
2651 #endif /* TERM_HELP */