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