[BACK]Return to gplt_x11.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/gplt_x11.c, Revision 1.1

1.1     ! maekawa     1: #ifndef lint
        !             2: static char *RCSid = "$Id: gplt_x11.c,v 1.71 1998/04/14 00:15:22 drd Exp $";
        !             3: #endif
        !             4:
        !             5: /* GNUPLOT - gplt_x11.c */
        !             6:
        !             7: /*[
        !             8:  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
        !             9:  *
        !            10:  * Permission to use, copy, and distribute this software and its
        !            11:  * documentation for any purpose with or without fee is hereby granted,
        !            12:  * provided that the above copyright notice appear in all copies and
        !            13:  * that both that copyright notice and this permission notice appear
        !            14:  * in supporting documentation.
        !            15:  *
        !            16:  * Permission to modify the software is granted, but not the right to
        !            17:  * distribute the complete modified source code.  Modifications are to
        !            18:  * be distributed as patches to the released version.  Permission to
        !            19:  * distribute binaries produced by compiling modified sources is granted,
        !            20:  * provided you
        !            21:  *   1. distribute the corresponding source modifications from the
        !            22:  *    released version in the form of a patch file along with the binaries,
        !            23:  *   2. add special version identification to distinguish your version
        !            24:  *    in addition to the base release version number,
        !            25:  *   3. provide your name and address as the primary contact for the
        !            26:  *    support of your modified version, and
        !            27:  *   4. retain our contact information in regard to use of the base
        !            28:  *    software.
        !            29:  * Permission to distribute the released version of the source code along
        !            30:  * with corresponding source modifications in the form of a patch file is
        !            31:  * granted with same provisions 2 through 4 for binary distributions.
        !            32:  *
        !            33:  * This software is provided "as is" without express or implied warranty
        !            34:  * to the extent permitted by applicable law.
        !            35: ]*/
        !            36:
        !            37:
        !            38: /* lph changes:
        !            39:  * (a) make EXPORT_SELECTION the default and specify NOEXPORT to undefine
        !            40:  * (b) append X11 terminal number to resource name
        !            41:  * (c) change cursor for active terminal
        !            42:  */
        !            43:
        !            44: /*-----------------------------------------------------------------------------
        !            45:  *   gnuplot_x11 - X11 outboard terminal driver for gnuplot 3.3
        !            46:  *
        !            47:  *   Requires installation of companion inboard x11 driver in gnuplot/term.c
        !            48:  *
        !            49:  *   Acknowledgements:
        !            50:  *      Chris Peterson (MIT)
        !            51:  *      Dana Chee (Bellcore)
        !            52:  *      Arthur Smith (Cornell)
        !            53:  *      Hendri Hondorp (University of Twente, The Netherlands)
        !            54:  *      Bill Kucharski (Solbourne)
        !            55:  *      Charlie Kline (University of Illinois)
        !            56:  *      Yehavi Bourvine (Hebrew University of Jerusalem, Israel)
        !            57:  *      Russell Lang (Monash University, Australia)
        !            58:  *      O'Reilly & Associates: X Window System - Volumes 1 & 2
        !            59:  *
        !            60:  *   This code is provided as is and with no warranties of any kind.
        !            61:  *
        !            62:  * drd: change to allow multiple windows to be maintained independently
        !            63:  *
        !            64:  * There is a mailing list for gnuplot users. Note, however, that the
        !            65:  * newsgroup
        !            66:  *     comp.graphics.apps.gnuplot
        !            67:  * is identical to the mailing list (they
        !            68:  * both carry the same set of messages). We prefer that you read the
        !            69:  * messages through that newsgroup, to subscribing to the mailing list.
        !            70:  * (If you can read that newsgroup, and are already on the mailing list,
        !            71:  * please send a message to majordomo@dartmouth.edu, asking to be
        !            72:  * removed from the mailing list.)
        !            73:  *
        !            74:  * The address for mailing to list members is
        !            75:  *        info-gnuplot@dartmouth.edu
        !            76:  * and for mailing administrative requests is
        !            77:  *        majordomo@dartmouth.edu
        !            78:  * The mailing list for bug reports is
        !            79:  *        bug-gnuplot@dartmouth.edu
        !            80:  * The list of those interested in beta-test versions is
        !            81:  *        info-gnuplot-beta@dartmouth.edu
        !            82:  *---------------------------------------------------------------------------*/
        !            83:
        !            84: /* drd : export the graph via ICCCM primary selection. well... not quite
        !            85:  * ICCCM since we dont support full list of targets, but this
        !            86:  * is a start.  define EXPORT_SELECTION if you want this feature
        !            87:  */
        !            88:
        !            89: /*lph: add a "feature" to undefine EXPORT_SELECTION
        !            90:    The following makes EXPORT_SELECTION the default and
        !            91:    defining NOEXPORT over-rides the default
        !            92:  */
        !            93:
        !            94: #ifdef HAVE_CONFIG_H
        !            95: # include "config.h"
        !            96: #endif
        !            97:
        !            98: #ifdef EXPORT_SELECTION
        !            99: # undef EXPORT_SELECTION
        !           100: #endif /* EXPORT SELECTION */
        !           101: #ifndef NOEXPORT
        !           102: # define EXPORT_SELECTION XA_PRIMARY
        !           103: #endif /* NOEXPORT */
        !           104:
        !           105:
        !           106: #if !(defined(VMS) || defined(CRIPPLED_SELECT))
        !           107: # define DEFAULT_X11
        !           108: #endif
        !           109:
        !           110: #if defined(VMS) && defined(CRIPPLED_SELECT)
        !           111: Error. Incompatible options.
        !           112: #endif
        !           113:
        !           114:
        !           115: #include <X11/Xos.h>
        !           116: #include <X11/Xlib.h>
        !           117: #include <X11/Xresource.h>
        !           118: #include <X11/Xutil.h>
        !           119: #include <X11/Xatom.h>
        !           120: #include <X11/keysym.h>
        !           121:
        !           122: #include <signal.h>
        !           123:
        !           124: #ifdef HAVE_SYS_BSDTYPES_H
        !           125: # include <sys/bsdtypes.h>
        !           126: #endif /* HAVE_SYS_BSDTYPES_H */
        !           127:
        !           128: #ifdef __EMX__
        !           129: /* for gethostname ... */
        !           130: # include <netdb.h>
        !           131: #endif
        !           132:
        !           133: #if defined(HAVE_SYS_SELECT_H) && !defined(VMS)
        !           134: # include <sys/select.h>
        !           135: #endif /* HAVE_SYS_SELECT_H && !VMS */
        !           136:
        !           137: #ifndef FD_SET
        !           138: # define FD_SET(n, p)    ((p)->fds_bits[0] |= (1 << ((n) % 32)))
        !           139: # define FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1 << ((n) % 32)))
        !           140: # define FD_ISSET(n, p)  ((p)->fds_bits[0] & (1 << ((n) % 32)))
        !           141: # define FD_ZERO(p)      memset((char *)(p),'\0',sizeof(*(p)))
        !           142: #endif /* not FD_SET */
        !           143:
        !           144: #include "plot.h"
        !           145:
        !           146: #if defined(HAVE_SYS_SYSTEMINFO_H) && defined(HAVE_SYSINFO)
        !           147: # include <sys/systeminfo.h>
        !           148: # define SYSINFO_METHOD "sysinfo"
        !           149: # define GP_SYSTEMINFO(host) sysinfo (SI_HOSTNAME, (host), MAXHOSTNAMELEN)
        !           150: #else
        !           151: # define SYSINFO_METHOD "gethostname"
        !           152: # define GP_SYSTEMINFO(host) gethostname ((host), MAXHOSTNAMELEN)
        !           153: #endif /* HAVE_SYS_SYSTEMINFO_H && HAVE_SYSINFO */
        !           154:
        !           155: #ifdef VMS
        !           156: # ifdef __DECC
        !           157: #  include <starlet.h>
        !           158: # endif                                /* __DECC */
        !           159: # define EXIT(status) sys$delprc(0,0)  /* VMS does not drop itself */
        !           160: #else
        !           161: # define EXIT(status) exit(status)
        !           162: #endif
        !           163:
        !           164: #ifdef OSK
        !           165: # define EINTR E_ILLFNC
        !           166: #endif
        !           167:
        !           168: /* information about one window/plot */
        !           169:
        !           170: typedef struct plot_struct {
        !           171:     Window window;
        !           172:     Pixmap pixmap;
        !           173:     unsigned int posn_flags;
        !           174:     int x, y;
        !           175:     unsigned int width, height;        /* window size */
        !           176:     unsigned int px, py;       /* pointsize */
        !           177:     int ncommands, max_commands;
        !           178:     char **commands;
        !           179: } plot_struct;
        !           180:
        !           181: void store_command __PROTO((char *line, plot_struct * plot));
        !           182: void prepare_plot __PROTO((plot_struct * plot, int term_number));
        !           183: void delete_plot __PROTO((plot_struct * plot));
        !           184:
        !           185: int record __PROTO((void));
        !           186: void process_event __PROTO((XEvent * event));  /* from Xserver */
        !           187:
        !           188: void mainloop __PROTO((void));
        !           189:
        !           190: void display __PROTO((plot_struct * plot));
        !           191:
        !           192: void reset_cursor __PROTO((void));
        !           193:
        !           194: void preset __PROTO((int argc, char *argv[]));
        !           195: char *pr_GetR __PROTO((XrmDatabase db, char *resource));
        !           196: void pr_color __PROTO((void));
        !           197: void pr_dashes __PROTO((void));
        !           198: void pr_font __PROTO((void));
        !           199: void pr_geometry __PROTO((void));
        !           200: void pr_pointsize __PROTO((void));
        !           201: void pr_width __PROTO((void));
        !           202: Window pr_window __PROTO((unsigned int flags, int x, int y, unsigned int width, unsigned height));
        !           203: void pr_raise __PROTO((void));
        !           204: void pr_persist __PROTO((void));
        !           205:
        !           206: #ifdef EXPORT_SELECTION
        !           207: void export_graph __PROTO((plot_struct * plot));
        !           208: void handle_selection_event __PROTO((XEvent * event));
        !           209: #endif
        !           210:
        !           211: #define FallbackFont "fixed"
        !           212:
        !           213: #define Ncolors 13
        !           214: unsigned long colors[Ncolors];
        !           215:
        !           216: #define Nwidths 10
        !           217: unsigned int widths[Nwidths] = { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        !           218:
        !           219: #define Ndashes 10
        !           220: char dashes[Ndashes][5];
        !           221:
        !           222: #define MAX_WINDOWS 16
        !           223:
        !           224: #define XC_crosshair 34
        !           225:
        !           226:
        !           227: struct plot_struct plot_array[MAX_WINDOWS];
        !           228:
        !           229:
        !           230: Display *dpy;
        !           231: int scr;
        !           232: Window root;
        !           233: Visual *vis;
        !           234: GC gc = (GC) 0;
        !           235: XFontStruct *font;
        !           236: int do_raise = 1, persist = 0;
        !           237: KeyCode q_keycode;
        !           238: Cursor cursor;
        !           239:
        !           240: int windows_open = 0;
        !           241:
        !           242: int gX = 100, gY = 100;
        !           243: unsigned int gW = 640, gH = 450;
        !           244: unsigned int gFlags = PSize;
        !           245:
        !           246: unsigned int BorderWidth = 2;
        !           247: unsigned int D;                        /* depth */
        !           248:
        !           249: Bool Mono = 0, Gray = 0, Rv = 0, Clear = 0;
        !           250: char Name[64] = "gnuplot";
        !           251: char Class[64] = "Gnuplot";
        !           252:
        !           253: int cx = 0, cy = 0, vchar;
        !           254: double xscale, yscale, pointsize;
        !           255: #define X(x) (int) ((x) * xscale)
        !           256: #define Y(y) (int) ((4095-(y)) * yscale)
        !           257:
        !           258: #define Nbuf 1024
        !           259: char buf[Nbuf], **commands = (char **) 0;
        !           260:
        !           261: FILE *X11_ipc;
        !           262: char X11_ipcpath[32];
        !           263:
        !           264: /* when using an ICCCM-compliant window manager, we can ask it
        !           265:  * to send us an event when user chooses 'close window'. We do this
        !           266:  * by setting WM_DELETE_WINDOW atom in property WM_PROTOCOLS
        !           267:  */
        !           268:
        !           269: Atom WM_PROTOCOLS, WM_DELETE_WINDOW;
        !           270:
        !           271: XPoint Diamond[5], Triangle[4];
        !           272: XSegment Plus[2], Cross[2], Star[4];
        !           273:
        !           274: /*-----------------------------------------------------------------------------
        !           275:  *   main program
        !           276:  *---------------------------------------------------------------------------*/
        !           277:
        !           278: int main(argc, argv)
        !           279: int argc;
        !           280: char *argv[];
        !           281: {
        !           282:
        !           283:
        !           284: #ifdef OSK
        !           285:     /* malloc large blocks, otherwise problems with fragmented mem */
        !           286:     _mallocmin(102400);
        !           287: #endif
        !           288: #ifdef __EMX__
        !           289:     /* close open file handles */
        !           290:     fcloseall();
        !           291: #endif
        !           292:
        !           293:     FPRINTF((stderr, "gnuplot_X11 starting up\n"));
        !           294:
        !           295:     preset(argc, argv);
        !           296:
        !           297: /* set up the alternative cursor */
        !           298:     cursor = XCreateFontCursor(dpy, XC_crosshair);
        !           299:
        !           300:     mainloop();
        !           301:
        !           302:     if (persist) {
        !           303:        FPRINTF((stderr, "waiting for %d windows\n, windows_open"));
        !           304:        /* read x events until all windows have been quit */
        !           305:        while (windows_open > 0) {
        !           306:            XEvent event;
        !           307:            XNextEvent(dpy, &event);
        !           308:            process_event(&event);
        !           309:        }
        !           310:     }
        !           311:     XCloseDisplay(dpy);
        !           312:
        !           313:     FPRINTF((stderr, "exiting\n"));
        !           314:
        !           315:     EXIT(0);
        !           316: }
        !           317:
        !           318: /*-----------------------------------------------------------------------------
        !           319:  *   mainloop processing - process X events and input from gnuplot
        !           320:  *
        !           321:  *   Three different versions of main loop processing are provided to support
        !           322:  *   three different platforms.
        !           323:  *
        !           324:  *   DEFAULT_X11:     use select() for both X events and input on stdin
        !           325:  *                    from gnuplot inboard driver
        !           326:  *
        !           327:  *   CRIPPLED_SELECT: use select() to service X events and check during
        !           328:  *                    select timeout for temporary plot file created
        !           329:  *                    by inboard driver
        !           330:  *
        !           331:  *   VMS:             use XNextEvent to service X events and AST to
        !           332:  *                    service input from gnuplot inboard driver on stdin
        !           333:  *---------------------------------------------------------------------------*/
        !           334:
        !           335:
        !           336: #ifdef DEFAULT_X11
        !           337: /*-----------------------------------------------------------------------------
        !           338:  *    DEFAULT_X11 mainloop
        !           339:  *---------------------------------------------------------------------------*/
        !           340:
        !           341: void mainloop()
        !           342: {
        !           343:     int nf, nfds, cn = ConnectionNumber(dpy), in;
        !           344:     struct timeval *timer = (struct timeval *) 0;
        !           345: #ifdef ISC22
        !           346:     struct timeval timeout;
        !           347: #endif
        !           348:     fd_set rset, tset;
        !           349:
        !           350:     X11_ipc = stdin;
        !           351:     in = fileno(X11_ipc);
        !           352:
        !           353:     FD_ZERO(&rset);
        !           354:     FD_SET(cn, &rset);
        !           355:
        !           356:     FD_SET(in, &rset);
        !           357:     nfds = (cn > in) ? cn + 1 : in + 1;
        !           358:
        !           359: #ifdef ISC22
        !           360: /* Added by Robert Eckardt, RobertE@beta.TP2.Ruhr-Uni-Bochum.de */
        !           361:     timeout.tv_sec = 0;                /* select() in ISC2.2 needs timeout */
        !           362:     timeout.tv_usec = 300000;  /* otherwise input from gnuplot is */
        !           363:     timer = &timeout;          /* suspended til next X event. */
        !           364: #endif /* ISC22   (0.3s are short enough not to be noticed */
        !           365:
        !           366:     while (1) {
        !           367:
        !           368:        /* XNextEvent does an XFlush() before waiting. But here.
        !           369:         * we must ensure that the queue is flushed, since we
        !           370:         * dont call XNextEvent until an event arrives. (I have
        !           371:         * twice wasted quite some time over this issue, so now
        !           372:         * I am making sure of it !
        !           373:         */
        !           374:
        !           375:        XFlush(dpy);
        !           376:
        !           377:        tset = rset;
        !           378:        nf = select((gp_nfds_t)nfds, gp_fd_set_p &tset, gp_fd_set_p 0,
        !           379:                     gp_fd_set_p 0, gp_timeval_p timer);
        !           380:        if (nf < 0) {
        !           381:            if (errno == EINTR)
        !           382:                continue;
        !           383:            fprintf(stderr, "gnuplot: select failed. errno:%d\n", errno);
        !           384:            EXIT(1);
        !           385:        }
        !           386:        if (nf > 0)
        !           387:            XNoOp(dpy);
        !           388:
        !           389:        if (FD_ISSET(cn, &tset)) {
        !           390:            /* used to use CheckMaskEvent() but that cannot receive
        !           391:             * maskable events such as ClientMessage. So now we do
        !           392:             * one event, then return to the select.
        !           393:             * And that almost works, except that under some Xservers
        !           394:             * running without a window manager (e.g. Hummingbird Exceed under Win95)
        !           395:             * a bogus ConfigureNotify is sent followed by a valid ConfigureNotify
        !           396:             * when the window is maximized.  The two events are queued, apparently
        !           397:             * in a single I/O because select() above doesn't see the second, valid
        !           398:             * event.  This little loop fixes the problem by flushing the
        !           399:             * event queue completely.
        !           400:             */
        !           401:            XEvent xe;
        !           402:            do {
        !           403:                XNextEvent(dpy, &xe);
        !           404:                process_event(&xe);
        !           405:            } while (XPending(dpy));
        !           406:        }
        !           407:        if (FD_ISSET(in, &tset)) {
        !           408:            if (!record())      /* end of input */
        !           409:                return;
        !           410:        }
        !           411:     }
        !           412: }
        !           413:
        !           414: #endif
        !           415:
        !           416:
        !           417: #ifdef CRIPPLED_SELECT
        !           418: /*-----------------------------------------------------------------------------
        !           419:  *    CRIPPLED_SELECT mainloop
        !           420:  *---------------------------------------------------------------------------*/
        !           421:
        !           422: void mainloop()
        !           423: {
        !           424:     int nf, nfds, cn = ConnectionNumber(dpy);
        !           425:     struct timeval timeout, *timer;
        !           426:     fd_set rset, tset;
        !           427:     unsigned long all = (unsigned long) (-1L);
        !           428:     XEvent xe;
        !           429:
        !           430:     FD_ZERO(&rset);
        !           431:     FD_SET(cn, &rset);
        !           432:
        !           433:     timeout.tv_sec = 1;
        !           434:     timeout.tv_usec = 0;
        !           435:     timer = &timeout;
        !           436:     sprintf(X11_ipcpath, "/tmp/Gnuplot_%d", getppid());
        !           437:     nfds = cn + 1;
        !           438:
        !           439:     while (1) {
        !           440:        XFlush(dpy);            /* see above */
        !           441:        tset = rset;
        !           442:        nf = select((gp_nfds_t)nfds, gp_fd_set_p &tset, gp_fd_set_p 0,
        !           443:                    gp_fd_set_p 0, gp_timeval_p timer);
        !           444:        if (nf < 0) {
        !           445:            if (errno == EINTR)
        !           446:                continue;
        !           447:            fprintf(stderr, "gnuplot: select failed. errno:%d\n", errno);
        !           448:            EXIT(1);
        !           449:        }
        !           450:        nf > 0 && XNoOp(dpy);
        !           451:        if (FD_ISSET(cn, &tset)) {
        !           452:            while (XCheckMaskEvent(dpy, all, &xe)) {
        !           453:                process_event(&xe);
        !           454:            }
        !           455:        }
        !           456:        if ((X11_ipc = fopen(X11_ipcpath, "r"))) {
        !           457:            unlink(X11_ipcpath);
        !           458:            record();
        !           459:            fclose(X11_ipc);
        !           460:        }
        !           461:     }
        !           462: }
        !           463: #endif /* CRIPPLED_SELECT */
        !           464:
        !           465:
        !           466: #ifdef VMS
        !           467: /*-----------------------------------------------------------------------------
        !           468:  *    VMS mainloop - Yehavi Bourvine - YEHAVI@VMS.HUJI.AC.IL
        !           469:  *---------------------------------------------------------------------------*/
        !           470:
        !           471: /*  In VMS there is no decent Select(). hence, we have to loop inside
        !           472:  *  XGetNextEvent for getting the next X window event. In order to get input
        !           473:  *  from the master we assign a channel to SYS$INPUT and use AST's in order to
        !           474:  *  receive data. In order to exit the mainloop, we need to somehow make XNextEvent
        !           475:  *  return from within the ast. We do this with a XSendEvent() to ourselves !
        !           476:  *  This needs a window to send the message to, so we create an unmapped window
        !           477:  *  for this purpose. Event type XClientMessage is perfect for this, but it
        !           478:  *  appears that such messages come from elsewhere (motif window manager, perhaps ?)
        !           479:  *  So we need to check fairly carefully that it is the ast event that has been received.
        !           480:  */
        !           481:
        !           482: #include <iodef.h>
        !           483: char STDIIN[] = "SYS$INPUT:";
        !           484: short STDIINchannel, STDIINiosb[4];
        !           485: struct { short size, type; char *address; } STDIINdesc;
        !           486: char STDIINbuffer[64];
        !           487: int status;
        !           488:
        !           489: ast()
        !           490: {
        !           491:     int status = sys$qio(0, STDIINchannel, IO$_READVBLK, STDIINiosb, record,
        !           492:                  0, STDIINbuffer, sizeof(STDIINbuffer) - 1, 0, 0, 0, 0);
        !           493:     if ((status & 0x1) == 0)
        !           494:        EXIT(status);
        !           495: }
        !           496:
        !           497: Window message_window;
        !           498:
        !           499: void mainloop()
        !           500: {
        !           501:     /* dummy unmapped window for receiving internally-generated terminate
        !           502:      * messages
        !           503:      */
        !           504:     message_window = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 1, 0, 0);
        !           505:
        !           506:     STDIINdesc.size = strlen(STDIIN);
        !           507:     STDIINdesc.type = 0;
        !           508:     STDIINdesc.address = STDIIN;
        !           509:     status = sys$assign(&STDIINdesc, &STDIINchannel, 0, 0, 0);
        !           510:     if ((status & 0x1) == 0)
        !           511:        EXIT(status);
        !           512:     ast();
        !           513:
        !           514:     for (;;) {
        !           515:        XEvent xe;
        !           516:        XNextEvent(dpy, &xe);
        !           517:        if (xe.type == ClientMessage && xe.xclient.window == message_window) {
        !           518:            if (xe.xclient.message_type == None &&
        !           519:                xe.xclient.format == 8 &&
        !           520:                strcmp(xe.xclient.data.b, "die gnuplot die") == 0) {
        !           521:                FPRINTF((stderr, "quit message from ast\n"));
        !           522:                return;
        !           523:            } else {
        !           524:                FPRINTF((stderr, "Bogus XClientMessage event from window manager ?\n"));
        !           525:            }
        !           526:        }
        !           527:        process_event(&xe);
        !           528:     }
        !           529: }
        !           530:
        !           531: #endif /* VMS */
        !           532:
        !           533: /* delete a window / plot */
        !           534:
        !           535: void delete_plot(plot)
        !           536: plot_struct *plot;
        !           537: {
        !           538:     int i;
        !           539:
        !           540:     FPRINTF((stderr, "Delete plot %d\n", plot - plot_array));
        !           541:
        !           542:     for (i = 0; i < plot->ncommands; ++i)
        !           543:        free(plot->commands[i]);
        !           544:     plot->ncommands = 0;
        !           545:
        !           546:     if (plot->window) {
        !           547:        FPRINTF((stderr, "Destroy window 0x%x\n", plot->window));
        !           548:        XDestroyWindow(dpy, plot->window);
        !           549:        plot->window = None;
        !           550:        --windows_open;
        !           551:     }
        !           552:     if (plot->pixmap) {
        !           553:        XFreePixmap(dpy, plot->pixmap);
        !           554:        plot->pixmap = None;
        !           555:     }
        !           556:     /* but preserve geometry */
        !           557: }
        !           558:
        !           559:
        !           560: /* prepare the plot structure */
        !           561:
        !           562: void prepare_plot(plot, term_number)
        !           563: plot_struct *plot;
        !           564: int term_number;
        !           565: {
        !           566:     int i;
        !           567:     char *term_name;
        !           568:
        !           569:     for (i = 0; i < plot->ncommands; ++i)
        !           570:        free(plot->commands[i]);
        !           571:     plot->ncommands = 0;
        !           572:
        !           573:     if (!plot->posn_flags) {
        !           574:        /* first time this window has been used - use default or -geometry
        !           575:         * settings
        !           576:         */
        !           577:        plot->posn_flags = gFlags;
        !           578:        plot->x = gX;
        !           579:        plot->y = gY;
        !           580:        plot->width = gW;
        !           581:        plot->height = gH;
        !           582:     }
        !           583:
        !           584:     if (!plot->window) {
        !           585:        plot->window = pr_window(plot->posn_flags, plot->x, plot->y, plot->width, plot->height);
        !           586:        ++windows_open;
        !           587:
        !           588:        /* append the X11 terminal number (if greater than zero) */
        !           589:
        !           590:        if (term_number) {
        !           591:            char new_name[60];
        !           592:            XFetchName(dpy, plot->window, &term_name);
        !           593:            FPRINTF((stderr, "Window title is %s\n", term_name));
        !           594:
        !           595:            sprintf(new_name, "%.55s%3d", term_name, term_number);
        !           596:            FPRINTF((stderr, "term_number  is %d\n", term_number));
        !           597:
        !           598:            XStoreName(dpy, plot->window, new_name);
        !           599:
        !           600:            sprintf(new_name, "gplt%3d", term_number);
        !           601:            XSetIconName(dpy, plot->window, new_name);
        !           602:        }
        !           603:     }
        !           604: /* We don't know that it is the same window as before, so we reset the
        !           605:  * cursors for all windows and then define the cursor for the active
        !           606:  * window
        !           607:  */
        !           608:     reset_cursor();
        !           609:     XDefineCursor(dpy, plot->window, cursor);
        !           610:
        !           611: }
        !           612:
        !           613: /* store a command in a plot structure */
        !           614:
        !           615: void store_command(buffer, plot)
        !           616: char *buffer;
        !           617: plot_struct *plot;
        !           618: {
        !           619:     char *p;
        !           620:
        !           621:     FPRINTF((stderr, "Store in %d : %s", plot - plot_array, buffer));
        !           622:
        !           623:     if (plot->ncommands >= plot->max_commands) {
        !           624:        plot->max_commands = plot->max_commands * 2 + 1;
        !           625:        plot->commands = (plot->commands)
        !           626:            ? (char **) realloc(plot->commands, plot->max_commands * sizeof(char *))
        !           627:        : (char **) malloc(sizeof(char *));
        !           628:     }
        !           629:     p = (char *) malloc((unsigned) strlen(buffer) + 1);
        !           630:     if (!plot->commands || !p) {
        !           631:        fputs("gnuplot: can't get memory. X11 aborted.\n", stderr);
        !           632:        EXIT(1);
        !           633:     }
        !           634:     plot->commands[plot->ncommands++] = strcpy(p, buffer);
        !           635: }
        !           636:
        !           637: #ifndef VMS
        !           638: /*-----------------------------------------------------------------------------
        !           639:  *   record - record new plot from gnuplot inboard X11 driver (Unix)
        !           640:  *---------------------------------------------------------------------------*/
        !           641:
        !           642: int record()
        !           643: {
        !           644:     static plot_struct *plot = plot_array;
        !           645:
        !           646:     while (fgets(buf, Nbuf, X11_ipc)) {
        !           647:        switch (*buf) {
        !           648:        case 'G':               /* enter graphics mode */
        !           649:            {
        !           650:                int plot_number = atoi(buf + 1);        /* 0 if none specified */
        !           651:
        !           652:                if (plot_number < 0 || plot_number >= MAX_WINDOWS)
        !           653:                    plot_number = 0;
        !           654:
        !           655:                FPRINTF((stderr, "plot for window number %d\n", plot_number));
        !           656:                plot = plot_array + plot_number;
        !           657:                prepare_plot(plot, plot_number);
        !           658:                continue;
        !           659:            }
        !           660:        case 'E':               /* leave graphics mode / suspend */
        !           661:            display(plot);
        !           662:            return 1;
        !           663:        case 'R':               /* leave x11 mode */
        !           664:            reset_cursor();
        !           665:            return 0;
        !           666:        default:
        !           667:            store_command(buf, plot);
        !           668:            continue;
        !           669:        }
        !           670:     }
        !           671:
        !           672:     /* get here if fgets fails */
        !           673:
        !           674: #ifdef OSK
        !           675:     if (feof(X11_ipc))         /* On OS-9 sometimes while resizing the window,  */
        !           676:        _cleareof(X11_ipc);     /* and plotting data, the eof or error flag of   */
        !           677:     if (ferror(X11_ipc))       /* X11_ipc stream gets set, while there is       */
        !           678:        clearerr(X11_ipc);      /* nothing wrong! Probably a bug in my select()? */
        !           679: #else
        !           680:     if (feof(X11_ipc) || ferror(X11_ipc))
        !           681:        return 0;
        !           682: #endif /* not OSK */
        !           683:
        !           684:     return 1;
        !           685: }
        !           686:
        !           687: #else /* VMS */
        !           688: /*-----------------------------------------------------------------------------
        !           689:  *   record - record new plot from gnuplot inboard X11 driver (VMS)
        !           690:  *---------------------------------------------------------------------------*/
        !           691:
        !           692: record()
        !           693: {
        !           694:     static plot_struct *plot = plot_array;
        !           695:
        !           696:     int status;
        !           697:
        !           698:     if ((STDIINiosb[0] & 0x1) == 0)
        !           699:        EXIT(STDIINiosb[0]);
        !           700:     STDIINbuffer[STDIINiosb[1]] = '\0';
        !           701:     strcpy(buf, STDIINbuffer);
        !           702:
        !           703:     switch (*buf) {
        !           704:     case 'G':                  /* enter graphics mode */
        !           705:        {
        !           706:            int plot_number = atoi(buf + 1);    /* 0 if none specified */
        !           707:            if (plot_number < 0 || plot_number >= MAX_WINDOWS)
        !           708:                plot_number = 0;
        !           709:            FPRINTF((stderr, "plot for window number %d\n", plot_number));
        !           710:            plot = plot_array + plot_number;
        !           711:            prepare_plot(plot, plot_number);
        !           712:            break;
        !           713:        }
        !           714:     case 'E':                  /* leave graphics mode */
        !           715:        display(plot);
        !           716:        break;
        !           717:     case 'R':                  /* exit x11 mode */
        !           718:        FPRINTF((stderr, "received R - sending ClientMessage\n"));
        !           719:        reset_cursor();
        !           720:        sys$cancel(STDIINchannel);
        !           721:        /* this is ridiculous - cook up an event to ourselves,
        !           722:         * in order to get the mainloop() out of the XNextEvent() call
        !           723:         * it seems that window manager can also send clientmessages,
        !           724:         * so put a checksum into the message
        !           725:         */
        !           726:        {
        !           727:            XClientMessageEvent event;
        !           728:            event.type = ClientMessage;
        !           729:            event.send_event = True;
        !           730:            event.display = dpy;
        !           731:            event.window = message_window;
        !           732:            event.message_type = None;
        !           733:            event.format = 8;
        !           734:            strcpy(event.data.b, "die gnuplot die");
        !           735:            XSendEvent(dpy, message_window, False, 0, (XEvent *) & event);
        !           736:            XFlush(dpy);
        !           737:        }
        !           738:        return;                 /* no ast */
        !           739:     default:
        !           740:        store_command(buf, plot);
        !           741:        break;
        !           742:     }
        !           743:     ast();
        !           744: }
        !           745: #endif /* VMS */
        !           746:
        !           747:
        !           748: /*-----------------------------------------------------------------------------
        !           749:  *   display - display a stored plot
        !           750:  *---------------------------------------------------------------------------*/
        !           751:
        !           752: void display(plot)
        !           753: plot_struct *plot;
        !           754: {
        !           755:     int n, x, y, sw, sl, lt = 0, width, type, point, px, py;
        !           756:     int user_width = 1;                /* as specified by plot...linewidth */
        !           757:     char *buffer, *str;
        !           758:     enum JUSTIFY jmode;
        !           759:
        !           760:     FPRINTF((stderr, "Display %d ; %d commands\n", plot - plot_array, plot->ncommands));
        !           761:
        !           762:     if (plot->ncommands == 0)
        !           763:        return;
        !           764:
        !           765:     /* set scaling factor between internal driver & window geometry */
        !           766:     xscale = plot->width / 4096.0;
        !           767:     yscale = plot->height / 4096.0;
        !           768:
        !           769:     /* initial point sizes, until overridden with P7xxxxyyyy */
        !           770:     px = (int) (xscale * pointsize);
        !           771:     py = (int) (yscale * pointsize);
        !           772:
        !           773:     /* create new pixmap & GC */
        !           774:     if (gc)
        !           775:        XFreeGC(dpy, gc);
        !           776:
        !           777:     if (!plot->pixmap) {
        !           778:        FPRINTF((stderr, "Create pixmap %d : %dx%dx%d\n", plot - plot_array, plot->width, plot->height, D));
        !           779:        plot->pixmap = XCreatePixmap(dpy, root, plot->width, plot->height, D);
        !           780:     }
        !           781:
        !           782:     gc = XCreateGC(dpy, plot->pixmap, 0, (XGCValues *) 0);
        !           783:
        !           784:     XSetFont(dpy, gc, font->fid);
        !           785:
        !           786:     /* set pixmap background */
        !           787:     XSetForeground(dpy, gc, colors[0]);
        !           788:     XFillRectangle(dpy, plot->pixmap, gc, 0, 0, plot->width, plot->height);
        !           789:     XSetBackground(dpy, gc, colors[0]);
        !           790:
        !           791:     if (!plot->window) {
        !           792:        plot->window = pr_window(plot->posn_flags, plot->x, plot->y, plot->width, plot->height);
        !           793:        ++windows_open;
        !           794:     }
        !           795:     /* top the window but don't put keyboard or mouse focus into it. */
        !           796:     if (do_raise)
        !           797:        XMapRaised(dpy, plot->window);
        !           798:
        !           799:     /* momentarily clear the window first if requested */
        !           800:     if (Clear) {
        !           801:        XClearWindow(dpy, plot->window);
        !           802:        XFlush(dpy);
        !           803:     }
        !           804:     /* loop over accumulated commands from inboard driver */
        !           805:     for (n = 0; n < plot->ncommands; n++) {
        !           806:        buffer = plot->commands[n];
        !           807:
        !           808:        /*   X11_vector(x,y) - draw vector  */
        !           809:        if (*buffer == 'V') {
        !           810:            sscanf(buffer, "V%4d%4d", &x, &y);
        !           811:            XDrawLine(dpy, plot->pixmap, gc, X(cx), Y(cy), X(x), Y(y));
        !           812:            cx = x;
        !           813:            cy = y;
        !           814:        }
        !           815:        /*   X11_move(x,y) - move  */
        !           816:        else if (*buffer == 'M')
        !           817:            sscanf(buffer, "M%4d%4d", &cx, &cy);
        !           818:
        !           819:        /*   X11_put_text(x,y,str) - draw text   */
        !           820:        else if (*buffer == 'T') {
        !           821:            sscanf(buffer, "T%4d%4d", &x, &y);
        !           822:            str = buffer + 9;
        !           823:            sl = strlen(str) - 1;
        !           824:            sw = XTextWidth(font, str, sl);
        !           825:
        !           826:            switch (jmode) {
        !           827:            case LEFT:
        !           828:                sw = 0;
        !           829:                break;
        !           830:            case CENTRE:
        !           831:                sw = -sw / 2;
        !           832:                break;
        !           833:            case RIGHT:
        !           834:                sw = -sw;
        !           835:                break;
        !           836:            }
        !           837:
        !           838:            XSetForeground(dpy, gc, colors[2]);
        !           839:            XDrawString(dpy, plot->pixmap, gc, X(x) + sw, Y(y) + vchar / 3, str, sl);
        !           840:            XSetForeground(dpy, gc, colors[lt + 3]);
        !           841:        } else if (*buffer == 'F') {    /* fill box */
        !           842:            int style, xtmp, ytmp, w, h;
        !           843:
        !           844:            if (sscanf(buffer + 1, "%4d%4d%4d%4d%4d", &style, &xtmp, &ytmp, &w, &h) == 5) {
        !           845:                /* gnuplot has origin at bottom left, but X uses top left
        !           846:                 * There may be an off-by-one (or more) error here.
        !           847:                 * style ignored here for the moment
        !           848:                 */
        !           849:                ytmp += h;              /* top left corner of rectangle to be filled */
        !           850:                w *= xscale;
        !           851:                h *= yscale;
        !           852:                XSetForeground(dpy, gc, colors[0]);
        !           853:                XFillRectangle(dpy, plot->pixmap, gc, X(xtmp), Y(ytmp), w, h);
        !           854:                XSetForeground(dpy, gc, colors[lt + 3]);
        !           855:            }
        !           856:        }
        !           857:        /*   X11_justify_text(mode) - set text justification mode  */
        !           858:        else if (*buffer == 'J')
        !           859:            sscanf(buffer, "J%4d", (int *) &jmode);
        !           860:
        !           861:        /*  X11_linewidth(width) - set line width */
        !           862:        else if (*buffer == 'W')
        !           863:            sscanf(buffer + 1, "%4d", &user_width);
        !           864:
        !           865:        /*   X11_linetype(type) - set line type  */
        !           866:        else if (*buffer == 'L') {
        !           867:            sscanf(buffer, "L%4d", &lt);
        !           868:            lt = (lt % 8) + 2;
        !           869:            /* default width is 0 {which X treats as 1} */
        !           870:            width = widths[lt] ? user_width * widths[lt] : user_width;
        !           871:            if (dashes[lt][0]) {
        !           872:                type = LineOnOffDash;
        !           873:                XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
        !           874:            } else {
        !           875:                type = LineSolid;
        !           876:            }
        !           877:            XSetForeground(dpy, gc, colors[lt + 3]);
        !           878:            XSetLineAttributes(dpy, gc, width, type, CapButt, JoinBevel);
        !           879:        }
        !           880:        /*   X11_point(number) - draw a point */
        !           881:        else if (*buffer == 'P') {
        !           882:            /* linux sscanf does not like %1d%4d%4d" with Oxxxxyyyy */
        !           883:            /* sscanf(buffer, "P%1d%4d%4d", &point, &x, &y); */
        !           884:            point = buffer[1] - '0';
        !           885:            sscanf(buffer + 2, "%4d%4d", &x, &y);
        !           886:            if (point == 7) {
        !           887:                /* set point size */
        !           888:                px = (int) (x * xscale * pointsize);
        !           889:                py = (int) (y * yscale * pointsize);
        !           890:            } else {
        !           891:                if (type != LineSolid || width != 0) {  /* select solid line */
        !           892:                    XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinBevel);
        !           893:                }
        !           894:                switch (point) {
        !           895:                case 0: /* dot */
        !           896:                    XDrawPoint(dpy, plot->pixmap, gc, X(x), Y(y));
        !           897:                    break;
        !           898:                case 1: /* do diamond */
        !           899:                    Diamond[0].x = (short) X(x) - px;
        !           900:                    Diamond[0].y = (short) Y(y);
        !           901:                    Diamond[1].x = (short) px;
        !           902:                    Diamond[1].y = (short) -py;
        !           903:                    Diamond[2].x = (short) px;
        !           904:                    Diamond[2].y = (short) py;
        !           905:                    Diamond[3].x = (short) -px;
        !           906:                    Diamond[3].y = (short) py;
        !           907:                    Diamond[4].x = (short) -px;
        !           908:                    Diamond[4].y = (short) -py;
        !           909:
        !           910:                    /*
        !           911:                     * Should really do a check with XMaxRequestSize()
        !           912:                     */
        !           913:                    XDrawLines(dpy, plot->pixmap, gc, Diamond, 5, CoordModePrevious);
        !           914:                    XDrawPoint(dpy, plot->pixmap, gc, X(x), Y(y));
        !           915:                    break;
        !           916:                case 2: /* do plus */
        !           917:                    Plus[0].x1 = (short) X(x) - px;
        !           918:                    Plus[0].y1 = (short) Y(y);
        !           919:                    Plus[0].x2 = (short) X(x) + px;
        !           920:                    Plus[0].y2 = (short) Y(y);
        !           921:                    Plus[1].x1 = (short) X(x);
        !           922:                    Plus[1].y1 = (short) Y(y) - py;
        !           923:                    Plus[1].x2 = (short) X(x);
        !           924:                    Plus[1].y2 = (short) Y(y) + py;
        !           925:
        !           926:                    XDrawSegments(dpy, plot->pixmap, gc, Plus, 2);
        !           927:                    break;
        !           928:                case 3: /* do box */
        !           929:                    XDrawRectangle(dpy, plot->pixmap, gc, X(x) - px, Y(y) - py, (px + px), (py + py));
        !           930:                    XDrawPoint(dpy, plot->pixmap, gc, X(x), Y(y));
        !           931:                    break;
        !           932:                case 4: /* do X */
        !           933:                    Cross[0].x1 = (short) X(x) - px;
        !           934:                    Cross[0].y1 = (short) Y(y) - py;
        !           935:                    Cross[0].x2 = (short) X(x) + px;
        !           936:                    Cross[0].y2 = (short) Y(y) + py;
        !           937:                    Cross[1].x1 = (short) X(x) - px;
        !           938:                    Cross[1].y1 = (short) Y(y) + py;
        !           939:                    Cross[1].x2 = (short) X(x) + px;
        !           940:                    Cross[1].y2 = (short) Y(y) - py;
        !           941:
        !           942:                    XDrawSegments(dpy, plot->pixmap, gc, Cross, 2);
        !           943:                    break;
        !           944:                case 5: /* do triangle */
        !           945:                    {
        !           946:                        short temp_x, temp_y;
        !           947:
        !           948:                        temp_x = (short) (1.33 * (double) px + 0.5);
        !           949:                        temp_y = (short) (1.33 * (double) py + 0.5);
        !           950:
        !           951:                        Triangle[0].x = (short) X(x);
        !           952:                        Triangle[0].y = (short) Y(y) - temp_y;
        !           953:                        Triangle[1].x = (short) temp_x;
        !           954:                        Triangle[1].y = (short) 2 *py;
        !           955:                        Triangle[2].x = (short) -(2 * temp_x);
        !           956:                        Triangle[2].y = (short) 0;
        !           957:                        Triangle[3].x = (short) temp_x;
        !           958:                        Triangle[3].y = (short) -(2 * py);
        !           959:
        !           960:                        XDrawLines(dpy, plot->pixmap, gc, Triangle, 4, CoordModePrevious);
        !           961:                        XDrawPoint(dpy, plot->pixmap, gc, X(x), Y(y));
        !           962:                    }
        !           963:                    break;
        !           964:                case 6: /* do star */
        !           965:                    Star[0].x1 = (short) X(x) - px;
        !           966:                    Star[0].y1 = (short) Y(y);
        !           967:                    Star[0].x2 = (short) X(x) + px;
        !           968:                    Star[0].y2 = (short) Y(y);
        !           969:                    Star[1].x1 = (short) X(x);
        !           970:                    Star[1].y1 = (short) Y(y) - py;
        !           971:                    Star[1].x2 = (short) X(x);
        !           972:                    Star[1].y2 = (short) Y(y) + py;
        !           973:                    Star[2].x1 = (short) X(x) - px;
        !           974:                    Star[2].y1 = (short) Y(y) - py;
        !           975:                    Star[2].x2 = (short) X(x) + px;
        !           976:                    Star[2].y2 = (short) Y(y) + py;
        !           977:                    Star[3].x1 = (short) X(x) - px;
        !           978:                    Star[3].y1 = (short) Y(y) + py;
        !           979:                    Star[3].x2 = (short) X(x) + px;
        !           980:                    Star[3].y2 = (short) Y(y) - py;
        !           981:
        !           982:                    XDrawSegments(dpy, plot->pixmap, gc, Star, 4);
        !           983:                    break;
        !           984:                }
        !           985:                if (type != LineSolid || width != 0) {  /* select solid line */
        !           986:                    XSetLineAttributes(dpy, gc, width, type, CapButt, JoinBevel);
        !           987:                }
        !           988:            }
        !           989:        }
        !           990:     }
        !           991:
        !           992:     /* set new pixmap as window background */
        !           993:     XSetWindowBackgroundPixmap(dpy, plot->window, plot->pixmap);
        !           994:
        !           995:     /* trigger exposure of background pixmap */
        !           996:     XClearWindow(dpy, plot->window);
        !           997:
        !           998: #ifdef EXPORT_SELECTION
        !           999:     export_graph(plot);
        !          1000: #endif
        !          1001:
        !          1002:     XFlush(dpy);
        !          1003: }
        !          1004:
        !          1005: /*---------------------------------------------------------------------------
        !          1006:  *  reset all cursors (since we dont have a record of the previous terminal #)
        !          1007:  *---------------------------------------------------------------------------*/
        !          1008:
        !          1009: void reset_cursor()
        !          1010: {
        !          1011:     int plot_number;
        !          1012:     plot_struct *plot = plot_array;
        !          1013:
        !          1014:     for (plot_number = 0, plot = plot_array;
        !          1015:         plot_number < MAX_WINDOWS;
        !          1016:         ++plot_number, ++plot) {
        !          1017:        if (plot->window) {
        !          1018:            FPRINTF((stderr, "Window for plot %d exists\n", plot_number));
        !          1019:            XUndefineCursor(dpy, plot->window);;
        !          1020:        }
        !          1021:     }
        !          1022:
        !          1023:     FPRINTF((stderr, "Cursors reset\n"));
        !          1024:     return;
        !          1025: }
        !          1026:
        !          1027: /*-----------------------------------------------------------------------------
        !          1028:  *   resize - rescale last plot if window resized
        !          1029:  *---------------------------------------------------------------------------*/
        !          1030:
        !          1031: plot_struct *find_plot(window)
        !          1032: Window window;
        !          1033: {
        !          1034:     int plot_number;
        !          1035:     plot_struct *plot = plot_array;
        !          1036:
        !          1037:     for (plot_number = 0, plot = plot_array;
        !          1038:         plot_number < MAX_WINDOWS;
        !          1039:         ++plot_number, ++plot) {
        !          1040:        if (plot->window == window) {
        !          1041:            FPRINTF((stderr, "Event for plot %d\n", plot_number));
        !          1042:            return plot;
        !          1043:        }
        !          1044:     }
        !          1045:
        !          1046:     FPRINTF((stderr, "Bogus window 0x%x in event !\n", window));
        !          1047:     return NULL;
        !          1048: }
        !          1049:
        !          1050: void process_event(event)
        !          1051: XEvent *event;
        !          1052: {
        !          1053:     FPRINTF((stderr, "Event 0x%x\n", event->type));
        !          1054:
        !          1055:     switch (event->type) {
        !          1056:     case ConfigureNotify:
        !          1057:        {
        !          1058:            plot_struct *plot = find_plot(event->xconfigure.window);
        !          1059:            if (plot) {
        !          1060:                int w = event->xconfigure.width, h = event->xconfigure.height;
        !          1061:
        !          1062:                /* store settings in case window is closed then recreated */
        !          1063:                plot->x = event->xconfigure.x;
        !          1064:                plot->y = event->xconfigure.y;
        !          1065:                plot->posn_flags = (plot->posn_flags & ~PPosition) | USPosition;
        !          1066:
        !          1067:                if (w > 1 && h > 1 && (w != plot->width || h != plot->height)) {
        !          1068:                    plot->width = w;
        !          1069:                    plot->height = h;
        !          1070:                    plot->posn_flags = (plot->posn_flags & ~PSize) | USSize;
        !          1071:                    if (plot->pixmap) {
        !          1072:                        /* it is the wrong size now */
        !          1073:                        FPRINTF((stderr, "Free pixmap %d\n", 0));
        !          1074:                        XFreePixmap(dpy, plot->pixmap);
        !          1075:                        plot->pixmap = None;
        !          1076:                    }
        !          1077:                    display(plot);
        !          1078:                }
        !          1079:            }
        !          1080:            break;
        !          1081:        }
        !          1082:     case KeyPress:
        !          1083:        if (event->xkey.keycode == q_keycode) {
        !          1084:            plot_struct *plot = find_plot(event->xkey.window);
        !          1085:            if (plot)
        !          1086:                delete_plot(plot);
        !          1087:        }
        !          1088:        break;
        !          1089:     case ClientMessage:
        !          1090:        if (event->xclient.message_type == WM_PROTOCOLS &&
        !          1091:            event->xclient.format == 32 &&
        !          1092:            event->xclient.data.l[0] == WM_DELETE_WINDOW) {
        !          1093:            plot_struct *plot = find_plot(event->xclient.window);
        !          1094:            if (plot)
        !          1095:                delete_plot(plot);
        !          1096:        }
        !          1097:        break;
        !          1098: #ifdef EXPORT_SELECTION
        !          1099:     case SelectionNotify:
        !          1100:     case SelectionRequest:
        !          1101:        handle_selection_event(event);
        !          1102:        break;
        !          1103: #endif
        !          1104:     }
        !          1105: }
        !          1106:
        !          1107: /*-----------------------------------------------------------------------------
        !          1108:  *   preset - determine options, open display, create window
        !          1109:  *---------------------------------------------------------------------------*/
        !          1110:
        !          1111: #define On(v) ( !strcmp(v,"on") || !strcmp(v,"true") || \
        !          1112:                 !strcmp(v,"On") || !strcmp(v,"True") || \
        !          1113:                 !strcmp(v,"ON") || !strcmp(v,"TRUE") )
        !          1114:
        !          1115: #define AppDefDir "/usr/lib/X11/app-defaults"
        !          1116: #ifndef MAXHOSTNAMELEN
        !          1117: #define MAXHOSTNAMELEN 64
        !          1118: #endif
        !          1119:
        !          1120: static XrmDatabase dbCmd, dbApp, dbDef, dbEnv, db = (XrmDatabase) 0;
        !          1121:
        !          1122: char *pr_GetR(), *getenv(), *type[20];
        !          1123: XrmValue value;
        !          1124:
        !          1125: static XrmOptionDescRec options[] = {
        !          1126:     {"-mono", ".mono", XrmoptionNoArg, (caddr_t) "on"},
        !          1127:     {"-gray", ".gray", XrmoptionNoArg, (caddr_t) "on"},
        !          1128:     {"-clear", ".clear", XrmoptionNoArg, (caddr_t) "on"},
        !          1129:     {"-tvtwm", ".tvtwm", XrmoptionNoArg, (caddr_t) "on"},
        !          1130:     {"-pointsize", ".pointsize", XrmoptionSepArg, (caddr_t) NULL},
        !          1131:     {"-display", ".display", XrmoptionSepArg, (caddr_t) NULL},
        !          1132:     {"-name", ".name", XrmoptionSepArg, (caddr_t) NULL},
        !          1133:     {"-geometry", "*geometry", XrmoptionSepArg, (caddr_t) NULL},
        !          1134:     {"-background", "*background", XrmoptionSepArg, (caddr_t) NULL},
        !          1135:     {"-bg", "*background", XrmoptionSepArg, (caddr_t) NULL},
        !          1136:     {"-foreground", "*foreground", XrmoptionSepArg, (caddr_t) NULL},
        !          1137:     {"-fg", "*foreground", XrmoptionSepArg, (caddr_t) NULL},
        !          1138:     {"-bordercolor", "*bordercolor", XrmoptionSepArg, (caddr_t) NULL},
        !          1139:     {"-bd", "*bordercolor", XrmoptionSepArg, (caddr_t) NULL},
        !          1140:     {"-borderwidth", ".borderwidth", XrmoptionSepArg, (caddr_t) NULL},
        !          1141:     {"-bw", ".borderwidth", XrmoptionSepArg, (caddr_t) NULL},
        !          1142:     {"-font", "*font", XrmoptionSepArg, (caddr_t) NULL},
        !          1143:     {"-fn", "*font", XrmoptionSepArg, (caddr_t) NULL},
        !          1144:     {"-reverse", "*reverseVideo", XrmoptionNoArg, (caddr_t) "on"},
        !          1145:     {"-rv", "*reverseVideo", XrmoptionNoArg, (caddr_t) "on"},
        !          1146:     {"+rv", "*reverseVideo", XrmoptionNoArg, (caddr_t) "off"},
        !          1147:     {"-iconic", "*iconic", XrmoptionNoArg, (caddr_t) "on"},
        !          1148:     {"-synchronous", "*synchronous", XrmoptionNoArg, (caddr_t) "on"},
        !          1149:     {"-xnllanguage", "*xnllanguage", XrmoptionSepArg, (caddr_t) NULL},
        !          1150:     {"-selectionTimeout", "*selectionTimeout", XrmoptionSepArg, (caddr_t) NULL},
        !          1151:     {"-title", ".title", XrmoptionSepArg, (caddr_t) NULL},
        !          1152:     {"-xrm", NULL, XrmoptionResArg, (caddr_t) NULL},
        !          1153:     {"-raise", "*raise", XrmoptionNoArg, (caddr_t) "on"},
        !          1154:     {"-noraise", "*raise", XrmoptionNoArg, (caddr_t) "off"},
        !          1155:     {"-persist", "*persist", XrmoptionNoArg, (caddr_t) "on"}
        !          1156: };
        !          1157:
        !          1158: #define Nopt (sizeof(options) / sizeof(options[0]))
        !          1159:
        !          1160: void preset(argc, argv)
        !          1161: int argc;
        !          1162: char *argv[];
        !          1163: {
        !          1164:     int Argc = argc;
        !          1165:     char **Argv = argv;
        !          1166:
        !          1167: #ifdef VMS
        !          1168:     char *ldisplay = (char *) 0;
        !          1169: #else
        !          1170:     char *ldisplay = getenv("DISPLAY");
        !          1171: #endif
        !          1172:     char *home = getenv("HOME");
        !          1173:     char *server_defaults, *env, buffer[256];
        !          1174:
        !          1175:     /* avoid bus error when env vars are not set */
        !          1176:     if (ldisplay == NULL)
        !          1177:        ldisplay = "";
        !          1178:     if (home == NULL)
        !          1179:        home = "";
        !          1180:
        !          1181: /*---set to ignore ^C and ^Z----------------------------------------------*/
        !          1182:
        !          1183:     signal(SIGINT, SIG_IGN);
        !          1184: #ifdef SIGTSTP
        !          1185:     signal(SIGTSTP, SIG_IGN);
        !          1186: #endif
        !          1187:
        !          1188: /*---prescan arguments for "-name"----------------------------------------*/
        !          1189:
        !          1190:     while (++Argv, --Argc > 0) {
        !          1191:        if (!strcmp(*Argv, "-name") && Argc > 1) {
        !          1192:            safe_strncpy(Name, Argv[1], sizeof(Name));
        !          1193:            safe_strncpy(Class, Argv[1], sizeof(Class));
        !          1194:            if (Class[0] >= 'a' && Class[0] <= 'z')
        !          1195:                Class[0] -= 0x20;
        !          1196:        }
        !          1197:     }
        !          1198:     Argc = argc;
        !          1199:     Argv = argv;
        !          1200:
        !          1201: /*---parse command line---------------------------------------------------*/
        !          1202:
        !          1203:     XrmInitialize();
        !          1204:     XrmParseCommand(&dbCmd, options, Nopt, Name, &Argc, Argv);
        !          1205:     if (Argc > 1) {
        !          1206:        fprintf(stderr, "\n\
        !          1207: gnuplot: bad option: %s\n\
        !          1208: gnuplot: X11 aborted.\n", Argv[1]);
        !          1209:        EXIT(1);
        !          1210:     }
        !          1211:     if (pr_GetR(dbCmd, ".display"))
        !          1212:        ldisplay = (char *) value.addr;
        !          1213:
        !          1214: /*---open display---------------------------------------------------------*/
        !          1215:
        !          1216:     dpy = XOpenDisplay(ldisplay);
        !          1217:     if (!dpy) {
        !          1218:        fprintf(stderr, "\n\
        !          1219: gnuplot: unable to open display '%s'\n\
        !          1220: gnuplot: X11 aborted.\n", ldisplay);
        !          1221:        EXIT(1);
        !          1222:     }
        !          1223:     scr = DefaultScreen(dpy);
        !          1224:     vis = DefaultVisual(dpy, scr);
        !          1225:     D = DefaultDepth(dpy, scr);
        !          1226:     root = DefaultRootWindow(dpy);
        !          1227:     server_defaults = XResourceManagerString(dpy);
        !          1228:
        !          1229: /*---get symcode for key q ---*/
        !          1230:
        !          1231:     q_keycode = XKeysymToKeycode(dpy, XK_q);
        !          1232:
        !          1233: /**** atoms we will need later ****/
        !          1234:
        !          1235:     WM_PROTOCOLS = XInternAtom(dpy, "WM_PROTOCOLS", False);
        !          1236:     WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
        !          1237:
        !          1238:
        !          1239: /*---get application defaults--(subset of Xt processing)------------------*/
        !          1240:
        !          1241: #ifdef VMS
        !          1242:     strcpy(buffer, "DECW$USER_DEFAULTS:GNUPLOT_X11.INI");
        !          1243: #else
        !          1244: # ifdef OS2
        !          1245: /* for Xfree86 ... */
        !          1246:     {
        !          1247:        char *appdefdir = "XFree86/lib/X11/app-defaults";
        !          1248:        char *xroot = getenv("X11ROOT");
        !          1249:        sprintf(buffer, "%s/%s/%s", xroot, appdefdir, "Gnuplot");
        !          1250:     }
        !          1251: # else
        !          1252:     sprintf(buffer, "%s/%s", AppDefDir, "Gnuplot");
        !          1253: # endif /* !OS2 */
        !          1254: #endif /* !VMS */
        !          1255:
        !          1256:     dbApp = XrmGetFileDatabase(buffer);
        !          1257:     XrmMergeDatabases(dbApp, &db);
        !          1258:
        !          1259: /*---get server or ~/.Xdefaults-------------------------------------------*/
        !          1260:
        !          1261:     if (server_defaults)
        !          1262:        dbDef = XrmGetStringDatabase(server_defaults);
        !          1263:     else {
        !          1264: #ifdef VMS
        !          1265:        strcpy(buffer, "DECW$USER_DEFAULTS:DECW$XDEFAULTS.DAT");
        !          1266: #else
        !          1267:        sprintf(buffer, "%s/.Xdefaults", home);
        !          1268: #endif
        !          1269:        dbDef = XrmGetFileDatabase(buffer);
        !          1270:     }
        !          1271:     XrmMergeDatabases(dbDef, &db);
        !          1272:
        !          1273: /*---get XENVIRONMENT or  ~/.Xdefaults-hostname---------------------------*/
        !          1274:
        !          1275: #ifndef VMS
        !          1276:     if ((env = getenv("XENVIRONMENT")) != NULL)
        !          1277:        dbEnv = XrmGetFileDatabase(env);
        !          1278:     else {
        !          1279:        char *p = NULL, host[MAXHOSTNAMELEN];
        !          1280:
        !          1281:        if (GP_SYSTEMINFO(host) < 0) {
        !          1282:            fprintf(stderr, "gnuplot: %s failed. X11 aborted.\n", SYSINFO_METHOD);
        !          1283:            EXIT(1);
        !          1284:        }
        !          1285:        if ((p = strchr(host, '.')) != NULL)
        !          1286:            *p = '\0';
        !          1287:        sprintf(buffer, "%s/.Xdefaults-%s", home, host);
        !          1288:        dbEnv = XrmGetFileDatabase(buffer);
        !          1289:     }
        !          1290:     XrmMergeDatabases(dbEnv, &db);
        !          1291: #endif /* not VMS */
        !          1292:
        !          1293: /*---merge command line options-------------------------------------------*/
        !          1294:
        !          1295:     XrmMergeDatabases(dbCmd, &db);
        !          1296:
        !          1297: /*---set geometry, font, colors, line widths, dash styles, point size-----*/
        !          1298:
        !          1299:     pr_geometry();
        !          1300:     pr_font();
        !          1301:     pr_color();
        !          1302:     pr_width();
        !          1303:     pr_dashes();
        !          1304:     pr_pointsize();
        !          1305:     pr_raise();
        !          1306:     pr_persist();
        !          1307: }
        !          1308:
        !          1309: /*-----------------------------------------------------------------------------
        !          1310:  *   pr_GetR - get resource from database using "-name" option (if any)
        !          1311:  *---------------------------------------------------------------------------*/
        !          1312:
        !          1313: char *
        !          1314:  pr_GetR(xrdb, resource)
        !          1315: XrmDatabase xrdb;
        !          1316: char *resource;
        !          1317: {
        !          1318:     char name[128], class[128], *rc;
        !          1319:
        !          1320:     strcpy(name, Name);
        !          1321:     strcat(name, resource);
        !          1322:     strcpy(class, Class);
        !          1323:     strcat(class, resource);
        !          1324:     rc = XrmGetResource(xrdb, name, class, type, &value)
        !          1325:        ? (char *) value.addr
        !          1326:        : (char *) 0;
        !          1327:     return (rc);
        !          1328: }
        !          1329:
        !          1330: /*-----------------------------------------------------------------------------
        !          1331:  *   pr_color - determine color values
        !          1332:  *---------------------------------------------------------------------------*/
        !          1333:
        !          1334: char color_keys[Ncolors][30] = {
        !          1335:     "background", "bordercolor", "text", "border", "axis",
        !          1336:     "line1", "line2", "line3", "line4",
        !          1337:     "line5", "line6", "line7", "line8"
        !          1338: };
        !          1339: char color_values[Ncolors][30] = {
        !          1340:     "white", "black", "black", "black", "black",
        !          1341:     "red", "green", "blue", "magenta",
        !          1342:     "cyan", "sienna", "orange", "coral"
        !          1343: };
        !          1344: char gray_values[Ncolors][30] = {
        !          1345:     "black", "white", "white", "gray50", "gray50",
        !          1346:     "gray100", "gray60", "gray80", "gray40",
        !          1347:     "gray90", "gray50", "gray70", "gray30"
        !          1348: };
        !          1349:
        !          1350: void pr_color()
        !          1351: {
        !          1352:     unsigned long black = BlackPixel(dpy, scr), white = WhitePixel(dpy, scr);
        !          1353:     char option[20], color[30], *v, *ctype;
        !          1354:     XColor xcolor;
        !          1355:     Colormap cmap;
        !          1356:     double intensity = -1;
        !          1357:     int n;
        !          1358:
        !          1359:     pr_GetR(db, ".mono") && On(value.addr) && Mono++;
        !          1360:     pr_GetR(db, ".gray") && On(value.addr) && Gray++;
        !          1361:     pr_GetR(db, ".reverseVideo") && On(value.addr) && Rv++;
        !          1362:
        !          1363:     if (!Gray && (vis->class == GrayScale || vis->class == StaticGray))
        !          1364:        Mono++;
        !          1365:
        !          1366:     if (!Mono) {
        !          1367:        cmap = DefaultColormap(dpy, scr);
        !          1368:        ctype = (Gray) ? "Gray" : "Color";
        !          1369:
        !          1370:        for (n = 0; n < Ncolors; n++) {
        !          1371:            strcpy(option, ".");
        !          1372:            strcat(option, color_keys[n]);
        !          1373:            (n > 1) && strcat(option, ctype);
        !          1374:            v = pr_GetR(db, option)
        !          1375:                ? (char *) value.addr
        !          1376:                : ((Gray) ? gray_values[n] : color_values[n]);
        !          1377:
        !          1378:            if (sscanf(v, "%30[^,],%lf", color, &intensity) == 2) {
        !          1379:                if (intensity < 0 || intensity > 1) {
        !          1380:                    fprintf(stderr, "\ngnuplot: invalid color intensity in '%s'\n",
        !          1381:                            color);
        !          1382:                    intensity = 1;
        !          1383:                }
        !          1384:            } else {
        !          1385:                strcpy(color, v);
        !          1386:                intensity = 1;
        !          1387:            }
        !          1388:
        !          1389:            if (!XParseColor(dpy, cmap, color, &xcolor)) {
        !          1390:                fprintf(stderr, "\ngnuplot: unable to parse '%s'. Using black.\n",
        !          1391:                        color);
        !          1392:                colors[n] = black;
        !          1393:            } else {
        !          1394:                xcolor.red *= intensity;
        !          1395:                xcolor.green *= intensity;
        !          1396:                xcolor.blue *= intensity;
        !          1397:                if (XAllocColor(dpy, cmap, &xcolor)) {
        !          1398:                    colors[n] = xcolor.pixel;
        !          1399:                } else {
        !          1400:                    fprintf(stderr, "\ngnuplot: can't allocate '%s'. Using black.\n",
        !          1401:                            v);
        !          1402:                    colors[n] = black;
        !          1403:                }
        !          1404:            }
        !          1405:        }
        !          1406:     } else {
        !          1407:        colors[0] = (Rv) ? black : white;
        !          1408:        for (n = 1; n < Ncolors; n++)
        !          1409:            colors[n] = (Rv) ? white : black;
        !          1410:     }
        !          1411: }
        !          1412:
        !          1413: /*-----------------------------------------------------------------------------
        !          1414:  *   pr_dashes - determine line dash styles
        !          1415:  *---------------------------------------------------------------------------*/
        !          1416:
        !          1417: char dash_keys[Ndashes][10] = {
        !          1418:     "border", "axis",
        !          1419:     "line1", "line2", "line3", "line4", "line5", "line6", "line7", "line8"
        !          1420: };
        !          1421:
        !          1422: char dash_mono[Ndashes][10] = {
        !          1423:     "0", "16",
        !          1424:     "0", "42", "13", "44", "15", "4441", "42", "13"
        !          1425: };
        !          1426:
        !          1427: char dash_color[Ndashes][10] = {
        !          1428:     "0", "16",
        !          1429:     "0", "0", "0", "0", "0", "0", "0", "0"
        !          1430: };
        !          1431:
        !          1432: void pr_dashes()
        !          1433: {
        !          1434:     int n, j, l, ok;
        !          1435:     char option[20], *v;
        !          1436:
        !          1437:     for (n = 0; n < Ndashes; n++) {
        !          1438:        strcpy(option, ".");
        !          1439:        strcat(option, dash_keys[n]);
        !          1440:        strcat(option, "Dashes");
        !          1441:        v = pr_GetR(db, option)
        !          1442:            ? (char *) value.addr
        !          1443:            : ((Mono) ? dash_mono[n] : dash_color[n]);
        !          1444:        l = strlen(v);
        !          1445:        if (l == 1 && *v == '0') {
        !          1446:            dashes[n][0] = (unsigned char) 0;
        !          1447:            continue;
        !          1448:        }
        !          1449:        for (ok = 0, j = 0; j < l; j++) {
        !          1450:            v[j] >= '1' && v[j] <= '9' && ok++;
        !          1451:        }
        !          1452:        if (ok != l || (ok != 2 && ok != 4)) {
        !          1453:            fprintf(stderr, "gnuplot: illegal dashes value %s:%s\n", option, v);
        !          1454:            dashes[n][0] = (unsigned char) 0;
        !          1455:            continue;
        !          1456:        }
        !          1457:        for (j = 0; j < l; j++) {
        !          1458:            dashes[n][j] = (unsigned char) (v[j] - '0');
        !          1459:        }
        !          1460:        dashes[n][l] = (unsigned char) 0;
        !          1461:     }
        !          1462: }
        !          1463:
        !          1464: /*-----------------------------------------------------------------------------
        !          1465:  *   pr_font - determine font
        !          1466:  *---------------------------------------------------------------------------*/
        !          1467:
        !          1468: void pr_font()
        !          1469: {
        !          1470:     char *fontname = pr_GetR(db, ".font");
        !          1471:
        !          1472:     if (!fontname)
        !          1473:        fontname = FallbackFont;
        !          1474:     font = XLoadQueryFont(dpy, fontname);
        !          1475:     if (!font) {
        !          1476:        fprintf(stderr, "\ngnuplot: can't load font '%s'\n", fontname);
        !          1477:        fprintf(stderr, "gnuplot: using font '%s' instead.\n", FallbackFont);
        !          1478:        font = XLoadQueryFont(dpy, FallbackFont);
        !          1479:        if (!font) {
        !          1480:            fprintf(stderr, "\
        !          1481: gnuplot: can't load font '%s'\n\
        !          1482: gnuplot: no useable font - X11 aborted.\n", FallbackFont);
        !          1483:            EXIT(1);
        !          1484:        }
        !          1485:     }
        !          1486:     vchar = font->ascent + font->descent;
        !          1487: }
        !          1488:
        !          1489: /*-----------------------------------------------------------------------------
        !          1490:  *   pr_geometry - determine window geometry
        !          1491:  *---------------------------------------------------------------------------*/
        !          1492:
        !          1493: void pr_geometry()
        !          1494: {
        !          1495:     char *geometry = pr_GetR(db, ".geometry");
        !          1496:     int x, y, flags;
        !          1497:     unsigned int w, h;
        !          1498:
        !          1499:     if (geometry) {
        !          1500:        flags = XParseGeometry(geometry, &x, &y, &w, &h);
        !          1501:        if (flags & WidthValue)
        !          1502:            gW = w;
        !          1503:        if (flags & HeightValue)
        !          1504:            gH = h;
        !          1505:        if (flags & (WidthValue | HeightValue))
        !          1506:            gFlags = (gFlags & ~PSize) | USSize;
        !          1507:
        !          1508:        if (flags & XValue)
        !          1509:            gX = (flags & XNegative) ? x + DisplayWidth(dpy, scr) - gW - BorderWidth * 2 : x;
        !          1510:
        !          1511:        if (flags & YValue)
        !          1512:            gY = (flags & YNegative) ? y + DisplayHeight(dpy, scr) - gH - BorderWidth * 2 : y;
        !          1513:
        !          1514:        if (flags & (XValue | YValue))
        !          1515:            gFlags = (gFlags & ~PPosition) | USPosition;
        !          1516:     }
        !          1517: }
        !          1518:
        !          1519: /*-----------------------------------------------------------------------------
        !          1520:  *   pr_pointsize - determine size of points for 'points' plotting style
        !          1521:  *---------------------------------------------------------------------------*/
        !          1522:
        !          1523: void pr_pointsize()
        !          1524: {
        !          1525:     if (pr_GetR(db, ".pointsize")) {
        !          1526:        if (sscanf((char *) value.addr, "%lf", &pointsize) == 1) {
        !          1527:            if (pointsize <= 0 || pointsize > 10) {
        !          1528:                fprintf(stderr, "\ngnuplot: invalid pointsize '%s'\n", value.addr);
        !          1529:                pointsize = 1;
        !          1530:            }
        !          1531:        } else {
        !          1532:            fprintf(stderr, "\ngnuplot: invalid pointsize '%s'\n", value.addr);
        !          1533:            pointsize = 1;
        !          1534:        }
        !          1535:     } else {
        !          1536:        pointsize = 1;
        !          1537:     }
        !          1538: }
        !          1539:
        !          1540: /*-----------------------------------------------------------------------------
        !          1541:  *   pr_width - determine line width values
        !          1542:  *---------------------------------------------------------------------------*/
        !          1543:
        !          1544: char width_keys[Nwidths][30] = {
        !          1545:     "border", "axis",
        !          1546:     "line1", "line2", "line3", "line4", "line5", "line6", "line7", "line8"
        !          1547: };
        !          1548:
        !          1549: void pr_width()
        !          1550: {
        !          1551:     int n;
        !          1552:     char option[20], *v;
        !          1553:
        !          1554:     for (n = 0; n < Nwidths; n++) {
        !          1555:        strcpy(option, ".");
        !          1556:        strcat(option, width_keys[n]);
        !          1557:        strcat(option, "Width");
        !          1558:        if ((v = pr_GetR(db, option)) != NULL) {
        !          1559:            if (*v < '0' || *v > '4' || strlen(v) > 1)
        !          1560:                fprintf(stderr, "gnuplot: illegal width value %s:%s\n", option, v);
        !          1561:            else
        !          1562:                widths[n] = (unsigned int) atoi(v);
        !          1563:        }
        !          1564:     }
        !          1565: }
        !          1566:
        !          1567: /*-----------------------------------------------------------------------------
        !          1568:  *   pr_window - create window
        !          1569:  *---------------------------------------------------------------------------*/
        !          1570:
        !          1571: Window pr_window(flags, x, y, width, height)
        !          1572: unsigned int flags;
        !          1573: int x, y;
        !          1574: unsigned int width, height;
        !          1575: {
        !          1576:     char *title = pr_GetR(db, ".title");
        !          1577:     static XSizeHints hints;
        !          1578:     int Tvtwm = 0;
        !          1579:
        !          1580:     Window win = XCreateSimpleWindow(dpy, root, x, y, width, height, BorderWidth,
        !          1581:                                     colors[1], colors[0]);
        !          1582:
        !          1583:     /* ask ICCCM-compliant window manager to tell us when close window
        !          1584:      * has been chosen, rather than just killing us
        !          1585:      */
        !          1586:
        !          1587:     XChangeProperty(dpy, win, WM_PROTOCOLS, XA_ATOM, 32, PropModeReplace,
        !          1588:                    (unsigned char *) &WM_DELETE_WINDOW, 1);
        !          1589:
        !          1590:     pr_GetR(db, ".clear") && On(value.addr) && Clear++;
        !          1591:     pr_GetR(db, ".tvtwm") && On(value.addr) && Tvtwm++;
        !          1592:
        !          1593:     if (!Tvtwm) {
        !          1594:        hints.flags = flags;
        !          1595:     } else {
        !          1596:        hints.flags = (flags & ~USPosition) | PPosition;        /* ? */
        !          1597:     }
        !          1598:     hints.x = gX;
        !          1599:     hints.y = gY;
        !          1600:     hints.width = width;
        !          1601:     hints.height = height;
        !          1602:
        !          1603:     XSetNormalHints(dpy, win, &hints);
        !          1604:
        !          1605:     if (pr_GetR(db, ".iconic") && On(value.addr)) {
        !          1606:        XWMHints wmh;
        !          1607:
        !          1608:        wmh.flags = StateHint;
        !          1609:        wmh.initial_state = IconicState;
        !          1610:        XSetWMHints(dpy, win, &wmh);
        !          1611:     }
        !          1612:     XStoreName(dpy, win, ((title) ? title : Class));
        !          1613:
        !          1614:     XSelectInput(dpy, win, KeyPressMask | StructureNotifyMask);
        !          1615:     XMapWindow(dpy, win);
        !          1616:
        !          1617:     return win;
        !          1618: }
        !          1619:
        !          1620:
        !          1621: /***** pr_raise ***/
        !          1622: void pr_raise()
        !          1623: {
        !          1624:     if (pr_GetR(db, ".raise"))
        !          1625:        do_raise = (On(value.addr));
        !          1626: }
        !          1627:
        !          1628:
        !          1629: void pr_persist()
        !          1630: {
        !          1631:     if (pr_GetR(db, ".persist"))
        !          1632:        persist = (On(value.addr));
        !          1633: }
        !          1634:
        !          1635: /************ code to handle selection export *********************/
        !          1636:
        !          1637: #ifdef EXPORT_SELECTION
        !          1638:
        !          1639: /* bit of a bodge, but ... */
        !          1640: static struct plot_struct *exported_plot;
        !          1641:
        !          1642: void export_graph(plot)
        !          1643: struct plot_struct *plot;
        !          1644: {
        !          1645:     FPRINTF((stderr, "export_graph(0x%x)\n", plot));
        !          1646:
        !          1647:     XSetSelectionOwner(dpy, EXPORT_SELECTION, plot->window, CurrentTime);
        !          1648:     /* to check we have selection, we would have to do a
        !          1649:      * GetSelectionOwner(), but if it failed, it failed - no big deal
        !          1650:      */
        !          1651:     exported_plot = plot;
        !          1652: }
        !          1653:
        !          1654: void handle_selection_event(event)
        !          1655: XEvent *event;
        !          1656: {
        !          1657:     switch (event->type) {
        !          1658:     case SelectionRequest:
        !          1659:        {
        !          1660:            XEvent reply;
        !          1661:
        !          1662:            static Atom XA_TARGETS = (Atom) 0;
        !          1663:            if (XA_TARGETS == 0)
        !          1664:                XA_TARGETS = XInternAtom(dpy, "TARGETS", False);
        !          1665:
        !          1666:            reply.type = SelectionNotify;
        !          1667:            reply.xselection.send_event = True;
        !          1668:            reply.xselection.display = event->xselectionrequest.display;
        !          1669:            reply.xselection.requestor = event->xselectionrequest.requestor;
        !          1670:            reply.xselection.selection = event->xselectionrequest.selection;
        !          1671:            reply.xselection.target = event->xselectionrequest.target;
        !          1672:            reply.xselection.property = event->xselectionrequest.property;
        !          1673:            reply.xselection.time = event->xselectionrequest.time;
        !          1674:
        !          1675:            FPRINTF((stderr, "selection request\n"));
        !          1676:
        !          1677:            if (reply.xselection.target == XA_TARGETS) {
        !          1678:                static Atom targets[] = {XA_PIXMAP, XA_COLORMAP};
        !          1679:
        !          1680:                FPRINTF((stderr, "Targets request from %d\n", reply.xselection.requestor));
        !          1681:
        !          1682:                XChangeProperty(dpy, reply.xselection.requestor,
        !          1683:                                reply.xselection.property, reply.xselection.target, 32, PropModeReplace,
        !          1684:                                (unsigned char *) targets, 2);
        !          1685:            } else if (reply.xselection.target == XA_COLORMAP) {
        !          1686:                Colormap cmap = DefaultColormap(dpy, 0);
        !          1687:
        !          1688:                FPRINTF((stderr, "colormap request from %d\n", reply.xselection.requestor));
        !          1689:
        !          1690:                XChangeProperty(dpy, reply.xselection.requestor,
        !          1691:                                reply.xselection.property, reply.xselection.target, 32, PropModeReplace,
        !          1692:                                (unsigned char *) &cmap, 1);
        !          1693:            } else if (reply.xselection.target == XA_PIXMAP) {
        !          1694:
        !          1695:                FPRINTF((stderr, "pixmap request from %d\n", reply.xselection.requestor));
        !          1696:
        !          1697:                XChangeProperty(dpy, reply.xselection.requestor,
        !          1698:                                reply.xselection.property, reply.xselection.target, 32, PropModeReplace,
        !          1699:                          (unsigned char *) &(exported_plot->pixmap), 1);
        !          1700:            } else {
        !          1701:                reply.xselection.property = None;
        !          1702:            }
        !          1703:
        !          1704:            XSendEvent(dpy, reply.xselection.requestor, False, 0L, &reply);
        !          1705:            /* we never block on XNextEvent(), so must flush manually
        !          1706:             * (took me *ages* to find this out !)
        !          1707:             */
        !          1708:
        !          1709:            XFlush(dpy);
        !          1710:        }
        !          1711:        break;
        !          1712:     }
        !          1713: }
        !          1714:
        !          1715: #endif /* EXPORT_SELECTION */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>