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