1 /*  Copyright (C) 1988-2005 by Brian Doty and the Institute
2                   of Global Environment and Society (IGES).
3 
4     See file COPYRIGHT for more information.   */
5 
6 /*
7  * Include ./configure's header file
8  */
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <X11/Xlib.h>
16 #include <X11/Xutil.h>
17 #include <X11/Xos.h>
18 #include <X11/Xatom.h>
19 #include <X11/keysym.h>
20 
21 #ifdef XLIBEMU
22 #include <conio.h>
23 char x11_initialized=0;
24 #endif
25 
26 #include "gx.h"
27 #include "bitmaps.h"
28 
29 /* Following function prototype has to go here since it
30    depends on X include information, which shouln't go in gx.h */
31 
32 /*  gxbcol:  Assign best rgb to color number from standard colormap */
33 int gxbcol (XStandardColormap*, XColor *);
34 
35 /* Interface for X11 Release 3  */
36 
37 /* Device interface level.  Following routines need to be
38    interfaced to the hardware:
39 
40    gxdbgn - Initialize graphics output.  Set up any hardware
41             scaling needed, clear the graphics display area,
42             etc.
43    gxdcol - Set hardware color.  The colors should be set up
44             as follows:
45             0 - black;   1 - white    2 - red     3 - green
46             4 - blue     5 - cyan     6 - magenta 7 - yellow
47             8 - orange   9 - purple  10 - yell-grn  11 - lt.blue
48            12 - ora.yell 3 - blu-grn 14 - blu-purp  15 - grey
49             If colors are not available then grey scales can
50             be used, or the call can be a no op.
51    gxdwid - Set hardware line weight.
52    gxdfrm - New frame.  If in single buffer mode, clear the active
53             display.  If in double buffer mode, clear the background
54             buffer.
55    gxdsgl - Initiate single buffer mode.  Normal mode of operation.
56    gxddbl - Initiate double buffer mode, if available.  Both the
57             foreground and background displays should be cleared.
58    gxdswp - Swap buffers when in double buffer mode.  Should take
59             no action if in single buffer mode.
60    gxdrec - Draw a color filled rectangle.
61    gxddrw - Draw a line using current attributes
62    gxdmov - Move to a new point
63    gxdend - Terminate graphics output.
64                                                                   */
65 
66 static int batch=0;                       /* Batch mode? */
67 static int wchose=0;                      /* Controls technique for wide lines 1= s/w 0 X server*/
68 static int lcolor,lwidth,owidth;          /* Current attributes */
69 static int grflg;                         /* Greyscale flag */
70 static int devbck;                        /* Device background */
71 static float xscl,yscl;                   /* Window Scaling     */
72 static int xxx,yyy;                       /* Old position       */
73 static float xsize, ysize;                /* User specified size*/
74 static unsigned long cvals[120];          /* Color pixel values */
75 static int cused[120];                    /* Color is assigned */
76 static int cmach[120];                    /* Color is matched */
77 static int dblmode;                       /* single or double buffering */
78 static int width,height,depth;            /* Window dimensions */
79 
80 static int reds[16] =   {  0,255,250,  0, 30,  0,240,230,240,160,160,  0,230,  0,130,170};
81 static int greens[16] = {  0,255, 60,220, 60,200,  0,220,130,  0,230,160,175,210,  0,170};
82 static int blues[16]  = {  0,255, 60,  0,255,200,130, 50, 40,200, 50,255, 45,140,220,170};
83 
84 static int greys[16] = {0,255,215,140,80,110,230,170,200,50,155,95,185,125,65,177};
85 static int grrev[16] = {0,1,14,3,8,7,9,5,4,6,13,12,11,10,2,15};
86 
87 /* Various arrays are kept for structures that describe displayed
88    widgets.  This information is kept in static arrays for
89    efficiency reasons -- so the arrays will tend to be in memory
90    together and will be much faster to scan when paging is
91    going on.  A linked list set up would be much easier to code
92    and much cleaner, but at least for now I will stick with
93    the pre-defined arrays.  */
94 
95 static struct gobj obj[512];    /* Displayed objects */
96 static struct gobj obj2[512];   /* Background objects */
97 static int obnum,obnum2;        /* Current number of objects */
98 static struct gbtn btn[256];    /* Current buttons */
99 static struct gbtn btn2[256];   /* Background buttons */
100 static struct grbb rbb[32];     /* Current rubber-band regions */
101 static struct grbb rbb2[32];    /* Background rbb regions */
102 static struct gdmu dmu[200];    /* Current dropmenus */
103 static struct gdmu dmu2[200];   /* Background dropmenus */
104 static struct gdlg dlg[1];      /* Current dialog */
105 
106 static struct gevent *evbase;   /* Anchor for GrADS event queue */
107 
108 /* All stuff passed to Xlib routines as args are put here in
109    static areas since we are not invoking Xlib routines from main*/
110 
111 static Screen *sptr;
112 Display *display=(Display *)NULL;
113 static int snum;
114 static GC gc;
115 static XGCValues values;
116 static XEvent report;
117 Window win=(Window) NULL;    /* used via extern in gagui */
118 static Pixmap pmap;
119 static Pixmap pmaps[200];
120 static Drawable drwbl;
121 static char *window_name = "GrADS " GRADS_VERSION "";
122 /*char *window_name = "GrADS";*/
123 static char *display_name = NULL;
124 static char *icon_name = "GrADS";
125 static Pixmap icon_pixmap;
126 static XSizeHints size_hints;
127 static XIconSize *size_list;
128 static int argc;
129 static char **argv;
130 static char *args[4];
131 static char *name = "grads";
132 static char *dgeom = "500x400+10+10";
133 static char *ugeom = NULL;
134 static Colormap cmap;
135 static XColor cell;
136 static XPoint *point;
137 static int dblmode;                     /* single or double buffering */
138 /*gl 980114 int width,height,depth; gl*/
139 static XFontStruct *font1, *font2, *font3;
140 /* XFontStruct *fontc1, *fontc2, *fontc3;  */
141 static XFontStruct *font1i, *font2i, *font3i;
142 static XSetWindowAttributes xsetw;
143 static int gfont,cfont;                       /* Font in use by grads */
144 
145 static int pfilld[200];
146 
147 static int rstate = 1;              /* Redraw state -- when zero,
148                                       acceptance of X Events is
149                                       blocked. */
150 static int bsflg;                   /* Backing store enabled or not */
151 static int excnt;                   /* Count of exposes to skip */
152 
153 /* Invokes usage of software to generate wide lines (vs Xserver) */
154 
gxwdln(void)155 void gxwdln (void) {
156   wchose=1;
157 }
158 
159 /* tell x interface that we are in batch mode */
160 
gxdbat(void)161 void gxdbat (void) {
162   batch = 1;
163 }
164 
165 /* Routine to specify user X stuff (geom string, window name).  Must be
166    called before gxdbgn to have any affect */
167 
gxdgeo(char * arg)168 void gxdgeo (char *arg) {
169   ugeom = arg;
170 }
171 
gxdbgn(float xsz,float ysz)172 void gxdbgn (float xsz, float ysz) {
173 int dw, dh, flag, i, ipos, jpos, border;
174 char **flist,*xfnam;
175 
176   for (i=0; i<200; i++) pfilld[i] = 0;
177   for (i=0; i<100; i++) cused[i] = 0;
178   for (i=0; i<256; i++) { btn[i].ch = NULL; btn2[i].ch = NULL; }
179   for (i=0; i<256; i++) { btn[i].num = -1; btn2[i].num = -1; }
180   for (i=0; i<32; i++) { rbb[i].num = -1; rbb2[i].num = -1; }
181   for (i=0; i<200; i++) { dmu[i].num = -1; dmu2[i].num = -1; }
182   for (i=0; i<512; i++) { obj[i].type = -1; obj2[i].type = -1; }
183   obnum = 0; obnum2 = 0;
184   evbase = NULL;
185   excnt = 0;
186 
187   args[0] = name;
188   args[1] = NULL;
189   argv = args;
190   argc = 1;
191 
192   xsize = xsz;
193   ysize = ysz;
194   border = 4;
195 
196   /* Connect to X server */
197 
198   if ( (display=XOpenDisplay(display_name)) == NULL ) {
199     printf("Error in GXSTRT: Unable to connect to X server\n");
200     exit( -1 );
201   }
202 
203   /* Get screen size from display structure macro, then figure out
204      proper window size */
205 
206   snum = DefaultScreen(display);
207   sptr = DefaultScreenOfDisplay(display);
208   bsflg = 0;
209   if (DoesBackingStore(sptr)) bsflg = 1;
210   cmap = DefaultColormap(display, snum);
211   dw = DisplayWidth(display, snum);
212   dh = DisplayHeight(display, snum);
213   depth = DefaultDepth(display, snum);
214   ipos = 0;
215   jpos = 0;
216 
217 #if defined (XLIBEMU)
218   x11_initialized = 1;    /*ams I need this for keyboard handling ams*/
219   if ( xsize >= ysize ) {           /* landscape */
220          dw = ( dw >= 800 ) ? 0.9*dw : 0.72*dw;
221   } else {                          /* portrait */
222          dw = ( dw >= 800 ) ? 0.7*dw*xsz/ysz : 0.56*dw*xsz/ysz;
223   }
224   dh = (int)((float)(dw)*ysz/xsz);
225 
226 #elif defined(XLIBEMU32)
227   if ( xsize >= ysize ) {           /* landscape */
228        dw = 0.96 * dw;
229        dh = (int)((float)(dw)*ysz/xsz);
230   } else {                          /* portrait */
231        dh = 0.96 * dh;
232        ipos = (int) dw;
233        dw = (int)((float)(dh)*xsz/ysz);
234        ipos = ( ipos - dw ) / 2;
235   }
236   border = 0;
237   GrMouseEraseCursor();
238 #else         /* not XLIBEMU (Generic Unix) */
239 
240   dw = dw/2;
241   dh = (int)((float)(dw)*ysz/xsz);
242 
243 #endif        /* XLIBEMU */
244 
245   xscl = (float)(dw)/xsize;
246   yscl = (float)(dh)/ysize;
247 
248 
249   size_hints.flags = PPosition | PSize ;
250   if (ugeom) {
251     XGeometry (display, snum, ugeom, dgeom, 4, 1, 1, 0, 0,
252         &ipos, &jpos, &dw, &dh);
253     size_hints.flags = USPosition | USSize ;
254   }
255   size_hints.x = ipos;
256   size_hints.y = jpos;
257   size_hints.width = dw;
258   size_hints.height = dh;
259   width = dw ; /* hoop */
260   height = dh ; /* hoop */
261   xscl = (float) (dw) / xsize ; /* hoop */
262   yscl = (float) (dh) / ysize ; /* hoop */
263 
264   /* Create window */
265 
266   win = XCreateSimpleWindow(display, RootWindow(display,snum),
267         ipos, jpos, dw, dh, border,
268         WhitePixel(display, snum), BlackPixel(display,snum));
269   devbck = 0;
270 
271   /* Set up icon pixmap */
272 
273   icon_pixmap = XCreateBitmapFromData(display, win, icon_bitmap_bits,
274                 icon_bitmap_width, icon_bitmap_height);
275 
276   /* Set standard properties */
277 
278   XSetStandardProperties(display, win, window_name, icon_name,
279        icon_pixmap, argv, argc, &size_hints);
280 
281   /* Set colors */
282 
283   for (i=0; i<16; i++) {
284     cell.red = reds[i]*256;
285     cell.blue = blues[i]*256;
286     cell.green = greens[i]*256;
287     if (XAllocColor(display, cmap, &cell)) {
288       cvals[i] = cell.pixel;
289     } else {
290       cvals[i] = cvals[1];    /* Assume white and black got allocated */
291     }
292     cused[i] = 1;
293   }
294   for (i=0; i<16; i++) {
295     cell.red = greys[i]*256;
296     cell.blue = greys[i]*256;
297     cell.green = greys[i]*256;
298     if (XAllocColor(display, cmap, &cell)) {
299       cvals[i+100] = cell.pixel;
300     } else {
301       cvals[i+100] = cvals[15];
302     }
303     cused[i+100] = 1;
304   }
305 
306   /* Select event types */
307 
308   XSelectInput(display, win, ButtonReleaseMask | ButtonPressMask |
309       ButtonMotionMask | ExposureMask | StructureNotifyMask);
310 
311   /* Get a Graphics Context */
312 
313   gc = XCreateGC(display, win, 0L, &values);
314   XSetForeground(display, gc, cvals[1]);
315   XSetLineAttributes(display, gc, 0L, LineSolid,
316                      CapButt, JoinBevel);
317   lwidth = 1;
318   owidth = 0;
319   lcolor = 1;
320   grflg = 0;
321 
322   /* Display Window */
323 
324   XMapWindow(display, win);
325 
326   /* We now have to wait for the expose event that indicates our
327      window is up.  Also handle any resizes so we get the scaling
328      right in case it gets changed right away.  We will check again
329      for resizes during frame operations */
330 
331 #ifndef __CYGWIN32__
332   flag = 1;
333   while (flag)  {
334     XNextEvent(display, &report);
335     switch  (report.type) {
336     case Expose:
337       if (report.xexpose.count != 0) break;
338       else flag = 0;
339       break;
340     case ConfigureNotify:
341       width = report.xconfigure.width;
342       height = report.xconfigure.height;
343       xscl = (float)(width)/xsize;
344       yscl = (float)(height)/ysize;
345       break;
346     }
347   }
348 #endif /* __CYGWIN32__ */
349 
350   /* Now ready for drawing, so we can exit. */
351 
352   drwbl = win;   /* Initial drawable is the visible window */
353   dblmode = 0;   /* Initially no double buffering mode     */
354 
355   xsetw.backing_store = Always;
356   XChangeWindowAttributes (display, win, CWBackingStore, &xsetw);
357 
358   /* Set up a font */
359 
360   font1 = NULL;
361   font2 = NULL;
362   font3 = NULL;
363   font1i = NULL;
364   font2i = NULL;
365   font3i = NULL;
366 
367   xfnam = gxgsym("GAXFS");
368   if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
369   else flist = NULL;
370   if (flist==NULL) {
371     flist = XListFonts (display, "-adobe-helvetica-bold-r-normal-*-80*", 1, &i);
372   }
373   if (flist==NULL) {
374     flist = XListFonts (display, "-adobe-helvetica-bold-r-normal-*-100*", 1, &i);
375   }
376   if (flist==NULL) {
377     font1 = XLoadQueryFont (display, "fixed");
378   } else {
379     font1 = XLoadQueryFont (display, *flist);
380     if (font1==NULL) printf ("ERROR: Unable to open a basic font!!!\n");
381     XFreeFontNames (flist);
382   }
383 
384   xfnam = gxgsym("GAXFSI");
385   if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
386   else flist = NULL;
387   if (flist==NULL) {
388     flist = XListFonts (display, "-adobe-helvetica-bold-o-normal-*-80*", 1, &i);
389   }
390   if (flist==NULL) {
391     flist = XListFonts (display, "-adobe-helvetica-bold-o-normal-*-100*", 1, &i);
392   }
393   if (flist==NULL) {
394     font1i = XLoadQueryFont (display, "fixed");
395   } else {
396     font1i = XLoadQueryFont (display, *flist);
397     if (font1i==NULL) font1i = font1;
398     XFreeFontNames (flist);
399   }
400 
401   xfnam = gxgsym("GAXFM");
402   if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
403   else flist = NULL;
404   if (flist==NULL) {
405     flist = XListFonts (display, "-adobe-helvetica-bold-r-normal--??-100*", 1, &i);
406   }
407   if (flist==NULL) {
408     flist = XListFonts (display, "-adobe-helvetica-bold-r-normal-*-120*", 1, &i);
409   }
410   if (flist==NULL) {
411     font2 = font1;
412   } else {
413     font2 = XLoadQueryFont (display, *flist);
414     if (font2==NULL) font2 = font1;
415     XFreeFontNames (flist);
416   }
417   xfnam = gxgsym("GAXFMI");
418   if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
419   else flist = NULL;
420   if (flist==NULL) {
421     flist = XListFonts (display, "-adobe-helvetica-bold-o-normal--??-100*", 1, &i);
422   }
423   if (flist==NULL) {
424     flist = XListFonts (display, "-adobe-helvetica-bold-o-normal-*-120*", 1, &i);
425   }
426   if (flist==NULL) {
427     font2i = font1i;
428   } else {
429     font2i = XLoadQueryFont (display, *flist);
430     if (font2i==NULL) font2i = font1i;
431     XFreeFontNames (flist);
432   }
433 
434   xfnam = gxgsym("GAXFL");
435   if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
436   else flist = NULL;
437   if (flist==NULL) {
438     flist = XListFonts (display, "-adobe-helvetica-bold-r-normal-*-140*", 1, &i);
439   }
440   if (flist==NULL) {
441     font3 = font2;
442   } else {
443     font3 = XLoadQueryFont (display, *flist);
444     if (font3==NULL) font3 = font2;
445     XFreeFontNames (flist);
446   }
447   xfnam = gxgsym("GAXFLI");
448   if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
449   else flist = NULL;
450   if (flist==NULL) {
451     flist = XListFonts (display, "-adobe-helvetica-bold-o-normal-*-140*", 1, &i);
452   }
453   if (flist==NULL) {
454     font3i = font2i;
455   } else {
456     font3i = XLoadQueryFont (display, *flist);
457     if (font3i==NULL) font3i = font2i;
458     XFreeFontNames (flist);
459   }
460   cfont = 0;
461   gxdsfn();
462 
463 #ifdef XLIBEMU
464   fvwm();
465   console();
466 #endif
467 
468 }
469 
gxgrey(int flag)470 void gxgrey (int flag) {
471   grflg = flag;
472 }
473 
gxdend(void)474 void gxdend (void) {
475   XFreeGC(display, gc);
476   XCloseDisplay(display);
477 }
478 
479 /* Frame action.  Values for action are:
480       0 -- new frame (clear display), wait before clearing.
481       1 -- new frame, no wait.
482       2 -- New frame in double buffer mode.
483       7 -- new frame, but just clear graphics.  Do not clear
484            event queue; redraw widgets.
485       8 -- clear only the event queue.
486       9 -- flush the X request buffer */
487 
gxdfrm(int iact)488 void gxdfrm (int iact) {
489 struct gevent *geve, *geve2;
490 int i;
491   if (iact==9) {
492     gxdeve(0);
493     XFlush(display);
494     return;
495   }
496   if (iact==0 || iact==1 || iact==7) {
497     XSetForeground(display, gc, cvals[devbck]);
498     XFillRectangle (display, drwbl, gc, 0, 0, width, height);
499     XSetForeground(display, gc, cvals[lcolor]);
500     for (i=0; i<512; i++) obj[i].type = -1;
501     obnum = 0;
502   }
503 
504   /* Flush X event queue.  If iact is 7, keep the event info,
505      otherwise discard it. */
506 
507   if (iact==7) gxdeve(0);
508   else {
509     while (XCheckMaskEvent(display, ButtonReleaseMask | ButtonPressMask |
510              ButtonMotionMask | KeyPressMask |
511              ExposureMask | StructureNotifyMask, &report)) {
512       if (report.type==ConfigureNotify) {
513         if(width!=report.xconfigure.width||height!=report.xconfigure.height){
514           width = report.xconfigure.width;
515           height = report.xconfigure.height;
516           xscl = (float)(width)/xsize;
517           yscl = (float)(height)/ysize;
518           gxdsfn();
519           if (iact==8) gxdrdw();
520         }
521       }
522     }
523 
524     /* Flush GrADS event queue */
525 
526     geve = evbase;
527     while (geve) {
528       geve2 = geve->forw;
529       free (geve);
530       geve = geve2;
531     }
532     evbase = NULL;
533   }
534 
535   /* Reset all widgets if appropriate. */
536 
537   if (iact<7 && iact!=2) gxrswd(0);
538 
539   /* Redraw all widgets if appropriate.*/
540 
541   if (iact==7) {
542     gxrdrw(0);
543     XFlush(display);
544   }
545 }
546 
547 /* Examine X event queue.  Flag tells us if we should wait for an
548    event.  Any GrADS events (mouse-button presses) are queued.  */
549 
gxdeve(int flag)550 int gxdeve (int flag) {
551 struct gevent *geve, *geve2;
552 int i,j,ii,jj,rc,wflg,button,eflg,idm,rdrflg;
553 
554   if (flag && evbase) flag = 0;   /* Don't wait if an event stacked */
555   wflg = flag;
556   eflg = 0;
557   rdrflg = 0;
558   while (1) {
559     if (wflg && !rdrflg) {
560       XMaskEvent(display, ButtonReleaseMask | ButtonPressMask |
561          ButtonMotionMask | KeyPressMask | ExposureMask | StructureNotifyMask, &report);
562       rc = 1;
563     } else {
564       rc = XCheckMaskEvent(display, ButtonReleaseMask | ButtonPressMask |
565          ButtonMotionMask | KeyPressMask | ExposureMask | StructureNotifyMask, &report);
566     }
567     if (!rc && rdrflg) {
568       gxdsfn();
569       gxdrdw();
570       rdrflg = 0;
571       continue;
572     }
573     if (!rc) break;
574 
575     switch  (report.type) {
576     case Expose:
577       if (excnt>0) excnt--;
578       else if (!bsflg) rdrflg = 1;
579       break;
580     case ButtonPress:
581       geve = (struct gevent *)malloc(sizeof(struct gevent));
582       if (geve==NULL) {
583         printf ("Memory allocation error in event queue!!!!!!\n");
584         eflg = 1;
585         break;
586       }
587       if (evbase==NULL) evbase = geve;
588       else {
589         geve2 = evbase;
590         while (geve2->forw) geve2 = geve2->forw;
591         geve2->forw = geve;
592       }
593       geve->forw = NULL;
594       i = report.xbutton.x;
595       j = report.xbutton.y;
596       button = report.xbutton.button;
597       if (button==Button1) button=1;
598       else if (button==Button2) button=2;
599       else if (button==Button3) button=3;
600       else if (button==Button4) button=4;
601       else if (button==Button5) button=5;
602       geve->mbtn = button;
603       geve->x = xsize*((float)i)/width;
604       geve->y = ysize - ysize*((float)j)/height;
605       geve->type = 0;
606 
607       /* Scan to see if point-click event was on one of our
608          widgets.  Handling depends on what is clicked on. */
609 
610       ii = 0;
611       while (ii<512 && obj[ii].type>-1) {
612         if (obj[ii].type!=0 && i>obj[ii].i1 && i<obj[ii].i2 &&
613                                j>obj[ii].j1 && j<obj[ii].j2) {
614           if (obj[ii].mb < 0 || obj[ii].mb == button) {
615             if (obj[ii].type==1) gxevbn(geve,ii);
616             else if (obj[ii].type==2) gxevrb(geve,ii,i,j);
617             else if (obj[ii].type==3) {
618               idm = ii;
619               while (idm != -999) idm = gxevdm(geve,idm,i,j);
620             }
621             ii = 100000;           /* Exit loop */
622           }
623         }
624         ii++;
625       }
626       wflg = 0;                  /* Check for more events, but don't
627                                     wait if there aren't any. */
628       break;
629     case ConfigureNotify:
630       if(width!=report.xconfigure.width||height!=report.xconfigure.height){
631         width = report.xconfigure.width;
632         height = report.xconfigure.height;
633         xscl = (float)(width)/xsize;
634         yscl = (float)(height)/ysize;
635         rdrflg = 1;
636       }
637       break;
638     }
639     if (eflg) break;
640   }
641   if (rdrflg) {
642     gxdsfn();
643     gxdrdw();
644   }
645 }
646 
647 /* Return info on mouse button press event.  Wait if requested. */
648 
gxdbtn(int flag,float * xpos,float * ypos,int * mbtn,int * type,int * info,float * rinfo)649 void gxdbtn (int flag, float *xpos, float *ypos,
650                         int *mbtn, int *type, int *info, float *rinfo) {
651 struct gevent *geve, *geve2;
652 int i;
653 
654   if (batch) {
655     *xpos = -999.9;
656     *ypos = -999.9;
657     return;
658   }
659 
660   gxdeve(flag);
661   if (evbase==NULL) {
662     *xpos = -999.9;
663     *ypos = -999.9;
664     *mbtn = -1;
665     *type = -1;
666   } else {
667     geve = evbase;
668     *xpos = geve->x;
669     *ypos = geve->y;
670     *mbtn = geve->mbtn;
671     *type = geve->type;
672     for (i=0; i<10; i++) *(info+i) = geve->info[i];
673     for (i=0; i<4; i++) *(rinfo+i) = geve->rinfo[i];
674     evbase = geve->forw;       /* Take even off queue */
675     free(geve);
676   }
677 
678 }
679 
gxdcol(int clr)680 void gxdcol (int clr){
681   if (clr<0) clr=0;
682   if (clr>99) clr=99;
683   if (devbck) {
684     if (clr==0) clr = 1;
685     else if (clr==1) clr = 0;
686   }
687   if (clr<16 && grflg) {
688     if (devbck) clr = grrev[clr];
689     clr+=100;
690   }
691   if (!cused[clr] && !cmach[clr]) clr=15;
692   XSetForeground(display, gc, cvals[clr]);
693   lcolor=clr;
694 }
695 
696 
697 static void qprint(XStandardColormap* bst);
698 
gxdacl(int clr,int red,int green,int blue)699 int gxdacl (int clr, int red, int green, int blue) {
700   int num;
701   XStandardColormap best;
702   int screen_num = DefaultScreen(display);
703 
704   if (clr<16 || clr>99) return 1;
705   if (cused[clr]) {
706      XFreeColors(display, cmap, &(cvals[clr]),1,0);
707      cused[clr]=0;
708   }
709   cell.red = red*256;
710   cell.blue = blue*256;
711   cell.green = green*256;
712   cmach[clr] = 0;
713   if (XAllocColor(display, cmap, &cell)) {
714     cvals[clr] = cell.pixel;
715     cused[clr] = 1;
716 #if !( defined(XLIBEMU) || defined(XLIBEMU32) )
717   } else if (XGetStandardColormap(display,
718              RootWindow(display,screen_num), &best, XA_RGB_BEST_MAP)) {
719     if (gxbcol(&best, &cell)) {
720       cvals[clr] = cell.pixel;
721       cmach[clr] = 1;
722       printf ("Color Match.  Color number = %i\n",clr);
723     } else {
724       printf ("Color Matching Error.  Color number = %i\n",clr);
725     }
726 #endif
727   } else {
728     printf ("Color Map Allocation Error.  Color number = %i\n",clr);
729   }
730   if (cused[clr] == 0 || cmach[clr] == 1) {
731     return 0;
732   } else {
733     return 1;
734   }
735 }
736 
gxbcol(XStandardColormap * best,XColor * cell)737 int gxbcol (XStandardColormap* best, XColor * cell) {
738   float red, green, blue;
739   unsigned long bestpixel;
740 
741   XColor color, colors[256];
742 
743   int d, i, j;
744   int min;
745 
746   for (i=0; i<256; i++) {
747     colors[i].pixel = i;
748   }
749 
750   XQueryColors(display, cmap, colors, 256);
751 
752   min = 65536;
753 
754   for (i=0; i<256; i++) {
755     d = abs(cell->red - colors[i].red)
756       + abs(cell->green - colors[i].green)
757       + abs(cell->blue - colors[i].blue);
758     if (d<min) { min = d;  bestpixel = i; }
759   }
760 
761   if (bestpixel < 256) {
762 
763     cell->pixel = bestpixel;
764     color.pixel = bestpixel;
765     XQueryColor(display, cmap, &color);
766     return 1;
767 
768   } else {
769     return 0;
770   }
771 
772 }
773 
gxdwid(int wid)774 void gxdwid (int wid){                 /* Set width     */
775 unsigned int lw;
776   lwidth=wid;
777   if (wchose) return;
778   lw = 0;
779 #ifndef XLIBEMU32
780   if (lwidth>5) lw=2;
781   if (lwidth>11) lw=3;
782 #endif
783   if (lw != owidth) {
784     XSetLineAttributes(display, gc, lw, LineSolid,
785                      CapButt, JoinBevel);
786   }
787   owidth = lw;
788 }
789 
gxdmov(float x,float y)790 void gxdmov (float x, float y){        /* Move to x,y   */
791   xxx = (int)(x*xscl+0.5);
792   yyy = height - (int)(y*yscl+0.5);
793 }
794 
gxddrw(float x,float y)795 void gxddrw (float x, float y){        /* Draw to x,y   */
796 int i, j;
797 int w,h;
798   i = (int)(x*xscl+0.5);
799   j = height - (int)(y*yscl+0.5);
800   XDrawLine (display, drwbl, gc, xxx, yyy, i, j);
801   if (wchose && lwidth>5) {
802     w = xxx - i;
803     if (w<0) w = -1*w;
804     h = yyy-j;
805     if (h<0) h = -1*h;
806     if (w<h) {
807       XDrawLine (display, drwbl, gc, xxx-1, yyy, i-1, j);
808       if (lwidth>11) XDrawLine (display, drwbl, gc, xxx+1, yyy, i+1, j);
809     } else {
810       XDrawLine (display, drwbl, gc, xxx, yyy-1, i, j-1);
811       if (lwidth>11) XDrawLine (display, drwbl, gc, xxx, yyy+1, i, j+1);
812     }
813   }
814   xxx = i;
815   yyy = j;
816   if (QLength(display)&&rstate) gxdeve(0);
817 }
818 
gxdrec(float x1,float x2,float y1,float y2)819 void gxdrec (float x1, float x2, float y1, float y2) {
820 int i1,i2,j1,j2;
821 
822   i1 = (int)(x1*xscl+0.5);
823   j1 = height - (int)(y1*yscl+0.5);
824   i2 = (int)(x2*xscl+0.5);
825   j2 = height - (int)(y2*yscl+0.5);
826   if (i1!=i2 && j1!=j2) {
827     XFillRectangle (display, drwbl, gc, i1, j2, i2-i1, j1-j2);
828   } else {
829     XDrawLine (display, drwbl, gc, i1, j1, i2, j2);
830   }
831   if (QLength(display)&&rstate) gxdeve(0);
832 }
833 
gxdsgl(void)834 void gxdsgl (void) {
835 int i;
836   if (dblmode) {
837     gxrswd(1);
838     for (i=0; i<512; i++) { obj[i].type=-1; obj2[i].type = -1;}
839     obnum = 0;  obnum2 = 0;
840     XFreePixmap (display, pmap);
841     drwbl = win;
842   }
843   dblmode = 0;
844   return;
845 }
846 
gxddbl(void)847 void gxddbl (void) {
848 int i;
849   pmap = XCreatePixmap (display, win, width, height, depth);
850   XSync(display, 0) ; /* hoop */
851   if (pmap==(Pixmap)NULL) {
852     printf ("Error allocating pixmap for animation mode\n");
853     printf ("Animation mode will not be enabled\n");
854     return;
855   }
856   dblmode = 1;
857   drwbl = pmap;
858   XSetForeground(display, gc, cvals[devbck]);
859   XFillRectangle (display, drwbl, gc, 0, 0, width, height);
860   XSetForeground(display, gc, cvals[lcolor]);
861   gxrswd(1);  /* Reset all widgets */
862   for (i=0; i<512; i++) { obj[i].type=-1; obj2[i].type = -1;}
863   obnum = 0;  obnum2 = 0;
864   return;
865 }
866 
867 void
dump_back_buffer(filename)868 dump_back_buffer(filename) /* hoop */
869     char *filename ; /* hoop */
870 { /* hoop */
871     FILE *xwdfile ; /* hoop */
872 
873     if (dblmode) { /* hoop */
874         set_display_screen(display, snum) ; /* hoop */
875         xwdfile = fopen(filename, "w") ; /* hoop */
876 	if (!xwdfile) { /* hoop */
877 	    fprintf(stderr, "Couldn't open outxwd argument for writing.\n") ; /* hoop */
878 	    return ; /* hoop */
879 	} /* hoop */
880         fflush(stderr) ; /* hoop */
881 	Window_Dump(win, xwdfile) ; /* hoop */
882 	Pixmap_Dump(pmap, xwdfile, 0, 0, width, height) ; /* hoop */
883 	fclose(xwdfile) ; /* hoop */
884     } /* hoop */
885 } /* hoop */
886 
887 void
dump_front_buffer(filename)888 dump_front_buffer(filename) /* hoop */
889     char *filename ; /* hoop */
890 { /* hoop */
891     FILE *xwdfile ; /* hoop */
892 
893     set_display_screen(display, snum) ; /* hoop */
894     xwdfile = fopen(filename, "w") ; /* hoop */
895     if (!xwdfile) { /* hoop */
896         fprintf(stderr, "Couldn't open outxwd argument for writing.\n") ; /* hoop */
897 	return ; /* hoop */
898     } /* hoop */
899     fflush(stderr) ; /* hoop */
900     Window_Dump(win, xwdfile) ; /* hoop */
901     Pixmap_Dump(win, xwdfile, 0, 0, width, height) ; /* hoop */
902     fclose(xwdfile) ; /* hoop */
903 } /* hoop */
904 
gxdswp(void)905 void gxdswp (void) {
906 int i;
907   if (dblmode) {
908     XCopyArea (display, pmap, win, gc, 0, 0, width, height, 0, 0);
909   }
910   XSetForeground(display, gc, cvals[devbck]);
911   XFillRectangle (display, drwbl, gc, 0, 0, width, height);
912   XSetForeground(display, gc, cvals[lcolor]);
913   gxrswd(0);
914   gxcpwd();
915   gxrswd(2);
916   return;
917 }
918 
gxqfil(void)919 int gxqfil (void) {
920   return (1);
921 }
922 
gxdfil(float * xy,int n)923 void gxdfil (float *xy, int n) {
924 int i;
925 float *pt;
926 XPoint *pnt;
927 
928   point = (XPoint *)malloc(sizeof(XPoint)*n);
929   if (point==NULL) {
930     printf ("Error in polygon fill routine gxdfil: \n");
931     printf ("   Unable to allocate enough memory for the request\n");
932     return;
933   }
934   pnt = point;
935   pt = xy;
936   for (i=0; i<n; i++) {
937     pnt->x = (int)(*pt*xscl+0.5);
938     pnt->y = height - (int)(*(pt+1)*yscl+0.5);
939     pt+=2;
940     pnt++;
941   }
942   XFillPolygon (display, drwbl, gc, point, n, Nonconvex, CoordModeOrigin);
943   free (point);
944   if (QLength(display)&&rstate) gxdeve(0);
945   return;
946 }
947 
gxdxsz(int xx,int yy)948 void gxdxsz (int xx, int yy) {
949   if (batch) return;
950   XResizeWindow (display, win, xx, yy);
951 }
952 
953 /* set hardware background color */
954 
gxdbck(int flg)955 void gxdbck (int flg) {
956 
957   devbck = flg;
958   if (devbck>1) devbck = 1;
959 }
960 
gxdbkq(void)961 int gxdbkq  (void) {
962    return (devbck);
963 }
964 
965 /* Routine to display a button widget */
966 /* Flags are cumbersome, sigh....
967       redraw -- indicates the button is being redrawn, probably
968                 due to a resize event.  When set, the assumption
969                 is that *pbn is NULL and is ignored
970       btnrel -- indicates the button is being redrawn in a new state
971                 due to a buttonpress/buttonrelease event.
972       nstat  -- forces the state to go to this new setting.
973                 Used for 'redraw button' command.  */
974 
gxdpbn(int bnum,struct gbtn * pbn,int redraw,int btnrel,int nstat)975 void gxdpbn (int bnum, struct gbtn *pbn, int redraw, int btnrel, int nstat) {
976 int i, j, w, h, ilo, ihi, jlo, jhi, ccc, len;
977 struct gbtn *gbb;
978 struct gobj *pob;
979   if (bnum<0 || bnum>255) return;
980   if (dblmode) {
981     gbb = &(btn2[bnum]);
982     if (btnrel) {
983       drwbl = win;
984       gbb = &(btn[bnum]);
985     }
986   } else gbb = &(btn[bnum]);
987   if (!redraw) {
988     *gbb = *pbn;
989     gbb->num = bnum;
990   }
991   if (!redraw || rstate==0) {
992     if (dblmode) {
993       if (obnum2>511) {
994         printf ("Error: Too many widgets on screen\n");
995         return;
996       }
997     } else {
998       if (obnum>511) {
999         printf ("Error: Too many widgets on screen\n");
1000         return;
1001       }
1002     }
1003     if (dblmode) {pob = &(obj2[obnum2]); obnum2++;}
1004     else {pob = &(obj[obnum]); obnum++;}
1005   }
1006   if (gbb->num<0) return;
1007   if (nstat>-1) gbb->state = nstat;
1008   if (redraw>1) {
1009     if (pbn->ch) {
1010       if (gbb->ch) free(gbb->ch);
1011       gbb->ch = pbn->ch;
1012       gbb->len = pbn->len;
1013     }
1014     if (redraw==3) {
1015       gbb->fc = pbn->fc; gbb->bc = pbn->bc;
1016       gbb->oc1 = pbn->oc1; gbb->oc2 = pbn->oc2;
1017       gbb->ftc = pbn->ftc; gbb->btc = pbn->btc;
1018       gbb->otc1 = pbn->otc1; gbb->otc2 = pbn->otc2;
1019     }
1020   }
1021   i = (int)(gbb->x*xscl+0.5);
1022   j = height - (int)(gbb->y*yscl+0.5);
1023   w = (int)(gbb->w*xscl+0.5);
1024   h = (int)(gbb->h*yscl+0.5);
1025   w = w - 2;
1026   h = h - 2;
1027   gbb->ilo = 1 + i - w/2;
1028   gbb->jlo = 1 + j - h/2;
1029   gbb->ihi = gbb->ilo + w;
1030   gbb->jhi = gbb->jlo + h;
1031   ilo = gbb->ilo;  ihi = gbb->ihi;
1032   jlo = gbb->jlo;  jhi = gbb->jhi;
1033   if (gbb->state) ccc = gbb->btc;
1034   else ccc = gbb->bc;
1035   if (ccc>-1) {
1036     gxdcol(ccc);
1037     XFillRectangle (display, drwbl, gc, gbb->ilo, gbb->jlo, w, h);
1038   }
1039   gxdwid(gbb->thk);
1040   if (gbb->state) ccc = gbb->otc1;
1041   else ccc = gbb->oc1;
1042   if (ccc>-1) {
1043     gxdcol(ccc);
1044     XDrawLine (display, drwbl, gc, ilo, jhi, ihi, jhi);
1045     XDrawLine (display, drwbl, gc, ihi, jhi, ihi, jlo);
1046   }
1047   if (gbb->state) ccc = gbb->otc2;
1048   else ccc = gbb->oc2;
1049   if (ccc>-1) {
1050     gxdcol(ccc);
1051     XDrawLine (display, drwbl, gc, ihi, jlo, ilo, jlo);
1052     XDrawLine (display, drwbl, gc, ilo, jlo, ilo, jhi);
1053   }
1054   if (gbb->state) ccc = gbb->ftc;
1055   else ccc = gbb->fc;
1056   if (ccc>-1) {
1057     len = 0;
1058     while (*(gbb->ch+len)) len++;
1059 /*    len++;*/
1060     gxdcol(ccc);
1061     if (gfont==1 && font1) {
1062       XSetFont (display, gc, font1->fid);
1063       w = XTextWidth(font1, gbb->ch, len);
1064       i = i - w/2;
1065       j = j + 5*font1->ascent/9;
1066     }
1067     if (gfont==2 && font2) {
1068       XSetFont (display, gc, font2->fid);
1069       w = XTextWidth(font2, gbb->ch, len);
1070       i = i - w/2;
1071       j = j + 5*font2->ascent/9;
1072     }
1073     if (gfont==3 && font3) {
1074       XSetFont (display, gc, font3->fid);
1075       w = XTextWidth(font3, gbb->ch, len);
1076       i = i - w/2;
1077       j = j + 5*font3->ascent/9;
1078     }
1079     XDrawString(display, drwbl, gc, i, j, gbb->ch, len);
1080   }
1081   gxdcol(lcolor);
1082   if (dblmode && btnrel) drwbl = pmap;
1083   if (!redraw || rstate==0) {
1084     pob->type = 1;
1085     pob->mb = -1;
1086     pob->i1 = ilo;  pob->i2 = ihi;
1087     pob->j1 = jlo;  pob->j2 = jhi;
1088     pob->iob.btn = gbb;
1089   }
1090   XFlush(display);
1091 }
1092 
1093 /* Routine to display a drop menu widget:
1094       redraw -- indicates the button is being redrawn, probably
1095                 due to a resize event.  When set, the assumption
1096                 is that *dmu is NULL and is ignored; info for
1097                 redrawing is obtained from the existing
1098                 structure list.
1099       nstat  -- re-defines the dropmenu.
1100                 Used for 'redraw dropmenu' command.  */
1101 
gxdrmu(int mnum,struct gdmu * pmu,int redraw,int nstat)1102 void gxdrmu (int mnum, struct gdmu *pmu, int redraw, int nstat) {
1103 int i, j, w, h, ilo, ihi, jlo, jhi, ccc, len, lw;
1104 struct gdmu *gmu;
1105 struct gobj *pob;
1106 
1107   if (mnum<0 || mnum>199) return;
1108   if (dblmode) gmu = &(dmu2[mnum]);
1109   else gmu = &(dmu[mnum]);
1110   if (!redraw) {
1111     *gmu = *pmu;
1112     gmu->num = mnum;
1113   }
1114   if (gmu->num<0) return;
1115   if (gmu->casc) return;
1116   if (!redraw || rstate==0) {
1117     if (dblmode) {
1118       if (obnum2>511) {
1119         printf ("Error: Too many widgets on screen\n");
1120         return;
1121       }
1122     } else {
1123       if (obnum>511) {
1124         printf ("Error: Too many widgets on screen\n");
1125         return;
1126       }
1127     }
1128     if (dblmode) {pob = &(obj2[obnum2]); obnum2++;}
1129     else {pob = &(obj[obnum]); obnum++;}
1130   }
1131   i = (int)(gmu->x*xscl+0.5);
1132   j = height - (int)(gmu->y*yscl+0.5);
1133   w = (int)(gmu->w*xscl+0.5);
1134   h = (int)(gmu->h*yscl+0.5);
1135   w = w - 2;
1136   h = h - 2;
1137   gmu->ilo = 1 + i - w/2;
1138   gmu->jlo = 1 + j - h/2;
1139   gmu->ihi = gmu->ilo + w;
1140   gmu->jhi = gmu->jlo + h;
1141   ilo = gmu->ilo;  ihi = gmu->ihi;
1142   jlo = gmu->jlo;  jhi = gmu->jhi;
1143   if (gmu->bc>-1) {
1144     gxdcol(gmu->bc);
1145     XFillRectangle (display, drwbl, gc, ilo, jlo, w+1, h+1);
1146   }
1147   lw = 1;
1148   if (gmu->thk>5) lw = 2;
1149   if (gmu->thk>12) lw = 3;
1150   gxdwid(1);
1151   if (gmu->oc1>-1) {
1152     gxdcol(gmu->oc1);
1153     XDrawLine (display, drwbl, gc, ilo, jhi, ihi, jhi);
1154     if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jhi-1, ihi-1, jhi-1);
1155     if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jhi-2, ihi-2, jhi-2);
1156     XDrawLine (display, drwbl, gc, ihi, jhi, ihi, jlo);
1157     if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jhi-1, ihi-1, jlo+1);
1158     if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jhi-2, ihi-2, jlo+2);
1159   }
1160   if (gmu->oc2>-1) {
1161     gxdcol(gmu->oc2);
1162     XDrawLine (display, drwbl, gc, ihi, jlo, ilo, jlo);
1163     if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jlo+1, ilo+1, jlo+1);
1164     if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jlo+2, ilo+2, jlo+2);
1165     XDrawLine (display, drwbl, gc, ilo, jlo, ilo, jhi);
1166     if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jlo+1, ilo+1, jhi-1);
1167     if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jlo+2, ilo+2, jhi-2);
1168   }
1169   if (gmu->fc>-1) {
1170     len = 0;
1171     while (*(gmu->ch+len)) len++;
1172 /*    len++;*/
1173     gxdcol(gmu->fc);
1174     if (gfont==1 && font1i) {
1175       XSetFont (display, gc, font1i->fid);
1176       w = XTextWidth(font1i, gmu->ch, len);
1177       i = ilo + font1i->ascent/2;
1178       j = j + 5*font1i->ascent/9;
1179     }
1180     if (gfont==2 && font2i) {
1181       XSetFont (display, gc, font2i->fid);
1182       w = XTextWidth(font2i, gmu->ch, len);
1183       i = ilo + font2i->ascent/2;
1184       j = j + 5*font2i->ascent/9;
1185     }
1186     if (gfont==3 && font3i) {
1187       XSetFont (display, gc, font3i->fid);
1188       w = XTextWidth(font3i, gmu->ch, len);
1189       i = ilo + font3i->ascent/2;
1190       j = j + 5*font3i->ascent/9;
1191     }
1192     XDrawString(display, drwbl, gc, i, j, gmu->ch, len);
1193     if (gfont==1 && font1) XSetFont (display, gc, font1->fid);
1194     if (gfont==2 && font2) XSetFont (display, gc, font2->fid);
1195     if (gfont==3 && font3) XSetFont (display, gc, font3->fid);
1196   }
1197   gxdcol(lcolor);
1198   if (!redraw || rstate==0) {
1199     pob->type = 3;
1200     pob->mb = -1;
1201     pob->i1 = ilo;  pob->i2 = ihi;
1202     pob->j1 = jlo;  pob->j2 = jhi;
1203     pob->iob.dmu = gmu;
1204   }
1205   XFlush(display);
1206 }
1207 
1208 /* Select font based on screen size */
1209 
gxdsfn(void)1210 void gxdsfn(void) {
1211 
1212   if (width<601 || height<421) {
1213     if (gfont!=1) {
1214       if (font1) XSetFont (display, gc, font1->fid);
1215       gfont = 1;
1216     }
1217   } else if (width<1001 || height<651) {
1218     if (gfont!=2) {
1219       if (font2) XSetFont (display, gc, font2->fid);
1220       gfont = 2;
1221     }
1222   } else {
1223     if (gfont!=3) {
1224       if (font3) XSetFont (display, gc, font3->fid);
1225       gfont = 3;
1226     }
1227   }
1228 /*   printf ("qqq font = %i\n",gfont); */
1229 }
1230 
1231 /* Routine to plot text */
1232 
gxdtxt(char * string,float x,float y)1233 void gxdtxt (char *string, float x, float y) {
1234 }
1235 /*
1236 int i,j,w,len,ft;
1237 
1238   if (cfont==0) gxdcf();
1239 
1240   w = gxdfsw ("XXXXX", 5, 2);
1241   i = (width-w*12)/2;
1242   if (i<0) i=0;
1243   if (x<0.0) j = height - (int)(y*yscl+0.5);
1244   else i = (int)(x*xscl+0.5);
1245 
1246   while (1) {
1247 
1248     if (*string=='\\') {
1249       ft = 1; if (*(string+1)=='1') ft = 1;
1250       else if (*(string+1)=='2') ft = 2;
1251       else if (*(string+1)=='3') ft = 3;
1252       string += 2;
1253     }
1254 
1255     len = 0;
1256     while (*(string+len)!='\0' && *(string+len)!='\\') len++;
1257     if (len==0) return;
1258 
1259     w = gxdfsw (string, len, ft);
1260 
1261     XDrawString(display, drwbl, gc, i, j, string, len);
1262 
1263     if (*(string+len)=='\0') break;
1264 
1265     i = i + w;
1266     string = string + len;
1267 
1268   }
1269 
1270   gxdsfn();
1271 }
1272 */
1273 
1274 /* Select font and get string width */
1275 
1276 /*  Draw text command no longer supported. */
1277 
1278 /*
1279 int gxdfsw (char *string, int len, int ftype) {
1280 int w;
1281   w = 0;
1282   if (gfont==1) {
1283     if (ftype==1 && font1) {
1284       XSetFont (display, gc, font1->fid);
1285       w = XTextWidth(font1, string, len);
1286     } else if (ftype==2 && fontc1) {
1287       XSetFont (display, gc, fontc1->fid);
1288       w = XTextWidth(fontc1, string, len);
1289     } else if (ftype==3 && fonti1) {
1290       XSetFont (display, gc, fonti1->fid);
1291       w = XTextWidth(fonti1, string, len);
1292     }
1293   } else if (gfont==2) {
1294     if (ftype==1 && font2) {
1295       XSetFont (display, gc, font2->fid);
1296       w = XTextWidth(font2, string, len);
1297     } else if (ftype==2 && fontc2) {
1298       XSetFont (display, gc, fontc2->fid);
1299       w = XTextWidth(fontc2, string, len);
1300     } else if (ftype==3 && fonti2) {
1301       XSetFont (display, gc, fonti2->fid);
1302       w = XTextWidth(fonti2, string, len);
1303     }
1304   } else if (gfont==3) {
1305     if (ftype==1 && font3) {
1306       XSetFont (display, gc, font3->fid);
1307       w = XTextWidth(font3, string, len);
1308     } else if (ftype==2 && fontc3) {
1309       XSetFont (display, gc, fontc3->fid);
1310       w = XTextWidth(fontc3, string, len);
1311     } else if (ftype==3 && fonti3) {
1312       XSetFont (display, gc, fonti3->fid);
1313       w = XTextWidth(fonti3, string, len);
1314     }
1315   }
1316   return (w);
1317 }
1318 */
1319 
1320 /* Set up courier fonts if draw text command gets issued. */
1321 
1322 /*
1323 void gxdcf (void) {
1324 char **flist;
1325 int i;
1326 
1327 
1328   fontc1 = NULL;
1329   fontc2 = NULL;
1330   fontc3 = NULL;
1331   fonti1 = NULL;
1332   fonti2 = NULL;
1333   fonti3 = NULL;
1334 
1335   flist = XListFonts (display, "-adobe-courier-bold-r-normal-*-80*", 1, &i);
1336   if (flist) {
1337     fontc1 = XLoadQueryFont (display, *flist);
1338     XFreeFontNames (flist);
1339   }
1340   flist = XListFonts (display, "-adobe-courier-bold-r-normal--??-100*", 1, &i);
1341   if (flist==NULL) {
1342     flist = XListFonts (display, "-adobe-courier-bold-r-normal-*-100*", 1, &i);
1343   }
1344   if (flist) {
1345     fontc2 = XLoadQueryFont (display, *flist);
1346     XFreeFontNames (flist);
1347   }
1348   flist = XListFonts (display, "-adobe-courier-bold-r-normal-*-140*", 1, &i);
1349   if (flist) {
1350     fontc3 = XLoadQueryFont (display, *flist);
1351     XFreeFontNames (flist);
1352   }
1353 
1354   flist = XListFonts (display, "-adobe-courier-bold-o-normal-*-80*", 1, &i);
1355   if (flist) {
1356     fonti1 = XLoadQueryFont (display, *flist);
1357     XFreeFontNames (flist);
1358   }
1359   flist = XListFonts (display, "-adobe-courier-bold-o-normal--??-100*", 1, &i);
1360   if (flist==NULL) {
1361     flist = XListFonts (display, "-adobe-courier-bold-o-normal-*-100*", 1, &i);
1362   }
1363   if (flist) {
1364     fonti2 = XLoadQueryFont (display, *flist);
1365     XFreeFontNames (flist);
1366   }
1367   flist = XListFonts (display, "-adobe-courier-bold-o-normal-*-140*", 1, &i);
1368   if (flist) {
1369     fonti3 = XLoadQueryFont (display, *flist);
1370     XFreeFontNames (flist);
1371   }
1372 
1373   cfont = 1;
1374 }
1375 */
1376 
1377 /* Attempt to redraw when user resizes window */
1378 
gxdrdw(void)1379 void gxdrdw (void) {
1380 int i;
1381   rstate = 0;
1382   XSetForeground(display, gc, cvals[devbck]);
1383   XFillRectangle (display, drwbl, gc, 0, 0, width, height);
1384   XSetForeground(display, gc, cvals[lcolor]);
1385   for (i=0; i<512; i++) obj[i].type = -1;
1386   obnum = 0;
1387   if (dblmode) {
1388     dblmode = 0;
1389     XFreePixmap (display, pmap);
1390     pmap = XCreatePixmap (display, win, width, height, depth);
1391     if (pmap==(Pixmap)NULL) {
1392       printf ("Error allocating pixmap for resize operation\n");
1393       printf ("Animation mode will be disabled\n");
1394       dblmode = 0;
1395       drwbl = win;
1396       rstate = 1;
1397       return;
1398     }
1399     drwbl = win;
1400     XSetForeground(display, gc, cvals[devbck]);
1401     XFillRectangle (display, drwbl, gc, 0, 0, width, height);
1402     XFillRectangle (display, pmap, gc, 0, 0, width, height);
1403     XSetForeground(display, gc, cvals[lcolor]);
1404     for (i=0; i<512; i++) obj2[i].type = -1;
1405     obnum2 = 0;
1406     gxhdrw(1);
1407     gxrdrw(1);
1408     dblmode = 1;
1409     drwbl = pmap;
1410   }
1411   gxhdrw(0);
1412   gxrdrw(0);
1413   rstate = 1;
1414 }
1415 
1416 /* Redraw all widgets.  Flag indicates whether to redraw
1417    foreground or background widgets. */
1418 
gxrdrw(int flag)1419 void gxrdrw (int flag) {
1420 int i;
1421   if (flag) {
1422     for (i=0; i<256; i++) {
1423       if (btn2[i].num>-1) gxdpbn(i, NULL, 1, 0, -1);
1424     }
1425     for (i=0; i<32; i++) {
1426       if (rbb2[i].num>-1) gxdrbb(i, rbb2[i].type,
1427             rbb2[i].xlo,rbb2[i].ylo,rbb2[i].xhi,rbb2[i].yhi,rbb2[i].mb);
1428     }
1429     for (i=0; i<200; i++) {
1430       if (dmu2[i].num>-1) gxdrmu(i, NULL, 1, -1);
1431     }
1432   } else {
1433     for (i=0; i<256; i++) {
1434       if (btn[i].num>-1) gxdpbn(i, NULL, 1, 0, -1);
1435     }
1436     for (i=0; i<32; i++) {
1437       if (rbb[i].num>-1) gxdrbb(i, rbb[i].type,
1438             rbb[i].xlo,rbb[i].ylo,rbb[i].xhi,rbb[i].yhi,rbb[i].mb);
1439     }
1440     for (i=0; i<200; i++) {
1441       if (dmu[i].num>-1) gxdrmu(i, NULL, 1, -1);
1442     }
1443   }
1444 }
1445 
1446 /* Reset all widgets; release memory as appropriate. */
1447 /* flag = 0 resets foreground, flag = 1 resets both,
1448    flag = 2 resets background only; for after swapping */
1449 
gxrswd(int flag)1450 void gxrswd(int flag) {
1451 int i;
1452 
1453   if (flag!=2) {
1454     for (i=0; i<256; i++) {
1455       if (btn[i].num>-1 && btn[i].ch!=NULL) free(btn[i].ch);
1456       btn[i].num = -1;
1457       btn[i].ch = NULL;
1458     }
1459     for (i=0; i<200; i++) {
1460       if (dmu[i].num>-1 && dmu[i].ch!=NULL) free(dmu[i].ch);
1461       dmu[i].num = -1;
1462       dmu[i].ch = NULL;
1463     }
1464     for (i=0; i<32; i++) rbb[i].num = -1;
1465   }
1466 
1467   if (flag) {
1468     for (i=0; i<256; i++) {
1469       if (flag!=2) {
1470         if (btn2[i].num>-1 && btn2[i].ch!=NULL) free(btn2[i].ch);
1471       }
1472       btn2[i].num = -1;
1473       btn2[i].ch = NULL;
1474     }
1475     for (i=0; i<200; i++) {
1476       if (flag!=2) {
1477         if (dmu2[i].num>-1 && dmu2[i].ch!=NULL) free(dmu2[i].ch);
1478       }
1479       dmu2[i].num = -1;
1480       dmu2[i].ch = NULL;
1481     }
1482     for (i=0; i<32; i++) rbb2[i].num = -1;
1483   }
1484 }
1485 
1486 
1487 /* Copy all widgets during swap in double buffer mode */
1488 
gxcpwd(void)1489 void gxcpwd(void) {
1490 struct grbb *grb;
1491 struct gbtn *gbn;
1492 struct gdmu *gmu;
1493 int i;
1494 
1495   for (i=0; i<256; i++) {
1496     if (btn2[i].num>-1) btn[i] = btn2[i];
1497   }
1498 
1499   for (i=0; i<200; i++) {
1500     if (dmu2[i].num>-1) dmu[i] = dmu2[i];
1501   }
1502 
1503   for (i=0; i<32; i++) {
1504     if (rbb2[i].num>-1) rbb[i] = rbb2[i];
1505   }
1506 
1507   /* Rebuild list of currently displayed items */
1508 
1509   for (i=0; i<512; i++) obj[i].type = -1;
1510   obnum = obnum2;
1511   for (i=0; i<obnum; i++) {
1512     obj[i] = obj2[i];
1513     if (obj[i].type==1) {
1514       gbn = obj[i].iob.btn;
1515       obj[i].iob.btn = &(btn[gbn->num]);
1516     } else if (obj[i].type==2) {
1517       grb = obj[i].iob.rbb;
1518       obj[i].iob.rbb = &(rbb[grb->num]);
1519     } else if (obj[i].type==3) {
1520       gmu = obj[i].iob.dmu;
1521       obj[i].iob.dmu = &(dmu[gmu->num]);
1522     }
1523   }
1524   for (i=0; i<512; i++) obj2[i].type = -1;
1525   obnum2 = 0;
1526 }
1527 
1528 /* Reset a particular widget, given widget type and number */
1529 /* Assumes arrays are used for holding all the widget info */
1530 
gxrs1wd(int wdtyp,int wdnum)1531 void gxrs1wd (int wdtyp, int wdnum) {
1532 struct grbb *grb;
1533 struct gbtn *gbn;
1534 struct gdmu *gmu;
1535 int ii,jj;
1536 
1537   if (wdtyp<1 || wdtyp>3) return;
1538   if (wdtyp==1 && (wdnum<0 || wdnum>255)) return;
1539   if (wdtyp==2 && (wdnum<0 || wdnum>31)) return;
1540   if (wdtyp==3 && (wdnum<0 || wdnum>199)) return;
1541 
1542   /* Remove this widget from the list of displayed items */
1543 
1544   ii = 0;
1545   while (ii<512 && obj[ii].type>-1) {
1546     if (obj[ii].type!=0 && obj[ii].type==wdtyp) {
1547       if (obj[ii].type==1) {
1548         gbn = obj[ii].iob.btn;
1549         jj = gbn->num;
1550       } else if (obj[ii].type==2) {
1551         grb = obj[ii].iob.rbb;
1552         jj = grb->num;
1553       } else if (obj[ii].type==3) {
1554         gmu = obj[ii].iob.dmu;
1555         jj = gmu->num;
1556       }
1557       if (jj==wdnum) {
1558         obj[ii].type = 0;   /* This should be enough to cause this */
1559                             /* widget to be ignored. */
1560         ii = 100000;   /* Exit loop */
1561       }
1562     }
1563     ii++;
1564   }
1565 
1566   /* Remove this widget from the widget array */
1567 
1568   if (wdtyp==1) {
1569     if (btn[wdnum].num>-1 && btn[wdnum].num != wdnum)  {
1570        printf ("Logic Error 64 in gxrs1wd\n");
1571     }
1572     if (btn[wdnum].num>-1 && btn[wdnum].ch!=NULL) free(btn[wdnum].ch);
1573     btn[wdnum].num = -1;
1574     btn[wdnum].ch = NULL;
1575   } else if (wdtyp==2) {
1576     if (rbb[wdnum].num>-1 && rbb[wdnum].num != wdnum) {
1577        printf ("Logic Error 65 in gxrs1wd\n");
1578     }
1579     rbb[wdnum].num = -1;
1580   } else if (wdtyp==3) {
1581     if (dmu[wdnum].num>-1 && dmu[wdnum].num != wdnum) {
1582        printf ("Logic Error 65 in gxrs1wd\n");
1583     }
1584     if (dmu[wdnum].num>-1 && dmu[wdnum].ch!=NULL) free(dmu[wdnum].ch);
1585     dmu[wdnum].num = -1;
1586     dmu[wdnum].ch = NULL;
1587   }
1588 }
1589 
1590 
1591 /* Click ocurred over a button object. */
1592 
gxevbn(struct gevent * geve,int iobj)1593 void gxevbn(struct gevent *geve, int iobj) {
1594 struct gbtn *gbn;
1595 int jj,c1,c2,i1,i2,j1,j2;
1596 
1597   /* Fill in button specific event info */
1598 
1599   geve->type = 1;
1600   gbn = obj[iobj].iob.btn;
1601   geve->info[0] = gbn->num;
1602 
1603   jj = gbn->num;
1604   if (btn[jj].state) {
1605     c1=btn[jj].otc1; c2=btn[jj].otc2;
1606     geve->info[1] = 0;
1607   } else {
1608     c1=btn[jj].oc1; c2=btn[jj].oc2;
1609     geve->info[1] = 1;
1610   }
1611 
1612   /* Redraw button outline as pressed, if appropriate
1613      (ie, if the outline colors are different) */
1614 
1615   i1=btn[jj].ilo; i2=btn[jj].ihi;
1616   j1=btn[jj].jlo; j2=btn[jj].jhi;
1617   if ( !(btn[jj].state && btn[jj].oc1==btn[jj].otc2 &&
1618          btn[jj].oc2==btn[jj].otc1)) {
1619     if (c2>-1 && c1>-1) {
1620       gxdwid(btn[jj].thk);
1621       gxdcol(c2);
1622       XDrawLine (display, win, gc, i1, j2, i2, j2);
1623       XDrawLine (display, win, gc, i2, j2, i2, j1);
1624       gxdcol(c1);
1625       XDrawLine (display, win, gc, i2, j1, i1, j1);
1626       XDrawLine (display, win, gc, i1, j1, i1, j2);
1627       XFlush(display);
1628     }
1629   }
1630 
1631   /* Wait for button release, and do final redraw
1632      of button with new state. */
1633 
1634   while (1) {
1635     XMaskEvent(display, ButtonReleaseMask | ButtonMotionMask, &report);
1636     if (report.type == ButtonRelease) break;
1637   }
1638 
1639   if (btn[jj].state) btn[jj].state=0;
1640   else btn[jj].state=1;
1641   gxdpbn (jj, NULL, 1, 1, -1);
1642   XFlush(display);
1643 }
1644 
1645 /* Click ocurred in a rubber-banded region.  */
1646 
gxevrb(struct gevent * geve,int iobj,int i,int j)1647 void gxevrb(struct gevent *geve, int iobj, int i, int j) {
1648 struct grbb *grb;
1649 int i1,i2,j1,j2,i1o,j1o,i2o,j2o,xoflg,typ;
1650 int ilo,ihi,jlo,jhi;
1651 
1652   /* Get rest of event info */
1653 
1654   geve->type = 2;
1655   grb = obj[iobj].iob.rbb;
1656   geve->info[0] = grb->num;
1657   typ = grb->type;
1658   ilo = obj[iobj].i1;  ihi = obj[iobj].i2;
1659   jlo = obj[iobj].j1;  jhi = obj[iobj].j2;
1660 
1661   /* Set foreground color to something that will show up when Xor'd */
1662 
1663   XSetForeground(display, gc, cvals[0]^cvals[1]);
1664   XSetFunction(display, gc, GXxor);
1665 
1666   /* Loop on button motion, waiting for button release */
1667 
1668   xoflg = 0;
1669   while (1) {
1670     XMaskEvent(display, ButtonReleaseMask|ButtonMotionMask, &report);
1671     if (report.type==MotionNotify) {
1672       if (xoflg) {
1673         if (typ==1)
1674            XDrawRectangle(display, win, gc, i1o, j1o, i2o-i1o, j2o-j1o);
1675         else XDrawLine (display, win, gc, i1o, j1o, i2o, j2o);
1676       }
1677       if (i<report.xmotion.x) { i1 = i; i2 = report.xmotion.x; }
1678       else { i2 = i; i1 = report.xmotion.x; }
1679       if (j<report.xmotion.y) { j1 = j; j2 = report.xmotion.y; }
1680       else { j2 = j; j1 = report.xmotion.y; }
1681       if (i1<ilo) i1 = ilo; if (i2>ihi) i2 = ihi;
1682       if (j1<jlo) j1 = jlo; if (j2>jhi) j2 = jhi;
1683       if (typ==1) XDrawRectangle (display, win, gc, i1, j1, i2-i1, j2-j1);
1684       else XDrawLine (display, win, gc, i1, j1, i2, j2);
1685       i1o=i1; i2o=i2; j1o=j1; j2o=j2; xoflg = 1;
1686     } else break;
1687   }
1688   if (xoflg) {
1689     if (typ==1)
1690        XDrawRectangle(display, win, gc, i1o, j1o, i2o-i1o, j2o-j1o);
1691     else XDrawLine (display, win, gc, i1o, j1o, i2o, j2o);
1692   }
1693   XSetForeground(display, gc, cvals[lcolor]);
1694   XSetFunction(display, gc, GXcopy);
1695   XFlush(display);
1696   i1 = report.xbutton.x; j1 = report.xbutton.y;
1697   if (i1<ilo) i1 = ilo; if (i1>ihi) i1 = ihi;
1698   if (j1<jlo) j1 = jlo; if (j1>jhi) j1 = jhi;
1699   geve->rinfo[0] = xsize*((float)i1)/width;
1700   geve->rinfo[1] = ysize - ysize*((float)j1)/height;
1701 }
1702 
1703 /* Set up a rubber-band region.  */
1704 
gxdrbb(int num,int type,float xlo,float ylo,float xhi,float yhi,int mbc)1705 void gxdrbb (int num, int type,
1706                    float xlo, float ylo, float xhi, float yhi, int mbc) {
1707 struct grbb *prb;
1708 struct gobj *pob;
1709 int i,obn,flag;
1710 
1711   if (num<0 || num>31) return;
1712   if (xlo>=xhi) return;
1713   if (ylo>=yhi) return;
1714 
1715   if (dblmode) {
1716     if (obnum2>511) return;
1717     pob = &(obj2[obnum2]); obnum2++;
1718     prb = &(rbb2[num]);
1719   } else {
1720     if (obnum>511) return;
1721     pob = &(obj[obnum]); obnum++;
1722     prb = &(rbb[num]);
1723   }
1724 
1725   pob->type = 2;
1726   pob->mb = mbc;
1727   pob->i1 = (int)(xlo*xscl+0.5);
1728   pob->i2 = (int)(xhi*xscl+0.5);
1729   pob->j1 = height - (int)(yhi*yscl+0.5);
1730   pob->j2 = height - (int)(ylo*yscl+0.5);
1731   pob->iob.rbb = prb;
1732   prb->num = num;
1733   prb->xlo = xlo; prb->xhi = xhi;
1734   prb->ylo = ylo; prb->yhi = yhi;
1735   prb->type = type;
1736   prb->mb = mbc;
1737 }
1738 
1739 /* Handle drop menu.  Create new (temporary) window and
1740    put the text in it.  Window is destroyed when the mouse
1741    button is released.  */
1742 
1743 static int dmrecu,dmi1[4],dmi2[4],dmj1[4],dmj2[4],dmnum[4],dmsel[4],dmcur[4];
1744 
gxevdm(struct gevent * geve,int iobj,int ipos,int jpos)1745 int gxevdm(struct gevent *geve, int iobj, int ipos, int jpos) {
1746 struct gdmu *gmu;
1747 int i,j,iorig,jorig,ival,ilo,ihi,jlo,jhi,w,h,len,lw;
1748 
1749   geve->type = 3;
1750   gmu = obj[iobj].iob.dmu;
1751 
1752   /* Redraw base using toggled colors */
1753 
1754   ilo = gmu->ilo; ihi = gmu->ihi;
1755   jlo = gmu->jlo; jhi = gmu->jhi;
1756   w = ihi - ilo;
1757   h = jhi - jlo;
1758   j = jlo + h/2 - 1;
1759   if (gmu->tbc>-1 && gmu->tfc>-1) {
1760     if (gmu->tbc>-1) {
1761       gxdcol(gmu->tbc);
1762       XFillRectangle (display, drwbl, gc, ilo, jlo, w+1, h+1);
1763     }
1764     if (gmu->tfc>-1) {
1765       len = 0;
1766       while (*(gmu->ch+len)) len++;
1767 /*    len++;*/
1768       gxdcol(gmu->tfc);
1769       if (gfont==1 && font1i) {
1770         XSetFont (display, gc, font1i->fid);
1771         w = XTextWidth(font1i, gmu->ch, len);
1772         i = ilo + font1i->ascent/2;
1773         j = j + 5*font1i->ascent/9;
1774       }
1775       if (gfont==2 && font2i) {
1776         XSetFont (display, gc, font2i->fid);
1777         w = XTextWidth(font2i, gmu->ch, len);
1778         i = ilo + font2i->ascent/2;
1779         j = j + 5*font2i->ascent/9;
1780       }
1781       if (gfont==3 && font3i) {
1782         XSetFont (display, gc, font3i->fid);
1783         w = XTextWidth(font3i, gmu->ch, len);
1784         i = ilo + font3i->ascent/2;
1785         j = j + 5*font3i->ascent/9;
1786       }
1787       XDrawString(display, drwbl, gc, i, j, gmu->ch, len);
1788     }
1789   }
1790   gxdwid(1);
1791   lw = 1;
1792   if (gmu->thk>5) lw = 2;
1793   if (gmu->thk>11) lw = 3;
1794   if (gmu->toc1>-1) {
1795     gxdcol(gmu->toc1);
1796     XDrawLine (display, drwbl, gc, ilo, jhi, ihi, jhi);
1797     if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jhi-1, ihi-1, jhi-1);
1798     if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jhi-2, ihi-2, jhi-2);
1799     XDrawLine (display, drwbl, gc, ihi, jhi, ihi, jlo);
1800     if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jhi-1, ihi-1, jlo+1);
1801     if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jhi-2, ihi-2, jlo+2);
1802   }
1803   if (gmu->toc2>-1) {
1804     gxdcol(gmu->toc2);
1805     XDrawLine (display, drwbl, gc, ihi, jlo, ilo, jlo);
1806     if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jlo+1, ilo+1, jlo+1);
1807     if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jlo+2, ilo+2, jlo+2);
1808     XDrawLine (display, drwbl, gc, ilo, jlo, ilo, jhi);
1809     if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jlo+1, ilo+1, jhi-1);
1810     if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jlo+2, ilo+2, jhi-2);
1811   }
1812 
1813   /* Set up and display first menu */
1814 
1815   iorig = obj[iobj].i1;
1816   jorig = obj[iobj].j2;
1817 
1818   dmrecu = -1;
1819   for (i=0; i<4; i++) {
1820     dmi1[i] = -1; dmi2[i] = -1; dmj1[i] = -1; dmj2[i] = -1;
1821     dmnum[i] = -1; dmsel[i] = -1;
1822   }
1823 
1824   ival = gxpopdm (gmu, iobj, iorig, iorig, jorig);
1825 
1826   /* Display base in standard colors */
1827 
1828   gxdsfn();
1829   w = ihi - ilo;
1830   h = jhi - jlo;
1831   j = jlo + h/2 - 1;
1832   if (gmu->bc>-1 && gmu->fc>-1) {
1833     if (gmu->bc>-1) {
1834       gxdcol(gmu->bc);
1835       XFillRectangle (display, drwbl, gc, ilo, jlo, w+1, h+1);
1836     }
1837     if (gmu->fc>-1) {
1838       len = 0;
1839       while (*(gmu->ch+len)) len++;
1840 /*    len++;*/
1841       gxdcol(gmu->fc);
1842       if (gfont==1 && font1i) {
1843         XSetFont (display, gc, font1i->fid);
1844         w = XTextWidth(font1i, gmu->ch, len);
1845         i = ilo + font1i->ascent/2;
1846         j = j + 5*font1i->ascent/9;
1847       }
1848       if (gfont==2 && font2i) {
1849         XSetFont (display, gc, font2i->fid);
1850         w = XTextWidth(font2i, gmu->ch, len);
1851         i = ilo + font2i->ascent/2;
1852         j = j + 5*font2i->ascent/9;
1853       }
1854       if (gfont==3 && font3i) {
1855         XSetFont (display, gc, font3i->fid);
1856         w = XTextWidth(font3i, gmu->ch, len);
1857         i = ilo + font3i->ascent/2;
1858         j = j + 5*font3i->ascent/9;
1859       }
1860       XDrawString(display, drwbl, gc, i, j, gmu->ch, len);
1861     }
1862   }
1863   gxdwid(gmu->thk);
1864   if (gmu->oc1>-1) {
1865     gxdcol(gmu->oc1);
1866     XDrawLine (display, drwbl, gc, ilo, jhi, ihi, jhi);
1867     if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jhi-1, ihi-1, jhi-1);
1868     if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jhi-2, ihi-2, jhi-2);
1869     XDrawLine (display, drwbl, gc, ihi, jhi, ihi, jlo);
1870     if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jhi-1, ihi-1, jlo+1);
1871     if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jhi-2, ihi-2, jlo+2);
1872   }
1873   if (gmu->oc2>-1) {
1874     gxdcol(gmu->oc2);
1875     XDrawLine (display, drwbl, gc, ihi, jlo, ilo, jlo);
1876     if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jlo+1, ilo+1, jlo+1);
1877     if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jlo+2, ilo+2, jlo+2);
1878     XDrawLine (display, drwbl, gc, ilo, jlo, ilo, jhi);
1879     if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jlo+1, ilo+1, jhi-1);
1880     if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jlo+2, ilo+2, jhi-2);
1881   }
1882   XFlush(display);
1883   for (i=0; i<4; i++) if (dmsel[i]<0) dmnum[i] = -1;
1884   geve->info[0] = dmnum[0];
1885   geve->info[1] = dmsel[0];
1886   geve->info[2] = dmnum[1];
1887   geve->info[3] = dmsel[1];
1888   geve->info[4] = dmnum[2];
1889   geve->info[5] = dmsel[2];
1890   geve->info[6] = dmnum[3];
1891   geve->info[7] = dmsel[3];
1892   return (ival);
1893 }
1894 
1895 /* pull-down menu */
1896 
gxpopdm(struct gdmu * gmu,int iobj,int porig,int iorig,int jorig)1897 int gxpopdm(struct gdmu *gmu, int iobj, int porig, int iorig, int jorig) {
1898 int flag,i,j,cnt,len,maxw,w,h,absx,absy,enter;
1899 int item,itemold,jmin,jmax,imin,imax,isiz,jsiz,j1,j2,dmflag,ii;
1900 int pimin,pjmin,pisiz,pjsiz,ptrs[200],eflag,lln,cascf,ecnt,itt,itt2;
1901 unsigned long lw;
1902 char *ch,ich[5];
1903 Pixmap tpmap;
1904 Window pop, dummy;
1905 GC gcp;
1906 
1907   dmrecu++;
1908   cnt = 0;
1909   ch = gmu->ch;
1910   len = 0;
1911   i = 0;
1912   if (dmrecu==0) {
1913     while (*(ch+len)) len++;
1914     ch = ch+len+1;
1915     i = len+1;
1916   }
1917   maxw = 0;
1918   cascf = 0;
1919   while (i<gmu->len) {
1920     len = 0;
1921     lln = 0;
1922     ptrs[cnt] = -1;
1923     eflag = 1;
1924     while (*(ch+len)) {
1925       if (i+len+4<gmu->len && *(ch+len)=='>' &&
1926            (*(ch+len+1)>='0' && *(ch+len+1)<='9') &&
1927            (*(ch+len+2)>='0' && *(ch+len+2)<='9') &&
1928             *(ch+len+3)=='>') {
1929         ich[0] = *(ch+len+1);
1930         ich[1] = *(ch+len+2);
1931         ich[2] = '\0';
1932         ptrs[cnt] =  atoi(ich);
1933         eflag = 0;
1934         lln--;
1935         cascf = 1;
1936       }
1937       if (i+len+5<gmu->len && *(ch+len)=='>' &&
1938            (*(ch+len+1)>='0' && *(ch+len+1)<='1') &&
1939            (*(ch+len+2)>='0' && *(ch+len+2)<='9') &&
1940            (*(ch+len+3)>='0' && *(ch+len+3)<='9') &&
1941             *(ch+len+4)=='>') {
1942         ich[0] = *(ch+len+1);
1943         ich[1] = *(ch+len+2);
1944         ich[2] = *(ch+len+3);
1945         ich[3] = '\0';
1946         ptrs[cnt] =  atoi(ich);
1947         eflag = 0;
1948         lln--;
1949         cascf = 1;
1950       }
1951       len++;
1952       if (eflag) lln++;
1953     }
1954     if (gfont==1 && font1i) {
1955       w = XTextWidth(font1i, ch, lln);
1956       h = font1i->ascent;
1957     }
1958     if (gfont==2 && font2i) {
1959       w = XTextWidth(font2i, ch, lln);
1960       h = font2i->ascent;
1961     }
1962     if (gfont==3 && font3i) {
1963       w = XTextWidth(font3i, ch, lln);
1964       h = font3i->ascent;
1965     }
1966     w = w + h;
1967     if (w>maxw) maxw = w;
1968     ch = ch+len+1;
1969     i = i+len+1;
1970     cnt++;
1971   }
1972   if (cascf) {
1973     ich[0] = 'x'; ich[1] = 'x'; ich[2] = 'x'; ich[3] = 'x';
1974     if (gfont==1 && font1i) w = XTextWidth(font1i, ich, 3);
1975     if (gfont==2 && font2i) w = XTextWidth(font2i, ich, 3);
1976     if (gfont==3 && font3i) w = XTextWidth(font3i, ich, 3);
1977     maxw = maxw + w;
1978   }
1979   h = h*2;
1980   jsiz = h * cnt;
1981   isiz = maxw;
1982   imin = iorig; imax = imin + isiz;
1983   jmin = jorig; jmax = jmin + jsiz;
1984   if (imax > width) {
1985     if (cascf) imax = iorig - isiz;
1986 /*    else imax = width;*/
1987     else imax = porig;
1988     imin = imax - isiz;
1989   }
1990   if (jmax > height) {
1991     jmax = height;
1992     jmin = jmax - jsiz;
1993   }
1994 
1995   dmi1[dmrecu] = imin; dmi2[dmrecu] = imax;
1996   dmj1[dmrecu] = jmin; dmj2[dmrecu] = jmax;
1997   dmnum[dmrecu] = gmu->num;
1998 
1999   xsetw.save_under = 1;
2000   if (!bsflg) {
2001     tpmap = XCreatePixmap (display, win, isiz, jsiz, depth);
2002     XSync(display, 0);
2003     if (tpmap) {
2004        pimin = imin; pjmin = jmin; pisiz = isiz; pjsiz = jsiz;
2005        XCopyArea (display, win, tpmap, gc, pimin, pjmin, pisiz, pjsiz, 0, 0);
2006     }
2007   }
2008   pop = XCreateWindow(display, win, imin, jmin, isiz, jsiz, 0,
2009         CopyFromParent, CopyFromParent, CopyFromParent,
2010         CWSaveUnder, &xsetw);
2011   XSelectInput(display, pop, ButtonReleaseMask | ButtonPressMask |
2012       ButtonMotionMask | ExposureMask | StructureNotifyMask);
2013   gcp = XCreateGC(display, pop, 0L, &values);
2014   XSetForeground(display, gcp, cvals[1]);
2015   lw = 1;
2016   if (gmu->thk>5) lw = 2;
2017   if (gmu->thk>11) lw = 3;
2018   XSetLineAttributes(display, gcp, lw, LineSolid,
2019                      CapButt, JoinBevel);
2020   XMapWindow(display, pop);
2021   flag = 1;
2022   while (flag)  {
2023     XMaskEvent(display, ExposureMask | StructureNotifyMask, &report);
2024     switch  (report.type) {
2025     case Expose:
2026       if (report.xexpose.count != 0) break;
2027       else flag = 0;
2028       break;
2029     case ConfigureNotify:
2030       break;
2031     }
2032   }
2033   if (gmu->bbc>-1) {
2034     XSetForeground(display, gcp, cvals[gmu->bbc]);
2035     XFillRectangle (display, pop, gcp, 0, 0, isiz, jsiz);
2036   }
2037   if (gmu->boc1 > -1) {
2038     XSetForeground(display, gcp, cvals[gmu->boc1]);
2039     XDrawLine (display, pop, gcp, 0, jsiz-1, isiz-1, jsiz-1);
2040     XDrawLine (display, pop, gcp, isiz-1, jsiz-1, isiz-1, 0);
2041   }
2042   if (gmu->boc2 > -1) {
2043     XSetForeground(display, gcp, cvals[gmu->boc2]);
2044     XDrawLine (display, pop, gcp, isiz-1, 0, 0, 0);
2045     XDrawLine (display, pop, gcp, 0, 0, 0, jsiz-1);
2046   }
2047   if (gfont==1 && font1i) XSetFont (display, gcp, font1i->fid);
2048   if (gfont==2 && font2i) XSetFont (display, gcp, font2i->fid);
2049   if (gfont==3 && font3i) XSetFont (display, gcp, font3i->fid);
2050   cnt = 0;
2051   ch = gmu->ch;
2052   len = 0;
2053   i=0;
2054   if (dmrecu==0) {
2055     while (*(ch+len)) len++;
2056     ch = ch+len+1;
2057     i = len+1;
2058   }
2059   while (i<gmu->len) {
2060     len = 0;
2061     lln = 0;
2062     eflag = 1;
2063     while (*(ch+len)) {
2064       if (i+len+4<gmu->len && *(ch+len)=='>' &&
2065            (*(ch+len+1)>='0' && *(ch+len+1)<='9') &&
2066            (*(ch+len+2)>='0' && *(ch+len+2)<='9') &&
2067             *(ch+len+3)=='>') {
2068         eflag = 0;
2069       }
2070       if (i+len+5<gmu->len && *(ch+len)=='>' &&
2071            (*(ch+len+1)>='0' && *(ch+len+1)<='1') &&
2072            (*(ch+len+2)>='0' && *(ch+len+2)<='9') &&
2073            (*(ch+len+3)>='0' && *(ch+len+3)<='9') &&
2074             *(ch+len+4)=='>') {
2075         eflag = 0;
2076       }
2077       len++;
2078       if (eflag) lln++;
2079     }
2080     if (gfont==1 && font1i) {
2081       w = XTextWidth(font1i, ch, lln);
2082     }
2083     if (gfont==2 && font2i) {
2084       w = XTextWidth(font2i, ch, lln);
2085     }
2086     if (gfont==3 && font3i) {
2087       w = XTextWidth(font3i, ch, lln);
2088     }
2089     j1 = h/4;
2090     j2 = (cnt+1)*h - h/3;
2091     XSetForeground(display, gcp, cvals[gmu->bfc]);
2092     XDrawString(display, pop, gcp, j1, j2, ch, lln);
2093     if (ptrs[cnt]>-1) {
2094       j1 = h/5;
2095       j2 = (cnt+1)*h - h/2;
2096       if (gmu->soc2 > -1) {
2097         XSetForeground(display, gcp, cvals[gmu->soc2]);
2098         XDrawLine (display, pop, gcp, isiz-j1*3, j2+j1, isiz-j1*3, j2-j1);
2099         XDrawLine (display, pop, gcp, isiz-j1*3, j2-j1, isiz-j1, j2);
2100       }
2101       if (gmu->soc1 > -1) {
2102         XSetForeground(display, gcp, cvals[gmu->soc1]);
2103         XDrawLine (display, pop, gcp, isiz-j1, j2, isiz-j1*3, j2+j1);
2104       }
2105     }
2106     ch = ch+len+1;
2107     i = i+len+1;
2108     cnt++;
2109   }
2110   itemold = -1;
2111   enter = 1;
2112 
2113   XTranslateCoordinates (display, win, RootWindow (display, snum), 0, 0,
2114 			      &absx, &absy, &dummy);
2115 
2116   /* Follow pointer around.  If it lands on another drop-menu
2117      header, exit to draw that one instead.  */
2118 
2119   dmflag = -999;
2120   ecnt = 0;
2121   while (1) {
2122     XMaskEvent(display, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, &report);
2123     if (report.type == ButtonPress || enter == 1) {
2124       i = report.xbutton.x_root;
2125       j = report.xbutton.y_root;
2126       i -= absx;
2127       j -= absy;
2128       item = (j-jmin)/h;
2129       if (i>imax || i<imin || j>jmax || j<jmin) item = -1;
2130       if (item > -1 && ptrs[item] > -1) {
2131         j1 = item*h+1;
2132         dmcur[dmrecu] = item;
2133         itt = ptrs[item];
2134         if (dmu[itt].num == itt) {
2135           dmflag = gxpopdm( &(dmu[ptrs[item]]), iobj, imin, imax, j1+jmin);
2136           if (dmflag != -99) {
2137             if (dmsel[dmrecu+1]<1) {
2138               item = -2;
2139               itemold = -2;
2140             }
2141           }
2142         }
2143       }
2144       dmflag = -999;
2145       itemold = item;
2146       if(enter == 1) {
2147         enter = 0;
2148       } else {
2149         break;
2150       }
2151     }
2152     if (report.type == ButtonRelease && item > -1) break;
2153     if (report.type == MotionNotify) {
2154       i = report.xmotion.x;
2155       j = report.xmotion.y;
2156       i = report.xmotion.x_root;
2157       j = report.xmotion.y_root;
2158       i -= absx;
2159       j -= absy;
2160       if (i>imax || i<imin || j>jmax || j<jmin ) {
2161         item = -1;
2162         if (dmrecu>0) {
2163           for (itt=0; itt<dmrecu; itt++) {
2164             if (i>=dmi1[itt] && i<=dmi2[itt] &&
2165                 j>=dmj1[itt] && j<=dmj2[itt]  ) {
2166               itt2 = (j-dmj1[itt])/h;
2167               if (itt2 != dmcur[itt]) {
2168                 dmflag = -99;
2169                 itt = 999;
2170               }
2171             }
2172           }
2173         }
2174       }
2175       else item = (j-jmin)/h;
2176       if (dmflag == -99) {itemold = -1; break; }
2177       if (item!=itemold) {
2178         if (item>-1) {
2179           j1 = item*h+lw; j2 = (item+1)*h-lw-1;
2180           if (gmu->soc2 > -1) {
2181             XSetForeground(display, gcp, cvals[gmu->soc2]);
2182             XDrawLine (display, pop, gcp, lw, j1, lw, j2);
2183             XDrawLine (display, pop, gcp, lw, j1, isiz-lw-1, j1);
2184           }
2185           if (gmu->soc1 > -1) {
2186             XSetForeground(display, gcp, cvals[gmu->soc1]);
2187             XDrawLine (display, pop, gcp, isiz-lw-1, j1, isiz-lw-1, j2);
2188             XDrawLine (display, pop, gcp, lw, j2, isiz-lw-1, j2);
2189           }
2190           if (ptrs[item]>-1) {
2191             j1 = h/5;
2192             j2 = (item+1)*h - h/2;
2193             if (gmu->soc1 > -1) {
2194               XSetForeground(display, gcp, cvals[gmu->soc1]);
2195               XDrawLine (display, pop, gcp, isiz-j1*3, j2+j1, isiz-j1*3, j2-j1);
2196               XDrawLine (display, pop, gcp, isiz-j1*3, j2-j1, isiz-j1, j2);
2197             }
2198             if (gmu->soc2 > -1) {
2199               XSetForeground(display, gcp, cvals[gmu->soc2]);
2200               XDrawLine (display, pop, gcp, isiz-j1, j2, isiz-j1*3, j2+j1);
2201             }
2202           }
2203           ecnt = 0;
2204         }
2205         if (itemold>-1) {
2206           j1 = itemold*h+lw; j2 = (itemold+1)*h-lw-1;
2207           if (gmu->bbc > -1) {
2208             XSetForeground(display, gcp, cvals[gmu->bbc]);
2209             XDrawLine (display, pop, gcp, lw, j1, lw, j2);
2210             XDrawLine (display, pop, gcp, lw, j1, isiz-lw-1, j1);
2211             XDrawLine (display, pop, gcp, isiz-lw-1, j1, isiz-lw-1, j2);
2212             XDrawLine (display, pop, gcp, lw, j2, isiz-lw-1, j2);
2213           }
2214           if (ptrs[itemold]>-1) {
2215             j1 = h/5;
2216             j2 = (itemold+1)*h - h/2;
2217             if (gmu->soc2 > -1) {
2218               XSetForeground(display, gcp, cvals[gmu->soc2]);
2219               XDrawLine (display, pop, gcp, isiz-j1*3, j2+j1, isiz-j1*3, j2-j1);
2220               XDrawLine (display, pop, gcp, isiz-j1*3, j2-j1, isiz-j1, j2);
2221             }
2222             if (gmu->soc1 > -1) {
2223               XSetForeground(display, gcp, cvals[gmu->soc1]);
2224               XDrawLine (display, pop, gcp, isiz-j1, j2, isiz-j1*3, j2+j1);
2225             }
2226           }
2227           ecnt = 0;
2228         }
2229       }
2230       if (ecnt > 3 && item > -1 && item==itemold && ptrs[item] > -1) {
2231         j1 = itemold*h+1;
2232         dmcur[dmrecu] = item;
2233         itt = ptrs[item];
2234         if (dmu[itt].num == itt) {
2235           dmflag = gxpopdm( &(dmu[ptrs[item]]), iobj, imin, imax, j1+jmin);
2236           if (dmflag != -99) {
2237             if (dmsel[dmrecu+1]<1) {
2238               item = -2;
2239               itemold = -2;
2240             }
2241             break;
2242           }
2243           dmflag = -999;
2244         }
2245       }
2246       if (item==itemold) ecnt++;
2247       itemold = item;
2248       if (item==-1) {
2249         ii = 0;
2250         while (ii<512 && obj[ii].type>-1) {
2251           if (ii != iobj && obj[ii].type==3 &&
2252               i>obj[ii].i1 && i<obj[ii].i2 && j>obj[ii].j1 && j<obj[ii].j2) {
2253             dmflag = ii;
2254             ii = 100000;           /* Exit loop */
2255           }
2256           ii++;
2257         }
2258       }
2259       if (dmflag > -1) break;
2260     }
2261   }
2262   dmsel[dmrecu] = itemold + 1;
2263   if (ptrs[itemold]>-1 && dmsel[dmrecu+1]<0) dmsel[dmrecu] = -1;
2264   XUnmapWindow(display,pop);
2265   XDestroyWindow(display,pop);
2266   if (!bsflg) {
2267     if (tpmap) {
2268       XCopyArea (display, tpmap, win, gc, 0, 0, pisiz, pjsiz, pimin, pjmin);
2269       XFreePixmap (display, tpmap);
2270     }
2271     excnt++;
2272   }
2273   XFlush(display);
2274   dmrecu--;
2275   return (dmflag);
2276 }
2277 
2278 /* Handle dialog box.  A new, temporary window is created,
2279    and text input is allowed.  Window is destroyed as soon as
2280    the enter key is detected.  */
2281 
2282 /* modified 102400 by love to support user settings for window with editing. */
2283 
gxdlg(struct gdlg * qry)2284 char *gxdlg (struct gdlg *qry) {
2285 int flag,i,j,cnt,len,maxw,w,h,rlen,plen,tlen;
2286 int dflag,cn,c0,c1,c2,i1,i2,ii,w1,w2,cflag,eflag,pflag;
2287 int item,itemold,jmin,jmax,imin,imax,isiz,jsiz,j1,j2;
2288 int n0,n1,n2,n3,n4,n5,n6,n7,p0,p1,p2,p3,p4,p5,p6,pl;
2289 float tt;
2290 Time lastBtnDown;
2291 char *tch,buff[80],*rch,ch[1],*pch;
2292 KeySym keysym;
2293 int pimin,pjmin,pisiz,pjsiz;
2294 Pixmap tpmap, wmap;
2295 Window pop;
2296 GC gcp;
2297 
2298   pch = (char *)malloc(512);
2299   if (pch==NULL) {
2300     printf ("Memory Allocation Error: Dialog Box\n");
2301     return '\0';
2302   }
2303   tch = (char *)malloc(512);
2304   if (tch==NULL) {
2305     printf ("Memory Allocation Error: Dialog Box\n");
2306     return '\0';
2307   }
2308   rch = (char *)malloc(512);
2309   if (rch==NULL) {
2310     printf ("Memory Allocation Error: Dialog Box\n");
2311     return '\0';
2312   }
2313   plen = 0;
2314   rlen = 0;
2315 
2316   XSelectInput(display, win, ButtonReleaseMask | ButtonPressMask |
2317       ButtonMotionMask | ExposureMask | StructureNotifyMask);
2318 
2319 /* Check for a '|' and split the input string into a prompt and
2320    an initial string.  Check for a '\' or '/' to split the line */
2321   len = 0;
2322   if (qry->ch) while (*(qry->ch+len)) len++;
2323   flag = 0;
2324   pflag = 0;
2325   c0 = 0;
2326   c1 = 0;
2327   c2 = 0;
2328   for (i = 0; i<len; i++) {
2329     *(tch-c1+i) = *(qry->ch+i);
2330     if ((*(qry->ch+i) == '|' || *(qry->ch+i) == '/') && pflag == 0) {
2331       c1 = i + 1;
2332       strcpy(pch,tch);
2333       pflag = i;
2334     }
2335     if (*(qry->ch+i) == '/' && flag == 0) flag = i;
2336   }
2337   plen = c1;
2338   if (*(pch) == '|' || *(pch) == '/') {*(pch) = '\0'; plen = 0;}
2339   if (*(pch+pflag) == '|' || *(pch+pflag) == '/') *(pch+pflag) = ' ';
2340   *(pch+c1) = '\0';
2341 
2342 /* Define input string */
2343   for (i = 0; i<len-c1; i++) { /* find leading blanks and new line indicators */
2344     if (*(tch+i) == '/' || *(tch+i) == ' ' || *(tch+i) == '|') continue;
2345     else {c2 = i; break;}
2346   }
2347   for (i = 0; i<len-c2; i++) 	/* remove leading blanks and new line indicators */
2348     *(rch+i) =  *(tch+c2+i);
2349   strcpy(tch,rch);
2350   tlen = len - c2 - c1;
2351   *(tch+tlen) = '\0';
2352 
2353   if (qry->x<0 &&qry->y<0 &&qry->h<0 &&qry->w<0)
2354     dflag = 1;
2355   else if (flag)
2356     dflag = 2;
2357   else
2358     dflag = 0;
2359 
2360   if (pflag && !flag) c0 = c1;
2361   if (dflag == 1 ) c0 = 0;
2362 
2363 /* Set width and height of dialog box */
2364   if (gfont==1 && font1i) {
2365     if (pch) w1 = XTextWidth(font1i, pch, plen);
2366     else w1 = 0;
2367     h = font1i->ascent;
2368   }
2369   if (gfont==2 && font2i) {
2370     if (pch) w1 = XTextWidth(font2i, pch, plen);
2371     else w1 = 0;
2372     h = font2i->ascent;
2373   }
2374   if (gfont==3 && font3i) {
2375     if (pch) w1 = XTextWidth(font3i, pch, plen);
2376     else w1 = 0;
2377     h = font3i->ascent;
2378   }
2379   if (gfont==1 && font1) {
2380     if (tch) w2 = XTextWidth(font1, tch, tlen);
2381     else w2 = 0;
2382     h = font1->ascent;
2383   }
2384   if (gfont==2 && font2) {
2385     if (tch) w2 = XTextWidth(font2, tch, tlen);
2386     else w2 = 0;
2387     h = font2->ascent;
2388    }
2389    if (gfont==3 && font3) {
2390     if (tch) w1 = XTextWidth(font3, tch, tlen);
2391     else w2 = 0;
2392     h = font3->ascent;
2393   }
2394   if (flag) w = ((w1)>(w2))?(w1):(w2);
2395   else w = w1 + w2;
2396   if (flag) h = h*1.8;
2397 
2398 
2399 /* Convert box size to pixels */
2400   if (qry->h == -1 ) {
2401     jsiz = h*5;
2402     if (jsiz>height) jsiz = height*3/4;
2403   }
2404   else jsiz = (int)(qry->h*yscl+0.5);
2405   if (qry->h == 0 ) jsiz = h*1.8;
2406 
2407   if (qry->w == -1 ) isiz = width*2/3;
2408   else isiz = (int)(qry->w*xscl+0.5);
2409   if (qry->w == 0 ) isiz = w+h*1.5;
2410 
2411   if (qry->x == -1 ) imin = (width-isiz)/2;
2412   else imin = qry->x*xscl+0.5-isiz/2;
2413 
2414   if (qry->y == -1 ) jmin = (height-jsiz)/2;
2415   else jmin = height - (qry->y*yscl+0.5+jsiz/2);
2416   pimin = imin; pjmin = jmin; pisiz = isiz; pjsiz = jsiz;
2417 
2418   xsetw.save_under = 1;
2419   if (!bsflg) {
2420     wmap = XCreatePixmap (display, win, width, height, depth);
2421     XSync(display, 0);
2422     if (wmap) {
2423        XCopyArea (display, win, wmap, gc, 0, 0, width, height, 0, 0);
2424     }
2425   }
2426   pop = XCreateWindow(display, win, pimin, pjmin, pisiz, pjsiz, 0,
2427         CopyFromParent, CopyFromParent, CopyFromParent,
2428         CWSaveUnder, &xsetw);
2429   XSelectInput(display, pop, ExposureMask | StructureNotifyMask | KeyPressMask);
2430   gcp = XCreateGC(display, pop, 0L, &values);
2431   if (qry->oc > -1) cn = qry->oc;
2432   else cn = 1;
2433   XSetForeground(display, gcp, cvals[cn]);
2434   XSetLineAttributes(display, gcp, 0L, LineSolid,
2435                      CapButt, JoinBevel);
2436   XMapWindow(display, pop);
2437   flag = 1;
2438   while (flag)  {
2439     XMaskEvent(display, ExposureMask | StructureNotifyMask, &report);
2440     switch  (report.type) {
2441     case Expose:
2442       if (report.xexpose.count != 0) break;
2443       else flag = 0;
2444       break;
2445     case ConfigureNotify:
2446       break;
2447     }
2448   }
2449 
2450 /* Draw dialog box and text */
2451   if (dflag == 1 && plen == 0) {
2452     plen = tlen;
2453     strcpy(pch,tch);
2454     tlen = 0;
2455     *(tch) = '\0';
2456   }
2457   if (qry->bc > -1) cn = qry->bc;
2458   else cn = 15;
2459   XSetForeground(display, gcp, cvals[cn]);
2460   XFillRectangle (display, pop, gcp, 0, 0, pisiz, pjsiz);
2461   if (qry->oc > -1) cn = qry->oc;
2462   else cn = 1;
2463   XSetForeground(display, gcp, cvals[cn]);
2464   XDrawRectangle (display, pop, gcp, 0, 0, pisiz-1, pjsiz-1);
2465   if (qry->th > 5) XDrawRectangle (display, pop, gcp, 1, 1, pisiz-3, pjsiz-3);
2466   if (qry->fc > -1) cn = qry->fc;
2467   else cn = 0;
2468   XSetForeground(display, gcp, cvals[cn]);
2469   if (dflag) {
2470     if (gfont==1 && font1i) XSetFont (display, gcp, font1i->fid);
2471     if (gfont==2 && font2i) XSetFont (display, gcp, font2i->fid);
2472     if (gfont==3 && font3i) XSetFont (display, gcp, font3i->fid);
2473     i = (isiz-w)/2;
2474     if (dflag == 1) {
2475       j = h*2;
2476     } else {
2477       j = jsiz*3/7;
2478     }
2479     XSetForeground(display, gcp, cvals[0]);
2480     if (plen>0) XDrawString(display, pop, gcp, i, j, pch, plen);
2481     if (qry->pc > -1) cn = qry->pc;
2482     else cn = 1;
2483     XSetForeground(display, gcp, cvals[cn]);
2484     if (plen>0) XDrawString(display, pop, gcp, i-1, j-1, pch, plen);
2485     if (gfont==1 && font1) XSetFont (display, gcp, font1->fid);
2486     if (gfont==2 && font2) XSetFont (display, gcp, font2->fid);
2487     if (gfont==3 && font3) XSetFont (display, gcp, font3->fid);
2488     if (dflag == 1) {
2489       j = h*4;
2490       j1 = h*2+1;
2491       j2 = jsiz-j1-1;
2492     } else {
2493       j = jsiz*6/7;
2494       j1 = jsiz*1/2;
2495       j2 = jsiz -j1 -1;
2496     }
2497     if (qry->fc > -1) cn = qry->fc;
2498     else cn = 0;
2499     XSetForeground(display, gcp, cvals[cn]);
2500     if (gfont==1 && font1) XSetFont (display, gcp, font1->fid);
2501     if (gfont==2 && font2) XSetFont (display, gcp, font2->fid);
2502     if (gfont==3 && font3) XSetFont (display, gcp, font3->fid);
2503     if (tlen>0) XDrawString(display, pop, gcp, i, j, tch, tlen);
2504     strcpy(rch,tch);
2505     rlen = tlen;
2506   } else {
2507     if (gfont==1 && font1) XSetFont (display, gcp, font1->fid);
2508     if (gfont==2 && font2) XSetFont (display, gcp, font2->fid);
2509     if (gfont==3 && font3) XSetFont (display, gcp, font3->fid);
2510     j1 = 1;
2511     j2 = jsiz -j1 -1;
2512     j = (j1+j2+h-1)/2;
2513     if (pflag) {
2514       i = h/2;
2515       strcpy(rch,pch);
2516       strcat(rch,tch);
2517       rlen = plen + tlen;
2518       if (rlen>0) XDrawString(display, pop, gcp, i, j, rch, rlen);
2519     } else {
2520       i = (isiz-w)/2;
2521       if (tlen>0) XDrawString(display, pop, gcp, i, j, tch, tlen);
2522       strcpy(rch,tch);
2523       rlen = tlen;
2524     }
2525   }
2526 
2527   if (!bsflg) {
2528     tpmap = XCreatePixmap (display, pop, pisiz, pjsiz, depth);
2529     XSync(display, 0);
2530     if (tpmap) {
2531        XCopyArea (display, pop, tpmap, gc, 0, 0, pisiz, pjsiz, 0, 0);
2532     }
2533   }
2534 
2535 /* Loop on edit session and exit on Enter */
2536   c1 = rlen;
2537   c2 = rlen;
2538   cflag = 0;
2539   eflag = 0;
2540   for (i=0; i<512; i++) *(tch+i) = '\0';
2541   lastBtnDown = 0;
2542   while (1) {
2543     XMaskEvent(display, ButtonReleaseMask | ButtonPressMask |
2544          ButtonMotionMask | KeyPressMask | ExposureMask | StructureNotifyMask, &report);
2545 
2546 /*mf 980112
2547   explicit cast of report to make it work on the NERSC j90
2548   this is NOT correct for X11R6.3
2549 mf*/
2550 
2551     if (report.type == NoExpose) continue;
2552 
2553     if (report.type == Expose || report.type == GraphicsExpose) {
2554       if (excnt>0) excnt--;
2555       if (!bsflg) {
2556         if (wmap && report.type == Expose) {
2557           XCopyArea (display, wmap, win, gc, 0, 0, width, height, 0, 0);
2558         }
2559         if (tpmap) {
2560           XCopyArea (display, tpmap, pop, gc, 0, 0, pisiz, pjsiz, 0, 0);
2561         }
2562       }
2563       XFlush(display);
2564     }
2565     if (!bsflg && report.type != Expose && report.type != GraphicsExpose && tpmap) {
2566       XFreePixmap (display, tpmap);
2567       tpmap = (Pixmap) NULL;
2568     }
2569     if (report.type == ButtonPress && report.xbutton.time < lastBtnDown + 300) {
2570       c1 = c0;
2571       c2 = rlen;
2572       i1 = (isiz-w)/2;
2573       i2 = (isiz+w)/2;
2574       cflag = 1;
2575     } else if (report.type == ButtonPress && rlen>0) {
2576       i1 = report.xbutton.x - imin;
2577       if (2*i1 > isiz-w && 2*i1 < isiz+w) c1 = (i1 - (isiz-w)/2 + 4)*rlen/w;
2578       if (2*i1 <= isiz-w) c1 = 0;
2579       if (2*i1 >= isiz+w) c1 = rlen;
2580       if (2*i1 <= isiz-w) i1 = (isiz-w)/2;
2581       if (2*i1 >= isiz+w) i1 = (isiz+w)/2;
2582       if (c1 < c0) c1 = c0;
2583       c2 = c1;
2584       lastBtnDown = report.xbutton.time;
2585     } else if ((report.type == ButtonRelease || report.type == MotionNotify) && rlen>0 && cflag==0) {
2586       i2 = report.xbutton.x - imin;
2587       if (2*i2 > isiz-w && 2*i2 < isiz+w) c2 = (i2 - (isiz-w)/2 + 8)*rlen/w;
2588       if (2*i2 <= isiz-w) c2 = c0;
2589       if (2*i2 >= isiz+w) c2 = rlen;
2590       if (2*i2 <= isiz-w) i2 = (isiz-w)/2;
2591       if (2*i2 >= isiz+w) i2 = (isiz+w)/2;
2592       if (c2 < c0) c2 = c0;
2593       cflag = 0;
2594     }
2595     if(rlen == 0) {
2596       i2 = isiz/2;
2597       i1 = isiz/2;
2598       c2 = c0;
2599       c1 = c0;
2600     }
2601     if (report.type ==  KeyPress) {
2602       cnt = XLookupString((XKeyEvent *)&report,buff,80,&keysym,NULL);
2603       if (cnt>0) {
2604         if (keysym==XK_Return || keysym==XK_Linefeed) {
2605           if (qry->nu == 1) {
2606             for (i=0; i<rlen-c0; i++) *(tch+i) = *(rch+c0+i);
2607             tlen = rlen-c0;
2608             ii = 0;
2609             n0=0; n1=0; n2=0; n3=0; n4=0; n5=0; n6=0; n7=0;
2610             p0=0; p1=0; p2=0; p3=0; p4=0; p5=0; p6=0;
2611             for (i = 0; i<tlen; i++) {
2612               if (*(tch+i) == '.') {n1++; p1=i+1;}
2613               if (*(tch+i) == '+') {n2++; p2=i+1;}
2614               if (*(tch+i) == '-') {n3++; p3=i+1;}
2615               if (*(tch+i) == 'e') {n4++; p4=i+1;}
2616               if (*(tch+i) == 'E') {n5++; p5=i+1;}
2617               if (*(tch+i) >= 'a' && *(tch+i) <= 'z' && *(tch+i) != 'e') n0=1;
2618               if (*(tch+i) >= 'A' && *(tch+i) <= 'Z' && *(tch+i) != 'E') n0=1;
2619               if (n0==1 && p0==0) p0 = i;
2620               if (n0==1) pl =i;
2621               if (*(tch+i) == '#') {n6++; p6=i+1;}
2622               if (*(tch+i) >= '0' && *(tch+i) <= '9') n7=1;
2623             }
2624             if (n1==1 && p1==1) ii = 1; /* require digit before decimal  */
2625             if (n1==1 && p1==2 && p2==1 && n2==1) ii = 1;
2626             if (n1==1 && p1==2 && p3==1 && n3==1) ii = 1;
2627             if (n1==1 && p1==2 && p2==p4+1 && n2==2) ii = 1;
2628             if (n1==1 && p1==2 && p3==p4+1 && n3==2) ii = 1;
2629             if (n1==1 && p1==2 && p2==p5+1 && n2==2) ii = 1;
2630             if (n1==1 && p1==2 && p3==p5+1 && n3==2) ii = 1;
2631             if (n1>1) ii = 2; /* too many decimal points */
2632             if (n2>=1 && p2>p4+1 && n4==1) ii = 3; /* misplaced + sign in exponent */
2633             if (n2>=1 && p2>p5+1 && n5==1) ii = 3;
2634             if (n3>=1 && p3>p4+1 && n4==1) ii = 4; /* misplaced - sign in exponent */
2635             if (n3>=1 && p3>p5+1 && n5==1) ii = 4;
2636             if (n2>=1 && p2>1 && n4+n5==0) ii = 5; /* misplaced + sign in number */
2637             if (n2>=1 && p2>1 && p2<p4 && n4==1) ii = 5;
2638             if (n2>=1 && p2>1 && p2<p5 && n5==1) ii = 5;
2639             if (n3>=1 && p3>1 && n4+n5==0) ii = 6; /* misplaced - sign in number */
2640             if (n3>=1 && p3>1 && p3<p4 && n4==1) ii = 6;
2641             if (n3>=1 && p3>1 && p3<p5 && n5==1) ii = 6;
2642             if (n1==1 && p1>p4 && n4==1) ii = 7; /* decimal in exponent */
2643             if (n1==1 && p1>p5 && n5==1) ii = 7;
2644             if (n4>0 && p4==tlen) ii = 8; /* missing exponent value */
2645             if (n5>0 && p5==tlen) ii = 8;
2646             if (n4>0 && p4==tlen-1 && p2==tlen) ii = 8;
2647             if (n5>0 && p5==tlen-1 && p2==tlen) ii = 8;
2648             if (n4>0 && p4==tlen-1 && p3==tlen) ii = 8;
2649             if (n5>0 && p5==tlen-1 && p3==tlen) ii = 8;
2650             if (n7==0) ii = 9; /* missing number value */
2651             if (n4>0 && p4==1) ii = 9;
2652             if (n5>0 && p5==1) ii = 9;
2653             if (n4>0 && p4==2 && p1==1) ii = 9;
2654             if (n5>0 && p5==2 && p1==1) ii = 9;
2655             if (n4>0 && p4==2 && p2==1) ii = 9;
2656             if (n5>0 && p5==2 && p2==1) ii = 9;
2657             if (n4>0 && p4==2 && p3==1) ii = 9;
2658             if (n5>0 && p5==2 && p3==1) ii = 9;
2659             if (n2>2) ii = 10; /* too many '+' signs */
2660             if (n3>2) ii = 11; /* too many '-' signs */
2661             if (n4+n5>1) ii = 12; /* too many exponent symbols */
2662             if (n6>0) ii = 13; /* # sign still present, number not entered */
2663             if (n0>0) ii = 14; /* number includes an alpha char */
2664             if (ii>1) { /* calculate error indices to highlight */
2665               eflag = 1;
2666               if (ii==2) {c1 = p1-1; c2 = p1;}
2667               if (ii==3) {c1 = p2-1; c2 = p2;}
2668               if (ii==4) {c1 = p3-1; c2 = p3;}
2669               if (ii==5) {c1 = p2-1; c2 = p2;}
2670               if (ii==6) {c1 = p3-1; c2 = p3;}
2671               if (ii==7) {c1 = p1-1; c2 = p1;}
2672               if (ii==8) {c1 = tlen; c2 = tlen+1;
2673                  *(tch+tlen)='#'; *(tch+tlen+1)='\0'; tlen++;}
2674               if (ii==9) {c1 = 0; c2 = 1;
2675                   strcpy(rch,tch); *(tch)='#';
2676                  for (i=1; i<tlen+1; i++) *(tch+i) = *(rch+i-1);
2677                  *(tch+tlen+1) = '\0';}
2678               if (ii==10) {c1 = p2-1; c2 = p2;}
2679               if (ii==11) {c1 = p3-1; c2 = p3;}
2680               if (ii==12) {
2681                 if (p5>p4) {c1 = p5-1; c2 = p5;}
2682                 else {c1 = p4-1; c2 = p4;}
2683               }
2684               if (ii==13) {c1 = p6-1; c2 = p6;}
2685               if (ii==14) {c1 = p0-1; c2 = pl+1;}
2686               rlen = tlen+c0;
2687               if (pflag && !dflag) {
2688                 c1 += plen; c2 += plen;
2689                 strcpy(rch,tch);
2690                 strcpy(tch,pch);
2691                 strcat(tch,rch);
2692                 rlen = strlen(tch);
2693               }
2694               strcpy(rch,tch);
2695 
2696             } else {
2697               eflag = 0;
2698                if (ii==1) { /* insert zero digit before decimal  */
2699                 strcpy(rch,tch);
2700                 tlen++;
2701                 ii = 0;
2702                 for (i=0; i<tlen; i++) {
2703                   if (i==p1-1) {
2704                     *(tch+i) = '0';
2705                     i++;
2706                   }
2707                   *(tch+i) = *(rch+ii);
2708                   ii++;
2709                 }
2710                 *(tch+tlen) = '\0';
2711               }
2712               rlen = tlen+c0;
2713               if (pflag && !dflag) {
2714                 strcpy(rch,tch);
2715                 strcpy(tch,pch);
2716                 strcat(tch,rch);
2717               }
2718               strcpy(rch,tch);
2719 
2720               break;
2721             }
2722           } else break;
2723         }
2724         if (keysym==XK_BackSpace && c1>c0) {
2725           strcpy(tch,rch);
2726           ii = 0;
2727           for (i=c0; i<rlen; i++) {
2728             if (i == c1-1 && c1 == c2) continue;
2729             if (i >= c1 && i < c2) continue;
2730             *(rch+ii) = *(tch+i);
2731             ii++;
2732           }
2733           rlen = ii;
2734           if (pflag && !dflag) {strcpy(tch,pch); strcat(tch,rch); strcpy(rch,tch); rlen+=plen;}
2735           *(rch+rlen) = '\0';
2736           c1--;
2737           c2 = c1;
2738         }
2739         if (keysym==XK_Delete) {
2740           strcpy(tch,rch);
2741           ii = 0;
2742           for (i=c0; i<rlen; i++) {
2743             if (i == c1 && c1 == c2) continue;
2744             if (i >= c1 && i < c2) continue;
2745             *(rch+ii) = *(tch+i);
2746             ii++;
2747           }
2748           rlen = ii;
2749           if (pflag && !dflag) {strcpy(tch,pch); strcat(tch,rch); strcpy(rch,tch); rlen+=plen;}
2750           if (c1==rlen &&c1>0) c1--;
2751           *(rch+rlen) = '\0';
2752           c2 = c1;
2753         }
2754         if (keysym>=XK_space && keysym<=XK_asciitilde) {
2755           if (qry->nu == 1) {
2756             *(ch) = buff[0];
2757             if ((*ch>='0' && *ch<='9') || *ch=='+' || *ch=='-' || *ch=='.' || *ch=='e' || *ch=='E') ;
2758             else continue;
2759           }
2760           strcpy(tch,rch);
2761           rlen += c1-c2+1;
2762           ii = 0;
2763           for (i=0; i<rlen; i++) {
2764             if (i == c1) {
2765               *(rch+c1) = buff[0];
2766               i++;
2767               ii += c2-c1;
2768             }
2769             *(rch+i) = *(tch+ii);
2770             ii++;
2771           }
2772           c1++;
2773           *(rch+rlen) = '\0';
2774           c2 = c1;
2775         }
2776         for (i=0; i<512; i++) *(tch+i) = '\0';
2777       }
2778 #if !( defined(XLIBEMU) || defined(XLIBEMU32) )
2779       if ((keysym==XK_KP_Left  ||keysym==XK_Left) && c1>c0) {if (c1==c2) c2--; c1--;}
2780       if ((keysym==XK_KP_Right ||keysym==XK_Right) && c1<rlen) {if (c1==c2) c2++; c1++;}
2781       if ((keysym==XK_KP_Down  ||keysym==XK_Down) && c2>c1) c2--;
2782       if ((keysym==XK_KP_Up    ||keysym==XK_Up) && c2<rlen) c2++;
2783 #endif
2784     }
2785     if (rlen>=0 && c1>=c2) {
2786       if (qry->bc > -1) cn = qry->bc;
2787       else cn = 15;
2788       XSetForeground(display, gcp, cvals[cn]);
2789       XFillRectangle (display, pop, gcp, 2, j1+1, isiz-4, j2-2);
2790       if (qry->fc > -1) cn = qry->fc;
2791       else cn = 0;
2792       XSetForeground(display, gcp, cvals[cn]);
2793       if (gfont==1 && font1) w = XTextWidth(font1, rch, rlen);
2794       if (gfont==2 && font2) w = XTextWidth(font2, rch, rlen);
2795       if (gfont==3 && font3) w = XTextWidth(font3, rch, rlen);
2796       if (w+h < isiz) i = (isiz-w)/2;
2797       else i = isiz-w-h/2;
2798       if (pflag && !dflag && w+h < isiz) i = h/2;
2799       if (c1>0) strncpy(tch,rch, (size_t) c1);
2800       *(tch+c1) = '\0';
2801       if (gfont==1 && font1) w1 = XTextWidth(font1, tch, c1);
2802       if (gfont==2 && font2) w1 = XTextWidth(font2, tch, c1);
2803       if (gfont==3 && font3) w1 = XTextWidth(font3, tch, c1);
2804       ii = i+w1;
2805       if (ii<=0) {
2806         i=-w1;
2807         XDrawString(display, pop, gcp, i, j, rch, rlen);
2808         XDrawString(display, pop, gcp, i, j, "|", 1);
2809       } else {
2810         XDrawString(display, pop, gcp, i, j, rch, rlen);
2811         XDrawString(display, pop, gcp, ii, j, "|", 1);
2812       }
2813     }
2814     if(c1<c2) {
2815       if (gfont==1 && font1) w = XTextWidth(font1, rch, rlen);
2816       if (gfont==2 && font2) w = XTextWidth(font2, rch, rlen);
2817       if (gfont==3 && font3) w = XTextWidth(font3, rch, rlen);
2818       if (w+h < isiz) i = (isiz-w)/2;
2819       else i = isiz-w-h/2;
2820       if (pflag && !dflag && w+h < isiz) i = h/2;
2821 
2822       if (c1>0) strncpy(tch,rch, (size_t) c1);
2823       *(tch+c1) = '\0';
2824       if (gfont==1 && font1) w1 = XTextWidth(font1, tch, c1);
2825       if (gfont==2 && font2) w1 = XTextWidth(font2, tch, c1);
2826       if (gfont==3 && font3) w1 = XTextWidth(font3, tch, c1);
2827       if (qry->bc > -1) cn = qry->bc;
2828       else cn = 15;
2829       XSetForeground(display, gcp, cvals[cn]);
2830       XFillRectangle (display, pop, gcp, 2, j1+1, isiz-4, j2-2);
2831       if (qry->fc > -1) cn = qry->fc;
2832       else cn = 0;
2833       XSetForeground(display, gcp, cvals[cn]);
2834       XDrawString(display, pop, gcp, i, j, tch, c1);
2835 
2836       for (ii=0; ii<c2-c1; ii++) *(tch+ii) = *(rch+ii+c1);
2837       *(tch+c2-c1) = '\0';
2838       if (gfont==1 && font1) w2 = XTextWidth(font1, tch, c2-c1);
2839       if (gfont==2 && font2) w2 = XTextWidth(font2, tch, c2-c1);
2840       if (gfont==3 && font3) w2 = XTextWidth(font3, tch, c2-c1);
2841       i += w1;
2842       if (qry->fc > -1) cn = qry->fc;
2843       else cn = 0;
2844       if (eflag) cn = 2;
2845       XSetForeground(display, gcp, cvals[cn]);
2846       XFillRectangle (display, pop, gcp, i, j1+1, w2, j2-2);
2847       if (qry->bc > -1) cn = qry->bc;
2848       else cn = 15;
2849       XSetForeground(display, gcp, cvals[cn]);
2850       XDrawString(display, pop, gcp, i, j, tch, c2-c1);
2851 
2852       for (ii=0; ii<rlen-c2; ii++) *(tch+ii) = *(rch+ii+c2);
2853       *(tch+rlen-c2) = '\0';
2854       i += w2;
2855       if (qry->bc > -1) cn = qry->bc;
2856       else cn = 15;
2857       XSetForeground(display, gcp, cvals[cn]);
2858       XFillRectangle (display, pop, gcp, i, j1+1, isiz-i2, j2-2);
2859       if (qry->fc > -1) cn = qry->fc;
2860       else cn = 0;
2861       XSetForeground(display, gcp, cvals[cn]);
2862       XDrawString(display, pop, gcp, i, j, tch, rlen-c2);
2863 
2864       if (qry->oc > -1) cn = qry->oc;
2865       else cn = 1;
2866       XSetForeground(display, gcp, cvals[cn]);
2867       XDrawRectangle (display, pop, gcp, 0, 0, isiz-1, jsiz-1);
2868       if (qry->th > 5) XDrawRectangle (display, pop, gcp, 1, 1, isiz-3, jsiz-3);
2869     }
2870     for (i=0; i<512; i++) *(tch+i) = '\0';
2871 
2872     if (!bsflg && report.type != Expose && report.type != GraphicsExpose && !tpmap) {
2873       tpmap = XCreatePixmap (display, pop, pisiz, pjsiz, depth);
2874       XSync(display, 0);
2875       if (tpmap) {
2876          XCopyArea (display, pop, tpmap, gc, 0, 0, pisiz, pjsiz, 0, 0);
2877       }
2878     }
2879   }
2880 
2881 /* Restore original screen */
2882   XUnmapWindow(display,pop);
2883   XDestroyWindow(display,pop);
2884   gxdsfn();
2885   XSelectInput(display, win, ButtonReleaseMask | ButtonPressMask |
2886       ButtonMotionMask | ExposureMask | StructureNotifyMask);
2887   if (!bsflg) {
2888     if (wmap) {
2889       XCopyArea (display, wmap, win, gc, 0, 0, width, height, 0, 0);
2890       XFreePixmap (display, wmap);
2891     }
2892     if (tpmap) {
2893       XFreePixmap (display, tpmap);
2894     }
2895     excnt++;
2896   }
2897   XFlush(display);
2898 
2899 /* Remove '+' signs */
2900   if (qry->nu == 1) {
2901     strcpy(tch,rch);
2902     ii = 0;
2903     for (i=0; i<rlen; i++) {
2904       if (*(rch+i)  == '+') continue;
2905       *(rch+ii) = *(tch+i);
2906       ii++;
2907     }
2908     rlen = ii;
2909   }
2910 /* Trim prompt string */
2911   if (pflag && !dflag) {
2912     strcpy(tch,rch);
2913     ii = 0;
2914     for (i=c0; i<rlen; i++) {
2915       *(rch+ii) = *(tch+i);
2916       ii++;
2917     }
2918     rlen = ii;
2919   }
2920   *(rch+rlen) = '\n';
2921   *(rch+rlen+1) = '\0';
2922   return (rch);
2923 }
2924 
2925 /* Screen save and show operation */
2926 /* Save from displayed window.  Do show operation to current
2927    window display, sometimes background */
2928 
gxdssv(int frame)2929 void gxdssv (int frame) {
2930   if (frame<0 || frame>199) return;
2931   if (!pfilld[frame]) {
2932     pmaps[frame] = XCreatePixmap (display, win, width, height, depth);
2933     if (pmaps[frame]==(Pixmap)NULL) {
2934       printf ("Error allocating pixmap for screen save operation\n");
2935       printf ("Screen will not be saved\n");
2936       return;
2937     }
2938     pfilld[frame] = 1;
2939   }
2940   XCopyArea (display, win, pmaps[frame], gc, 0, 0, width, height, 0, 0);
2941 }
2942 
gxdssh(int cnt)2943 void gxdssh (int cnt) {
2944 int i,j;
2945   if (cnt<0 || cnt>199) return;
2946   if (pfilld[cnt]) XCopyArea (display, pmaps[cnt], drwbl, gc, 0, 0, width, height, 0, 0);
2947 }
2948 
gxdsfr(int frame)2949 void gxdsfr (int frame) {
2950 
2951   if (frame<0 || frame>199) return;
2952   if (pfilld[frame]) {
2953     XFreePixmap (display, pmaps[frame]);
2954     pfilld[frame] = 0;
2955   }
2956 }
2957 
2958 /* Routine to install stipple pixmaps to provide pattern fills for
2959    recf and polyf.  Choices include solid, dot, line and open.
2960    Check and line density can be controlled as well as line angle. */
2961 
gxdptn(int typ,int den,int ang)2962 void gxdptn (int typ, int den, int ang) {
2963 unsigned char *bitmap_bits;
2964 int bitmap_width, bitmap_height;
2965 Pixmap stipple_pixmap;
2966 
2967   if (typ==0) {
2968     bitmap_bits = open_bitmap_bits;
2969     bitmap_width = open_bitmap_width;
2970     bitmap_height = open_bitmap_height;
2971   }
2972   else if (typ==1) {
2973     XSetFillStyle (display, gc, FillSolid);
2974     return;
2975   }
2976   else if (typ==2) {
2977     if (den==6) {
2978       bitmap_bits = dot_6_bitmap_bits;
2979       bitmap_width = dot_6_bitmap_width;
2980       bitmap_height = dot_6_bitmap_height;
2981     }
2982     else if (den==5) {
2983       bitmap_bits = dot_5_bitmap_bits;
2984       bitmap_width = dot_5_bitmap_width;
2985       bitmap_height = dot_5_bitmap_height;
2986     }
2987     else if (den==4) {
2988       bitmap_bits = dot_4_bitmap_bits;
2989       bitmap_width = dot_4_bitmap_width;
2990       bitmap_height = dot_4_bitmap_height;
2991     }
2992     else if (den==3) {
2993       bitmap_bits = dot_3_bitmap_bits;
2994       bitmap_width = dot_3_bitmap_width;
2995       bitmap_height = dot_3_bitmap_height;
2996     }
2997     else if (den==2) {
2998       bitmap_bits = dot_2_bitmap_bits;
2999       bitmap_width = dot_2_bitmap_width;
3000       bitmap_height = dot_2_bitmap_height;
3001     }
3002     else if (den==1) {
3003       bitmap_bits = dot_1_bitmap_bits;
3004       bitmap_width = dot_1_bitmap_width;
3005       bitmap_height = dot_1_bitmap_height;
3006     }
3007     else {
3008       printf ("Error in density specification: density = %d\n",den);
3009       return;
3010     }
3011   }
3012   else if (typ==3) {
3013     if (ang==0) {
3014       if (den==5) {
3015         bitmap_bits = line_0_5_bitmap_bits;
3016         bitmap_width = line_0_5_bitmap_width;
3017         bitmap_height = line_0_5_bitmap_height;
3018       }
3019       else if (den==4) {
3020         bitmap_bits = line_0_4_bitmap_bits;
3021         bitmap_width = line_0_4_bitmap_width;
3022         bitmap_height = line_0_4_bitmap_height;
3023       }
3024       else if (den==3) {
3025         bitmap_bits = line_0_3_bitmap_bits;
3026         bitmap_width = line_0_3_bitmap_width;
3027         bitmap_height = line_0_3_bitmap_height;
3028       }
3029       else if (den==2) {
3030         bitmap_bits = line_0_2_bitmap_bits;
3031         bitmap_width = line_0_2_bitmap_width;
3032         bitmap_height = line_0_2_bitmap_height;
3033       }
3034       else if (den==1) {
3035         bitmap_bits = line_0_1_bitmap_bits;
3036         bitmap_width = line_0_1_bitmap_width;
3037         bitmap_height = line_0_1_bitmap_height;
3038       }
3039       else {
3040         printf ("Error in density specification: density = %d\n",den);
3041         return;
3042       }
3043     }
3044     else if (ang==30) {
3045       if (den==5) {
3046         bitmap_bits = line_30_5_bitmap_bits;
3047         bitmap_width = line_30_5_bitmap_width;
3048         bitmap_height = line_30_5_bitmap_height;
3049       }
3050       else if (den==4) {
3051         bitmap_bits = line_30_4_bitmap_bits;
3052         bitmap_width = line_30_4_bitmap_width;
3053         bitmap_height = line_30_4_bitmap_height;
3054       }
3055       else if (den==3) {
3056         bitmap_bits = line_30_3_bitmap_bits;
3057         bitmap_width = line_30_3_bitmap_width;
3058         bitmap_height = line_30_3_bitmap_height;
3059       }
3060       else if (den==2) {
3061         bitmap_bits = line_30_2_bitmap_bits;
3062         bitmap_width = line_30_2_bitmap_width;
3063         bitmap_height = line_30_2_bitmap_height;
3064       }
3065       else if (den==1) {
3066         bitmap_bits = line_30_1_bitmap_bits;
3067         bitmap_width = line_30_1_bitmap_width;
3068         bitmap_height = line_30_1_bitmap_height;
3069       }
3070       else {
3071         printf ("Error in density specification: density = %d\n",den);
3072         return;
3073       }
3074     }
3075     else if (ang==45) {
3076       if (den==5) {
3077         bitmap_bits = line_45_5_bitmap_bits;
3078         bitmap_width = line_45_5_bitmap_width;
3079         bitmap_height = line_45_5_bitmap_height;
3080       }
3081       else if (den==4) {
3082         bitmap_bits = line_45_4_bitmap_bits;
3083         bitmap_width = line_45_4_bitmap_width;
3084         bitmap_height = line_45_4_bitmap_height;
3085       }
3086       else if (den==3) {
3087         bitmap_bits = line_45_3_bitmap_bits;
3088         bitmap_width = line_45_3_bitmap_width;
3089         bitmap_height = line_45_3_bitmap_height;
3090       }
3091       else if (den==2) {
3092         bitmap_bits = line_45_2_bitmap_bits;
3093         bitmap_width = line_45_2_bitmap_width;
3094         bitmap_height = line_45_2_bitmap_height;
3095       }
3096       else if (den==1) {
3097         bitmap_bits = line_45_1_bitmap_bits;
3098         bitmap_width = line_45_1_bitmap_width;
3099         bitmap_height = line_45_1_bitmap_height;
3100       }
3101       else {
3102         printf ("Error in density specification: density = %d\n",den);
3103         return;
3104       }
3105     }
3106     else if (ang==60) {
3107       if (den==5) {
3108         bitmap_bits = line_60_5_bitmap_bits;
3109         bitmap_width = line_60_5_bitmap_width;
3110         bitmap_height = line_60_5_bitmap_height;
3111       }
3112       else if (den==4) {
3113         bitmap_bits = line_60_4_bitmap_bits;
3114         bitmap_width = line_60_4_bitmap_width;
3115         bitmap_height = line_60_4_bitmap_height;
3116       }
3117       else if (den==3) {
3118         bitmap_bits = line_60_3_bitmap_bits;
3119         bitmap_width = line_60_3_bitmap_width;
3120         bitmap_height = line_60_3_bitmap_height;
3121       }
3122       else if (den==2) {
3123         bitmap_bits = line_60_2_bitmap_bits;
3124         bitmap_width = line_60_2_bitmap_width;
3125         bitmap_height = line_60_2_bitmap_height;
3126       }
3127       else if (den==1) {
3128         bitmap_bits = line_60_1_bitmap_bits;
3129         bitmap_width = line_60_1_bitmap_width;
3130         bitmap_height = line_60_1_bitmap_height;
3131       }
3132       else {
3133         printf ("Error in density specification: density = %d\n",den);
3134         return;
3135       }
3136     }
3137     else if (ang==-30) {
3138       if (den==5) {
3139         bitmap_bits = line_120_5_bitmap_bits;
3140         bitmap_width = line_120_5_bitmap_width;
3141         bitmap_height = line_120_5_bitmap_height;
3142       }
3143       else if (den==4) {
3144         bitmap_bits = line_120_4_bitmap_bits;
3145         bitmap_width = line_120_4_bitmap_width;
3146         bitmap_height = line_120_4_bitmap_height;
3147       }
3148       else if (den==3) {
3149         bitmap_bits = line_120_3_bitmap_bits;
3150         bitmap_width = line_120_3_bitmap_width;
3151         bitmap_height = line_120_3_bitmap_height;
3152       }
3153       else if (den==2) {
3154         bitmap_bits = line_120_2_bitmap_bits;
3155         bitmap_width = line_120_2_bitmap_width;
3156         bitmap_height = line_120_2_bitmap_height;
3157       }
3158       else if (den==1) {
3159         bitmap_bits = line_120_1_bitmap_bits;
3160         bitmap_width = line_120_1_bitmap_width;
3161         bitmap_height = line_120_1_bitmap_height;
3162       }
3163       else {
3164         printf ("Error in density specification: density = %d\n",den);
3165         return;
3166       }
3167     }
3168     else if (ang==-45) {
3169       if (den==5) {
3170         bitmap_bits = line_135_5_bitmap_bits;
3171         bitmap_width = line_135_5_bitmap_width;
3172         bitmap_height = line_135_5_bitmap_height;
3173       }
3174       else if (den==4) {
3175         bitmap_bits = line_135_4_bitmap_bits;
3176         bitmap_width = line_135_4_bitmap_width;
3177         bitmap_height = line_135_4_bitmap_height;
3178       }
3179       else if (den==3) {
3180         bitmap_bits = line_135_3_bitmap_bits;
3181         bitmap_width = line_135_3_bitmap_width;
3182         bitmap_height = line_135_3_bitmap_height;
3183       }
3184       else if (den==2) {
3185         bitmap_bits = line_135_2_bitmap_bits;
3186         bitmap_width = line_135_2_bitmap_width;
3187         bitmap_height = line_135_2_bitmap_height;
3188       }
3189       else if (den==1) {
3190         bitmap_bits = line_135_1_bitmap_bits;
3191         bitmap_width = line_135_1_bitmap_width;
3192         bitmap_height = line_135_1_bitmap_height;
3193       }
3194       else {
3195         printf ("Error in density specification: density = %d\n",den);
3196         return;
3197       }
3198     }
3199     else if (ang==-60) {
3200       if (den==5) {
3201         bitmap_bits = line_150_5_bitmap_bits;
3202         bitmap_width = line_150_5_bitmap_width;
3203         bitmap_height = line_150_5_bitmap_height;
3204       }
3205       else if (den==4) {
3206         bitmap_bits = line_150_4_bitmap_bits;
3207         bitmap_width = line_150_4_bitmap_width;
3208         bitmap_height = line_150_4_bitmap_height;
3209       }
3210       else if (den==3) {
3211         bitmap_bits = line_150_3_bitmap_bits;
3212         bitmap_width = line_150_3_bitmap_width;
3213         bitmap_height = line_150_3_bitmap_height;
3214       }
3215       else if (den==2) {
3216         bitmap_bits = line_150_2_bitmap_bits;
3217         bitmap_width = line_150_2_bitmap_width;
3218         bitmap_height = line_150_2_bitmap_height;
3219       }
3220       else if (den==1) {
3221         bitmap_bits = line_150_1_bitmap_bits;
3222         bitmap_width = line_150_1_bitmap_width;
3223         bitmap_height = line_150_1_bitmap_height;
3224       }
3225       else {
3226         printf ("Error in density specification: density = %d\n",den);
3227         return;
3228       }
3229     }
3230     else if (ang==90||ang==-90) {
3231       if (den==5) {
3232         bitmap_bits = line_90_5_bitmap_bits;
3233         bitmap_width = line_90_5_bitmap_width;
3234         bitmap_height = line_90_5_bitmap_height;
3235       }
3236       else if (den==4) {
3237         bitmap_bits = line_90_4_bitmap_bits;
3238         bitmap_width = line_90_4_bitmap_width;
3239         bitmap_height = line_90_4_bitmap_height;
3240       }
3241       else if (den==3) {
3242         bitmap_bits = line_90_3_bitmap_bits;
3243         bitmap_width = line_90_3_bitmap_width;
3244         bitmap_height = line_90_3_bitmap_height;
3245       }
3246       else if (den==2) {
3247         bitmap_bits = line_90_2_bitmap_bits;
3248         bitmap_width = line_90_2_bitmap_width;
3249         bitmap_height = line_90_2_bitmap_height;
3250       }
3251       else if (den==1) {
3252         bitmap_bits = line_90_1_bitmap_bits;
3253         bitmap_width = line_90_1_bitmap_width;
3254         bitmap_height = line_90_1_bitmap_height;
3255       }
3256       else {
3257         printf ("Error in density specification: density = %d\n",den);
3258         return;
3259       }
3260     }
3261     else {
3262       printf ("Error in angle specification: angle = %d\n",ang);
3263       return;
3264     }
3265   }
3266   else {
3267     printf ("Error in fill specification: type = %d\n",typ);
3268     return;
3269   }
3270 
3271   if (typ>1) {
3272     stipple_pixmap = XCreateBitmapFromData(display, win, bitmap_bits,
3273 		     bitmap_width, bitmap_height);
3274     XSetStipple(display, gc, stipple_pixmap);
3275     XSetFillStyle(display, gc, FillStippled);
3276   }
3277 }
3278 
3279 /*gl 980114 - function to save window info gl*/
3280 /*
3281  * int
3282  * win_data ---  Saves current window information
3283  */
3284 
win_data(struct xinfo * xinf)3285 int win_data (struct xinfo *xinf) {
3286   int absx, absy;
3287   Window dummy;
3288   XWindowAttributes result;
3289 
3290   if (display == (Display *) NULL || win == (Window) NULL) return 0;
3291   if (!XGetWindowAttributes (display, win, &result) ) return 0;
3292   if (!XTranslateCoordinates (display, win, RootWindow (display, snum), 0, 0,
3293 			      &absx, &absy, &dummy) ) return 0;
3294   xinf->winid=(int)win;
3295   xinf->winw=result.width;
3296   xinf->winh=result.height;
3297   xinf->winb=result.border_width;
3298   xinf->winx=absx;
3299   xinf->winy=absy;
3300   return 1;
3301 }
3302 
3303