home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / GRAPHICS / gnuplot32x.tar.Z / gnuplot32x.tar / os9gnuplot3 / gnuplot_X11.c < prev    next >
C/C++ Source or Header  |  1992-06-25  |  19KB  |  612 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: gnuplot_x11.c,v 3.26 92/03/24 22:35:52 woo Exp Locker: woo $";
  3. #endif
  4.  
  5. /* small modifications for OS-9 68K neccesary. See for OSK define!
  6.  *
  7.  * changed 25.6.1992 by Dietmar Budelsky
  8.  *
  9.  * budelsky@snert.ikp.uni-koeln.de or
  10.  * budelsky@haegar.ikp.uni-koeln.de
  11.  */
  12.  
  13. /*-----------------------------------------------------------------------------
  14.  *   gnuplot_x11 - X11 outboard terminal driver for gnuplot 3
  15.  *
  16.  *   Requires installation of companion inboard x11 driver in gnuplot/term.c
  17.  *
  18.  *   Acknowledgements: 
  19.  *      Chris Peterson (MIT)
  20.  *      Dana Chee (Bellcore) 
  21.  *      Arthur Smith (Cornell)
  22.  *      Hendri Hondorp (University of Twente, The Netherlands)
  23.  *      Bill Kucharski (Solbourne)
  24.  *      Charlie Kline (University of Illinois)
  25.  *      O'Reilly & Associates: X Window System - Volumes 1 & 2
  26.  *
  27.  *   This code is provided as is and with no warranties of any kind.
  28.  *       
  29.  *   Ed Kubaitis (ejk@uiuc.edu)
  30.  *   Computing & Communications Services Office 
  31.  *   University of Illinois, Urbana
  32.  *---------------------------------------------------------------------------*/
  33.  
  34. #include <X11/Xos.h>
  35. #include <X11/Xlib.h>
  36. #include <X11/Xutil.h>
  37. #include <X11/Xatom.h>
  38. #include <X11/Xresource.h>
  39.  
  40. #include <stdio.h>
  41. #include <signal.h>
  42.  
  43. #ifndef FD_SET
  44. #ifndef OLD_SELECT
  45. #include <sys/select.h>
  46. #else   /* OLD_SELECT */
  47. #define FD_SET(n, p)    ((p)->fds_bits[0] |= (1 << ((n) % 32)))
  48. #define FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1 << ((n) % 32)))
  49. #define FD_ISSET(n, p)  ((p)->fds_bits[0] & (1 << ((n) % 32)))
  50. #define FD_ZERO(p)      bzero((char *)(p), sizeof(*(p)))
  51. #endif  /* OLD_SELECT */
  52. #endif  /* FD_SET */
  53.  
  54. #include <errno.h>
  55. extern int errno;
  56.  
  57. #define FallbackFont "fixed"
  58. #define Ncolors 13
  59. unsigned long colors[Ncolors];
  60.  
  61. char dashes[10][5] = { {0}, {1,6,0}, 
  62.    {0}, {4,2,0}, {1,3,0}, {4,4,0}, {1,5,0}, {4,4,4,1,0}, {4,2,0}, {1,3,0}
  63.    };
  64.  
  65. Display *dpy; int scr; Window win, root;
  66. Visual *vis; GC gc = (GC)0; Pixmap pixmap; XFontStruct *font;
  67. unsigned int W = 640, H = 450; int D, gX = 100, gY = 100;
  68.  
  69. Bool Mono = 0, Gray = 0, Rv = 0, Clear = 0;
  70. char Name[64] = "gnuplot";
  71. char Class[64] = "Gnuplot";
  72.  
  73. int cx=0, cy=0, vchar, nc = 0, ncalloc = 0;
  74. double xscale, yscale;
  75. #define X(x) (int) (x * xscale)
  76. #define Y(y) (int) ((4095-y) * yscale)
  77. enum JUSTIFY { LEFT, CENTRE, RIGHT } jmode;
  78.  
  79. #define Nbuf 1024
  80. char buf[Nbuf], **commands = (char **)0;
  81.  
  82. FILE *X11_ipc = stdin;
  83. char X11_ipcpath[32];
  84.  
  85.  
  86. /*-----------------------------------------------------------------------------
  87.  *   main program 
  88.  *---------------------------------------------------------------------------*/
  89.  
  90. main(argc, argv) int argc; char *argv[]; {
  91.  
  92.    preset(argc, argv);
  93.    mainloop();
  94.    exit(0);
  95.  
  96.    }
  97.  
  98. /*-----------------------------------------------------------------------------
  99.  *   mainloop - process X events and input from gnuplot
  100.  *
  101.  *   On systems with a fully implemented select(), select is used (without
  102.  *   timeout) to sense both input from the X server network connection and
  103.  *   pipe input from gnuplot. On platforms with an incomplete or faulty 
  104.  *   select(), select (with timeout) is used for the server, and a temporary 
  105.  *   file rather than a pipe is used for gnuplot input.
  106.  *---------------------------------------------------------------------------*/
  107.  
  108. mainloop() {
  109.    int nf, nfds, cn = ConnectionNumber(dpy), in = fileno(X11_ipc);
  110.    struct timeval timeout, *timer = (struct timeval *)0;
  111.    fd_set rset, tset;
  112.    unsigned long all = 0xffffffff;
  113.    XEvent xe;
  114.  
  115.    FD_ZERO(&rset);
  116.    FD_SET(cn, &rset);
  117.  
  118. #ifndef CRIPPLED_SELECT
  119.    FD_SET(in, &rset);
  120.    nfds = (cn > in) ? cn + 1 : in + 1;
  121. #else  /* CRIPPLED_SELECT */
  122.    timeout.tv_sec = 1;
  123.    timeout.tv_usec = 0;
  124.    timer = &timeout;
  125.    sprintf(X11_ipcpath, "/tmp/Gnuplot_%d", getppid());
  126.    nfds = cn + 1;
  127. #endif /* CRIPPLED_SELECT */
  128.  
  129.    while(1) {
  130.       tset = rset;
  131.       nf = select(nfds, &tset, (fd_set *)0, (fd_set *)0, timer);
  132.       if (nf < 0) {
  133.      if (errno == EINTR) continue;
  134.      fprintf(stderr, "gnuplot: select failed. errno:%d\n", errno);
  135.      exit(1);
  136.      }
  137.       nf > 0 && XNoOp(dpy);
  138.       if (FD_ISSET(cn, &tset)) {
  139.      while (XCheckMaskEvent(dpy, all, &xe)) {
  140.         (xe.type == ConfigureNotify)  && resize(&xe); 
  141.         }
  142.      }
  143. #ifndef CRIPPLED_SELECT
  144.       FD_ISSET(in, &tset) && accept();
  145. #else  /* CRIPPLED_SELECT */
  146.       if ((X11_ipc = fopen(X11_ipcpath, "r"))) {
  147.      unlink(X11_ipcpath);
  148.      accept();
  149.      fclose(X11_ipc);
  150.      }
  151. #endif /* CRIPPLED_SELECT */
  152.  
  153. #ifdef OSK
  154. /* CRIPPLED_SELECT very UNIX specific, so not possible under OSK.
  155.  *
  156.  * select() for further plots hangs on OSK until the old plot is
  157.  * "touched" on the screen.
  158.  * To avoid it, the timeout must be set for OSK   a f t e r
  159.  * the first plot, because the first plot with timeout would
  160.  * be produced   v e r y   slowly.
  161.  *
  162.  * changes made by Dietmar Budelsky
  163.  */ 
  164.       if (!timer) {
  165.          timeout.tv_sec = 1;
  166.          timeout.tv_usec = 0;
  167.          timer = &timeout;
  168.       }
  169. #endif /* OSK */
  170.  
  171.       }
  172.    }
  173.  
  174. /*-----------------------------------------------------------------------------
  175.  *   accept - accept & record new plot from gnuplot inboard X11 driver
  176.  *---------------------------------------------------------------------------*/
  177.  
  178. accept() {
  179.  
  180.    while (fgets(buf, Nbuf, X11_ipc)) {
  181.      if (*buf == 'G') {                           /* enter graphics mode */
  182.      if (commands) {
  183.         int n; for (n=0; n<nc; n++) free(commands[n]);
  184.         free(commands);
  185.         }
  186.      commands = (char **)0; nc = ncalloc = 0;
  187.          }
  188.       else if (*buf == 'E') { display(); break; } /* leave graphics mode */
  189.       else if (*buf == 'R') { exit(0); }          /* leave X11/x11 mode  */
  190.       else {                                      /* record command      */
  191.      char *p;
  192.      if (nc >= ncalloc) {
  193.         ncalloc = ncalloc*2 + 1;
  194.         commands = (commands)
  195.            ? (char **)realloc(commands, ncalloc * sizeof(char *))
  196.            : (char **)malloc(sizeof(char *));
  197.         }
  198.      p = (char *)malloc((unsigned)strlen(buf)+1);
  199.      if (!commands || !p) {
  200.         fprintf(stderr, "gnuplot: can't get memory. X11 aborted.\n");
  201.         exit(1);
  202.         }
  203.      commands[nc++] = strcpy(p, buf);
  204.      }
  205.       }
  206.    if (feof(X11_ipc) || ferror(X11_ipc)) exit(1);
  207.    }
  208.  
  209. /*-----------------------------------------------------------------------------
  210.  *   display - display last plot from gnuplot inboard X11 driver
  211.  *---------------------------------------------------------------------------*/
  212.  
  213. display() {
  214.    int n, x, y, sw, sl, lt, width, type;
  215.    char *buf, *str;
  216.  
  217.    if (!nc) return;
  218.  
  219.    /* set scaling factor between internal driver & window geometry */
  220.    xscale = (double)W / 4096.;  yscale = (double)H / 4096.;  
  221.  
  222.    /* create new pixmap & GC */
  223.    if (gc) { XFreeGC(dpy, gc); XFreePixmap(dpy, pixmap); }
  224.    pixmap = XCreatePixmap(dpy, root, W, H, D);
  225.    gc = XCreateGC(dpy, pixmap, 0, (XGCValues *)0);
  226.    XSetFont(dpy, gc, font->fid);
  227.  
  228.    /* set pixmap background */
  229.    XSetForeground(dpy, gc, colors[0]);
  230.    XFillRectangle(dpy, pixmap, gc, 0, 0, W, H);
  231.    XSetBackground(dpy, gc, colors[0]);
  232.  
  233.    /* set new pixmap as window background */
  234.    XSetWindowBackgroundPixmap(dpy, win, pixmap);
  235.  
  236.    /* momentarily clear the window first if requested */
  237.    if (Clear) {
  238.       XClearWindow(dpy, win);
  239.       XFlush(dpy);
  240.       }
  241.  
  242.    /* loop over accumulated commands from inboard driver */
  243.    for (n=0; n<nc; n++) {
  244.       buf = commands[n];
  245.  
  246.       /*   X11_vector(x,y) - draw vector  */
  247.       if (*buf == 'V') { 
  248.      sscanf(buf, "V%4d%4d", &x, &y);  
  249.      XDrawLine(dpy, pixmap, gc, X(cx), Y(cy), X(x), Y(y));
  250.      cx = x; cy = y;
  251.      }
  252.  
  253.       /*   X11_move(x,y) - move  */
  254.       else if (*buf == 'M') 
  255.      sscanf(buf, "M%4d%4d", &cx, &cy);  
  256.  
  257.       /*   X11_put_text(x,y,str) - draw text   */
  258.       else if (*buf == 'T') { 
  259.      sscanf(buf, "T%4d%4d", &x, &y);  
  260.      str = buf + 9; sl = strlen(str) - 1;
  261.      sw = XTextWidth(font, str, sl);
  262.      switch(jmode) {
  263.         case LEFT:   sw = 0;     break;
  264.         case CENTRE: sw = -sw/2; break;
  265.         case RIGHT:  sw = -sw;   break;
  266.         }
  267.      XSetForeground(dpy, gc, colors[2]);
  268.      XDrawString(dpy, pixmap, gc, X(x)+sw, Y(y)+vchar/3, str, sl);
  269.      XSetForeground(dpy, gc, colors[lt+3]);
  270.      }
  271.  
  272.       /*   X11_justify_text(mode) - set text justification mode  */
  273.       else if (*buf == 'J') 
  274.      sscanf(buf, "J%4d", &jmode);
  275.  
  276.       /*   X11_linetype(type) - set line type  */
  277.       else if (*buf == 'L') { 
  278.      sscanf(buf, "L%4d", <);
  279.      lt = (lt%8)+2;
  280.      width = (lt == 0) ? 2 : 0;
  281.      if (!Mono) {
  282.         if (lt != 1) 
  283.            type = LineSolid;
  284.         else {
  285.            type = LineOnOffDash;
  286.            XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
  287.            }
  288.         XSetForeground(dpy, gc, colors[lt+3]);
  289.         }
  290.      else {
  291.         type  = (lt == 0 || lt == 2) ? LineSolid : LineOnOffDash;
  292.         if (dashes[lt][0])
  293.            XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
  294.         }
  295.      XSetLineAttributes( dpy,gc, width, type, CapButt, JoinBevel);
  296.      }
  297.       }
  298.  
  299.    /* trigger exposure of background pixmap */
  300.    XClearWindow(dpy,win);
  301.    XFlush(dpy);
  302.    }
  303.  
  304. /*-----------------------------------------------------------------------------
  305.  *   resize - rescale last plot if window resized
  306.  *---------------------------------------------------------------------------*/
  307.  
  308. Bool init = True;
  309.  
  310. resize(xce) XConfigureEvent *xce; {
  311.    if (!init || xce->width != W || xce->height != H) {
  312.       W = xce->width; H = xce->height;
  313.       display();
  314.       init = True;
  315.       }
  316.    }
  317.  
  318.  
  319. /*-----------------------------------------------------------------------------
  320.  *   preset - determine options, open display, create window
  321.  *---------------------------------------------------------------------------*/
  322.  
  323. #define On(v) ( !strcmp(v,"on") || !strcmp(v,"true") || \
  324.         !strcmp(v,"On") || !strcmp(v,"True") )
  325.  
  326. #define AppDefDir "/usr/lib/X11/app-defaults"
  327. #ifndef MAXHOSTNAMELEN
  328. #define MAXHOSTNAMELEN 64
  329. #endif
  330.  
  331. static XrmDatabase dbCmd, dbApp, dbDef, dbEnv, db = (XrmDatabase)0;
  332.  
  333. char *pr_GetR(), *getenv(), *type[20];
  334. XrmValue value;
  335.  
  336. #define Nopt 25
  337. static XrmOptionDescRec options[] = {
  338.    {"-mono",             ".mono",             XrmoptionNoArg,   "on" },
  339.    {"-gray",             ".gray",             XrmoptionNoArg,   "on" },
  340.    {"-clear",            ".clear",            XrmoptionNoArg,   "on" },
  341.    {"-display",          ".display",          XrmoptionSepArg,  NULL },
  342.    {"-name",             ".name",             XrmoptionSepArg,  NULL },
  343.    {"-geometry",         "*geometry",         XrmoptionSepArg,  NULL },
  344.    {"-background",       "*background",       XrmoptionSepArg,  NULL },
  345.    {"-bg",               "*background",       XrmoptionSepArg,  NULL },
  346.    {"-foreground",       "*foreground",       XrmoptionSepArg,  NULL },
  347.    {"-fg",               "*foreground",       XrmoptionSepArg,  NULL },
  348.    {"-bordercolor",      "*bordercolor",      XrmoptionSepArg,  NULL },
  349.    {"-bd",               "*bordercolor",      XrmoptionSepArg,  NULL },
  350.    {"-borderwidth",      ".borderwidth",      XrmoptionSepArg,  NULL },
  351.    {"-bw",               ".borderwidth",      XrmoptionSepArg,  NULL },
  352.    {"-font",             "*font",             XrmoptionSepArg,  NULL },
  353.    {"-fn",               "*font",             XrmoptionSepArg,  NULL },
  354.    {"-reverse",          "*reverseVideo",     XrmoptionNoArg,   "on" },
  355.    {"-rv",               "*reverseVideo",     XrmoptionNoArg,   "on" },
  356.    {"+rv",               "*reverseVideo",     XrmoptionNoArg,   "off"},
  357.    {"-iconic",           "*iconic",           XrmoptionNoArg,   "on" },
  358.    {"-synchronous",      "*synchronous",      XrmoptionNoArg,   "on" },
  359.    {"-xnllanguage",      "*xnllanguage",      XrmoptionSepArg,  NULL },
  360.    {"-selectionTimeout", "*selectionTimeout", XrmoptionSepArg,  NULL },
  361.    {"-title",            ".title",            XrmoptionSepArg,  NULL },
  362.    {"-xrm",              NULL,                XrmoptionResArg,  NULL },
  363.    };
  364.  
  365. preset(argc, argv) int argc; char *argv[]; {
  366.    int Argc = argc; char **Argv = argv;
  367.  
  368.    char *display = getenv("DISPLAY"),  *home = getenv("HOME");
  369.    char *server_defaults, *env, buf[256];
  370.  
  371.    /*---set to ignore ^C and ^Z----------------------------------------------*/
  372.  
  373.    signal(SIGINT, SIG_IGN);
  374. #ifdef SIGTSTP
  375.    signal(SIGTSTP, SIG_IGN);
  376. #endif
  377.  
  378.    /*---prescan arguments for "-name"----------------------------------------*/
  379.  
  380.    while(++Argv, --Argc > 0) {
  381.       if (!strcmp(*Argv, "-name") && Argc > 1) {
  382.      strncpy(Name, Argv[1], 64);
  383.      strncpy(Class, Argv[1], 64);
  384.      if (Class[0] >= 'a' && Class[0] <= 'z') Class[0] -= 0x20;
  385.      }
  386.       }
  387.    Argc = argc; Argv = argv;
  388.  
  389.    /*---parse command line---------------------------------------------------*/
  390.  
  391.    XrmInitialize();
  392.    XrmParseCommand(&dbCmd, options, Nopt, Name, &Argc, Argv);
  393.    if (Argc > 1) {
  394.       fprintf(stderr, "\ngnuplot: bad option: %s\n", Argv[1]);
  395.       fprintf(stderr, "gnuplot: X11 aborted.\n");
  396.       exit(1);
  397.       }
  398.    if (pr_GetR(dbCmd, ".display")) display = value.addr;
  399.  
  400.    /*---open display---------------------------------------------------------*/
  401.  
  402.    dpy = XOpenDisplay(display); 
  403.    if (!dpy) {
  404.       fprintf(stderr, "\ngnuplot: unable to open display '%s'\n", display);
  405.       fprintf(stderr, "gnuplot: X11 aborted.\n");
  406.       exit(1);
  407.       }
  408.    scr = DefaultScreen(dpy);
  409.    vis = DefaultVisual(dpy,scr);
  410.    D = DefaultDepth(dpy,scr);
  411.    root = DefaultRootWindow(dpy);
  412.    server_defaults = XResourceManagerString(dpy);
  413.  
  414.    /*---get application defaults--(subset of Xt processing)------------------*/
  415.  
  416.    sprintf(buf, "%s/%s", AppDefDir, "Gnuplot");
  417.    dbApp = XrmGetFileDatabase(buf);
  418.    XrmMergeDatabases(dbApp, &db);
  419.  
  420.    /*---get server or ~/.Xdefaults-------------------------------------------*/
  421.  
  422.    if (server_defaults)
  423.       dbDef = XrmGetStringDatabase(server_defaults);
  424.    else {
  425.       sprintf(buf, "%s/.Xdefaults", home);
  426.       dbDef = XrmGetFileDatabase(buf);
  427.       }
  428.    XrmMergeDatabases(dbDef, &db);
  429.  
  430.    /*---get XENVIRONMENT or  ~/.Xdefaults-hostname---------------------------*/
  431.  
  432.    if (env = getenv("XENVIRONMENT")) 
  433.       dbEnv = XrmGetFileDatabase(env);
  434.    else {
  435.       char *p, host[MAXHOSTNAMELEN];
  436.       if (gethostname(host, MAXHOSTNAMELEN) < 0) {
  437.      fprintf(stderr, "gnuplot: gethostname failed. X11 aborted.\n");
  438.      exit(1);
  439.      }
  440.       if (p = index(host, '.')) *p = '\0';
  441.       sprintf(buf, "%s/.Xdefaults-%s", home, host);
  442.       dbEnv = XrmGetFileDatabase(buf);
  443.       }
  444.    XrmMergeDatabases(dbEnv, &db);
  445.  
  446.    /*---merge command line options-------------------------------------------*/
  447.  
  448.    XrmMergeDatabases(dbCmd, &db);
  449.  
  450.    /*---determine geometry, font and colors----------------------------------*/
  451.  
  452.    pr_geometry();
  453.    pr_font();
  454.    pr_color();
  455.  
  456.    /*---create window--------------------------------------------------------*/
  457.  
  458.    pr_window();
  459.  
  460.    } 
  461.  
  462. /*-----------------------------------------------------------------------------
  463.  *   pr_GetR - get resource from database using "-name" option (if any)
  464.  *---------------------------------------------------------------------------*/
  465.  
  466. char *
  467. pr_GetR(db, resource) XrmDatabase db; char *resource; {
  468.    char name[128], class[128], *rc;
  469.  
  470.    strcpy(name, Name); strcat(name, resource);
  471.    strcpy(class, Class); strcat(class, resource);
  472.    rc = XrmGetResource(db, name, class, type, &value)
  473.       ? (char *)value.addr 
  474.       : (char *)0;
  475.    return(rc);
  476.    }
  477.  
  478. /*-----------------------------------------------------------------------------
  479.  *   pr_color - determine color values
  480.  *---------------------------------------------------------------------------*/
  481.  
  482. char color_keys[Ncolors][30] =   { 
  483.    "background", "bordercolor", "text", "border", "axis", 
  484.    "line1", "line2", "line3",  "line4", 
  485.    "line5", "line6", "line7",  "line8" 
  486.    };
  487. char color_values[Ncolors][30] = { 
  488.    "white", "black",  "black",  "black",  "black", 
  489.    "red",   "green",  "blue",   "magenta", 
  490.    "cyan",  "sienna", "orange", "coral" 
  491.    };
  492. char gray_values[Ncolors][30] = { 
  493.    "black",   "white",  "white",  "gray50", "gray50",
  494.    "gray100", "gray60", "gray80", "gray40", 
  495.    "gray90",  "gray50", "gray70", "gray30" 
  496.    };
  497.  
  498. pr_color() {
  499.    unsigned long black = BlackPixel(dpy, scr), white = WhitePixel(dpy,scr);
  500.    char option[20], *v, *type = (Gray) ? "Gray" : "Color";
  501.    XColor used, exact;
  502.    Colormap cmap;
  503.    int n;
  504.  
  505.    pr_GetR(db, ".mono")         && On(value.addr) && Mono++;
  506.    pr_GetR(db, ".gray")         && On(value.addr) && Gray++;
  507.    pr_GetR(db, ".reverseVideo") && On(value.addr) && Rv++;
  508.  
  509.    if (!Gray && (vis->class == GrayScale || vis->class == StaticGray)) Mono++;
  510.  
  511.    if (!Mono) {
  512.       cmap = DefaultColormap(dpy, scr);
  513.       for (n=0; n<Ncolors; n++) {
  514.      strcpy(option, ".");
  515.      strcat(option, color_keys[n]);
  516.      (n > 1) && strcat(option, type);
  517.      v = pr_GetR(db, option) 
  518.          ? value.addr
  519.          : ((Gray) ? gray_values[n] : color_values[n]);
  520.      if (XAllocNamedColor(dpy, cmap, v, &used, &exact))
  521.         colors[n] = used.pixel;
  522.      else {
  523.         fprintf(stderr, "\ngnuplot: can't allocate %s:%s\n", option, v);
  524.         fprintf(stderr, "gnuplot: reverting to monochrome\n");
  525.         Mono++; break;
  526.         }
  527.      }
  528.       }
  529.    if (Mono) {
  530.       colors[0] = (Rv) ? black : white ;
  531.       for (n=1; n<Ncolors; n++)  colors[n] = (Rv) ? white : black;
  532.       }
  533.    }
  534.  
  535. /*-----------------------------------------------------------------------------
  536.  *   pr_font - determine font          
  537.  *---------------------------------------------------------------------------*/
  538.  
  539. pr_font() {
  540.    char *fontname = pr_GetR(db, ".font");
  541.  
  542.    if (!fontname) fontname = FallbackFont;
  543.    font = XLoadQueryFont(dpy, fontname);
  544.    if (!font) {
  545.       fprintf(stderr, "\ngnuplot: can't load font '%s'\n", fontname);
  546.       fprintf(stderr, "gnuplot: using font '%s' instead.\n", FallbackFont);
  547.       font = XLoadQueryFont(dpy, FallbackFont);
  548.       if (!font) {
  549.      fprintf(stderr, "gnuplot: can't load font '%s'\n", FallbackFont);
  550.      fprintf(stderr, "gnuplot: no useable font - X11 aborted.\n");
  551.          exit(1);
  552.      }
  553.       }
  554.    vchar = font->ascent + font->descent;
  555.    }
  556.  
  557. /*-----------------------------------------------------------------------------
  558.  *   pr_geometry - determine window geometry      
  559.  *---------------------------------------------------------------------------*/
  560.  
  561. pr_geometry() {
  562.    char *geometry = pr_GetR(db, ".geometry");
  563.    int x, y, flags;
  564.    unsigned int w, h; 
  565.  
  566.    if (geometry) {
  567.       flags = XParseGeometry(geometry, &x, &y, &w, &h);
  568.  
  569.       if (flags & WidthValue)  W = w;
  570.       if (flags & HeightValue) H = h;
  571.       if (flags & XValue) {
  572.      if (flags & XNegative) x += DisplayWidth(dpy,scr);
  573.      gX = x;
  574.      }
  575.       if (flags & YValue) {
  576.      if (flags & YNegative) y += DisplayHeight(dpy,scr);
  577.      gY = y;
  578.      }
  579.       }
  580.    }
  581.  
  582. /*-----------------------------------------------------------------------------
  583.  *   pr_window - create window 
  584.  *---------------------------------------------------------------------------*/
  585.  
  586. pr_window() {
  587.    char *title =  pr_GetR(db, ".title");
  588.    XSizeHints hints;
  589.  
  590.    win = XCreateSimpleWindow(dpy, root, gX, gY, W, H, 2, colors[1], colors[0]);
  591.  
  592.    pr_GetR(db, ".clear") && On(value.addr) && Clear++;
  593.  
  594.    hints.flags = PPosition;
  595.    hints.x = gX; hints.y = gY;
  596.    XSetNormalHints(dpy, win, &hints);
  597.  
  598.    if (pr_GetR(db, ".iconic") && On(value.addr)) {
  599.       XWMHints wmh;
  600.  
  601.       wmh.flags = StateHint ;
  602.       wmh.initial_state = IconicState;
  603.       XSetWMHints(dpy, win, &wmh);
  604.       } 
  605.  
  606.    XStoreName(dpy, win, ((title) ? title : Class));
  607.  
  608.    XSelectInput(dpy, win, StructureNotifyMask);
  609.    XMapWindow(dpy, win);
  610.    
  611.    }
  612.