home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 May / cica_0595_4.zip / cica_0595_4 / UTIL / GPT34SRC / GPLT_X11.C < prev    next >
C/C++ Source or Header  |  1993-05-25  |  32KB  |  973 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: gplt_x11.c%v 3.38.2.118 1993/04/19 23:35:13 woo Exp woo $";
  3. #endif
  4.  
  5.  
  6. /*-----------------------------------------------------------------------------
  7.  *   gnuplot_x11 - X11 outboard terminal driver for gnuplot 3.3
  8.  *
  9.  *   Requires installation of companion inboard x11 driver in gnuplot/term.c
  10.  *
  11.  *   Acknowledgements: 
  12.  *      Chris Peterson (MIT)
  13.  *      Dana Chee (Bellcore) 
  14.  *      Arthur Smith (Cornell)
  15.  *      Hendri Hondorp (University of Twente, The Netherlands)
  16.  *      Bill Kucharski (Solbourne)
  17.  *      Charlie Kline (University of Illinois)
  18.  *      Yehavi Bourvine (Hebrew University of Jerusalem, Israel)
  19.  *      Russell Lang (Monash University, Australia)
  20.  *      O'Reilly & Associates: X Window System - Volumes 1 & 2
  21.  *
  22.  *   This code is provided as is and with no warranties of any kind.
  23.  *       
  24.  * There is a mailing list for gnuplot users. Note, however, that the
  25.  * newsgroup 
  26.  *    comp.graphics.gnuplot 
  27.  * is identical to the mailing list (they
  28.  * both carry the same set of messages). We prefer that you read the
  29.  * messages through that newsgroup, to subscribing to the mailing list.
  30.  * (If you can read that newsgroup, and are already on the mailing list,
  31.  * please send a message info-gnuplot-request@dartmouth.edu, asking to be
  32.  * removed from the mailing list.)
  33.  *
  34.  * The address for mailing to list members is
  35.  *       info-gnuplot@dartmouth.edu
  36.  * and for mailing administrative requests is 
  37.  *       info-gnuplot-request@dartmouth.edu
  38.  * The mailing list for bug reports is 
  39.  *       bug-gnuplot@dartmouth.edu
  40.  * The list of those interested in beta-test versions is
  41.  *       info-gnuplot-beta@dartmouth.edu
  42.  *---------------------------------------------------------------------------*/
  43.  
  44. #define DEFAULT_X11
  45. #if defined(VMS) || defined(CRIPPLED_SELECT)
  46. #undef DEFAULT_X11
  47. #endif
  48. #if defined(VMS) && defined(CRIPPLED_SELECT)
  49. Error. Incompatible options.
  50. #endif
  51.  
  52. #include <X11/Xos.h>
  53. #include <X11/Xlib.h>
  54. #include <X11/Xutil.h>
  55. #include <X11/Xatom.h>
  56. #include <X11/Xresource.h>
  57.  
  58. #include <stdio.h>
  59. #include <signal.h>
  60.  
  61. #ifdef BSD_TYPES
  62. #include <sys/bsdtypes.h>
  63. #endif /* BSD_TYPES */
  64.  
  65. #ifdef OLD_SELECT
  66. #define FD_SET(n, p)    ((p)->fds_bits[0] |= (1 << ((n) % 32)))
  67. #define FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1 << ((n) % 32)))
  68. #define FD_ISSET(n, p)  ((p)->fds_bits[0] & (1 << ((n) % 32)))
  69. #define FD_ZERO(p)      bzero((char *)(p), sizeof(*(p)))
  70. #endif /* OLD_SELECT */
  71.  
  72. #if !defined(VMS) && !defined(FD_SET)
  73. #include <sys/select.h>
  74. #endif /* !VMS && !FD_SET */
  75.  
  76. #ifdef SOLARIS
  77. #include <sys/systeminfo.h>
  78. #endif /* SOLARIS */
  79.  
  80.  
  81. #include <errno.h>
  82. extern int errno;
  83.  
  84. #define FallbackFont "fixed"
  85.  
  86. #define Ncolors 13
  87. unsigned long colors[Ncolors];
  88.  
  89. #define Nwidths 10
  90. unsigned int widths[Nwidths] = { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  91.  
  92. #define Ndashes 10
  93. char dashes[Ndashes][5];
  94.  
  95. Display *dpy; int scr; Window win, root;
  96. Visual *vis; GC gc = (GC)0; Pixmap pixmap; XFontStruct *font;
  97. unsigned int W = 640, H = 450; int D, gX = 100, gY = 100;
  98. unsigned int BorderWidth = 2;
  99. unsigned User_Size = 0, User_Position = 0; /* User specified? */
  100.  
  101.  
  102. Bool Mono = 0, Gray = 0, Rv = 0, Clear = 0;
  103. char Name[64] = "gnuplot";
  104. char Class[64] = "Gnuplot";
  105.  
  106. int cx=0, cy=0, vchar, nc = 0, ncalloc = 0;
  107. double xscale, yscale, pointsize;
  108. #define X(x) (int) (x * xscale)
  109. #define Y(y) (int) ((4095-y) * yscale)
  110. enum JUSTIFY { LEFT, CENTRE, RIGHT } jmode;
  111.  
  112. #define Nbuf 1024
  113. char buf[Nbuf], **commands = (char **)0;
  114.  
  115. FILE *X11_ipc;
  116. char X11_ipcpath[32];
  117.  
  118. #ifdef OW_BOTCH
  119. static void dummy() { XtInitialize; }
  120. #endif
  121.  
  122.  
  123. /*-----------------------------------------------------------------------------
  124.  *   main program 
  125.  *---------------------------------------------------------------------------*/
  126.  
  127. main(argc, argv) int argc; char *argv[]; {
  128.  
  129.    preset(argc, argv);
  130.    mainloop();
  131.    exit(0);
  132.  
  133.    }
  134.  
  135. /*-----------------------------------------------------------------------------
  136.  *   mainloop processing - process X events and input from gnuplot
  137.  *
  138.  *   Three different versions of main loop processing are provided to support
  139.  *   three different platforms.
  140.  * 
  141.  *   DEFAULT_X11:     use select() for both X events and input on stdin 
  142.  *                    from gnuplot inboard driver
  143.  *
  144.  *   CRIPPLED_SELECT: use select() to service X events and check during 
  145.  *                    select timeout for temporary plot file created
  146.  *                    by inboard driver
  147.  *
  148.  *   VMS:             use XNextEvent to service X events and AST to
  149.  *                    service input from gnuplot inboard driver on stdin 
  150.  *---------------------------------------------------------------------------*/
  151.  
  152.  
  153. #ifdef DEFAULT_X11
  154. /*-----------------------------------------------------------------------------
  155.  *    DEFAULT_X11 mainloop
  156.  *---------------------------------------------------------------------------*/
  157.  
  158. mainloop() {
  159.    int nf, nfds, cn = ConnectionNumber(dpy), in = fileno(stdin);
  160.    struct timeval timeout, *timer = (struct timeval *)0;
  161.    fd_set rset, tset;
  162.    unsigned long all = 0xffffffff;
  163.    XEvent xe;
  164.  
  165.    X11_ipc = stdin;
  166.  
  167.    FD_ZERO(&rset);
  168.    FD_SET(cn, &rset);
  169.  
  170.    FD_SET(in, &rset);
  171.    nfds = (cn > in) ? cn + 1 : in + 1;
  172.  
  173. #ifdef ISC22
  174. /* Added by Robert Eckardt, RobertE@beta.TP2.Ruhr-Uni-Bochum.de */
  175.    timeout.tv_sec  = 0;        /* select() in ISC2.2 needs timeout */
  176.    timeout.tv_usec = 300000;    /* otherwise input from gnuplot is */
  177.    timer = &timeout;        /* suspended til next X event. */
  178. #endif /* ISC22      (0.3s are short enough not to be noticed */
  179.  
  180.    while(1) {
  181.       tset = rset;
  182.       nf = select(nfds, &tset, (fd_set *)0, (fd_set *)0, timer);
  183.       if (nf < 0) {
  184.      if (errno == EINTR) continue;
  185.      fprintf(stderr, "gnuplot: select failed. errno:%d\n", errno);
  186.      exit(1);
  187.      }
  188.       nf > 0 && XNoOp(dpy);
  189.       if (FD_ISSET(cn, &tset)) {
  190.      while (XCheckMaskEvent(dpy, all, &xe)) {
  191.         (xe.type == ConfigureNotify)  && resize(&xe); 
  192.         }
  193.      }
  194.       FD_ISSET(in, &tset) && record();
  195.       }
  196.    }
  197.  
  198. #endif
  199.  
  200.  
  201. #ifdef CRIPPLED_SELECT
  202. /*-----------------------------------------------------------------------------
  203.  *    CRIPPLED_SELECT mainloop
  204.  *---------------------------------------------------------------------------*/
  205.  
  206. mainloop() {
  207.    int nf, nfds, cn = ConnectionNumber(dpy);
  208.    struct timeval timeout, *timer;
  209.    fd_set rset, tset;
  210.    unsigned long all = 0xffffffff;
  211.    XEvent xe;
  212.  
  213.    FD_ZERO(&rset);
  214.    FD_SET(cn, &rset);
  215.  
  216.    timeout.tv_sec = 1;
  217.    timeout.tv_usec = 0;
  218.    timer = &timeout;
  219.    sprintf(X11_ipcpath, "/tmp/Gnuplot_%d", getppid());
  220.    nfds = cn + 1;
  221.  
  222.    while(1) {
  223.       tset = rset;
  224.       nf = select(nfds, &tset, (fd_set *)0, (fd_set *)0, timer);
  225.       if (nf < 0) {
  226.      if (errno == EINTR) continue;
  227.      fprintf(stderr, "gnuplot: select failed. errno:%d\n", errno);
  228.      exit(1);
  229.      }
  230.       nf > 0 && XNoOp(dpy);
  231.       if (FD_ISSET(cn, &tset)) {
  232.      while (XCheckMaskEvent(dpy, all, &xe)) {
  233.         (xe.type == ConfigureNotify)  && resize(&xe); 
  234.         }
  235.      }
  236.       if ((X11_ipc = fopen(X11_ipcpath, "r"))) {
  237.      unlink(X11_ipcpath);
  238.      record();
  239.      fclose(X11_ipc);
  240.      }
  241.       }
  242.    }
  243. #endif /* CRIPPLED_SELECT */
  244.  
  245.  
  246. #ifdef VMS
  247. /*-----------------------------------------------------------------------------
  248.  *    VMS mainloop - Yehavi Bourvine - YEHAVI@VMS.HUJI.AC.IL
  249.  *---------------------------------------------------------------------------*/
  250.  
  251. /*  In VMS there is no decent Select(). hence, we have to loop inside
  252.  *  XGetNextEvent for getting the next X window event. In order to get input
  253.  *  from the master we assign a channel to SYS$INPUT and use AST's in order to
  254.  *  receive data. */
  255.  
  256. #include <iodef.h>
  257. char    STDIIN[] = "SYS$INPUT:";
  258. short   STDIINchannel, STDIINiosb[4];
  259. struct  { short size, type; char  *address; } STDIINdesc;
  260. char    STDIINbuffer[64];
  261. int     status;
  262.  
  263.  
  264. mainloop() {
  265.    XEvent xe;
  266.  
  267.    STDIINdesc.size = strlen(STDIIN); 
  268.    STDIINdesc.type = 0;
  269.    STDIINdesc.address = STDIIN;
  270.    status = sys$assign(&STDIINdesc, &STDIINchannel, 0, 0, 0);
  271.    if((status & 0x1) == 0)  exit(status); 
  272.    ast();
  273.  
  274.    for(;;) {
  275.       XNextEvent(dpy, &xe);
  276.       (xe.type == ConfigureNotify)  && resize(&xe); 
  277.       }
  278.    }
  279.  
  280. ast() {
  281.    int record();
  282.    int status = sys$qio(0, STDIINchannel, IO$_READVBLK, STDIINiosb, record,
  283.                 0, STDIINbuffer, sizeof(STDIINbuffer) -1,0, 0, 0, 0);
  284.    if((status & 0x1) == 0) exit(status);
  285.    }
  286. #endif /* VMS */
  287.  
  288.  
  289. #ifndef VMS
  290. /*-----------------------------------------------------------------------------
  291.  *   record - record new plot from gnuplot inboard X11 driver (Unix)
  292.  *---------------------------------------------------------------------------*/
  293.  
  294. record() {
  295.  
  296.    while (fgets(buf, Nbuf, X11_ipc)) {
  297.      if (*buf == 'G') {                           /* enter graphics mode */
  298.      if (commands) {
  299.         int n; for (n=0; n<nc; n++) free(commands[n]);
  300.         free(commands);
  301.         }
  302.      commands = (char **)0; nc = ncalloc = 0;
  303.          }
  304.       else if (*buf == 'E') { display(); break; } /* leave graphics mode */
  305.       else if (*buf == 'R') { exit(0); }          /* leave X11/x11 mode  */
  306.       else {                                      /* record command      */
  307.      char *p;
  308.      if (nc >= ncalloc) {
  309.         ncalloc = ncalloc*2 + 1;
  310.         commands = (commands)
  311.            ? (char **)realloc(commands, ncalloc * sizeof(char *))
  312.            : (char **)malloc(sizeof(char *));
  313.         }
  314.      p = (char *)malloc((unsigned)strlen(buf)+1);
  315.      if (!commands || !p) {
  316.         fprintf(stderr, "gnuplot: can't get memory. X11 aborted.\n");
  317.         exit(1);
  318.         }
  319.      commands[nc++] = strcpy(p, buf);
  320.      }
  321.       }
  322.    if (feof(X11_ipc) || ferror(X11_ipc)) exit(1);
  323.    }
  324.  
  325. #else    /* VMS */
  326. /*-----------------------------------------------------------------------------
  327.  *   record - record new plot from gnuplot inboard X11 driver (VMS)
  328.  *---------------------------------------------------------------------------*/
  329.  
  330. record() {
  331.    int    status;
  332.  
  333.    if((STDIINiosb[0] & 0x1) == 0) exit(STDIINiosb[0]);
  334.    STDIINbuffer[STDIINiosb[1]] = '\0';
  335.    strcpy(buf, STDIINbuffer);
  336.  
  337.    if (*buf == 'G') {                           /* enter graphics mode */
  338.       if (commands) {
  339.          int n; for (n=0; n<nc; n++) free(commands[n]);
  340.          free(commands);
  341.          }
  342.        commands = (char **)0; nc = ncalloc = 0;
  343.        }
  344.    else if (*buf == 'E') {                      /* leave graphics mode */
  345.       display(); 
  346.       }
  347.    else if (*buf == 'R') {                      /* leave x11/X11 mode  */
  348.        sys$cancel(STDIINchannel);
  349.        XCloseDisplay(dpy);
  350.        sys$delprc(0,0);      /* Somehow it doesn't drop itself... */
  351.        exit(1); 
  352.        }
  353.    else {                                       /* record command      */
  354.       char *p;
  355.       if (nc >= ncalloc) {
  356.      ncalloc = ncalloc*2 + 1;
  357.      commands = (commands)
  358.         ? (char **)realloc(commands, ncalloc * sizeof(char *))
  359.         : (char **)malloc(sizeof(char *));
  360.      }
  361.       p = (char *)malloc((unsigned)strlen(buf)+1);
  362.       if (!commands || !p) {
  363.      fprintf(stderr, "gnuplot: can't get memory. X11 aborted.\n");
  364.      exit(1);
  365.      }
  366.       commands[nc++] = strcpy(p, buf);
  367.       }
  368.    ast();
  369.    }
  370. #endif /* VMS */
  371.  
  372. /*-----------------------------------------------------------------------------
  373.  *   display - display last plot from gnuplot inboard X11 driver
  374.  *---------------------------------------------------------------------------*/
  375.  
  376. display() {
  377.    int n, x, y, sw, sl, lt, width, type, point, px, py;
  378.    char *buf, *str;
  379.  
  380.    if (!nc) return;
  381.  
  382.    /* set scaling factor between internal driver & window geometry */
  383.    xscale = (double)W / 4096.;  yscale = (double)H / 4096.;  
  384.  
  385.    /* create new pixmap & GC */
  386.    if (gc) { XFreeGC(dpy, gc); XFreePixmap(dpy, pixmap); }
  387.    pixmap = XCreatePixmap(dpy, root, W, H, D);
  388.    gc = XCreateGC(dpy, pixmap, 0, (XGCValues *)0);
  389.    XSetFont(dpy, gc, font->fid);
  390.  
  391.    /* set pixmap background */
  392.    XSetForeground(dpy, gc, colors[0]);
  393.    XFillRectangle(dpy, pixmap, gc, 0, 0, W, H);
  394.    XSetBackground(dpy, gc, colors[0]);
  395.  
  396.    /* set new pixmap as window background */
  397.    XSetWindowBackgroundPixmap(dpy, win, pixmap);
  398.  
  399.    /* top the window but don't put keyboard or mouse focus into it. */
  400.    XMapRaised(dpy, win);
  401.  
  402.    /* momentarily clear the window first if requested */
  403.    if (Clear) {
  404.       XClearWindow(dpy, win);
  405.       XFlush(dpy);
  406.       }
  407.  
  408.    /* loop over accumulated commands from inboard driver */
  409.    for (n=0; n<nc; n++) {
  410.       buf = commands[n];
  411.  
  412.       /*   X11_vector(x,y) - draw vector  */
  413.       if (*buf == 'V') { 
  414.      sscanf(buf, "V%4d%4d", &x, &y);  
  415.      XDrawLine(dpy, pixmap, gc, X(cx), Y(cy), X(x), Y(y));
  416.      cx = x; cy = y;
  417.      }
  418.  
  419.       /*   X11_move(x,y) - move  */
  420.       else if (*buf == 'M') 
  421.      sscanf(buf, "M%4d%4d", &cx, &cy);  
  422.  
  423.       /*   X11_put_text(x,y,str) - draw text   */
  424.       else if (*buf == 'T') { 
  425.      sscanf(buf, "T%4d%4d", &x, &y);  
  426.      str = buf + 9; sl = strlen(str) - 1;
  427.      sw = XTextWidth(font, str, sl);
  428.      switch(jmode) {
  429.         case LEFT:   sw = 0;     break;
  430.         case CENTRE: sw = -sw/2; break;
  431.         case RIGHT:  sw = -sw;   break;
  432.         }
  433.      XSetForeground(dpy, gc, colors[2]);
  434.      XDrawString(dpy, pixmap, gc, X(x)+sw, Y(y)+vchar/3, str, sl);
  435.      XSetForeground(dpy, gc, colors[lt+3]);
  436.      }
  437.  
  438.       /*   X11_justify_text(mode) - set text justification mode  */
  439.       else if (*buf == 'J') 
  440.      sscanf(buf, "J%4d", &jmode);
  441.  
  442.       /*   X11_linetype(type) - set line type  */
  443.       else if (*buf == 'L') { 
  444.      sscanf(buf, "L%4d", <);
  445.      lt = (lt%8)+2;
  446.      width = widths[lt];
  447.      if (dashes[lt][0]) {
  448.         type = LineOnOffDash;
  449.         XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
  450.         }
  451.      else {
  452.         type = LineSolid;
  453.         }
  454.      XSetForeground(dpy, gc, colors[lt+3]);
  455.      XSetLineAttributes( dpy,gc, width, type, CapButt, JoinBevel);
  456.        }
  457.  
  458.       /*   X11_point(number) - draw a point */
  459.       else if (*buf == 'P') { 
  460.       sscanf(buf, "P%1d%4d%4d", &point, &x, &y);  
  461.       if (point==7) {
  462.          /* set point size */
  463.          px = (int) (x * xscale * pointsize);
  464.          py = (int) (y * yscale * pointsize);
  465.          }
  466.       else {
  467.         if (type != LineSolid || width != 0) {  /* select solid line */
  468.            XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinBevel);
  469.            }
  470.         switch(point) {
  471.            case 0: /* dot */
  472.            XDrawLine(dpy,pixmap,gc, X(x), Y(y), X(x), Y(y));
  473.            break;
  474.            case 1: /* do diamond */ 
  475.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y), X(x), Y(y)-py);
  476.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)-py, X(x)+px, Y(y));
  477.            XDrawLine(dpy,pixmap,gc, X(x)+px, Y(y), X(x), Y(y)+py);
  478.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)+py, X(x)-px, Y(y));
  479.            XDrawLine(dpy,pixmap,gc, X(x), Y(y), X(x), Y(y));
  480.            break;
  481.            case 2: /* do plus */ 
  482.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y), X(x)+px, Y(y));
  483.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)-py, X(x), Y(y)+py);
  484.            break;
  485.            case 3: /* do box */ 
  486.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)-py, X(x)+px, Y(y)-py);
  487.            XDrawLine(dpy,pixmap,gc, X(x)+px, Y(y)-py, X(x)+px, Y(y)+py);
  488.            XDrawLine(dpy,pixmap,gc, X(x)+px, Y(y)+py, X(x)-px, Y(y)+py);
  489.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)+py, X(x)-px, Y(y)-py);
  490.            XDrawLine(dpy,pixmap,gc, X(x), Y(y), X(x), Y(y));
  491.            break;
  492.            case 4: /* do X */ 
  493.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)-py, X(x)+px, Y(y)+py);
  494.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)+py, X(x)+px, Y(y)-py);
  495.            break;
  496.            case 5: /* do triangle */ 
  497.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)-(4*px/3), 
  498.                  X(x)-(4*px/3), Y(y)+(2*py/3));
  499.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)-(4*px/3), 
  500.                  X(x)+(4*px/3), Y(y)+(2*py/3));
  501.            XDrawLine(dpy,pixmap,gc, X(x)-(4*px/3), Y(y)+(2*py/3), 
  502.                  X(x)+(4*px/3), Y(y)+(2*py/3));
  503.            XDrawLine(dpy,pixmap,gc, X(x), Y(y), X(x), Y(y));
  504.            break;
  505.            case 6: /* do star */ 
  506.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y), X(x)+px, Y(y));
  507.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)-py, X(x), Y(y)+py);
  508.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)-py, X(x)+px, Y(y)+py);
  509.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)+py, X(x)+px, Y(y)-py);
  510.            break;
  511.            }
  512.         if (type != LineSolid || width != 0) {  /* select solid line */
  513.            XSetLineAttributes(dpy, gc, width, type, CapButt, JoinBevel);
  514.            }
  515.         }
  516.      }
  517.       }
  518.  
  519.    /* trigger exposure of background pixmap */
  520.    XClearWindow(dpy,win);
  521.    XFlush(dpy);
  522.    }
  523.  
  524. /*-----------------------------------------------------------------------------
  525.  *   resize - rescale last plot if window resized
  526.  *---------------------------------------------------------------------------*/
  527.  
  528. resize(xce) XConfigureEvent *xce; {
  529.    int w = xce->width, h = xce->height;
  530.    
  531.    if (w>1 && h>1 && (w != W || h != H)) {
  532.       W = w; H = h;
  533.       display();
  534.       }
  535.    }
  536.  
  537.  
  538. /*-----------------------------------------------------------------------------
  539.  *   preset - determine options, open display, create window
  540.  *---------------------------------------------------------------------------*/
  541.  
  542. #define On(v) ( !strcmp(v,"on") || !strcmp(v,"true") || \
  543.         !strcmp(v,"On") || !strcmp(v,"True") )
  544.  
  545. #define AppDefDir "/usr/lib/X11/app-defaults"
  546. #ifndef MAXHOSTNAMELEN
  547. #define MAXHOSTNAMELEN 64
  548. #endif
  549.  
  550. static XrmDatabase dbCmd, dbApp, dbDef, dbEnv, db = (XrmDatabase)0;
  551.  
  552. char *pr_GetR(), *getenv(), *type[20];
  553. XrmValue value;
  554.  
  555. #define Nopt 27
  556. static XrmOptionDescRec options[] = {
  557.    {"-mono",             ".mono",             XrmoptionNoArg,   "on" },
  558.    {"-gray",             ".gray",             XrmoptionNoArg,   "on" },
  559.    {"-clear",            ".clear",            XrmoptionNoArg,   "on" },
  560.    {"-tvtwm",            ".tvtwm",            XrmoptionNoArg,   "on" },
  561.    {"-pointsize",        ".pointsize",        XrmoptionSepArg,  NULL },
  562.    {"-display",          ".display",          XrmoptionSepArg,  NULL },
  563.    {"-name",             ".name",             XrmoptionSepArg,  NULL },
  564.    {"-geometry",         "*geometry",         XrmoptionSepArg,  NULL },
  565.    {"-background",       "*background",       XrmoptionSepArg,  NULL },
  566.    {"-bg",               "*background",       XrmoptionSepArg,  NULL },
  567.    {"-foreground",       "*foreground",       XrmoptionSepArg,  NULL },
  568.    {"-fg",               "*foreground",       XrmoptionSepArg,  NULL },
  569.    {"-bordercolor",      "*bordercolor",      XrmoptionSepArg,  NULL },
  570.    {"-bd",               "*bordercolor",      XrmoptionSepArg,  NULL },
  571.    {"-borderwidth",      ".borderwidth",      XrmoptionSepArg,  NULL },
  572.    {"-bw",               ".borderwidth",      XrmoptionSepArg,  NULL },
  573.    {"-font",             "*font",             XrmoptionSepArg,  NULL },
  574.    {"-fn",               "*font",             XrmoptionSepArg,  NULL },
  575.    {"-reverse",          "*reverseVideo",     XrmoptionNoArg,   "on" },
  576.    {"-rv",               "*reverseVideo",     XrmoptionNoArg,   "on" },
  577.    {"+rv",               "*reverseVideo",     XrmoptionNoArg,   "off"},
  578.    {"-iconic",           "*iconic",           XrmoptionNoArg,   "on" },
  579.    {"-synchronous",      "*synchronous",      XrmoptionNoArg,   "on" },
  580.    {"-xnllanguage",      "*xnllanguage",      XrmoptionSepArg,  NULL },
  581.    {"-selectionTimeout", "*selectionTimeout", XrmoptionSepArg,  NULL },
  582.    {"-title",            ".title",            XrmoptionSepArg,  NULL },
  583.    {"-xrm",              NULL,                XrmoptionResArg,  NULL },
  584.    };
  585.  
  586. preset(argc, argv) int argc; char *argv[]; {
  587.    int Argc = argc; char **Argv = argv;
  588.  
  589.    char *display = getenv("DISPLAY"),  *home = getenv("HOME");
  590.    char *server_defaults, *env, buf[256];
  591.  
  592.    /*---set to ignore ^C and ^Z----------------------------------------------*/
  593.  
  594.    signal(SIGINT, SIG_IGN);
  595. #ifdef SIGTSTP
  596.    signal(SIGTSTP, SIG_IGN);
  597. #endif
  598.  
  599.    /*---prescan arguments for "-name"----------------------------------------*/
  600.  
  601.    while(++Argv, --Argc > 0) {
  602.       if (!strcmp(*Argv, "-name") && Argc > 1) {
  603.      strncpy(Name, Argv[1], 64);
  604.      strncpy(Class, Argv[1], 64);
  605.      if (Class[0] >= 'a' && Class[0] <= 'z') Class[0] -= 0x20;
  606.      }
  607.       }
  608.    Argc = argc; Argv = argv;
  609.  
  610.    /*---parse command line---------------------------------------------------*/
  611.  
  612.    XrmInitialize();
  613.    XrmParseCommand(&dbCmd, options, Nopt, Name, &Argc, Argv);
  614.    if (Argc > 1) {
  615.       fprintf(stderr, "\ngnuplot: bad option: %s\n", Argv[1]);
  616.       fprintf(stderr, "gnuplot: X11 aborted.\n");
  617.       exit(1);
  618.       }
  619.    if (pr_GetR(dbCmd, ".display")) display = value.addr;
  620.  
  621.    /*---open display---------------------------------------------------------*/
  622.  
  623.    dpy = XOpenDisplay(display); 
  624.    if (!dpy) {
  625.       fprintf(stderr, "\ngnuplot: unable to open display '%s'\n", display);
  626.       fprintf(stderr, "gnuplot: X11 aborted.\n");
  627.       exit(1);
  628.       }
  629.    scr = DefaultScreen(dpy);
  630.    vis = DefaultVisual(dpy,scr);
  631.    D = DefaultDepth(dpy,scr);
  632.    root = DefaultRootWindow(dpy);
  633.    server_defaults = XResourceManagerString(dpy);
  634.  
  635.    /*---get application defaults--(subset of Xt processing)------------------*/
  636.  
  637.    sprintf(buf, "%s/%s", AppDefDir, "Gnuplot");
  638.    dbApp = XrmGetFileDatabase(buf);
  639.    XrmMergeDatabases(dbApp, &db);
  640.  
  641.    /*---get server or ~/.Xdefaults-------------------------------------------*/
  642.  
  643.    if (server_defaults)
  644.       dbDef = XrmGetStringDatabase(server_defaults);
  645.    else {
  646.       sprintf(buf, "%s/.Xdefaults", home);
  647.       dbDef = XrmGetFileDatabase(buf);
  648.       }
  649.    XrmMergeDatabases(dbDef, &db);
  650.  
  651.    /*---get XENVIRONMENT or  ~/.Xdefaults-hostname---------------------------*/
  652.  
  653. #ifndef VMS
  654.    if (env = getenv("XENVIRONMENT")) 
  655.       dbEnv = XrmGetFileDatabase(env);
  656.    else {
  657.       char *p, host[MAXHOSTNAMELEN];
  658. #ifdef SOLARIS
  659.       if (sysinfo(SI_HOSTNAME, host, MAXHOSTNAMELEN) < 0) {
  660.          fprintf(stderr, "gnuplot: sysinfo failed. X11 aborted.\n");
  661. #else
  662.       if (gethostname(host, MAXHOSTNAMELEN) < 0) {
  663.          fprintf(stderr, "gnuplot: gethostname failed. X11 aborted.\n");
  664. #endif /* SOLARIS */
  665.      exit(1);
  666.      }
  667.       if (p = index(host, '.')) *p = '\0';
  668.       sprintf(buf, "%s/.Xdefaults-%s", home, host);
  669.       dbEnv = XrmGetFileDatabase(buf);
  670.       }
  671.    XrmMergeDatabases(dbEnv, &db);
  672. #endif   /* not VMS */
  673.  
  674.    /*---merge command line options-------------------------------------------*/
  675.  
  676.    XrmMergeDatabases(dbCmd, &db);
  677.  
  678.    /*---set geometry, font, colors, line widths, dash styles, point size-----*/
  679.  
  680.    pr_geometry();
  681.    pr_font();
  682.    pr_color();
  683.    pr_width();
  684.    pr_dashes();
  685.    pr_pointsize();
  686.  
  687.    /*---create window--------------------------------------------------------*/
  688.  
  689.    pr_window();
  690.  
  691.    } 
  692.  
  693. /*-----------------------------------------------------------------------------
  694.  *   pr_GetR - get resource from database using "-name" option (if any)
  695.  *---------------------------------------------------------------------------*/
  696.  
  697. char *
  698. pr_GetR(db, resource) XrmDatabase db; char *resource; {
  699.    char name[128], class[128], *rc;
  700.  
  701.    strcpy(name, Name); strcat(name, resource);
  702.    strcpy(class, Class); strcat(class, resource);
  703.    rc = XrmGetResource(db, name, class, type, &value)
  704.       ? (char *)value.addr 
  705.       : (char *)0;
  706.    return(rc);
  707.    }
  708.  
  709. /*-----------------------------------------------------------------------------
  710.  *   pr_color - determine color values
  711.  *---------------------------------------------------------------------------*/
  712.  
  713. char color_keys[Ncolors][30] =   { 
  714.    "background", "bordercolor", "text", "border", "axis", 
  715.    "line1", "line2", "line3",  "line4", 
  716.    "line5", "line6", "line7",  "line8" 
  717.    };
  718. char color_values[Ncolors][30] = { 
  719.    "white", "black",  "black",  "black",  "black", 
  720.    "red",   "green",  "blue",   "magenta", 
  721.    "cyan",  "sienna", "orange", "coral" 
  722.    };
  723. char gray_values[Ncolors][30] = { 
  724.    "black",   "white",  "white",  "gray50", "gray50",
  725.    "gray100", "gray60", "gray80", "gray40", 
  726.    "gray90",  "gray50", "gray70", "gray30" 
  727.    };
  728.  
  729. pr_color() {
  730.    unsigned long black = BlackPixel(dpy, scr), white = WhitePixel(dpy,scr);
  731.    char option[20], color[30], *v, *type; 
  732.    XColor xcolor;
  733.    Colormap cmap;
  734.    double intensity = -1;
  735.    int n;
  736.  
  737.    pr_GetR(db, ".mono")         && On(value.addr) && Mono++;
  738.    pr_GetR(db, ".gray")         && On(value.addr) && Gray++;
  739.    pr_GetR(db, ".reverseVideo") && On(value.addr) && Rv++;
  740.  
  741.    if (!Gray && (vis->class == GrayScale || vis->class == StaticGray)) Mono++;
  742.  
  743.    if (!Mono) {
  744.       cmap = DefaultColormap(dpy, scr);
  745.       type = (Gray) ? "Gray" : "Color";
  746.  
  747.       for (n=0; n<Ncolors; n++) {
  748.      strcpy(option, ".");
  749.      strcat(option, color_keys[n]);
  750.      (n > 1) && strcat(option, type);
  751.      v = pr_GetR(db, option) 
  752.          ? value.addr
  753.          : ((Gray) ? gray_values[n] : color_values[n]);
  754.  
  755.      if (sscanf(v,"%30[^,],%lf", color, &intensity) == 2) {
  756.         if (intensity < 0 || intensity > 1) {
  757.            fprintf(stderr, "\ngnuplot: invalid color intensity in '%s'\n",
  758.                        color);
  759.            intensity = 1;
  760.            }
  761.         }
  762.      else { 
  763.         strcpy(color, v);
  764.         intensity = 1;
  765.         }
  766.  
  767.      if (!XParseColor(dpy, cmap, color, &xcolor)) {
  768.         fprintf(stderr, "\ngnuplot: unable to parse '%s'. Using black.\n",
  769.                     color);
  770.         colors[n] = black;
  771.         }
  772.      else {
  773.         xcolor.red *= intensity;
  774.         xcolor.green *= intensity;
  775.         xcolor.blue *= intensity;
  776.         if (XAllocColor(dpy, cmap, &xcolor)) {
  777.            colors[n] = xcolor.pixel;
  778.            }
  779.         else {
  780.            fprintf(stderr, "\ngnuplot: can't allocate '%s'. Using black.\n",
  781.                         v);
  782.            colors[n] = black;
  783.            }
  784.         }
  785.      }
  786.       }
  787.    else {
  788.       colors[0] = (Rv) ? black : white ;
  789.       for (n=1; n<Ncolors; n++)  colors[n] = (Rv) ? white : black;
  790.       }
  791.    }
  792.  
  793. /*-----------------------------------------------------------------------------
  794.  *   pr_dashes - determine line dash styles 
  795.  *---------------------------------------------------------------------------*/
  796.  
  797. char dash_keys[Ndashes][10] =   { 
  798.    "border", "axis",
  799.    "line1", "line2", "line3",  "line4", "line5", "line6", "line7",  "line8" 
  800.    };
  801.  
  802. char dash_mono[Ndashes][10] =   { 
  803.    "0", "16",
  804.    "0", "42", "13",  "44", "15", "4441", "42",  "13" 
  805.    };
  806.  
  807. char dash_color[Ndashes][10] =   { 
  808.    "0", "16",
  809.    "0", "0", "0", "0", "0", "0", "0", "0" 
  810.    };
  811.  
  812. pr_dashes() {
  813.    int n, j, l, ok;
  814.    char option[20], *v; 
  815.    for (n=0; n<Ndashes; n++) {
  816.       strcpy(option, ".");
  817.       strcat(option, dash_keys[n]);
  818.       strcat(option, "Dashes");
  819.       v = pr_GetR(db, option) 
  820.       ? value.addr
  821.       : ((Mono) ? dash_mono[n] : dash_color[n]);
  822.       l = strlen(v);
  823.       if (l == 1 && *v == '0') {
  824.      dashes[n][0] = (unsigned char)0;
  825.      continue;
  826.      }
  827.       for (ok=0, j=0; j<l; j++) { v[j] >= '1' && v[j] <= '9' && ok++; }
  828.       if (ok != l || (ok != 2 && ok != 4)) {
  829.      fprintf(stderr, "gnuplot: illegal dashes value %s:%s\n", option, v);
  830.      dashes[n][0] = (unsigned char)0;
  831.      continue;
  832.      }
  833.       for(j=0; j<l; j++) {
  834.      dashes[n][j] = (unsigned char) (v[j] - '0');
  835.      }
  836.       dashes[n][l] = (unsigned char)0;
  837.       }
  838.    }
  839.  
  840. /*-----------------------------------------------------------------------------
  841.  *   pr_font - determine font          
  842.  *---------------------------------------------------------------------------*/
  843.  
  844. pr_font() {
  845.    char *fontname = pr_GetR(db, ".font");
  846.  
  847.    if (!fontname) fontname = FallbackFont;
  848.    font = XLoadQueryFont(dpy, fontname);
  849.    if (!font) {
  850.       fprintf(stderr, "\ngnuplot: can't load font '%s'\n", fontname);
  851.       fprintf(stderr, "gnuplot: using font '%s' instead.\n", FallbackFont);
  852.       font = XLoadQueryFont(dpy, FallbackFont);
  853.       if (!font) {
  854.      fprintf(stderr, "gnuplot: can't load font '%s'\n", FallbackFont);
  855.      fprintf(stderr, "gnuplot: no useable font - X11 aborted.\n");
  856.          exit(1);
  857.      }
  858.       }
  859.    vchar = font->ascent + font->descent;
  860.    }
  861.  
  862. /*-----------------------------------------------------------------------------
  863.  *   pr_geometry - determine window geometry      
  864.  *---------------------------------------------------------------------------*/
  865.  
  866. pr_geometry() {
  867.    char *geometry = pr_GetR(db, ".geometry");
  868.    int x, y, flags;
  869.    unsigned int w, h; 
  870.  
  871.    if (geometry) {
  872.       flags = XParseGeometry(geometry, &x, &y, &w, &h);
  873.       if (flags & WidthValue)  User_Size = 1, W = w;
  874.       if (flags & HeightValue) User_Size = 1, H = h;
  875.       if (flags & XValue) {
  876.          if (flags & XNegative)
  877.             x += DisplayWidth(dpy,scr) - W - BorderWidth*2;
  878.          User_Position = 1, gX = x;
  879.          }
  880.       if (flags & YValue) {
  881.          if (flags & YNegative)
  882.             y += DisplayHeight(dpy,scr) - H - BorderWidth*2;
  883.          User_Position = 1, gY = y;
  884.          }
  885.       }
  886.    }
  887.  
  888. /*-----------------------------------------------------------------------------
  889.  *   pr_pointsize - determine size of points for 'points' plotting style
  890.  *---------------------------------------------------------------------------*/
  891.  
  892. pr_pointsize() {
  893.    char *p = pr_GetR(db, ".pointsize") ? value.addr : "1.0" ;
  894.  
  895.    if (sscanf(p,"%lf", &pointsize) == 1) {
  896.       if (pointsize <= 0 || pointsize > 10) {
  897.      fprintf(stderr, "\ngnuplot: invalid pointsize '%s'\n", p);
  898.      pointsize = 1;
  899.      }
  900.       }
  901.    else { 
  902.       fprintf(stderr, "\ngnuplot: invalid pointsize '%s'\n", p);
  903.       pointsize = 1;
  904.       }
  905.    }
  906.  
  907. /*-----------------------------------------------------------------------------
  908.  *   pr_width - determine line width values
  909.  *---------------------------------------------------------------------------*/
  910.  
  911. char width_keys[Nwidths][30] =   { 
  912.    "border", "axis",
  913.    "line1", "line2", "line3",  "line4", "line5", "line6", "line7",  "line8" 
  914.    };
  915.  
  916. pr_width() {
  917.    int n;
  918.    char option[20], *v; 
  919.    for (n=0; n<Nwidths; n++) {
  920.       strcpy(option, ".");
  921.       strcat(option, width_keys[n]);
  922.       strcat(option, "Width");
  923.       if (v = pr_GetR(db, option)) {
  924.      if ( *v < '0' || *v > '4' || strlen(v) > 1)
  925.         fprintf(stderr, "gnuplot: illegal width value %s:%s\n", option, v);
  926.      else 
  927.         widths[n] = (unsigned int)atoi(v);
  928.      }
  929.       }
  930.    }
  931.  
  932. /*-----------------------------------------------------------------------------
  933.  *   pr_window - create window 
  934.  *---------------------------------------------------------------------------*/
  935.  
  936. pr_window() {
  937.    char *title =  pr_GetR(db, ".title");
  938.    static XSizeHints hints;
  939.    int Tvtwm = 0;
  940.  
  941.    win = XCreateSimpleWindow(dpy, root, gX, gY, W, H, BorderWidth,
  942.                              colors[1], colors[0]);
  943.  
  944.    pr_GetR(db, ".clear") && On(value.addr) && Clear++;
  945.    pr_GetR(db, ".tvtwm") && On(value.addr) && Tvtwm++;
  946.  
  947.    if (!Tvtwm) {
  948.       hints.flags = (User_Position ? USPosition : PPosition);
  949.       hints.flags |= (User_Size ? USSize : PSize);
  950.       }
  951.    else {
  952.       hints.flags = PPosition;
  953.       }
  954.    hints.x = gX; hints.y = gY;        
  955.    hints.width = W; hints.height = H;
  956.  
  957.    XSetNormalHints(dpy, win, &hints);
  958.  
  959.    if (pr_GetR(db, ".iconic") && On(value.addr)) {
  960.       XWMHints wmh;
  961.  
  962.       wmh.flags = StateHint ;
  963.       wmh.initial_state = IconicState;
  964.       XSetWMHints(dpy, win, &wmh);
  965.       } 
  966.  
  967.    XStoreName(dpy, win, ((title) ? title : Class));
  968.  
  969.    XSelectInput(dpy, win, StructureNotifyMask);
  970.    XMapWindow(dpy, win);
  971.    
  972.    }
  973.