1 /*
2  * Grace - GRaphing, Advanced Computation and Exploration of data
3  *
4  * Home page: http://plasma-gate.weizmann.ac.il/Grace/
5  *
6  * Copyright (c) 1991-1995 Paul J Turner, Portland, OR
7  * Copyright (c) 1996-2003 Grace Development Team
8  *
9  * Maintained by Evgeny Stambulchik
10  *
11  *
12  *                           All Rights Reserved
13  *
14  *    This program is free software; you can redistribute it and/or modify
15  *    it under the terms of the GNU General Public License as published by
16  *    the Free Software Foundation; either version 2 of the License, or
17  *    (at your option) any later version.
18  *
19  *    This program is distributed in the hope that it will be useful,
20  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *    GNU General Public License for more details.
23  *
24  *    You should have received a copy of the GNU General Public License
25  *    along with this program; if not, write to the Free Software
26  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  */
28 
29 /*
30  *
31  * utilities for Motif
32  *
33  */
34 
35 #include <config.h>
36 #include <cmath.h>
37 
38 #include <stdlib.h>
39 #include <ctype.h>
40 #include <stdarg.h>
41 
42 #include <X11/X.h>
43 #include <X11/Xatom.h>
44 #include <X11/cursorfont.h>
45 
46 #include <Xm/Xm.h>
47 #include <Xm/Protocols.h>
48 #include <Xm/BulletinB.h>
49 #include <Xm/MessageB.h>
50 #include <Xm/DialogS.h>
51 #include <Xm/FileSB.h>
52 #include <Xm/Frame.h>
53 #include <Xm/Form.h>
54 #include <Xm/Scale.h>
55 #include <Xm/Label.h>
56 #include <Xm/LabelG.h>
57 #include <Xm/List.h>
58 #include <Xm/PushB.h>
59 #include <Xm/CascadeBG.h>
60 #include <Xm/RowColumn.h>
61 #include <Xm/Separator.h>
62 #include <Xm/Text.h>
63 #include <Xm/ToggleB.h>
64 #include <Xm/ArrowBG.h>
65 
66 #ifdef WITH_EDITRES
67 #  include <X11/Xmu/Editres.h>
68 #endif
69 
70 #if XmVersion < 2000
71 #  define XmStringConcatAndFree(a, b) XmStringConcat(a, b); XmStringFree(a); XmStringFree(b)
72 #endif
73 
74 #include "Tab.h"
75 #include "motifinc.h"
76 
77 #include "defines.h"
78 #include "globals.h"
79 #include "draw.h"
80 #include "patterns.h"
81 #include "jbitmaps.h"
82 #include "t1fonts.h"
83 #include "graphs.h"
84 #include "utils.h"
85 #include "events.h"
86 #include "parser.h"
87 #include "protos.h"
88 
89 static XmStringCharSet charset = XmFONTLIST_DEFAULT_TAG;
90 
91 /* lookup table to determine if character is a floating point digit
92  * only allowable char's [0-9.eE]
93  */
94 unsigned char fpdigit[256] = {
95 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
96 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
97 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
98 			      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
99 			      0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 			      0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
107 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
109 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 			      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
111 
112 
113 extern Display *disp;
114 extern Window root;
115 extern int depth;
116 
117 extern XtAppContext app_con;
118 
119 extern unsigned long xvlibcolors[];
120 
121 
122 static OptionItem *color_option_items = NULL;
123 static int ncolor_option_items = 0;
124 static OptionStructure **color_selectors = NULL;
125 static int ncolor_selectors = 0;
126 
label_to_resname(const char * s,const char * suffix)127 static char *label_to_resname(const char *s, const char *suffix)
128 {
129     char *retval, *rs;
130     int capitalize = FALSE;
131 
132     retval = copy_string(NULL, s);
133     rs = retval;
134     while (*s) {
135         if (isalnum(*s)) {
136             if (capitalize == TRUE) {
137                 *rs = toupper(*s);
138                 capitalize = FALSE;
139             } else {
140                 *rs = tolower(*s);
141             }
142             rs++;
143         } else {
144             capitalize = TRUE;
145         }
146         s++;
147     }
148     *rs = '\0';
149     if (suffix != NULL) {
150         retval = concat_strings(retval, suffix);
151     }
152     return retval;
153 }
154 
155 
ManageChild(Widget w)156 void ManageChild(Widget w)
157 {
158     XtManageChild(w);
159 }
160 
UnmanageChild(Widget w)161 void UnmanageChild(Widget w)
162 {
163     XtUnmanageChild(w);
164 }
165 
SetSensitive(Widget w,int onoff)166 void SetSensitive(Widget w, int onoff)
167 {
168     XtSetSensitive(w, onoff ? True : False);
169 }
170 
GetParent(Widget w)171 Widget GetParent(Widget w)
172 {
173     if (w) {
174         return (XtParent(w));
175     } else {
176         errmsg("Internal error: GetParent() called with NULL widget");
177         return NULL;
178     }
179 }
180 
RegisterEditRes(Widget shell)181 void RegisterEditRes(Widget shell)
182 {
183 #ifdef WITH_EDITRES
184     XtAddEventHandler(shell, (EventMask) 0, True, _XEditResCheckMessages, NULL);
185 #endif
186 }
187 
SetDimensions(Widget w,unsigned int width,unsigned int height)188 void SetDimensions(Widget w, unsigned int width, unsigned int height)
189 {
190     XtVaSetValues(w,
191         XmNwidth, (Dimension) width,
192         XmNheight, (Dimension) height,
193         NULL);
194 }
195 
GetDimensions(Widget w,unsigned int * width,unsigned int * height)196 void GetDimensions(Widget w, unsigned int *width, unsigned int *height)
197 {
198     Dimension ww, wh;
199 
200     XtVaGetValues(w,
201         XmNwidth, &ww,
202         XmNheight, &wh,
203         NULL);
204 
205     *width  = (unsigned int) ww;
206     *height = (unsigned int) wh;
207 }
208 
209 #define MAX_PULLDOWN_LENGTH 30
210 
CreateOptionChoice(Widget parent,char * labelstr,int ncols,int nchoices,OptionItem * items)211 OptionStructure *CreateOptionChoice(Widget parent, char *labelstr, int ncols,
212                                                 int nchoices, OptionItem *items)
213 {
214     Arg args[2];
215     XmString str;
216     OptionStructure *retval;
217 
218     retval = xmalloc(sizeof(OptionStructure));
219 
220     XtSetArg(args[0], XmNpacking, XmPACK_COLUMN);
221     retval->pulldown = XmCreatePulldownMenu(parent, "pulldownMenu", args, 1);
222 
223     retval->ncols = ncols;
224 
225     retval->nchoices = 0;
226     retval->options = NULL;
227     UpdateOptionChoice(retval, nchoices, items);
228 
229     str = XmStringCreateLocalized(labelstr);
230     XtSetArg(args[0], XmNlabelString, str);
231     XtSetArg(args[1], XmNsubMenuId, retval->pulldown);
232 
233     retval->menu = XmCreateOptionMenu(parent, "optionMenu", args, 2);
234 
235     XmStringFree(str);
236 
237     XtManageChild(retval->menu);
238 
239     return retval;
240 }
241 
UpdateOptionChoice(OptionStructure * optp,int nchoices,OptionItem * items)242 void UpdateOptionChoice(OptionStructure *optp, int nchoices, OptionItem *items)
243 {
244     int i, nold, ncols, nw;
245     Widget *wlist;
246 
247     nold = optp->nchoices;
248 
249     if (optp->ncols == 0) {
250         ncols = 1;
251     } else {
252         ncols = optp->ncols;
253     }
254 
255     /* Don't create too tall pulldowns */
256     if (nchoices > MAX_PULLDOWN_LENGTH*ncols) {
257         ncols = (nchoices + MAX_PULLDOWN_LENGTH - 1)/MAX_PULLDOWN_LENGTH;
258     }
259 
260     XtVaSetValues(optp->pulldown, XmNnumColumns, ncols, NULL);
261 
262     nw = nold - nchoices;
263     if (nw > 0) {
264         /* Unmanage extra items before destroying to speed the things up */
265         wlist = xmalloc(nw*sizeof(Widget));
266         for (i = nchoices; i < nold; i++) {
267             wlist[i - nchoices] = optp->options[i].widget;
268         }
269         XtUnmanageChildren(wlist, nw);
270         xfree(wlist);
271 
272         for (i = nchoices; i < nold; i++) {
273             XtDestroyWidget(optp->options[i].widget);
274         }
275     }
276 
277     optp->options = xrealloc(optp->options, nchoices*sizeof(OptionWidgetItem));
278     optp->nchoices = nchoices;
279 
280     for (i = nold; i < nchoices; i++) {
281         optp->options[i].widget =
282                   XmCreatePushButton(optp->pulldown, "button", NULL, 0);
283     }
284 
285     for (i = 0; i < nchoices; i++) {
286 	optp->options[i].value = items[i].value;
287 	if (items[i].label != NULL) {
288             XmString str, ostr;
289             XtVaGetValues(optp->options[i].widget, XmNlabelString, &ostr, NULL);
290             str = XmStringCreateLocalized(items[i].label);
291             if (XmStringCompare(str, ostr) != True) {
292                 XtVaSetValues(optp->options[i].widget, XmNlabelString, str, NULL);
293             }
294             XmStringFree(str);
295         }
296     }
297 
298     nw = nchoices - nold;
299     if (nw > 0) {
300         wlist = xmalloc(nw*sizeof(Widget));
301         for (i = nold; i < nchoices; i++) {
302             wlist[i - nold] = optp->options[i].widget;
303         }
304         XtManageChildren(wlist, nw);
305         xfree(wlist);
306     }
307 }
308 
CreateBitmapOptionChoice(Widget parent,char * labelstr,int ncols,int nchoices,int width,int height,BitmapOptionItem * items)309 OptionStructure *CreateBitmapOptionChoice(Widget parent, char *labelstr, int ncols,
310                 int nchoices, int width, int height, BitmapOptionItem *items)
311 {
312     int i;
313     XmString str;
314     OptionStructure *retval;
315     Pixel fg, bg;
316     Pixmap ptmp;
317 
318     retval = xmalloc(sizeof(OptionStructure));
319     if (retval == NULL) {
320         errmsg("Malloc error in CreateBitmapOptionChoice()");
321     }
322     retval->nchoices = nchoices;
323     retval->options = xmalloc(nchoices*sizeof(OptionWidgetItem));
324     if (retval->options == NULL) {
325         errmsg("Malloc error in CreateBitmapOptionChoice()");
326         XCFREE(retval);
327         return retval;
328     }
329 
330 
331     retval->pulldown = XmCreatePulldownMenu(parent, "pulldownMenu", NULL, 0);
332     XtVaSetValues(retval->pulldown,
333                   XmNentryAlignment, XmALIGNMENT_CENTER,
334                   NULL);
335 
336     if (ncols > 0) {
337         XtVaSetValues(retval->pulldown,
338                       XmNpacking, XmPACK_COLUMN,
339                       XmNnumColumns, ncols,
340                       NULL);
341     }
342 
343     XtVaGetValues(retval->pulldown,
344                   XmNforeground, &fg,
345                   XmNbackground, &bg,
346                   NULL);
347 
348     for (i = 0; i < nchoices; i++) {
349 	retval->options[i].value = items[i].value;
350         if (items[i].bitmap != NULL) {
351             ptmp = XCreatePixmapFromBitmapData(disp, root,
352                                     (char *) items[i].bitmap, width, height,
353                                     fg, bg, depth);
354             retval->options[i].widget =
355                 XtVaCreateWidget("pixButton", xmPushButtonWidgetClass,
356                                  retval->pulldown,
357 	                         XmNlabelType, XmPIXMAP,
358 	                         XmNlabelPixmap, ptmp,
359 	                         NULL);
360         } else {
361 	    retval->options[i].widget =
362                   XmCreatePushButton(retval->pulldown, "None", NULL, 0);
363         }
364 
365     }
366     for (i = 0; i < nchoices; i++) {
367         XtManageChild(retval->options[i].widget);
368     }
369 
370     retval->menu = XmCreateOptionMenu(parent, "optionMenu", NULL, 0);
371     str = XmStringCreateLocalized(labelstr);
372     XtVaSetValues(retval->menu,
373 		  XmNlabelString, str,
374 		  XmNsubMenuId, retval->pulldown,
375 		  NULL);
376     XmStringFree(str);
377     XtManageChild(retval->menu);
378 
379     return retval;
380 }
381 
382 
SetOptionChoice(OptionStructure * opt,int value)383 void SetOptionChoice(OptionStructure *opt, int value)
384 {
385     int i;
386     Arg a;
387 
388     if (opt->options == NULL || opt->nchoices <= 0) {
389         return;
390     }
391 
392     for (i = 0; i < opt->nchoices; i++) {
393         if (opt->options[i].value == value) {
394             XtSetArg(a, XmNmenuHistory, opt->options[i].widget);
395             XtSetValues(opt->menu, &a, 1);
396             return;
397         }
398     }
399 }
400 
GetOptionChoice(OptionStructure * opt)401 int GetOptionChoice(OptionStructure *opt)
402 {
403     Arg a;
404     Widget warg;
405     int i;
406 
407     if (opt->options == NULL || opt->nchoices <= 0) {
408         errmsg("Internal error in GetOptionChoice()");
409         return 0;
410     }
411 
412     XtSetArg(a, XmNmenuHistory, &warg);
413     XtGetValues(opt->menu, &a, 1);
414 
415     for (i = 0; i < opt->nchoices; i++) {
416         if (opt->options[i].widget == warg) {
417             return(opt->options[i].value);
418         }
419     }
420     errmsg("Internal error in GetOptionChoice()");
421     return 0;
422 }
423 
424 typedef struct {
425     OptionStructure *opt;
426     void (*cbproc)();
427     void *anydata;
428 } OC_CBdata;
429 
oc_int_cb_proc(Widget w,XtPointer client_data,XtPointer call_data)430 static void oc_int_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
431 {
432     int value;
433 
434     OC_CBdata *cbdata = (OC_CBdata *) client_data;
435 
436     value = GetOptionChoice(cbdata->opt);
437     cbdata->cbproc(value, cbdata->anydata);
438 }
439 
AddOptionChoiceCB(OptionStructure * opt,OC_CBProc cbproc,void * anydata)440 void AddOptionChoiceCB(OptionStructure *opt, OC_CBProc cbproc, void *anydata)
441 {
442     OC_CBdata *cbdata;
443     int i;
444 
445     cbdata = xmalloc(sizeof(OC_CBdata));
446 
447     cbdata->opt = opt;
448     cbdata->cbproc = cbproc;
449     cbdata->anydata = anydata;
450     for (i = 0; i < opt->nchoices; i++) {
451         XtAddCallback(opt->options[i].widget, XmNactivateCallback,
452                                     oc_int_cb_proc, (XtPointer) cbdata);
453     }
454 }
455 
456 
457 static char list_translation_table[] = "\
458     Ctrl<Key>A: list_selectall_action()\n\
459     Ctrl<Key>U: list_unselectall_action()\n\
460     Ctrl<Key>I: list_invertselection_action()";
461 
CreateListChoice(Widget parent,char * labelstr,int type,int nvisible,int nchoices,OptionItem * items)462 ListStructure *CreateListChoice(Widget parent, char *labelstr, int type,
463                                 int nvisible, int nchoices, OptionItem *items)
464 {
465     Arg args[4];
466     Widget lab;
467     ListStructure *retval;
468 
469     retval = xmalloc(sizeof(ListStructure));
470     retval->rc = XmCreateRowColumn(parent, "rcList", NULL, 0);
471     AddHelpCB(retval->rc, "doc/UsersGuide.html#list-selector");
472 
473     lab = XmCreateLabel(retval->rc, labelstr, NULL, 0);
474     XtManageChild(lab);
475 
476     XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
477     XtSetArg(args[1], XmNscrollBarDisplayPolicy, XmSTATIC);
478     if (type == LIST_TYPE_SINGLE) {
479         XtSetArg(args[2], XmNselectionPolicy, XmSINGLE_SELECT);
480     } else {
481         XtSetArg(args[2], XmNselectionPolicy, XmEXTENDED_SELECT);
482     }
483     XtSetArg(args[3], XmNvisibleItemCount, nvisible);
484     retval->list = XmCreateScrolledList(retval->rc, "listList", args, 4);
485     retval->values = NULL;
486 
487     XtOverrideTranslations(retval->list,
488                              XtParseTranslationTable(list_translation_table));
489 
490     UpdateListChoice(retval, nchoices, items);
491 
492     XtManageChild(retval->list);
493 
494     XtManageChild(retval->rc);
495 
496     return retval;
497 }
498 
UpdateListChoice(ListStructure * listp,int nchoices,OptionItem * items)499 void UpdateListChoice(ListStructure *listp, int nchoices, OptionItem *items)
500 {
501     int i, nsel;
502     int *selvalues;
503     XmString str;
504 
505     if (listp == NULL) {
506         return;
507     }
508 
509     nsel = GetListChoices(listp, &selvalues);
510 
511     listp->nchoices = nchoices;
512     listp->values = xrealloc(listp->values, nchoices*SIZEOF_INT);
513     for (i = 0; i < nchoices; i++) {
514         listp->values[i] = items[i].value;
515     }
516 
517     XmListDeleteAllItems(listp->list);
518     for (i = 0; i < nchoices; i++) {
519 	str = XmStringCreateLocalized(items[i].label);
520         XmListAddItemUnselected(listp->list, str, 0);
521         XmStringFree(str);
522     }
523     SelectListChoices(listp, nsel, selvalues);
524     if (nsel > 0) {
525         xfree(selvalues);
526     }
527 }
528 
SelectListChoice(ListStructure * listp,int choice)529 int SelectListChoice(ListStructure *listp, int choice)
530 {
531     int top, visible;
532     int i = 0;
533 
534     while (i < listp->nchoices && listp->values[i] != choice) {
535         i++;
536     }
537     if (i < listp->nchoices) {
538         i++;
539         XmListDeselectAllItems(listp->list);
540         XmListSelectPos(listp->list, i, True);
541         XtVaGetValues(listp->list, XmNtopItemPosition, &top,
542                                  XmNvisibleItemCount, &visible,
543                                  NULL);
544         if (i < top) {
545             XmListSetPos(listp->list, i);
546         } else if (i >= top + visible) {
547             XmListSetBottomPos(listp->list, i);
548         }
549 
550         return RETURN_SUCCESS;
551     } else {
552         return RETURN_FAILURE;
553     }
554 }
555 
SelectListChoices(ListStructure * listp,int nchoices,int * choices)556 void SelectListChoices(ListStructure *listp, int nchoices, int *choices)
557 {
558     int i = 0, j;
559     unsigned char selection_type_save;
560     int bottom, visible;
561 
562     XtVaGetValues(listp->list, XmNselectionPolicy, &selection_type_save, NULL);
563     XtVaSetValues(listp->list, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL);
564 
565     XmListDeselectAllItems(listp->list);
566     for (j = 0; j < nchoices; j++) {
567         i = 0;
568         while (i < listp->nchoices && listp->values[i] != choices[j]) {
569             i++;
570         }
571         if (i < listp->nchoices) {
572             i++;
573             XmListSelectPos(listp->list, i, True);
574         }
575     }
576 
577     if (nchoices > 0) {
578         /* Rewind list so the last choice is always visible */
579         XtVaGetValues(listp->list, XmNtopItemPosition, &bottom,
580                                  XmNvisibleItemCount, &visible,
581                                  NULL);
582         if (i > bottom) {
583             XmListSetBottomPos(listp->list, i);
584         } else if (i <= bottom - visible) {
585             XmListSetPos(listp->list, i);
586         }
587     }
588 
589     XtVaSetValues(listp->list, XmNselectionPolicy, selection_type_save, NULL);
590 }
591 
GetListChoices(ListStructure * listp,int ** values)592 int GetListChoices(ListStructure *listp, int **values)
593 {
594     int i, n;
595 
596     if (XmListGetSelectedPos(listp->list, values, &n) != True) {
597         return 0;
598     }
599 
600     for (i = 0; i < n; i++) {
601         (*values)[i] = listp->values[(*values)[i] - 1];
602     }
603 
604     return n;
605 }
606 
GetSingleListChoice(ListStructure * listp,int * value)607 int GetSingleListChoice(ListStructure *listp, int *value)
608 {
609     int n, *values, retval;
610 
611     n = GetListChoices(listp, &values);
612     if (n == 1) {
613         *value = values[0];
614         retval = RETURN_SUCCESS;
615     } else {
616         retval = RETURN_FAILURE;
617     }
618     if (n > 0) {
619         xfree(values);
620     }
621     return retval;
622 }
623 
624 typedef struct {
625     ListStructure *listp;
626     void (*cbproc)();
627     void *anydata;
628 } List_CBdata;
629 
list_int_cb_proc(Widget w,XtPointer client_data,XtPointer call_data)630 static void list_int_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
631 {
632     int n, *values;
633     List_CBdata *cbdata = (List_CBdata *) client_data;
634 
635     n = GetListChoices(cbdata->listp, &values);
636 
637     cbdata->cbproc(n, values, cbdata->anydata);
638 
639     if (n > 0) {
640         xfree(values);
641     }
642 }
643 
AddListChoiceCB(ListStructure * listp,List_CBProc cbproc,void * anydata)644 void AddListChoiceCB(ListStructure *listp, List_CBProc cbproc, void *anydata)
645 {
646     List_CBdata *cbdata;
647 
648     cbdata = xmalloc(sizeof(List_CBdata));
649     cbdata->listp = listp;
650     cbdata->cbproc = (List_CBProc) cbproc;
651     cbdata->anydata = anydata;
652     XtAddCallback(listp->list,
653         XmNsingleSelectionCallback,   list_int_cb_proc, (XtPointer) cbdata);
654     XtAddCallback(listp->list,
655         XmNmultipleSelectionCallback, list_int_cb_proc, (XtPointer) cbdata);
656     XtAddCallback(listp->list,
657         XmNextendedSelectionCallback, list_int_cb_proc, (XtPointer) cbdata);
658 }
659 
660 
spin_arrow_cb(Widget w,XtPointer client_data,XtPointer call_data)661 static void spin_arrow_cb(Widget w, XtPointer client_data, XtPointer call_data)
662 {
663     SpinStructure *spinp;
664     double value, incr;
665 
666     spinp = (SpinStructure *) client_data;
667     value = GetSpinChoice(spinp);
668     incr = spinp->incr;
669 
670     if (w == spinp->arrow_up) {
671         incr =  spinp->incr;
672     } else if (w == spinp->arrow_down) {
673         incr = -spinp->incr;
674     } else {
675         errmsg("Wrong call to spin_arrow_cb()");
676         return;
677     }
678     value += incr;
679     SetSpinChoice(spinp, value);
680 }
681 
CreateSpinChoice(Widget parent,char * s,int len,int type,double min,double max,double incr)682 SpinStructure *CreateSpinChoice(Widget parent, char *s, int len,
683                         int type, double min, double max, double incr)
684 {
685     SpinStructure *retval;
686     Widget fr, form;
687     XmString str;
688 
689     if (min >= max) {
690         errmsg("min >= max in CreateSpinChoice()!");
691         return NULL;
692     }
693 
694     retval = xmalloc(sizeof(SpinStructure));
695 
696     retval->type = type;
697     retval->min = min;
698     retval->max = max;
699     retval->incr = incr;
700 
701     retval->rc = XtVaCreateWidget("rc", xmRowColumnWidgetClass, parent,
702         XmNorientation, XmHORIZONTAL,
703         NULL);
704     str = XmStringCreateLocalized(s);
705     XtVaCreateManagedWidget("label", xmLabelWidgetClass, retval->rc,
706 	XmNlabelString, str,
707 	NULL);
708     XmStringFree(str);
709     fr = XtVaCreateWidget("fr", xmFrameWidgetClass, retval->rc,
710         XmNshadowType, XmSHADOW_ETCHED_OUT,
711         NULL);
712     form = XtVaCreateWidget("form", xmFormWidgetClass, fr,
713         NULL);
714     retval->text = XtVaCreateWidget("text", xmTextWidgetClass, form,
715 	XmNtraversalOn, True,
716 	XmNcolumns, len,
717 	NULL);
718     retval->arrow_up = XtVaCreateWidget("form", xmArrowButtonGadgetClass, form,
719         XmNarrowDirection, XmARROW_UP,
720         NULL);
721     XtAddCallback(retval->arrow_up, XmNactivateCallback,
722         spin_arrow_cb, (XtPointer) retval);
723     retval->arrow_down = XtVaCreateWidget("form", xmArrowButtonGadgetClass, form,
724         XmNarrowDirection, XmARROW_DOWN,
725         NULL);
726     XtAddCallback(retval->arrow_down, XmNactivateCallback,
727         spin_arrow_cb, (XtPointer) retval);
728     XtVaSetValues(retval->text,
729         XmNtopAttachment, XmATTACH_FORM,
730         XmNleftAttachment, XmATTACH_FORM,
731         XmNbottomAttachment, XmATTACH_FORM,
732         XmNrightAttachment, XmATTACH_NONE,
733         NULL);
734     XtVaSetValues(retval->arrow_down,
735         XmNtopAttachment, XmATTACH_FORM,
736         XmNbottomAttachment, XmATTACH_FORM,
737         XmNleftAttachment, XmATTACH_WIDGET,
738         XmNleftWidget, retval->text,
739         XmNrightAttachment, XmATTACH_NONE,
740         NULL);
741     XtVaSetValues(retval->arrow_up,
742         XmNtopAttachment, XmATTACH_FORM,
743         XmNbottomAttachment, XmATTACH_FORM,
744         XmNrightAttachment, XmATTACH_FORM,
745         XmNleftAttachment, XmATTACH_WIDGET,
746         XmNleftWidget, retval->arrow_down,
747         NULL);
748 
749     XtManageChild(retval->text);
750     XtManageChild(retval->arrow_up);
751     XtManageChild(retval->arrow_down);
752     XtManageChild(form);
753     XtManageChild(fr);
754     XtManageChild(retval->rc);
755 
756     return retval;
757 }
758 
SetSpinChoice(SpinStructure * spinp,double value)759 void SetSpinChoice(SpinStructure *spinp, double value)
760 {
761     char buf[64];
762 
763     if (value < spinp->min) {
764         XBell(disp, 50);
765         value = spinp->min;
766     } else if (value > spinp->max) {
767         XBell(disp, 50);
768         value = spinp->max;
769     }
770 
771     if (spinp->type == SPIN_TYPE_FLOAT) {
772         sprintf(buf, "%g", value);
773     } else {
774         sprintf(buf, "%d", (int) rint(value));
775     }
776     XmTextSetString(spinp->text, buf);
777 }
778 
GetSpinChoice(SpinStructure * spinp)779 double GetSpinChoice(SpinStructure *spinp)
780 {
781     double retval;
782 
783     xv_evalexpr(spinp->text, &retval);
784     if (retval < spinp->min) {
785         errmsg("Input value below min limit in GetSpinChoice()");
786         retval = spinp->min;
787         SetSpinChoice(spinp, retval);
788     } else if (retval > spinp->max) {
789         errmsg("Input value above max limit in GetSpinChoice()");
790         retval = spinp->max;
791         SetSpinChoice(spinp, retval);
792     }
793 
794     if (spinp->type == SPIN_TYPE_INT) {
795         return rint(retval);
796     } else {
797         return retval;
798     }
799 }
800 
801 
CreateTextInput(Widget parent,char * s)802 TextStructure *CreateTextInput(Widget parent, char *s)
803 {
804     TextStructure *retval;
805     XmString str;
806 
807     retval = xmalloc(sizeof(TextStructure));
808     retval->form = XtVaCreateWidget("form", xmFormWidgetClass, parent, NULL);
809 
810     str = XmStringCreateLocalized(s);
811     retval->label = XtVaCreateManagedWidget("label",
812         xmLabelWidgetClass, retval->form,
813         XmNlabelString, str,
814         XmNtopAttachment, XmATTACH_FORM,
815         XmNbottomAttachment, XmATTACH_FORM,
816         XmNleftAttachment, XmATTACH_FORM,
817         XmNrightAttachment, XmATTACH_NONE,
818         NULL);
819     XmStringFree(str);
820 
821     retval->text = XtVaCreateManagedWidget("cstext",
822         xmTextWidgetClass, retval->form,
823         XmNtraversalOn, True,
824         XmNtopAttachment, XmATTACH_FORM,
825         XmNbottomAttachment, XmATTACH_FORM,
826         XmNleftAttachment, XmATTACH_WIDGET,
827         XmNleftWidget, retval->label,
828         XmNrightAttachment, XmATTACH_FORM,
829         NULL);
830 
831     XtManageChild(retval->form);
832 
833     return retval;
834 }
835 
cstext_edit_action(Widget w,XEvent * e,String * par,Cardinal * npar)836 void cstext_edit_action(Widget w, XEvent *e, String *par, Cardinal *npar)
837 {
838     create_fonttool(w);
839 }
840 
841 static char cstext_translation_table[] = "\
842     Ctrl<Key>E: cstext_edit_action()";
843 
CreateCSText(Widget parent,char * s)844 TextStructure *CreateCSText(Widget parent, char *s)
845 {
846     TextStructure *retval;
847 
848     retval = CreateTextInput(parent, s);
849     XtOverrideTranslations(retval->text,
850         XtParseTranslationTable(cstext_translation_table));
851 
852     return retval;
853 }
854 
GetTextString(TextStructure * cst)855 char *GetTextString(TextStructure *cst)
856 {
857     static char *buf = NULL;
858     char *s;
859 
860     s = XmTextGetString(cst->text);
861     buf = copy_string(buf, s);
862     XtFree(s);
863 
864     return buf;
865 }
866 
SetTextString(TextStructure * cst,char * s)867 void SetTextString(TextStructure *cst, char *s)
868 {
869     XmTextSetString(cst->text, s ? s : "");
870 }
871 
872 typedef struct {
873     void (*cbproc)();
874     void *anydata;
875 } Text_CBdata;
876 
text_int_cb_proc(Widget w,XtPointer client_data,XtPointer call_data)877 static void text_int_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
878 {
879     Text_CBdata *cbdata = (Text_CBdata *) client_data;
880     cbdata->cbproc(cbdata->anydata);
881 }
882 
AddTextInputCB(TextStructure * cst,Text_CBProc cbproc,void * data)883 void AddTextInputCB(TextStructure *cst, Text_CBProc cbproc, void *data)
884 {
885     Text_CBdata *cbdata;
886 
887     cbdata = xmalloc(sizeof(Text_CBdata));
888     cbdata->anydata = data;
889     cbdata->cbproc = cbproc;
890 
891     XtAddCallback(cst->text,
892         XmNactivateCallback, text_int_cb_proc, (XtPointer) cbdata);
893 }
894 
GetTextCursorPos(TextStructure * cst)895 int GetTextCursorPos(TextStructure *cst)
896 {
897     return XmTextGetInsertionPosition(cst->text);
898 }
899 
TextInsert(TextStructure * cst,int pos,char * s)900 void TextInsert(TextStructure *cst, int pos, char *s)
901 {
902     XmTextInsert(cst->text, pos, s);
903 }
904 
905 
906 typedef struct {
907     void (*cbproc)();
908     void *anydata;
909 } Button_CBdata;
910 
CreateButton(Widget parent,char * label)911 Widget CreateButton(Widget parent, char *label)
912 {
913     Widget button;
914     XmString xmstr;
915 
916     xmstr = XmStringCreateLocalized(label);
917     button = XtVaCreateManagedWidget("button",
918         xmPushButtonWidgetClass, parent,
919         XmNalignment, XmALIGNMENT_CENTER,
920     	XmNlabelString, xmstr,
921 /*
922  *         XmNmarginLeft, 5,
923  *         XmNmarginRight, 5,
924  *         XmNmarginTop, 3,
925  *         XmNmarginBottom, 2,
926  */
927     	NULL);
928     XmStringFree(xmstr);
929 
930     return button;
931 }
932 
CreateBitmapButton(Widget parent,int width,int height,const unsigned char * bits)933 Widget CreateBitmapButton(Widget parent,
934     int width, int height, const unsigned char *bits)
935 {
936     Widget button;
937     Pixmap pm;
938     Pixel fg, bg;
939 
940     button = XtVaCreateManagedWidget("button",
941         xmPushButtonWidgetClass, parent,
942 	XmNlabelType, XmPIXMAP,
943     	NULL);
944 
945 /*
946  * We need to get right fore- and background colors for pixmap.
947  */
948     XtVaGetValues(button,
949 		  XmNforeground, &fg,
950 		  XmNbackground, &bg,
951 		  NULL);
952     pm = XCreatePixmapFromBitmapData(disp,
953         root, (char *) bits, width, height, fg, bg, depth);
954     XtVaSetValues(button, XmNlabelPixmap, pm, NULL);
955 
956     return button;
957 }
958 
button_int_cb_proc(Widget w,XtPointer client_data,XtPointer call_data)959 static void button_int_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
960 {
961     Button_CBdata *cbdata = (Button_CBdata *) client_data;
962     cbdata->cbproc(cbdata->anydata);
963 }
964 
AddButtonCB(Widget button,Button_CBProc cbproc,void * data)965 void AddButtonCB(Widget button, Button_CBProc cbproc, void *data)
966 {
967     Button_CBdata *cbdata;
968 
969     cbdata = xmalloc(sizeof(Button_CBdata));
970     cbdata->anydata = data;
971     cbdata->cbproc = cbproc;
972     XtAddCallback(button,
973         XmNactivateCallback, button_int_cb_proc, (XtPointer) cbdata);
974 }
975 
fsb_setcwd_cb(void * data)976 static void fsb_setcwd_cb(void *data)
977 {
978     char *bufp;
979     XmString directory;
980     Widget fsb = (Widget) data;
981 
982     XtVaGetValues(fsb, XmNdirectory, &directory, NULL);
983     bufp = GetStringSimple(directory);
984     XmStringFree(directory);
985     if (bufp != NULL) {
986         set_workingdir(bufp);
987         XtFree(bufp);
988     }
989 }
990 
991 #define FSB_CWD     0
992 #define FSB_HOME    1
993 #define FSB_ROOT    2
994 #define FSB_CYGDRV  3
995 
fsb_cd_cb(int value,void * data)996 static void fsb_cd_cb(int value, void *data)
997 {
998     char *bufp;
999     XmString dir, pattern, dirmask;
1000     Widget FSB = (Widget) data;
1001 
1002     switch (value) {
1003     case FSB_CWD:
1004         bufp = get_workingdir();
1005         break;
1006     case FSB_HOME:
1007 	bufp = get_userhome();
1008         break;
1009     case FSB_ROOT:
1010         bufp = "/";
1011         break;
1012     case FSB_CYGDRV:
1013         bufp = "/cygdrive/";
1014         break;
1015     default:
1016         return;
1017     }
1018 
1019     XtVaGetValues(FSB, XmNpattern, &pattern, NULL);
1020 
1021     dir = XmStringCreateLocalized(bufp);
1022     dirmask = XmStringConcatAndFree(dir, pattern);
1023 
1024     XmFileSelectionDoSearch(FSB, dirmask);
1025     XmStringFree(dirmask);
1026 }
1027 
1028 static OptionItem fsb_items[] = {
1029     {FSB_CWD,  "Cwd"},
1030     {FSB_HOME, "Home"},
1031     {FSB_ROOT, "/"}
1032 #ifdef __CYGWIN__
1033     ,{FSB_CYGDRV, "My Computer"}
1034 #endif
1035 };
1036 
1037 #define FSB_ITEMS_NUM   sizeof(fsb_items)/sizeof(OptionItem)
1038 
1039 #if XmVersion >= 2000
show_hidden_cb(int onoff,void * data)1040 static void show_hidden_cb(int onoff, void *data)
1041 {
1042     FSBStructure *fsb = (FSBStructure *) data;
1043     XtVaSetValues(fsb->FSB, XmNfileFilterStyle,
1044         onoff ? XmFILTER_NONE:XmFILTER_HIDDEN_FILES, NULL);
1045 }
1046 #endif
1047 
CreateFileSelectionBox(Widget parent,char * s)1048 FSBStructure *CreateFileSelectionBox(Widget parent, char *s)
1049 {
1050     FSBStructure *retval;
1051     OptionStructure *opt;
1052     Widget fr, form, button;
1053     XmString xmstr;
1054     char *bufp, *resname;
1055 
1056     retval = xmalloc(sizeof(FSBStructure));
1057     resname = label_to_resname(s, "FSB");
1058     retval->FSB = XmCreateFileSelectionDialog(parent, resname, NULL, 0);
1059     xfree(resname);
1060     retval->dialog = XtParent(retval->FSB);
1061     handle_close(retval->dialog);
1062     bufp = copy_string(NULL, "Grace: ");
1063     bufp = concat_strings(bufp, s);
1064     XtVaSetValues(retval->dialog, XmNtitle, bufp, NULL);
1065     xfree(bufp);
1066 
1067     xmstr = XmStringCreateLocalized(get_workingdir());
1068     XtVaSetValues(retval->FSB, XmNdirectory, xmstr, NULL);
1069     XmStringFree(xmstr);
1070 
1071     XtAddCallback(retval->FSB,
1072         XmNcancelCallback, destroy_dialog, retval->dialog);
1073     AddHelpCB(retval->FSB, "doc/UsersGuide.html#FS-dialog");
1074 
1075     retval->rc = XmCreateRowColumn(retval->FSB, "rc", NULL, 0);
1076 #if XmVersion >= 2000
1077     button = CreateToggleButton(retval->rc, "Show hidden files");
1078     AddToggleButtonCB(button, show_hidden_cb, retval);
1079     XtVaSetValues(retval->FSB, XmNfileFilterStyle, XmFILTER_HIDDEN_FILES, NULL);
1080 #endif
1081     fr = CreateFrame(retval->rc, NULL);
1082     form = XtVaCreateWidget("form", xmFormWidgetClass, fr, NULL);
1083     opt = CreateOptionChoice(form, "Chdir to:", 1, FSB_ITEMS_NUM, fsb_items);
1084     AddOptionChoiceCB(opt, fsb_cd_cb, (void *) retval->FSB);
1085     button = CreateButton(form, "Set as cwd");
1086     AddButtonCB(button, fsb_setcwd_cb, (void *) retval->FSB);
1087 
1088     XtVaSetValues(opt->menu,
1089         XmNleftAttachment, XmATTACH_FORM,
1090         XmNtopAttachment, XmATTACH_FORM,
1091         XmNbottomAttachment, XmATTACH_FORM,
1092         XmNrightAttachment, XmATTACH_NONE,
1093         NULL);
1094     XtVaSetValues(button,
1095         XmNleftAttachment, XmATTACH_NONE,
1096         XmNtopAttachment, XmATTACH_FORM,
1097         XmNbottomAttachment, XmATTACH_FORM,
1098         XmNrightAttachment, XmATTACH_FORM,
1099         NULL);
1100     XtManageChild(form);
1101 
1102     XtManageChild(retval->rc);
1103 
1104     return retval;
1105 }
1106 
1107 typedef struct {
1108     FSBStructure *fsb;
1109     int (*cbproc)();
1110     void *anydata;
1111 } FSB_CBdata;
1112 
fsb_int_cb_proc(Widget w,XtPointer client_data,XtPointer call_data)1113 static void fsb_int_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
1114 {
1115     char *s;
1116     int ok;
1117 
1118     FSB_CBdata *cbdata = (FSB_CBdata *) client_data;
1119     XmFileSelectionBoxCallbackStruct *cbs =
1120         (XmFileSelectionBoxCallbackStruct *) call_data;
1121 
1122     s = GetStringSimple(cbs->value);
1123     if (s == NULL) {
1124 	errmsg("Error converting XmString to char string");
1125 	return;
1126     }
1127 
1128     set_wait_cursor();
1129 
1130     ok = cbdata->cbproc(s, cbdata->anydata);
1131     XtFree(s);
1132     if (ok) {
1133         XtUnmanageChild(cbdata->fsb->dialog);
1134     }
1135     unset_wait_cursor();
1136 }
1137 
AddFileSelectionBoxCB(FSBStructure * fsb,FSB_CBProc cbproc,void * anydata)1138 void AddFileSelectionBoxCB(FSBStructure *fsb, FSB_CBProc cbproc, void *anydata)
1139 {
1140     FSB_CBdata *cbdata;
1141 
1142     cbdata = xmalloc(sizeof(FSB_CBdata));
1143     cbdata->fsb = fsb;
1144     cbdata->cbproc = (FSB_CBProc) cbproc;
1145     cbdata->anydata = anydata;
1146     XtAddCallback(fsb->FSB,
1147         XmNokCallback, fsb_int_cb_proc, (XtPointer) cbdata);
1148 }
1149 
SetFileSelectionBoxPattern(FSBStructure * fsb,char * pattern)1150 void SetFileSelectionBoxPattern(FSBStructure *fsb, char *pattern)
1151 {
1152     XmString xmstr;
1153 
1154     if (pattern != NULL) {
1155         xmstr = XmStringCreateLocalized(pattern);
1156         XtVaSetValues(fsb->FSB, XmNpattern, xmstr, NULL);
1157         XmStringFree(xmstr);
1158     }
1159 }
1160 
CreateLabel(Widget parent,char * s)1161 Widget CreateLabel(Widget parent, char *s)
1162 {
1163     Widget label;
1164 
1165     label = XtVaCreateManagedWidget(s,
1166         xmLabelWidgetClass, parent,
1167         XmNalignment, XmALIGNMENT_BEGINNING,
1168         XmNrecomputeSize, True,
1169         NULL);
1170     return label;
1171 }
1172 
AlignLabel(Widget w,int alignment)1173 void AlignLabel(Widget w, int alignment)
1174 {
1175     unsigned char xm_alignment;
1176 
1177     switch(alignment) {
1178     case ALIGN_BEGINNING:
1179         xm_alignment = XmALIGNMENT_BEGINNING;
1180         break;
1181     case ALIGN_CENTER:
1182         xm_alignment = XmALIGNMENT_CENTER;
1183         break;
1184     case ALIGN_END:
1185         xm_alignment = XmALIGNMENT_END;
1186         break;
1187     default:
1188         errmsg("Internal error in AlignLabel()");
1189         return;
1190         break;
1191     }
1192     XtVaSetValues(w,
1193         XmNalignment, xm_alignment,
1194         NULL);
1195 }
1196 
1197 static OptionItem *font_option_items;
1198 static OptionItem *settype_option_items;
1199 static BitmapOptionItem *pattern_option_items;
1200 static BitmapOptionItem *lines_option_items;
1201 
1202 #define LINES_BM_HEIGHT 15
1203 #define LINES_BM_WIDTH  64
1204 
init_option_menus(void)1205 int init_option_menus(void) {
1206     int i, j, k, l, n;
1207 
1208     n = number_of_fonts();
1209     font_option_items = xmalloc(n*sizeof(OptionItem));
1210     if (font_option_items == NULL) {
1211         errmsg("Malloc error in init_option_menus()");
1212         return RETURN_FAILURE;
1213     }
1214     for (i = 0; i < n; i++) {
1215         font_option_items[i].value = i;
1216         font_option_items[i].label = get_fontalias(i);
1217     }
1218 
1219     n = number_of_patterns();
1220     pattern_option_items = xmalloc(n*sizeof(BitmapOptionItem));
1221     if (pattern_option_items == NULL) {
1222         errmsg("Malloc error in init_option_menus()");
1223         xfree(font_option_items);
1224         return RETURN_FAILURE;
1225     }
1226     for (i = 0; i < n; i++) {
1227         pattern_option_items[i].value = i;
1228         if (i == 0) {
1229             pattern_option_items[i].bitmap = NULL;
1230         } else {
1231             pattern_option_items[i].bitmap = pat_bits[i];
1232         }
1233     }
1234 
1235     n = number_of_linestyles();
1236     lines_option_items = xmalloc(n*sizeof(BitmapOptionItem));
1237     if (lines_option_items == NULL) {
1238         errmsg("Malloc error in init_option_menus()");
1239         xfree(pattern_option_items);
1240         xfree(font_option_items);
1241         return RETURN_FAILURE;
1242     }
1243     for (i = 0; i < n; i++) {
1244         lines_option_items[i].value = i;
1245         if (i == 0) {
1246             lines_option_items[i].bitmap = NULL;
1247             continue;
1248         }
1249 
1250         lines_option_items[i].bitmap =
1251               xcalloc(LINES_BM_HEIGHT*LINES_BM_WIDTH/8/SIZEOF_CHAR, SIZEOF_CHAR);
1252 
1253         k = LINES_BM_WIDTH*(LINES_BM_HEIGHT/2);
1254         while (k < LINES_BM_WIDTH*(LINES_BM_HEIGHT/2 + 1)) {
1255             for (j = 0; j < dash_array_length[i]; j++) {
1256                 for (l = 0; l < dash_array[i][j]; l++) {
1257                     if (k < LINES_BM_WIDTH*(LINES_BM_HEIGHT/2 + 1)) {
1258                         if (j % 2 == 0) {
1259                             /* black */
1260                             lines_option_items[i].bitmap[k/8] |= 1 << k % 8;
1261                         }
1262                         k++;
1263                     }
1264                 }
1265             }
1266         }
1267     }
1268 
1269     settype_option_items = xmalloc(NUMBER_OF_SETTYPES*sizeof(OptionItem));
1270     if (settype_option_items == NULL) {
1271         errmsg("Malloc error in init_option_menus()");
1272         return RETURN_FAILURE;
1273     }
1274     for (i = 0; i < NUMBER_OF_SETTYPES; i++) {
1275         settype_option_items[i].value = i;
1276         settype_option_items[i].label = copy_string(NULL, set_types(i));
1277         lowtoupper(settype_option_items[i].label);
1278     }
1279 
1280     return RETURN_SUCCESS;
1281 }
1282 
CreateFontChoice(Widget parent,char * s)1283 OptionStructure *CreateFontChoice(Widget parent, char *s)
1284 {
1285     return (CreateOptionChoice(parent,
1286         s, 0, number_of_fonts(), font_option_items));
1287 }
1288 
CreatePatternChoice(Widget parent,char * s)1289 OptionStructure *CreatePatternChoice(Widget parent, char *s)
1290 {
1291     return (CreateBitmapOptionChoice(parent, s, 4, number_of_patterns(),
1292                                      16, 16, pattern_option_items));
1293 }
1294 
CreateLineStyleChoice(Widget parent,char * s)1295 OptionStructure *CreateLineStyleChoice(Widget parent, char *s)
1296 {
1297     return (CreateBitmapOptionChoice(parent, s, 0, number_of_linestyles(),
1298                         LINES_BM_WIDTH, LINES_BM_HEIGHT, lines_option_items));
1299 }
1300 
CreateSetTypeChoice(Widget parent,char * s)1301 OptionStructure *CreateSetTypeChoice(Widget parent, char *s)
1302 {
1303     return (CreateOptionChoice(parent,
1304         s, 0, NUMBER_OF_SETTYPES, settype_option_items));
1305 }
1306 
1307 static BitmapOptionItem just_option_items[12] =
1308 {
1309     {JUST_LEFT  |JUST_BLINE , j_lm_o_bits},
1310     {JUST_CENTER|JUST_BLINE , j_cm_o_bits},
1311     {JUST_RIGHT |JUST_BLINE , j_rm_o_bits},
1312     {JUST_LEFT  |JUST_BOTTOM, j_lb_b_bits},
1313     {JUST_CENTER|JUST_BOTTOM, j_cb_b_bits},
1314     {JUST_RIGHT |JUST_BOTTOM, j_rb_b_bits},
1315     {JUST_LEFT  |JUST_MIDDLE, j_lm_b_bits},
1316     {JUST_CENTER|JUST_MIDDLE, j_cm_b_bits},
1317     {JUST_RIGHT |JUST_MIDDLE, j_rm_b_bits},
1318     {JUST_LEFT  |JUST_TOP   , j_lt_b_bits},
1319     {JUST_CENTER|JUST_TOP   , j_ct_b_bits},
1320     {JUST_RIGHT |JUST_TOP   , j_rt_b_bits}
1321 };
1322 
CreateJustChoice(Widget parent,char * s)1323 OptionStructure *CreateJustChoice(Widget parent, char *s)
1324 {
1325     return (CreateBitmapOptionChoice(parent, s, 4,
1326         12, JBITMAP_WIDTH, JBITMAP_HEIGHT, just_option_items));
1327 }
1328 
CreateRestrictionChoice(Widget parent,char * s)1329 RestrictionStructure *CreateRestrictionChoice(Widget parent, char *s)
1330 {
1331     RestrictionStructure *retval;
1332     Widget rc;
1333     OptionItem restr_items[7];
1334 
1335     restr_items[0].value = RESTRICT_NONE;
1336     restr_items[0].label = "None";
1337     restr_items[1].value = RESTRICT_REG0;
1338     restr_items[1].label = "Region 0";
1339     restr_items[2].value = RESTRICT_REG1;
1340     restr_items[2].label = "Region 1";
1341     restr_items[3].value = RESTRICT_REG2;
1342     restr_items[3].label = "Region 2";
1343     restr_items[4].value = RESTRICT_REG3;
1344     restr_items[4].label = "Region 3";
1345     restr_items[5].value = RESTRICT_REG4;
1346     restr_items[5].label = "Region 4";
1347     restr_items[6].value = RESTRICT_WORLD;
1348     restr_items[6].label = "Inside graph";
1349 
1350     retval = xmalloc(sizeof(RestrictionStructure));
1351 
1352     retval->frame = CreateFrame(parent, s);
1353     rc = XtVaCreateWidget("rc",
1354         xmRowColumnWidgetClass, retval->frame,
1355         XmNorientation, XmHORIZONTAL,
1356         NULL);
1357 
1358     retval->r_sel = CreateOptionChoice(rc,
1359         "Restriction:", 1, 7, restr_items);
1360     retval->negate = CreateToggleButton(rc, "Negated");
1361     XtManageChild(rc);
1362 
1363     return retval;
1364 }
1365 
1366 
1367 static OptionItem *graph_select_items = NULL;
1368 static int ngraph_select_items = 0;
1369 static ListStructure **graph_selectors = NULL;
1370 static int ngraph_selectors = 0;
1371 
graph_select_cb(Widget list,XtPointer client_data,XtPointer call_data)1372 void graph_select_cb(Widget list, XtPointer client_data, XtPointer call_data)
1373 {
1374     XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data;
1375     ListStructure *plist = (ListStructure *) client_data;
1376     int gno;
1377 
1378     gno = plist->values[cbs->item_position - 1];
1379     switch_current_graph(gno);
1380 }
1381 
update_graph_selectors(void)1382 void update_graph_selectors(void)
1383 {
1384     int i, new_n = number_of_graphs();
1385     char buf[64];
1386     OptionItem *p;
1387 
1388     for (i = 0; i < ngraph_select_items; i++) {
1389         xfree(graph_select_items[i].label);
1390     }
1391     p = xrealloc(graph_select_items, new_n*sizeof(OptionItem));
1392     if (p == NULL && new_n != 0) {
1393         ngraph_select_items = 0;
1394         return;
1395     } else {
1396         graph_select_items = p;
1397     }
1398 
1399     for (i = 0; i < new_n; i++) {
1400         graph_select_items[i].value = i;
1401         sprintf(buf, "(%c) G%d (%d sets)",
1402             is_graph_hidden(i) ? '-':'+', i, number_of_sets(i));
1403         graph_select_items[i].label = copy_string(NULL, buf);
1404     }
1405     ngraph_select_items = new_n;
1406 
1407     for (i = 0; i < ngraph_selectors; i++) {
1408         UpdateListChoice(graph_selectors[i],
1409             ngraph_select_items, graph_select_items);
1410     }
1411 }
1412 
1413 typedef struct {
1414     Widget popup;
1415     Widget label_item;
1416     Widget focus_item;
1417     Widget hide_item;
1418     Widget show_item;
1419     Widget duplicate_item;
1420     Widget kill_item;
1421     Widget copy12_item;
1422     Widget copy21_item;
1423     Widget move12_item;
1424     Widget move21_item;
1425     Widget swap_item;
1426 } GraphPopupMenu;
1427 
1428 typedef enum {
1429     GraphMenuFocusCB,
1430     GraphMenuHideCB,
1431     GraphMenuShowCB,
1432     GraphMenuDuplicateCB,
1433     GraphMenuKillCB,
1434     GraphMenuCopy12CB,
1435     GraphMenuCopy21CB,
1436     GraphMenuMove12CB,
1437     GraphMenuMove21CB,
1438     GraphMenuSwapCB,
1439     GraphMenuNewCB
1440 } GraphMenuCBtype;
1441 
graph_menu_cb(ListStructure * listp,GraphMenuCBtype type)1442 void graph_menu_cb(ListStructure *listp, GraphMenuCBtype type)
1443 {
1444     int err = FALSE;
1445     int i, n, *values;
1446     char buf[32];
1447 
1448     n = GetListChoices(listp, &values);
1449 
1450     switch (type) {
1451     case GraphMenuFocusCB:
1452         if (n == 1) {
1453             switch_current_graph(values[0]);
1454         } else {
1455             err = TRUE;
1456         }
1457         break;
1458     case GraphMenuHideCB:
1459         if (n > 0) {
1460             for (i = 0; i < n; i++) {
1461                 set_graph_hidden(values[i], TRUE);
1462             }
1463         } else {
1464             err = TRUE;
1465         }
1466         break;
1467     case GraphMenuShowCB:
1468         if (n > 0) {
1469             for (i = 0; i < n; i++) {
1470                 set_graph_hidden(values[i], FALSE);
1471             }
1472         } else {
1473             err = TRUE;
1474         }
1475         break;
1476     case GraphMenuDuplicateCB:
1477         if (n > 0) {
1478             for (i = 0; i < n; i++) {
1479                 duplicate_graph(values[i]);
1480             }
1481         } else {
1482             err = TRUE;
1483         }
1484         break;
1485     case GraphMenuKillCB:
1486         if (n > 0) {
1487             if (yesno("Kill selected graph(s)?", NULL, NULL, NULL)) {
1488                 for (i = n - 1; i >= 0; i--) {
1489                     kill_graph(values[i]);
1490                 }
1491             }
1492         } else {
1493             err = TRUE;
1494         }
1495         break;
1496     case GraphMenuCopy12CB:
1497         if (n == 2) {
1498             sprintf(buf, "Overwrite G%d?", values[1]);
1499             if (yesno(buf, NULL, NULL, NULL)) {
1500                 copy_graph(values[0], values[1]);
1501             }
1502         } else {
1503             err = TRUE;
1504         }
1505         break;
1506     case GraphMenuCopy21CB:
1507         if (n == 2) {
1508             sprintf(buf, "Overwrite G%d?", values[0]);
1509             if (yesno(buf, NULL, NULL, NULL)) {
1510                 copy_graph(values[1], values[0]);
1511             }
1512         } else {
1513             err = TRUE;
1514         }
1515         break;
1516     case GraphMenuMove12CB:
1517         if (n == 2) {
1518             sprintf(buf, "Replace G%d?", values[1]);
1519             if (yesno(buf, NULL, NULL, NULL)) {
1520                 move_graph(values[0], values[1]);
1521             }
1522         } else {
1523             err = TRUE;
1524         }
1525         break;
1526     case GraphMenuMove21CB:
1527         if (n == 2) {
1528             sprintf(buf, "Replace G%d?", values[0]);
1529             if (yesno(buf, NULL, NULL, NULL)) {
1530                 move_graph(values[1], values[0]);
1531             }
1532         } else {
1533             err = TRUE;
1534         }
1535         break;
1536     case GraphMenuSwapCB:
1537         if (n == 2) {
1538             swap_graph(values[0], values[1]);
1539         } else {
1540             err = TRUE;
1541         }
1542         break;
1543     case GraphMenuNewCB:
1544         set_graph_active(number_of_graphs());
1545         break;
1546     default:
1547         err = TRUE;
1548         break;
1549     }
1550 
1551     if (n > 0) {
1552         xfree(values);
1553     }
1554 
1555     if (err == FALSE) {
1556         update_all();
1557         xdrawgraph();
1558     }
1559 }
1560 
switch_focus_proc(void * data)1561 void switch_focus_proc(void *data)
1562 {
1563     graph_menu_cb((ListStructure *) data, GraphMenuFocusCB);
1564 }
1565 
hide_graph_proc(void * data)1566 void hide_graph_proc(void *data)
1567 {
1568     graph_menu_cb((ListStructure *) data, GraphMenuHideCB);
1569 }
1570 
show_graph_proc(void * data)1571 void show_graph_proc(void *data)
1572 {
1573     graph_menu_cb((ListStructure *) data, GraphMenuShowCB);
1574 }
1575 
duplicate_graph_proc(void * data)1576 void duplicate_graph_proc(void *data)
1577 {
1578     graph_menu_cb((ListStructure *) data, GraphMenuDuplicateCB);
1579 }
1580 
kill_graph_proc(void * data)1581 void kill_graph_proc(void *data)
1582 {
1583     graph_menu_cb((ListStructure *) data, GraphMenuKillCB);
1584 }
1585 
copy12_graph_proc(void * data)1586 void copy12_graph_proc(void *data)
1587 {
1588     graph_menu_cb((ListStructure *) data, GraphMenuCopy12CB);
1589 }
1590 
copy21_graph_proc(void * data)1591 void copy21_graph_proc(void *data)
1592 {
1593     graph_menu_cb((ListStructure *) data, GraphMenuCopy21CB);
1594 }
1595 
move12_graph_proc(void * data)1596 void move12_graph_proc(void *data)
1597 {
1598     graph_menu_cb((ListStructure *) data, GraphMenuMove12CB);
1599 }
1600 
move21_graph_proc(void * data)1601 void move21_graph_proc(void *data)
1602 {
1603     graph_menu_cb((ListStructure *) data, GraphMenuMove21CB);
1604 }
1605 
swap_graph_proc(void * data)1606 void swap_graph_proc(void *data)
1607 {
1608     graph_menu_cb((ListStructure *) data, GraphMenuSwapCB);
1609 }
1610 
create_new_graph_proc(void * data)1611 void create_new_graph_proc(void *data)
1612 {
1613     graph_menu_cb((ListStructure *) data, GraphMenuNewCB);
1614 }
1615 
CreateGraphPopupEntries(ListStructure * listp)1616 GraphPopupMenu *CreateGraphPopupEntries(ListStructure *listp)
1617 {
1618     GraphPopupMenu *graph_popup_menu;
1619     Widget popup;
1620 
1621     graph_popup_menu = xmalloc(sizeof(GraphPopupMenu));
1622 
1623     popup = XmCreatePopupMenu(listp->list, "graphPopupMenu", NULL, 0);
1624 #if XmVersion >= 2000
1625     XtVaSetValues(popup, XmNpopupEnabled, XmPOPUP_DISABLED, NULL);
1626 #else
1627     XtVaSetValues(popup, XmNpopupEnabled, False, NULL);
1628 #endif
1629     graph_popup_menu->popup = popup;
1630 
1631     graph_popup_menu->label_item = CreateMenuLabel(popup, "Selection:");
1632     CreateMenuSeparator(popup);
1633     graph_popup_menu->focus_item = CreateMenuButton(popup, "Focus to", 'F',
1634     	switch_focus_proc, (void *) listp);
1635     CreateMenuSeparator(popup);
1636     graph_popup_menu->hide_item = CreateMenuButton(popup, "Hide", 'H',
1637     	hide_graph_proc, (void *) listp);
1638     graph_popup_menu->show_item = CreateMenuButton(popup, "Show", 'S',
1639     	show_graph_proc, (void *) listp);
1640     graph_popup_menu->duplicate_item = CreateMenuButton(popup,"Duplicate", 'D',
1641     	duplicate_graph_proc, (void *) listp);
1642     graph_popup_menu->kill_item = CreateMenuButton(popup, "Kill", 'K',
1643     	kill_graph_proc, (void *) listp);
1644     CreateMenuSeparator(popup);
1645     graph_popup_menu->copy12_item = CreateMenuButton(popup, "Copy 1 to 2", '\0',
1646     	copy12_graph_proc, (void *) listp);
1647     graph_popup_menu->copy21_item = CreateMenuButton(popup, "Copy 2 to 1", '\0',
1648     	copy21_graph_proc, (void *) listp);
1649     graph_popup_menu->move12_item = CreateMenuButton(popup, "Move 1 to 2", '\0',
1650     	move12_graph_proc, (void *) listp);
1651     graph_popup_menu->move21_item = CreateMenuButton(popup, "Move 2 to 1", '\0',
1652     	move21_graph_proc, (void *) listp);
1653     graph_popup_menu->swap_item = CreateMenuButton(popup, "Swap", 'w',
1654     	swap_graph_proc, (void *) listp);
1655     CreateMenuSeparator(popup);
1656     CreateMenuButton(popup, "Create new", 'C',
1657     	create_new_graph_proc, (void *) listp);
1658 
1659     return graph_popup_menu;
1660 }
1661 
graph_popup(Widget parent,ListStructure * listp,XButtonPressedEvent * event)1662 void graph_popup(Widget parent, ListStructure *listp, XButtonPressedEvent *event)
1663 {
1664     int i, n;
1665     int *values;
1666     char buf[64];
1667     Widget popup;
1668     GraphPopupMenu* graph_popup_menu;
1669 
1670     if (event->button != 3) {
1671         return;
1672     }
1673 
1674     graph_popup_menu = (GraphPopupMenu*) listp->anydata;
1675     popup = graph_popup_menu->popup;
1676 
1677     n = GetListChoices(listp, &values);
1678     if (n > 0) {
1679         sprintf(buf, "G%d", values[0]);
1680         for (i = 1; i < n; i++) {
1681             if (strlen(buf) > 30) {
1682                 strcat(buf, "...");
1683                 break;
1684             }
1685             sprintf(buf, "%s, G%d", buf, values[i]);
1686         }
1687     } else {
1688         strcpy(buf, "None");
1689     }
1690 
1691     SetLabel(graph_popup_menu->label_item, buf);
1692 
1693     if (n == 0) {
1694         XtSetSensitive(graph_popup_menu->hide_item, False);
1695         XtSetSensitive(graph_popup_menu->show_item, False);
1696         XtSetSensitive(graph_popup_menu->duplicate_item, False);
1697         XtSetSensitive(graph_popup_menu->kill_item, False);
1698     } else {
1699         XtSetSensitive(graph_popup_menu->hide_item, True);
1700         XtSetSensitive(graph_popup_menu->show_item, True);
1701         XtSetSensitive(graph_popup_menu->duplicate_item, True);
1702         XtSetSensitive(graph_popup_menu->kill_item, True);
1703     }
1704     if (n == 1) {
1705         XtSetSensitive(graph_popup_menu->focus_item, True);
1706     } else {
1707         XtSetSensitive(graph_popup_menu->focus_item, False);
1708     }
1709     if (n == 2) {
1710         sprintf(buf, "Copy G%d to G%d", values[0], values[1]);
1711         SetLabel(graph_popup_menu->copy12_item, buf);
1712         XtManageChild(graph_popup_menu->copy12_item);
1713         sprintf(buf, "Copy G%d to G%d", values[1], values[0]);
1714         SetLabel(graph_popup_menu->copy21_item, buf);
1715         XtManageChild(graph_popup_menu->copy21_item);
1716         sprintf(buf, "Move G%d to G%d", values[0], values[1]);
1717         SetLabel(graph_popup_menu->move12_item, buf);
1718         XtManageChild(graph_popup_menu->move12_item);
1719         sprintf(buf, "Move G%d to G%d", values[1], values[0]);
1720         SetLabel(graph_popup_menu->move21_item, buf);
1721         XtManageChild(graph_popup_menu->move21_item);
1722         XtSetSensitive(graph_popup_menu->swap_item, True);
1723     } else {
1724         XtUnmanageChild(graph_popup_menu->copy12_item);
1725         XtUnmanageChild(graph_popup_menu->copy21_item);
1726         XtUnmanageChild(graph_popup_menu->move12_item);
1727         XtUnmanageChild(graph_popup_menu->move21_item);
1728         XtSetSensitive(graph_popup_menu->swap_item, False);
1729     }
1730 
1731     if (n > 0) {
1732         xfree(values);
1733     }
1734     XmMenuPosition(popup, event);
1735     XtManageChild(popup);
1736 }
1737 
list_selectall(Widget list)1738 static void list_selectall(Widget list)
1739 {
1740     int i, n;
1741     unsigned char selection_type_save;
1742 
1743     XtVaGetValues(list,
1744                   XmNselectionPolicy, &selection_type_save,
1745                   XmNitemCount, &n,
1746                   NULL);
1747     if (selection_type_save == XmSINGLE_SELECT) {
1748         XBell(disp, 50);
1749         return;
1750     }
1751 
1752     XtVaSetValues(list, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL);
1753 
1754     XmListDeselectAllItems(list);
1755     for (i = 1; i <= n; i++) {
1756         XmListSelectPos(list, i, False);
1757     }
1758 
1759     XtVaSetValues(list, XmNselectionPolicy, selection_type_save, NULL);
1760 }
1761 
list_selectall_action(Widget w,XEvent * e,String * par,Cardinal * npar)1762 void list_selectall_action(Widget w, XEvent *e, String *par, Cardinal *npar)
1763 {
1764     list_selectall(w);
1765 }
1766 
list_selectall_cb(void * data)1767 static void list_selectall_cb(void *data)
1768 {
1769     ListStructure *listp = (ListStructure *) data;
1770     list_selectall(listp->list);
1771 }
1772 
list_unselectall(Widget list)1773 static void list_unselectall(Widget list)
1774 {
1775     XmListDeselectAllItems(list);
1776 }
1777 
list_unselectall_action(Widget w,XEvent * e,String * par,Cardinal * npar)1778 void list_unselectall_action(Widget w, XEvent *e, String *par, Cardinal *npar)
1779 {
1780     list_unselectall(w);
1781 }
1782 
list_unselectall_cb(void * data)1783 static void list_unselectall_cb(void *data)
1784 {
1785     ListStructure *listp = (ListStructure *) data;
1786     list_unselectall(listp->list);
1787 }
1788 
list_invertselection(Widget list)1789 static void list_invertselection(Widget list)
1790 {
1791     int i, n;
1792     unsigned char selection_type_save;
1793 
1794     XtVaGetValues(list,
1795         XmNselectionPolicy, &selection_type_save,
1796         XmNitemCount, &n,
1797         NULL);
1798     if (selection_type_save == XmSINGLE_SELECT) {
1799         XBell(disp, 50);
1800         return;
1801     }
1802 
1803     XtVaSetValues(list, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL);
1804     for (i = 0; i < n; i++) {
1805         XmListSelectPos(list, i, False);
1806     }
1807     XtVaSetValues(list, XmNselectionPolicy, selection_type_save, NULL);
1808 }
1809 
list_invertselection_cb(void * data)1810 static void list_invertselection_cb(void *data)
1811 {
1812     ListStructure *listp = (ListStructure *) data;
1813     list_invertselection(listp->list);
1814 }
1815 
list_invertselection_action(Widget w,XEvent * e,String * par,Cardinal * npar)1816 void list_invertselection_action(Widget w, XEvent *e, String *par,
1817 				 Cardinal *npar)
1818 {
1819     list_invertselection(w);
1820 }
1821 
set_graph_selectors(int gno)1822 void set_graph_selectors(int gno)
1823 {
1824     int i;
1825 
1826     for (i = 0; i < ngraph_selectors; i++) {
1827         SelectListChoice(graph_selectors[i], gno);
1828     }
1829 }
1830 
CreateGraphChoice(Widget parent,char * labelstr,int type)1831 ListStructure *CreateGraphChoice(Widget parent, char *labelstr, int type)
1832 {
1833     ListStructure *retvalp;
1834     int nvisible;
1835 
1836     ngraph_selectors++;
1837     graph_selectors = xrealloc(graph_selectors,
1838                                     ngraph_selectors*sizeof(ListStructure *));
1839 
1840     nvisible = (type == LIST_TYPE_SINGLE) ? 2 : 4;
1841     retvalp = CreateListChoice(parent, labelstr, type, nvisible,
1842                                ngraph_select_items, graph_select_items);
1843     if (retvalp == NULL) {
1844         return NULL;
1845     }
1846     AddHelpCB(retvalp->rc, "doc/UsersGuide.html#graph-selector");
1847     graph_selectors[ngraph_selectors - 1] = retvalp;
1848 
1849     XtAddCallback(retvalp->list, XmNdefaultActionCallback,
1850                                graph_select_cb, retvalp);
1851     retvalp->anydata = CreateGraphPopupEntries(retvalp);
1852 
1853     XtAddEventHandler(retvalp->list, ButtonPressMask, False,
1854                             (XtEventHandler) graph_popup, retvalp);
1855 
1856     if (ngraph_select_items == 0) {
1857         update_graph_selectors();
1858     } else {
1859         UpdateListChoice(retvalp, ngraph_select_items, graph_select_items);
1860     }
1861 
1862     SelectListChoice(retvalp, get_cg());
1863 
1864     return retvalp;
1865 }
1866 
1867 /* Set selectors */
1868 static ListStructure **set_selectors = NULL;
1869 static int nset_selectors = 0;
1870 
UpdateSetChoice(ListStructure * listp,int gno)1871 void UpdateSetChoice(ListStructure *listp, int gno)
1872 {
1873     int i, j, n = number_of_sets(gno);
1874     char buf[64];
1875     OptionItem *set_select_items;
1876     SetChoiceData *sdata;
1877 
1878     sdata = (SetChoiceData *) listp->anydata;
1879     sdata->gno = gno;
1880 
1881     if (n <= 0) {
1882         UpdateListChoice(listp, 0, NULL);
1883         return;
1884     }
1885 
1886     set_select_items = xmalloc(n*sizeof(OptionItem));
1887     if (set_select_items == NULL) {
1888         return;
1889     }
1890 
1891     for (i = 0, j = 0; i < n; i++) {
1892         if ((sdata->show_nodata == TRUE || is_set_active(gno, i) == TRUE) &&
1893             (sdata->show_hidden == TRUE || is_set_hidden(gno, i) != TRUE )) {
1894             set_select_items[j].value = i;
1895             sprintf(buf, "(%c) G%d.S%d[%d][%d]",
1896                 is_set_hidden(gno, i) ? '-':'+',
1897                 gno, i, dataset_cols(gno, i), getsetlength(gno, i));
1898             set_select_items[j].label = copy_string(NULL, buf);
1899             if (sdata->view_comments == TRUE) {
1900                 set_select_items[j].label =
1901                     concat_strings(set_select_items[j].label, " \"");
1902                 set_select_items[j].label =
1903                     concat_strings(set_select_items[j].label,
1904                     getcomment(gno, i));
1905                 set_select_items[j].label =
1906                     concat_strings(set_select_items[j].label, "\"");
1907             }
1908             j++;
1909         }
1910     }
1911     UpdateListChoice(listp, j, set_select_items);
1912 
1913     xfree(set_select_items);
1914 }
1915 
update_set_selectors(int gno)1916 void update_set_selectors(int gno)
1917 {
1918     int i, cg;
1919     SetChoiceData *sdata;
1920 
1921     cg = get_cg();
1922     update_graph_selectors();
1923     for (i = 0; i < nset_selectors; i++) {
1924         sdata = (SetChoiceData *) set_selectors[i]->anydata;
1925         if (sdata->standalone == TRUE && (gno == cg || gno == ALL_GRAPHS)) {
1926             UpdateSetChoice(set_selectors[i], cg);
1927         } else if (sdata->standalone == FALSE && sdata->gno == gno) {
1928             UpdateSetChoice(set_selectors[i], gno);
1929         }
1930     }
1931 }
1932 
set_menu_cb(ListStructure * listp,SetMenuCBtype type)1933 void set_menu_cb(ListStructure *listp, SetMenuCBtype type)
1934 {
1935     SetChoiceData *sdata;
1936     int err = FALSE;
1937     int gno;
1938     int i, n, setno, *values;
1939     char buf[32];
1940 
1941     n = GetListChoices(listp, &values);
1942     sdata = (SetChoiceData *) listp->anydata;
1943     gno = sdata->gno;
1944 
1945     switch (type) {
1946     case SetMenuHideCB:
1947         if (n > 0) {
1948             for (i = 0; i < n; i++) {
1949                 set_set_hidden(gno, values[i], TRUE);
1950             }
1951         } else {
1952             err = TRUE;
1953         }
1954         break;
1955     case SetMenuShowCB:
1956         if (n > 0) {
1957             for (i = 0; i < n; i++) {
1958                 set_set_hidden(gno, values[i], FALSE);
1959             }
1960         } else {
1961             err = TRUE;
1962         }
1963         break;
1964     case SetMenuBringfCB:
1965         if (n == 1) {
1966             pushset(gno, values[0], PUSH_SET_TOFRONT);
1967         } else {
1968             err = TRUE;
1969         }
1970         break;
1971     case SetMenuSendbCB:
1972         if (n == 1) {
1973             pushset(gno, values[0], PUSH_SET_TOBACK);
1974         } else {
1975             err = TRUE;
1976         }
1977         break;
1978     case SetMenuDuplicateCB:
1979         if (n > 0) {
1980             for (i = 0; i < n; i++) {
1981                 setno = nextset(gno);
1982                 do_copyset(gno, values[i], gno, setno);
1983             }
1984         } else {
1985             err = TRUE;
1986         }
1987         break;
1988     case SetMenuKillCB:
1989         if (n > 0) {
1990             if (yesno("Kill selected set(s)?", NULL, NULL, NULL)) {
1991                 for (i = 0; i < n; i++) {
1992                     killset(gno, values[i]);
1993                 }
1994             }
1995         } else {
1996             err = TRUE;
1997         }
1998         break;
1999     case SetMenuKillDCB:
2000         if (n > 0) {
2001             if (yesno("Kill data in selected set(s)?", NULL, NULL, NULL)) {
2002                 for (i = 0; i < n; i++) {
2003                     killsetdata(gno, values[i]);
2004                     setcomment(gno, values[i], "");
2005                 }
2006             }
2007         } else {
2008             err = TRUE;
2009         }
2010         break;
2011     case SetMenuCopy12CB:
2012         if (n == 2) {
2013             sprintf(buf, "Overwrite S%d?", values[1]);
2014             if (yesno(buf, NULL, NULL, NULL)) {
2015                 do_copyset(gno, values[0], gno, values[1]);
2016             }
2017         } else {
2018             err = TRUE;
2019         }
2020         break;
2021     case SetMenuCopy21CB:
2022         if (n == 2) {
2023             sprintf(buf, "Overwrite S%d?", values[0]);
2024             if (yesno(buf, NULL, NULL, NULL)) {
2025                 do_copyset(gno, values[1], gno, values[0]);
2026             }
2027         } else {
2028             err = TRUE;
2029         }
2030         break;
2031     case SetMenuMove12CB:
2032         if (n == 2) {
2033             sprintf(buf, "Replace S%d?", values[1]);
2034             if (yesno(buf, NULL, NULL, NULL)) {
2035                 moveset(gno, values[0], gno, values[1]);
2036             }
2037         } else {
2038             err = TRUE;
2039         }
2040         break;
2041     case SetMenuMove21CB:
2042         if (n == 2) {
2043             sprintf(buf, "Replace S%d?", values[0]);
2044             if (yesno(buf, NULL, NULL, NULL)) {
2045                 moveset(gno, values[1], gno, values[0]);
2046             }
2047         } else {
2048             err = TRUE;
2049         }
2050         break;
2051     case SetMenuSwapCB:
2052         if (n == 2) {
2053             swapset(gno, values[0], gno, values[1]);
2054         } else {
2055             err = TRUE;
2056         }
2057         break;
2058     case SetMenuNewFCB:
2059             create_leval_frame((void *) gno);
2060         break;
2061     case SetMenuNewSCB:
2062             if ((setno = nextset(gno)) != -1) {
2063                 setcomment(gno, setno, "Editor");
2064                 set_set_hidden(gno, setno, FALSE);
2065                 create_ss_frame(gno, setno);
2066             } else {
2067                 err = TRUE;
2068             }
2069         break;
2070     case SetMenuNewECB:
2071             if ((setno = nextset(gno)) != -1) {
2072                 setcomment(gno, setno, "Editor");
2073                 set_set_hidden(gno, setno, FALSE);
2074                 do_ext_editor(gno, setno);
2075             } else {
2076                 err = TRUE;
2077             }
2078         break;
2079     case SetMenuNewBCB:
2080             create_eblock_frame(gno);
2081         break;
2082     case SetMenuEditSCB:
2083         if (n == 1) {
2084             create_ss_frame(gno, values[0]);
2085         } else {
2086             err = TRUE;
2087         }
2088         break;
2089     case SetMenuEditECB:
2090         if (n == 1) {
2091             do_ext_editor(gno, values[0]);
2092         } else {
2093             err = TRUE;
2094         }
2095         break;
2096     case SetMenuPackCB:
2097         packsets(gno);
2098         break;
2099     default:
2100         err = TRUE;
2101         break;
2102     }
2103 
2104     if (n > 0) {
2105         xfree(values);
2106     }
2107 
2108     if (err == FALSE) {
2109         update_all();
2110         xdrawgraph();
2111     }
2112 }
2113 
2114 
hide_set_proc(void * data)2115 void hide_set_proc(void *data)
2116 {
2117     set_menu_cb((ListStructure *) data, SetMenuHideCB);
2118 }
2119 
show_set_proc(void * data)2120 void show_set_proc(void *data)
2121 {
2122     set_menu_cb((ListStructure *) data, SetMenuShowCB);
2123 }
2124 
bringf_set_proc(void * data)2125 void bringf_set_proc(void *data)
2126 {
2127     set_menu_cb((ListStructure *) data, SetMenuBringfCB);
2128 }
2129 
sendb_set_proc(void * data)2130 void sendb_set_proc(void *data)
2131 {
2132     set_menu_cb((ListStructure *) data, SetMenuSendbCB);
2133 }
2134 
duplicate_set_proc(void * data)2135 void duplicate_set_proc(void *data)
2136 {
2137     set_menu_cb((ListStructure *) data, SetMenuDuplicateCB);
2138 }
2139 
kill_set_proc(void * data)2140 void kill_set_proc(void *data)
2141 {
2142     set_menu_cb((ListStructure *) data, SetMenuKillCB);
2143 }
2144 
killd_set_proc(void * data)2145 void killd_set_proc(void *data)
2146 {
2147     set_menu_cb((ListStructure *) data, SetMenuKillDCB);
2148 }
2149 
copy12_set_proc(void * data)2150 void copy12_set_proc(void *data)
2151 {
2152     set_menu_cb((ListStructure *) data, SetMenuCopy12CB);
2153 }
2154 
copy21_set_proc(void * data)2155 void copy21_set_proc(void *data)
2156 {
2157     set_menu_cb((ListStructure *) data, SetMenuCopy21CB);
2158 }
2159 
move12_set_proc(void * data)2160 void move12_set_proc(void *data)
2161 {
2162     set_menu_cb((ListStructure *) data, SetMenuMove12CB);
2163 }
2164 
move21_set_proc(void * data)2165 void move21_set_proc(void *data)
2166 {
2167     set_menu_cb((ListStructure *) data, SetMenuMove21CB);
2168 }
2169 
swap_set_proc(void * data)2170 void swap_set_proc(void *data)
2171 {
2172     set_menu_cb((ListStructure *) data, SetMenuSwapCB);
2173 }
2174 
newF_set_proc(void * data)2175 void newF_set_proc(void *data)
2176 {
2177     set_menu_cb((ListStructure *) data, SetMenuNewFCB);
2178 }
2179 
newS_set_proc(void * data)2180 void newS_set_proc(void *data)
2181 {
2182     set_menu_cb((ListStructure *) data, SetMenuNewSCB);
2183 }
2184 
newE_set_proc(void * data)2185 void newE_set_proc(void *data)
2186 {
2187     set_menu_cb((ListStructure *) data, SetMenuNewECB);
2188 }
2189 
newB_set_proc(void * data)2190 void newB_set_proc(void *data)
2191 {
2192     set_menu_cb((ListStructure *) data, SetMenuNewBCB);
2193 }
2194 
editS_set_proc(void * data)2195 void editS_set_proc(void *data)
2196 {
2197     set_menu_cb((ListStructure *) data, SetMenuEditSCB);
2198 }
2199 
editE_set_proc(void * data)2200 void editE_set_proc(void *data)
2201 {
2202     set_menu_cb((ListStructure *) data, SetMenuEditECB);
2203 }
2204 
pack_set_proc(void * data)2205 void pack_set_proc(void *data)
2206 {
2207     set_menu_cb((ListStructure *) data, SetMenuPackCB);
2208 }
2209 
shownd_set_proc(int onoff,void * data)2210 void shownd_set_proc(int onoff, void *data)
2211 {
2212     ListStructure *listp = (ListStructure *) data;
2213     SetChoiceData *sdata = (SetChoiceData *) listp->anydata;
2214 
2215     sdata->show_nodata = onoff;
2216     UpdateSetChoice(listp, sdata->gno);
2217 }
2218 
showh_set_proc(int onoff,void * data)2219 void showh_set_proc(int onoff, void *data)
2220 {
2221     ListStructure *listp = (ListStructure *) data;
2222     SetChoiceData *sdata = (SetChoiceData *) listp->anydata;
2223 
2224     sdata->show_hidden = onoff;
2225     UpdateSetChoice(listp, sdata->gno);
2226 }
2227 
view_comments_set_proc(int onoff,void * data)2228 void view_comments_set_proc(int onoff, void *data)
2229 {
2230     ListStructure *listp = (ListStructure *) data;
2231     SetChoiceData *sdata = (SetChoiceData *) listp->anydata;
2232 
2233     sdata->view_comments = onoff;
2234     UpdateSetChoice(listp, sdata->gno);
2235 }
2236 
update_set_proc(void * data)2237 void update_set_proc(void *data)
2238 {
2239     ListStructure *listp = (ListStructure *) data;
2240     SetChoiceData *sdata = (SetChoiceData *) listp->anydata;
2241 
2242     UpdateSetChoice(listp, sdata->gno);
2243 }
2244 
CreateSetPopupEntries(ListStructure * listp)2245 SetPopupMenu *CreateSetPopupEntries(ListStructure *listp)
2246 {
2247     SetPopupMenu *set_popup_menu;
2248     Widget popup, submenupane;
2249 
2250     set_popup_menu = xmalloc(sizeof(SetPopupMenu));
2251     popup = XmCreatePopupMenu(listp->list, "setPopupMenu", NULL, 0);
2252 #if XmVersion >= 2000
2253     XtVaSetValues(popup, XmNpopupEnabled, XmPOPUP_DISABLED, NULL);
2254 #else
2255     XtVaSetValues(popup, XmNpopupEnabled, False, NULL);
2256 #endif
2257     set_popup_menu->popup = popup;
2258 
2259     set_popup_menu->label_item = CreateMenuLabel(popup, "Selection:");
2260 
2261     CreateMenuSeparator(popup);
2262 
2263     set_popup_menu->hide_item = CreateMenuButton(popup, "Hide", '\0',
2264     	hide_set_proc, (void *) listp);
2265     set_popup_menu->show_item = CreateMenuButton(popup, "Show", '\0',
2266     	show_set_proc, (void *) listp);
2267     set_popup_menu->bringf_item = CreateMenuButton(popup, "Bring to front", '\0',
2268     	bringf_set_proc, (void *) listp);
2269     set_popup_menu->sendb_item = CreateMenuButton(popup, "Send to back", '\0',
2270     	sendb_set_proc, (void *) listp);
2271     CreateMenuSeparator(popup);
2272     set_popup_menu->duplicate_item = CreateMenuButton(popup, "Duplicate", '\0',
2273     	duplicate_set_proc, (void *) listp);
2274     set_popup_menu->kill_item = CreateMenuButton(popup, "Kill", '\0',
2275     	kill_set_proc, (void *) listp);
2276     set_popup_menu->killd_item = CreateMenuButton(popup, "Kill data", '\0',
2277     	killd_set_proc, (void *) listp);
2278     CreateMenuSeparator(popup);
2279     set_popup_menu->copy12_item = CreateMenuButton(popup, "Copy 1 to 2", '\0',
2280     	copy12_set_proc, (void *) listp);
2281     set_popup_menu->copy21_item = CreateMenuButton(popup, "Copy 2 to 1", '\0',
2282     	copy21_set_proc, (void *) listp);
2283     set_popup_menu->move12_item = CreateMenuButton(popup, "Move 1 to 2", '\0',
2284     	move12_set_proc, (void *) listp);
2285     set_popup_menu->move21_item = CreateMenuButton(popup, "Move 2 to 1", '\0',
2286     	move21_set_proc, (void *) listp);
2287     set_popup_menu->swap_item = CreateMenuButton(popup, "Swap", '\0',
2288     	swap_set_proc, (void *) listp);
2289     CreateMenuSeparator(popup);
2290     set_popup_menu->edit_item = CreateMenu(popup, "Edit", 'E', FALSE);
2291     CreateMenuButton(set_popup_menu->edit_item, "In spreadsheet", '\0',
2292     	editS_set_proc, (void *) listp);
2293     CreateMenuButton(set_popup_menu->edit_item, "In text editor", '\0',
2294     	editE_set_proc, (void *) listp);
2295     submenupane = CreateMenu(popup, "Create new", '\0', FALSE);
2296     CreateMenuButton(submenupane, "By formula", '\0',
2297     	newF_set_proc, (void *) listp);
2298     CreateMenuButton(submenupane, "In spreadsheet", '\0',
2299     	newS_set_proc, (void *) listp);
2300     CreateMenuButton(submenupane, "In text editor", '\0',
2301     	newE_set_proc, (void *) listp);
2302     CreateMenuButton(submenupane, "From block data", '\0',
2303     	newB_set_proc, (void *) listp);
2304 
2305     CreateMenuSeparator(popup);
2306 
2307     CreateMenuButton(popup, "Pack all sets", '\0',
2308     	pack_set_proc, (void *) listp);
2309 
2310     CreateMenuSeparator(popup);
2311 
2312     submenupane = CreateMenu(popup, "Selector operations", 'o', FALSE);
2313     CreateMenuToggle(submenupane,
2314         "View set comments", '\0', view_comments_set_proc, (void *) listp);
2315     CreateMenuSeparator(submenupane);
2316     set_popup_menu->shownd_item = CreateMenuToggle(submenupane,
2317         "Show data-less", '\0', shownd_set_proc, (void *) listp);
2318     set_popup_menu->showh_item = CreateMenuToggle(submenupane,
2319         "Show hidden", '\0', showh_set_proc, (void *) listp);
2320     CreateMenuSeparator(submenupane);
2321     CreateMenuButton(submenupane, "Select all", '\0',
2322     	list_selectall_cb, (void *) listp);
2323     CreateMenuButton(submenupane, "Unselect all", '\0',
2324     	list_unselectall_cb, (void *) listp);
2325     CreateMenuButton(submenupane, "Invert selection", '\0',
2326     	list_invertselection_cb, (void *) listp);
2327     CreateMenuSeparator(submenupane);
2328     CreateMenuButton(submenupane, "Update", '\0',
2329     	update_set_proc, (void *) listp);
2330 
2331     return set_popup_menu;
2332 }
2333 
set_popup(Widget parent,ListStructure * listp,XButtonPressedEvent * event)2334 void set_popup(Widget parent, ListStructure *listp, XButtonPressedEvent *event)
2335 {
2336     SetChoiceData *sdata;
2337     int i, n;
2338     int *values;
2339     char buf[64];
2340     Widget popup;
2341     SetPopupMenu* set_popup_menu;
2342 
2343     if (event->button != 3) {
2344         return;
2345     }
2346 
2347     sdata = (SetChoiceData *) listp->anydata;
2348     set_popup_menu = sdata->menu;
2349     popup = set_popup_menu->popup;
2350 
2351     n = GetListChoices(listp, &values);
2352     if (n > 0) {
2353         sprintf(buf, "S%d", values[0]);
2354         for (i = 1; i < n; i++) {
2355             if (strlen(buf) > 30) {
2356                 strcat(buf, "...");
2357                 break;
2358             }
2359             sprintf(buf, "%s, S%d", buf, values[i]);
2360         }
2361     } else {
2362         strcpy(buf, "None");
2363     }
2364 
2365     SetLabel(set_popup_menu->label_item, buf);
2366 
2367     SetToggleButtonState(set_popup_menu->shownd_item, sdata->show_nodata);
2368     SetToggleButtonState(set_popup_menu->showh_item, sdata->show_hidden);
2369 
2370     if (n == 0) {
2371         XtSetSensitive(set_popup_menu->hide_item, False);
2372         XtSetSensitive(set_popup_menu->show_item, False);
2373         XtSetSensitive(set_popup_menu->duplicate_item, False);
2374         XtSetSensitive(set_popup_menu->kill_item, False);
2375         XtSetSensitive(set_popup_menu->killd_item, False);
2376     } else {
2377         XtSetSensitive(set_popup_menu->hide_item, True);
2378         XtSetSensitive(set_popup_menu->show_item, True);
2379         XtSetSensitive(set_popup_menu->duplicate_item, True);
2380         XtSetSensitive(set_popup_menu->kill_item, True);
2381         XtSetSensitive(set_popup_menu->killd_item, True);
2382     }
2383     if (n == 1) {
2384         XtSetSensitive(set_popup_menu->bringf_item, True);
2385         XtSetSensitive(set_popup_menu->sendb_item, True);
2386         XtSetSensitive(set_popup_menu->edit_item, True);
2387     } else {
2388         XtSetSensitive(set_popup_menu->bringf_item, False);
2389         XtSetSensitive(set_popup_menu->sendb_item, False);
2390         XtSetSensitive(set_popup_menu->edit_item, False);
2391     }
2392     if (n == 2) {
2393         sprintf(buf, "Copy S%d to S%d", values[0], values[1]);
2394         SetLabel(set_popup_menu->copy12_item, buf);
2395         XtManageChild(set_popup_menu->copy12_item);
2396         sprintf(buf, "Copy S%d to S%d", values[1], values[0]);
2397         SetLabel(set_popup_menu->copy21_item, buf);
2398         XtManageChild(set_popup_menu->copy21_item);
2399         sprintf(buf, "Move S%d to S%d", values[0], values[1]);
2400         SetLabel(set_popup_menu->move12_item, buf);
2401         XtManageChild(set_popup_menu->move12_item);
2402         sprintf(buf, "Move S%d to S%d", values[1], values[0]);
2403         SetLabel(set_popup_menu->move21_item, buf);
2404         XtManageChild(set_popup_menu->move21_item);
2405         XtSetSensitive(set_popup_menu->swap_item, True);
2406     } else {
2407         XtUnmanageChild(set_popup_menu->copy12_item);
2408         XtUnmanageChild(set_popup_menu->copy21_item);
2409         XtUnmanageChild(set_popup_menu->move12_item);
2410         XtUnmanageChild(set_popup_menu->move21_item);
2411         XtSetSensitive(set_popup_menu->swap_item, False);
2412     }
2413 
2414     if (n > 0) {
2415         xfree(values);
2416     }
2417     XmMenuPosition(popup, event);
2418     XtManageChild(popup);
2419 }
2420 
ss_edit_cb(Widget list,XtPointer client_data,XtPointer call_data)2421 static void ss_edit_cb(Widget list, XtPointer client_data, XtPointer call_data)
2422 {
2423     XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data;
2424     ListStructure *plist = (ListStructure *) client_data;
2425     SetChoiceData *sdata = (SetChoiceData *) plist->anydata;
2426     int gno, setno;
2427 
2428     gno = sdata->gno;
2429     setno = plist->values[cbs->item_position - 1];
2430     create_ss_frame(gno, setno);
2431 }
2432 
2433 
CreateSetChoice(Widget parent,char * labelstr,int type,int standalone)2434 ListStructure *CreateSetChoice(Widget parent, char *labelstr,
2435                                         int type, int standalone)
2436 {
2437     ListStructure *retvalp;
2438     SetChoiceData *sdata;
2439     int nvisible;
2440 
2441     nvisible = (type == LIST_TYPE_SINGLE) ? 4 : 8;
2442     retvalp = CreateListChoice(parent, labelstr, type, nvisible, 0, NULL);
2443     if (retvalp == NULL) {
2444         return NULL;
2445     }
2446     AddHelpCB(retvalp->rc, "doc/UsersGuide.html#set-selector");
2447 
2448     sdata = xmalloc(sizeof(SetChoiceData));
2449     if (sdata == NULL) {
2450         XCFREE(retvalp);
2451         return NULL;
2452     }
2453 
2454     sdata->standalone = standalone;
2455     sdata->view_comments = FALSE;
2456     sdata->show_hidden = TRUE;
2457     sdata->show_nodata = FALSE;
2458     sdata->menu = CreateSetPopupEntries(retvalp);
2459     XtAddEventHandler(retvalp->list, ButtonPressMask, False,
2460                             (XtEventHandler) set_popup, retvalp);
2461 
2462     XtAddCallback(retvalp->list, XmNdefaultActionCallback, ss_edit_cb, retvalp);
2463 
2464     retvalp->anydata = sdata;
2465 
2466     if (standalone == TRUE) {
2467         UpdateSetChoice(retvalp, get_cg());
2468     }
2469 
2470     nset_selectors++;
2471     set_selectors = xrealloc(set_selectors,
2472                                 nset_selectors*sizeof(ListStructure *));
2473     set_selectors[nset_selectors - 1] = retvalp;
2474 
2475     return retvalp;
2476 }
2477 
update_sets_cb(int n,int * values,void * data)2478 static void update_sets_cb(int n, int *values, void *data)
2479 {
2480     int gno;
2481     ListStructure *set_listp = (ListStructure *) data;
2482 
2483     if (n == 1) {
2484         gno = values[0];
2485     } else {
2486         gno = -1;
2487     }
2488     UpdateSetChoice(set_listp, gno);
2489 }
2490 
CreateGraphSetSelector(Widget parent,char * s,int sel_type)2491 GraphSetStructure *CreateGraphSetSelector(Widget parent, char *s, int sel_type)
2492 {
2493     GraphSetStructure *retval;
2494     Widget rc;
2495 
2496     retval = xmalloc(sizeof(GraphSetStructure));
2497     retval->frame = CreateFrame(parent, s);
2498     rc = XtVaCreateWidget("rc", xmRowColumnWidgetClass, retval->frame, NULL);
2499     retval->graph_sel = CreateGraphChoice(rc, "Graph:", LIST_TYPE_SINGLE);
2500     retval->set_sel = CreateSetChoice(rc, "Set:", sel_type, FALSE);
2501     AddListChoiceCB(retval->graph_sel,
2502         update_sets_cb, (void *) retval->set_sel);
2503     UpdateSetChoice(retval->set_sel, get_cg());
2504     XtManageChild(rc);
2505 
2506     return retval;
2507 }
2508 
CreateSrcDestSelector(Widget parent,int sel_type)2509 SrcDestStructure *CreateSrcDestSelector(Widget parent, int sel_type)
2510 {
2511     SrcDestStructure *retval;
2512 
2513     retval = xmalloc(sizeof(SrcDestStructure));
2514 
2515     retval->form = XtVaCreateWidget("form",
2516         xmFormWidgetClass, parent,
2517         XmNfractionBase, 2,
2518         NULL);
2519     retval->src  = CreateGraphSetSelector(retval->form, "Source", sel_type);
2520     retval->dest = CreateGraphSetSelector(retval->form, "Destination", sel_type);
2521     XtVaSetValues(retval->src->frame,
2522         XmNtopAttachment, XmATTACH_FORM,
2523         XmNbottomAttachment, XmATTACH_FORM,
2524         XmNleftAttachment, XmATTACH_FORM,
2525         XmNrightAttachment, XmATTACH_POSITION,
2526         XmNrightPosition, 1,
2527         NULL);
2528 
2529     XtVaSetValues(retval->dest->frame,
2530         XmNtopAttachment, XmATTACH_FORM,
2531         XmNbottomAttachment, XmATTACH_FORM,
2532         XmNleftAttachment, XmATTACH_POSITION,
2533         XmNleftPosition, 1,
2534         XmNrightAttachment, XmATTACH_FORM,
2535         NULL);
2536 
2537     XtManageChild(retval->form);
2538 
2539     return retval;
2540 }
2541 
2542 
paint_color_selector(OptionStructure * optp)2543 void paint_color_selector(OptionStructure *optp)
2544 {
2545     int i, color;
2546     long bg, fg;
2547 
2548     for (i = 0; i < ncolor_option_items; i++) {
2549         color = color_option_items[i].value;
2550         bg = xvlibcolors[color];
2551 	if ((get_colorintensity(color) < 0.5 && is_video_reversed() == FALSE) ||
2552             (get_colorintensity(color) > 0.5 && is_video_reversed() == TRUE )) {
2553 	    fg = xvlibcolors[0];
2554 	} else {
2555 	    fg = xvlibcolors[1];
2556 	}
2557 	XtVaSetValues(optp->options[i].widget,
2558             XmNbackground, bg,
2559             XmNforeground, fg,
2560             NULL);
2561     }
2562 }
2563 
update_color_selectors(void)2564 void update_color_selectors(void)
2565 {
2566     int i, j;
2567     CMap_entry *pcmap;
2568 
2569     for (i = 0, j = 0; i < number_of_colors(); i++) {
2570         pcmap = get_cmap_entry(i);
2571         if (pcmap != NULL && pcmap->ctype == COLOR_MAIN) {
2572             j++;
2573         }
2574     }
2575     ncolor_option_items = j;
2576 
2577     color_option_items = xrealloc(color_option_items,
2578                                     ncolor_option_items*sizeof(OptionItem));
2579     for (i = 0, j = 0; i < number_of_colors(); i++) {
2580         pcmap = get_cmap_entry(i);
2581         if (pcmap != NULL && pcmap->ctype == COLOR_MAIN) {
2582             color_option_items[j].value = i;
2583             color_option_items[j].label = get_colorname(i);
2584             j++;
2585         }
2586     }
2587 
2588     for (i = 0; i < ncolor_selectors; i++) {
2589         UpdateOptionChoice(color_selectors[i],
2590                             ncolor_option_items, color_option_items);
2591         paint_color_selector(color_selectors[i]);
2592     }
2593 
2594 }
2595 
CreateColorChoice(Widget parent,char * s)2596 OptionStructure *CreateColorChoice(Widget parent, char *s)
2597 {
2598     OptionStructure *retvalp = NULL;
2599 
2600     ncolor_selectors++;
2601     color_selectors = xrealloc(color_selectors,
2602                                     ncolor_selectors*sizeof(OptionStructure *));
2603     if (color_selectors == NULL) {
2604         errmsg("Malloc failed in CreateColorChoice()");
2605         return retvalp;
2606     }
2607 
2608     retvalp = CreateOptionChoice(parent, s, 4,
2609                                 ncolor_option_items, color_option_items);
2610 
2611     color_selectors[ncolor_selectors - 1] = retvalp;
2612 
2613     paint_color_selector(retvalp);
2614 
2615     return retvalp;
2616 }
2617 
CreateLineWidthChoice(Widget parent,char * s)2618 SpinStructure *CreateLineWidthChoice(Widget parent, char *s)
2619 {
2620     return CreateSpinChoice(parent, s, 3, SPIN_TYPE_FLOAT, 0.0, MAX_LINEWIDTH, 0.5);
2621 }
2622 
2623 
2624 
CreatePanelChoice(Widget parent,char * labelstr,int nchoices,...)2625 Widget *CreatePanelChoice(Widget parent, char *labelstr, int nchoices,...)
2626 {
2627     va_list var;
2628     int i = 0;
2629     XmString str;
2630     char *s;
2631     Widget *retval;
2632 
2633     nchoices--;
2634 
2635     retval = (Widget *) XtMalloc((nchoices + 2) * sizeof(Widget));
2636 
2637     retval[1] = XmCreatePulldownMenu(parent, "pulldown", NULL, 0);
2638 
2639     va_start(var, nchoices);
2640     i = 0;
2641     while ((s = va_arg(var, char *)) != NULL) {
2642 	retval[i + 2] = XmCreatePushButton(retval[1], s, NULL, 0);
2643 	i++;
2644     }
2645     if (i != nchoices) {
2646 	errmsg("Incorrect number of selections in CreatePanelChoice()");
2647     }
2648     va_end(var);
2649 
2650     XtManageChildren(retval + 2, nchoices);
2651 
2652     retval[0] = XmCreateOptionMenu(parent, "optionmenu", NULL, 0);
2653     str = XmStringCreateLocalized(labelstr);
2654     XtVaSetValues(retval[0],
2655 		  XmNlabelString, str,
2656 		  XmNsubMenuId, retval[1],
2657 		  NULL);
2658     XmStringFree(str);
2659     XtManageChild(retval[0]);
2660 
2661     return retval;
2662 }
2663 
2664 
SetChoice(Widget * w,int value)2665 void SetChoice(Widget * w, int value)
2666 {
2667     Arg a;
2668     Cardinal nchoices;
2669 
2670     if (w == (Widget *) NULL) {
2671 	errwin("Internal error, SetChoice: Attempt to set NULL Widget");
2672 	return;
2673     }
2674 
2675     XtSetArg(a, XmNnumChildren, &nchoices);
2676     XtGetValues(w[1], &a, 1);
2677 
2678     if (value >= nchoices) {
2679 	errwin("Value not found in SetChoice()");
2680 	return;
2681     }
2682     XtSetArg(a, XmNmenuHistory, w[value + 2]);
2683     XtSetValues(w[0], &a, 1);
2684 }
2685 
GetChoice(Widget * w)2686 int GetChoice(Widget * w)
2687 {
2688     Arg a;
2689     Widget warg;
2690     int i;
2691 
2692     if (w == NULL) {
2693 	errwin("Internal error, GetChoice called with NULL argument");
2694 	return 0;
2695     }
2696     XtSetArg(a, XmNmenuHistory, &warg);
2697     XtGetValues(w[0], &a, 1);
2698     i = 0;
2699     while (w[i + 2] != warg) {
2700 	if (w[i + 2] == NULL) {
2701 	    errwin("Internal error, GetChoice: Found NULL in Widget list");
2702 	    return 0;
2703 	}
2704 	i++;
2705     }
2706     return i;
2707 }
2708 
2709 static OptionItem fmt_option_items[32] =
2710 {
2711     {FORMAT_DECIMAL,        "Decimal"             },
2712     {FORMAT_EXPONENTIAL,    "Exponential"         },
2713     {FORMAT_GENERAL,        "General"             },
2714     {FORMAT_POWER,          "Power"               },
2715     {FORMAT_SCIENTIFIC,     "Scientific"          },
2716     {FORMAT_ENGINEERING,    "Engineering"         },
2717     {FORMAT_COMPUTING,      "Computing (K,M,G,...)"},
2718     {FORMAT_DDMMYY,         "DD-MM-YY"            },
2719     {FORMAT_MMDDYY,         "MM-DD-YY"            },
2720     {FORMAT_YYMMDD,         "YY-MM-DD"            },
2721     {FORMAT_MMYY,           "MM-YY"               },
2722     {FORMAT_MMDD,           "MM-DD"               },
2723     {FORMAT_MONTHDAY,       "Month-DD"            },
2724     {FORMAT_DAYMONTH,       "DD-Month"            },
2725     {FORMAT_MONTHS,         "Month (abrev.)"      },
2726     {FORMAT_MONTHSY,        "Month (abrev.)-YY"   },
2727     {FORMAT_MONTHL,         "Month"               },
2728     {FORMAT_DAYOFWEEKS,     "Day of week (abrev.)"},
2729     {FORMAT_DAYOFWEEKL,     "Day of week"         },
2730     {FORMAT_DAYOFYEAR,      "Day of year"         },
2731     {FORMAT_HMS,            "HH:MM:SS"            },
2732     {FORMAT_MMDDHMS,        "MM-DD HH:MM:SS"      },
2733     {FORMAT_MMDDYYHMS,      "MM-DD-YY HH:MM:SS"   },
2734     {FORMAT_YYMMDDHMS,      "YY-MM-DD HH:MM:SS"   },
2735     {FORMAT_DEGREESLON,     "Degrees (lon)"       },
2736     {FORMAT_DEGREESMMLON,   "DD MM' (lon)"        },
2737     {FORMAT_DEGREESMMSSLON, "DD MM' SS.s\" (lon)" },
2738     {FORMAT_MMSSLON,        "MM' SS.s\" (lon)"    },
2739     {FORMAT_DEGREESLAT,     "Degrees (lat)"       },
2740     {FORMAT_DEGREESMMLAT,   "DD MM' (lat)"        },
2741     {FORMAT_DEGREESMMSSLAT, "DD MM' SS.s\" (lat)" },
2742     {FORMAT_MMSSLAT,        "MM' SS.s\" (lat)"    }
2743 };
2744 
CreateFormatChoice(Widget parent,char * s)2745 OptionStructure *CreateFormatChoice(Widget parent, char *s)
2746 {
2747     OptionStructure *retval;
2748 
2749     retval = CreateOptionChoice(parent, s, 4, 31, fmt_option_items);
2750 
2751     return(retval);
2752 }
2753 
2754 static OptionItem as_option_items[4] =
2755 {
2756     {AUTOSCALE_NONE, "None"},
2757     {AUTOSCALE_X,    "X"},
2758     {AUTOSCALE_Y,    "Y"},
2759     {AUTOSCALE_XY,   "XY"}
2760 };
2761 
CreateASChoice(Widget parent,char * s)2762 OptionStructure *CreateASChoice(Widget parent, char *s)
2763 {
2764     OptionStructure *retval;
2765 
2766     retval = CreateOptionChoice(parent, s, 1, 4, as_option_items);
2767     /* As init value, use this */
2768     SetOptionChoice(retval, autoscale_onread);
2769 
2770     return(retval);
2771 }
2772 
CreatePrecisionChoice(Widget parent,char * s)2773 Widget *CreatePrecisionChoice(Widget parent, char *s)
2774 {
2775     Widget *w;
2776 
2777     w = CreatePanelChoice(parent, s,
2778                           11,
2779                           "0", "1", "2", "3", "4",
2780                           "5", "6", "7", "8", "9",
2781                           NULL);
2782 
2783     return(w);
2784 }
2785 
2786 
CreateScale(Widget parent,char * s,int min,int max,int delta)2787 Widget CreateScale(Widget parent, char *s, int min, int max, int delta)
2788 {
2789     Widget w;
2790     XmString str;
2791 
2792     str = XmStringCreateLocalized(s);
2793 
2794     w = XtVaCreateManagedWidget("scroll",
2795         xmScaleWidgetClass, parent,
2796 	XmNtitleString, str,
2797 	XmNminimum, min,
2798 	XmNmaximum, max,
2799         XmNscaleMultiple, delta,
2800 	XmNvalue, 0,
2801 	XmNshowValue, True,
2802 	XmNprocessingDirection, XmMAX_ON_RIGHT,
2803 	XmNorientation, XmHORIZONTAL,
2804 #if XmVersion >= 2000
2805 	XmNsliderMark, XmROUND_MARK,
2806 #endif
2807 	NULL);
2808 
2809     XmStringFree(str);
2810 
2811     return w;
2812 }
2813 
SetScaleValue(Widget w,int value)2814 void SetScaleValue(Widget w, int value)
2815 {
2816     XtVaSetValues(w, XmNvalue, value, NULL);
2817 }
2818 
GetScaleValue(Widget w)2819 int GetScaleValue(Widget w)
2820 {
2821     int value;
2822     XtVaGetValues(w, XmNvalue, &value, NULL);
2823     return value;
2824 }
2825 
SetScaleWidth(Widget w,int width)2826 void SetScaleWidth(Widget w, int width)
2827 {
2828     XtVaSetValues(w, XmNscaleWidth, (Dimension) width, NULL);
2829 }
2830 
CreateAngleChoice(Widget parent,char * s)2831 Widget CreateAngleChoice(Widget parent, char *s)
2832 {
2833     return CreateScale(parent, s, 0, 360, 10);
2834 }
2835 
GetAngleChoice(Widget w)2836 int GetAngleChoice(Widget w)
2837 {
2838     return GetScaleValue(w);
2839 }
2840 
SetAngleChoice(Widget w,int angle)2841 void SetAngleChoice(Widget w, int angle)
2842 {
2843     SetScaleValue(w, angle);
2844 }
2845 
CreateCharSizeChoice(Widget parent,char * s)2846 Widget CreateCharSizeChoice(Widget parent, char *s)
2847 {
2848     return CreateScale(parent, s, 0, 1000, 25);
2849 }
2850 
GetCharSizeChoice(Widget w)2851 double GetCharSizeChoice(Widget w)
2852 {
2853     return ((double) GetScaleValue(w)/100);
2854 }
2855 
SetCharSizeChoice(Widget w,double size)2856 void SetCharSizeChoice(Widget w, double size)
2857 {
2858     int value = (int) rint(size*100);
2859     SetScaleValue(w, value);
2860 }
2861 
2862 
CreateToggleButton(Widget parent,char * s)2863 Widget CreateToggleButton(Widget parent, char *s)
2864 {
2865     return (XtVaCreateManagedWidget(s, xmToggleButtonWidgetClass, parent, NULL));
2866 }
2867 
GetToggleButtonState(Widget w)2868 int GetToggleButtonState(Widget w)
2869 {
2870     return (XmToggleButtonGetState(w));
2871 }
2872 
SetToggleButtonState(Widget w,int value)2873 void SetToggleButtonState(Widget w, int value)
2874 {
2875     if (w == NULL) {
2876         return;
2877     }
2878     XmToggleButtonSetState(w, value ? True:False, False);
2879 
2880     return;
2881 }
2882 
2883 typedef struct {
2884     void (*cbproc)();
2885     void *anydata;
2886 } TB_CBdata;
2887 
tb_int_cb_proc(Widget w,XtPointer client_data,XtPointer call_data)2888 static void tb_int_cb_proc(Widget w, XtPointer client_data, XtPointer call_data)
2889 {
2890     int onoff;
2891 
2892     TB_CBdata *cbdata = (TB_CBdata *) client_data;
2893 
2894     onoff = GetToggleButtonState(w);
2895     cbdata->cbproc(onoff, cbdata->anydata);
2896 }
2897 
AddToggleButtonCB(Widget w,TB_CBProc cbproc,void * anydata)2898 void AddToggleButtonCB(Widget w, TB_CBProc cbproc, void *anydata)
2899 {
2900     TB_CBdata *cbdata;
2901 
2902     cbdata = xmalloc(sizeof(TB_CBdata));
2903 
2904     cbdata->cbproc = cbproc;
2905     cbdata->anydata = anydata;
2906     XtAddCallback(w,
2907         XmNvalueChangedCallback, tb_int_cb_proc, (XtPointer) cbdata);
2908 }
2909 
CreateDialogForm(Widget parent,char * s)2910 Widget CreateDialogForm(Widget parent, char *s)
2911 {
2912     Widget dialog, w;
2913     char *bufp;
2914     int standalone;
2915 
2916     if (parent == NULL) {
2917         standalone = TRUE;
2918         parent = XtAppCreateShell("XMgrace", "XMgrace",
2919             topLevelShellWidgetClass, disp,
2920             NULL, 0);
2921     } else {
2922         standalone = FALSE;
2923     }
2924     bufp = label_to_resname(s, "Dialog");
2925     dialog = XmCreateDialogShell(parent, bufp, NULL, 0);
2926     xfree(bufp);
2927 
2928     if (standalone) {
2929         RegisterEditRes(dialog);
2930     }
2931 
2932     handle_close(dialog);
2933 
2934     bufp = copy_string(NULL, "Grace: ");
2935     bufp = concat_strings(bufp, s);
2936     XtVaSetValues(dialog,
2937         XmNtitle, bufp,
2938         NULL);
2939     xfree(bufp);
2940 
2941     w = XmCreateForm(dialog, "form", NULL, 0);
2942 
2943     return w;
2944 }
2945 
SetDialogFormResizable(Widget form,int onoff)2946 void SetDialogFormResizable(Widget form, int onoff)
2947 {
2948     XtVaSetValues(form,
2949         XmNresizePolicy, onoff ? XmRESIZE_ANY:XmRESIZE_NONE,
2950         NULL);
2951     XtVaSetValues(XtParent(form),
2952         XmNallowShellResize, onoff ? True:False,
2953         NULL);
2954 }
2955 
AddDialogFormChild(Widget form,Widget child)2956 void AddDialogFormChild(Widget form, Widget child)
2957 {
2958     Widget last_widget;
2959 
2960     XtVaGetValues(form, XmNuserData, &last_widget, NULL);
2961     if (last_widget) {
2962         XtVaSetValues(child,
2963             XmNtopAttachment, XmATTACH_WIDGET,
2964             XmNtopWidget, last_widget,
2965             NULL);
2966         XtVaSetValues(last_widget,
2967             XmNbottomAttachment, XmATTACH_NONE,
2968             NULL);
2969     } else {
2970         XtVaSetValues(child,
2971             XmNtopAttachment, XmATTACH_FORM,
2972             NULL);
2973     }
2974     XtVaSetValues(child,
2975         XmNleftAttachment, XmATTACH_FORM,
2976         XmNrightAttachment, XmATTACH_FORM,
2977         XmNbottomAttachment, XmATTACH_FORM,
2978         NULL);
2979     XtVaSetValues(form,
2980         XmNuserData, child,
2981         NULL);
2982 }
2983 
2984 typedef struct {
2985     Widget form;
2986     int close;
2987     int (*cbproc)();
2988     void *anydata;
2989 } AACDialog_CBdata;
2990 
aacdialog_int_cb_proc(void * data)2991 void aacdialog_int_cb_proc(void *data)
2992 {
2993     AACDialog_CBdata *cbdata;
2994     int retval;
2995 
2996     set_wait_cursor();
2997 
2998     cbdata = (AACDialog_CBdata *) data;
2999 
3000     retval = cbdata->cbproc(cbdata->anydata);
3001 
3002     if (cbdata->close && retval == RETURN_SUCCESS) {
3003         XtUnmanageChild(XtParent(cbdata->form));
3004     }
3005 
3006     unset_wait_cursor();
3007 }
3008 
CreateAACDialog(Widget form,Widget container,AACDialog_CBProc cbproc,void * data)3009 void CreateAACDialog(Widget form,
3010     Widget container, AACDialog_CBProc cbproc, void *data)
3011 {
3012     Widget fr, aacbut[3];
3013     AACDialog_CBdata *cbdata_accept, *cbdata_apply;
3014     char *aaclab[3] = {"Apply", "Accept", "Close"};
3015 
3016     fr = CreateFrame(form, NULL);
3017     XtVaSetValues(fr,
3018         XmNtopAttachment, XmATTACH_NONE,
3019         XmNleftAttachment, XmATTACH_FORM,
3020         XmNrightAttachment, XmATTACH_FORM,
3021         XmNbottomAttachment, XmATTACH_FORM,
3022         NULL);
3023     CreateCommandButtons(fr, 3, aacbut, aaclab);
3024 
3025     AddDialogFormChild(form, container);
3026     XtVaSetValues(container,
3027         XmNbottomAttachment, XmATTACH_WIDGET,
3028         XmNbottomWidget, fr,
3029         NULL);
3030 
3031     XtVaSetValues(form, XmNcancelButton, aacbut[2], NULL);
3032 
3033     cbdata_accept = xmalloc(sizeof(AACDialog_CBdata));
3034     cbdata_accept->form    = form;
3035     cbdata_accept->anydata = data;
3036     cbdata_accept->cbproc  = cbproc;
3037     cbdata_accept->close   = TRUE;
3038 
3039     cbdata_apply  = xmalloc(sizeof(AACDialog_CBdata));
3040     cbdata_apply->form     = form;
3041     cbdata_apply->anydata  = data;
3042     cbdata_apply->cbproc   = cbproc;
3043     cbdata_apply->close    = FALSE;
3044 
3045     AddButtonCB(aacbut[0], aacdialog_int_cb_proc, cbdata_apply);
3046     AddButtonCB(aacbut[1], aacdialog_int_cb_proc, cbdata_accept);
3047     AddButtonCB(aacbut[2], destroy_dialog_cb, XtParent(form));
3048 
3049     XtManageChild(container);
3050     XtManageChild(form);
3051 }
3052 
CreateTransformDialogForm(Widget parent,char * s,int sel_type)3053 TransformStructure *CreateTransformDialogForm(Widget parent,
3054     char *s, int sel_type)
3055 {
3056     TransformStructure *retval;
3057 
3058     retval = xmalloc(sizeof(TransformStructure));
3059 
3060     retval->form = CreateDialogForm(parent, s);
3061 
3062     retval->srcdest = CreateSrcDestSelector(retval->form, sel_type);
3063     AddDialogFormChild(retval->form, retval->srcdest->form);
3064 
3065 /*
3066  *     retval->restr = CreateRestrictionChoice(retval->form, "Source data filtering");
3067  *     AddDialogFormChild(retval->form, retval->restr->frame);
3068  */
3069 
3070     return retval;
3071 }
3072 
GetTransformDialogSettings(TransformStructure * tdialog,int exclusive,int * gsrc,int * gdest,int * nssrc,int ** svaluessrc,int * nsdest,int ** svaluesdest)3073 int GetTransformDialogSettings(TransformStructure *tdialog, int exclusive,
3074         int *gsrc, int *gdest,
3075         int *nssrc, int **svaluessrc, int *nsdest, int **svaluesdest)
3076 {
3077     int gsrc_ok, gdest_ok;
3078 
3079     gsrc_ok = GetSingleListChoice(tdialog->srcdest->src->graph_sel, gsrc);
3080     gdest_ok = GetSingleListChoice(tdialog->srcdest->dest->graph_sel, gdest);
3081     if (gsrc_ok == RETURN_FAILURE || gdest_ok == RETURN_FAILURE) {
3082         errmsg("Please select single source and destination graphs");
3083 	return RETURN_FAILURE;
3084     }
3085 
3086     *nssrc = GetListChoices(tdialog->srcdest->src->set_sel, svaluessrc);
3087     if (*nssrc == 0) {
3088         errmsg("No source sets selected");
3089 	return RETURN_FAILURE;
3090     }
3091     *nsdest = GetListChoices(tdialog->srcdest->dest->set_sel, svaluesdest);
3092     if (*nsdest != 0 && *nssrc != *nsdest) {
3093         errmsg("Different number of source and destination sets");
3094         xfree(*svaluessrc);
3095         xfree(*svaluesdest);
3096 	return RETURN_FAILURE;
3097     }
3098 
3099     /* check for mutually exclusive selections */
3100     if (exclusive && *gsrc == *gdest && *nsdest != 0) {
3101         int i;
3102         for (i = 0; i < *nssrc; i++) {
3103             if ((*svaluessrc)[i] == (*svaluesdest)[i]) {
3104                 xfree(*svaluessrc);
3105                 xfree(*svaluesdest);
3106                 errmsg("Source and destination set(s) are not mutually exclusive");
3107 	        return RETURN_FAILURE;
3108             }
3109         }
3110     }
3111 
3112     return RETURN_SUCCESS;
3113 }
3114 
CreateVContainer(Widget parent)3115 Widget CreateVContainer(Widget parent)
3116 {
3117     Widget rc;
3118 
3119     rc = XmCreateRowColumn(parent, "VContainer", NULL, 0);
3120     XtManageChild(rc);
3121 
3122     return rc;
3123 }
3124 
CreateHContainer(Widget parent)3125 Widget CreateHContainer(Widget parent)
3126 {
3127     Widget rc;
3128 
3129     rc = XmCreateRowColumn(parent, "HContainer", NULL, 0);
3130     XtVaSetValues(rc, XmNorientation, XmHORIZONTAL, NULL);
3131     XtManageChild(rc);
3132 
3133     return rc;
3134 }
3135 
3136 
CreateFrame(Widget parent,char * s)3137 Widget CreateFrame(Widget parent, char *s)
3138 {
3139     Widget fr;
3140 
3141     fr = XtVaCreateManagedWidget("frame", xmFrameWidgetClass, parent, NULL);
3142     if (s != NULL) {
3143         XtVaCreateManagedWidget(s, xmLabelGadgetClass, fr,
3144 				XmNchildType, XmFRAME_TITLE_CHILD,
3145 				NULL);
3146     }
3147 
3148     return (fr);
3149 }
3150 
3151 
3152 typedef struct {
3153     int ncols;
3154     int nrows;
3155 } GridData;
3156 
CreateGrid(Widget parent,int ncols,int nrows)3157 Widget CreateGrid(Widget parent, int ncols, int nrows)
3158 {
3159     Widget w;
3160     int nfractions;
3161     GridData *gd;
3162 
3163     if (ncols <= 0 || nrows <= 0) {
3164         errmsg("Wrong call to CreateGrid()");
3165         ncols = 1;
3166         nrows = 1;
3167     }
3168 
3169     nfractions = 0;
3170     do {
3171         nfractions++;
3172     } while (nfractions % ncols || nfractions % nrows);
3173 
3174     gd = xmalloc(sizeof(GridData));
3175     gd->ncols = ncols;
3176     gd->nrows = nrows;
3177 
3178     w = XmCreateForm(parent, "grid_form", NULL, 0);
3179     XtVaSetValues(w,
3180         XmNfractionBase, nfractions,
3181         XmNuserData, gd,
3182         NULL);
3183 
3184     XtManageChild(w);
3185     return w;
3186 }
3187 
PlaceGridChild(Widget grid,Widget w,int col,int row)3188 void PlaceGridChild(Widget grid, Widget w, int col, int row)
3189 {
3190     int nfractions, w1, h1;
3191     GridData *gd;
3192 
3193     XtVaGetValues(grid,
3194         XmNfractionBase, &nfractions,
3195         XmNuserData, &gd,
3196         NULL);
3197 
3198     if (gd == NULL) {
3199         errmsg("PlaceGridChild() called with a non-grid widget");
3200         return;
3201     }
3202     if (col < 0 || col >= gd->ncols) {
3203         errmsg("PlaceGridChild() called with wrong `col' argument");
3204         return;
3205     }
3206     if (row < 0 || row >= gd->nrows) {
3207         errmsg("PlaceGridChild() called with wrong `row' argument");
3208         return;
3209     }
3210 
3211     w1 = nfractions/gd->ncols;
3212     h1 = nfractions/gd->nrows;
3213 
3214     XtVaSetValues(w,
3215         XmNleftAttachment  , XmATTACH_POSITION,
3216         XmNleftPosition    , col*w1           ,
3217         XmNrightAttachment , XmATTACH_POSITION,
3218         XmNrightPosition   , (col + 1)*w1     ,
3219         XmNtopAttachment   , XmATTACH_POSITION,
3220         XmNtopPosition     , row*h1           ,
3221         XmNbottomAttachment, XmATTACH_POSITION,
3222         XmNbottomPosition  , (row + 1)*h1     ,
3223         NULL);
3224 }
3225 
3226 
CreateTab(Widget parent)3227 Widget CreateTab(Widget parent)
3228 {
3229     Widget tab;
3230 
3231     tab = XtVaCreateManagedWidget("tab", xmTabWidgetClass, parent, NULL);
3232 
3233     return (tab);
3234 }
3235 
CreateTabPage(Widget parent,char * s)3236 Widget CreateTabPage(Widget parent, char *s)
3237 {
3238     Widget w;
3239     XmString str;
3240 
3241     w = XmCreateRowColumn(parent, "tabPage", NULL, 0);
3242     str = XmStringCreateLocalized(s);
3243     XtVaSetValues(w, XmNtabLabel, str, NULL);
3244     XmStringFree(str);
3245     XtManageChild(w);
3246 
3247     return (w);
3248 }
3249 
SelectTabPage(Widget tab,Widget w)3250 void SelectTabPage(Widget tab, Widget w)
3251 {
3252     XmTabSetTabWidget(tab, w, True);
3253 }
3254 
CreateTextItem2(Widget parent,int len,char * s)3255 Widget CreateTextItem2(Widget parent, int len, char *s)
3256 {
3257     Widget w;
3258     Widget rc;
3259     XmString str;
3260     rc = XmCreateRowColumn(parent, "rc", NULL, 0);
3261     XtVaSetValues(rc, XmNorientation, XmHORIZONTAL, NULL);
3262     str = XmStringCreateLocalized(s);
3263     XtVaCreateManagedWidget("label", xmLabelWidgetClass, rc,
3264 			    XmNlabelString, str,
3265 			    NULL);
3266     XmStringFree(str);
3267     w = XtVaCreateManagedWidget("text", xmTextWidgetClass, rc,
3268 				XmNtraversalOn, True,
3269 				XmNcolumns, len,
3270 				NULL);
3271     XtManageChild(rc);
3272     return w;
3273 }
3274 
CreateTextItem4(Widget parent,int len,char * label)3275 Widget CreateTextItem4(Widget parent, int len, char *label)
3276 {
3277     Widget retval;
3278     XtVaCreateManagedWidget(label, xmLabelWidgetClass, parent, NULL);
3279     retval = XtVaCreateManagedWidget("text",
3280         xmTextWidgetClass, parent,
3281         XmNcolumns, len,
3282         NULL);
3283     return retval;
3284 }
3285 
3286 
3287 /*
3288  * create a multiline editable window
3289  * parent = parent widget
3290  * hgt    = number of lines in edit window
3291  * s      = label for window
3292  *
3293  * returns the edit window widget
3294  */
CreateScrollTextItem2(Widget parent,int hgt,char * s)3295 Widget CreateScrollTextItem2(Widget parent, int hgt, char *s)
3296 {
3297     Widget w, form, label;
3298     XmString str;
3299     Arg args[4];
3300     int ac;
3301 
3302     form = XmCreateForm(parent, "form", NULL, 0);
3303 
3304     str = XmStringCreateLocalized(s);
3305     label = XtVaCreateManagedWidget("label",
3306         xmLabelWidgetClass, form,
3307 	XmNlabelString, str,
3308 	XmNtopAttachment, XmATTACH_FORM,
3309 	XmNleftAttachment, XmATTACH_FORM,
3310 	XmNrightAttachment, XmATTACH_FORM,
3311 	NULL);
3312     XmStringFree(str);
3313 
3314     ac = 0;
3315     if (hgt > 0) {
3316         XtSetArg(args[ac], XmNrows, hgt); ac++;
3317     }
3318     XtSetArg(args[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
3319     XtSetArg(args[ac], XmNwordWrap, True); ac++;
3320     XtSetArg(args[ac], XmNvisualPolicy, XmVARIABLE); ac++;
3321     w = XmCreateScrolledText(form, "text", args, ac);
3322     XtVaSetValues(XtParent(w),
3323 	XmNtopAttachment, XmATTACH_WIDGET,
3324         XmNtopWidget, label,
3325 	XmNleftAttachment, XmATTACH_FORM,
3326 	XmNrightAttachment, XmATTACH_FORM,
3327 	XmNbottomAttachment, XmATTACH_FORM,
3328 	NULL);
3329     XtManageChild(w);
3330 
3331     XtManageChild(form);
3332     return w;
3333 }
3334 
3335 
xv_getstr(Widget w)3336 char *xv_getstr(Widget w)
3337 /*
3338  * return the string from a text widget
3339  *
3340  * NB - newlines are converted to spaces
3341  */
3342 {
3343     char *s;
3344     int i;
3345     static char buf[MAX_STRING_LENGTH];
3346 
3347     strncpy(buf, s = XmTextGetString(w), MAX_STRING_LENGTH - 1);
3348     XtFree(s);
3349 
3350     i=strlen(buf);
3351     for (i--; i >= 0; i--) {
3352         if (buf[i] == '\n') {
3353             buf[i] = ' ';
3354         }
3355     }
3356     return buf;
3357 }
3358 
3359 
3360 /*
3361  * xv_evalexpr - take a text field and pass it to the parser if it needs to
3362  * evaluated, else use atof().
3363  * place the double result in answer
3364  * if an error, return False, else True
3365  */
xv_evalexpr(Widget w,double * answer)3366 Boolean xv_evalexpr(Widget w, double *answer )
3367 {
3368     char *s;
3369     static char *buf = NULL;
3370     int i, len, ier = 0;
3371     double result;
3372 
3373     buf = copy_string(buf, s = XmTextGetString(w));
3374     XtFree(s);
3375 
3376     if (!(len = strlen( buf ) )) { /* check for zero length */
3377         *answer = 0;
3378         return RETURN_FAILURE;
3379     }
3380     /* first character may be a sign */
3381     if (!fpdigit[(int) buf[0]] && buf[0] != '-' && buf[0] != '+') {
3382         i = len +1;
3383     } else {
3384         i = 1;
3385     }
3386 
3387     for (; i<len; i++) {
3388         if (!fpdigit[(int) buf[i]]) {
3389             break;
3390         }
3391     }
3392 
3393     if (i == len) {         /* only floating point digits */
3394         *answer = atof( buf );
3395         return RETURN_SUCCESS;
3396     } else {                /* must evaluate an expression */
3397         ier = s_scanner(buf, &result);
3398         if( !ier ) {
3399             *answer = result;
3400             return RETURN_SUCCESS;
3401         } else {
3402             *answer = 0;
3403             return RETURN_FAILURE;
3404         }
3405     }
3406 }
3407 
3408 /*
3409  * xv_evalexpri - take a text field and pass it to the parser if it needs to
3410  * evaluated, else use atoi().
3411  * place the integer result in answer
3412  * if an error, return False, else True
3413  */
xv_evalexpri(Widget w,int * answer)3414 Boolean xv_evalexpri(Widget w, int *answer )
3415 {
3416     char *s;
3417     static char *buf = NULL;
3418     int i, len, ier = 0;
3419     double result;
3420 
3421     buf = copy_string(buf, s = XmTextGetString(w));
3422     XtFree(s);
3423 
3424     if (!(len = strlen( buf ) )) { /* check for zero length */
3425         *answer = 0;
3426         return RETURN_FAILURE;
3427     }
3428     /* first character may be a sign */
3429     if (!fpdigit[(int) buf[0]] && buf[0] != '-' && buf[0] != '+') {
3430         i = len +1;
3431     } else {
3432         i = 1;
3433     }
3434 
3435     for (; i<len; i++) {
3436         if (!fpdigit[(int) buf[i]]) {
3437             break;
3438         }
3439     }
3440 
3441     if (i == len) {             /* only floating point digits */
3442         *answer = atoi(buf);
3443         return RETURN_SUCCESS;
3444     } else {                    /* must evaluate an expression */
3445         ier = s_scanner(buf, &result);
3446         if( !ier ) {
3447             *answer = (int)result;
3448             return RETURN_SUCCESS;
3449         } else {
3450             *answer = 0;
3451             return RETURN_FAILURE;
3452         }
3453     }
3454 }
3455 
3456 
xv_setstr(Widget w,char * s)3457 void xv_setstr(Widget w, char *s)
3458 {
3459     if (w != NULL) {
3460         XmTextSetString(w, s ? s : "");
3461     }
3462 }
3463 
3464 /*
3465  * generic unmanage popup routine, used elswhere
3466  */
destroy_dialog(Widget w,XtPointer client_data,XtPointer call_data)3467 void destroy_dialog(Widget w, XtPointer client_data, XtPointer call_data)
3468 {
3469     XtUnmanageChild((Widget) client_data);
3470 }
3471 
3472 /*
3473  * same for AddButtonCB
3474  */
destroy_dialog_cb(void * data)3475 void destroy_dialog_cb(void *data)
3476 {
3477     XtUnmanageChild((Widget) data);
3478 }
3479 
3480 /* if user tried to close from WM */
wm_exit_cb(Widget w,XtPointer client_data,XtPointer call_data)3481 static void wm_exit_cb(Widget w, XtPointer client_data, XtPointer call_data)
3482 {
3483     bailout();
3484 }
3485 
3486 /*
3487  * handle the close item on the WM menu
3488  */
handle_close(Widget w)3489 void handle_close(Widget w)
3490 {
3491     Atom WM_DELETE_WINDOW;
3492 
3493     XtVaSetValues(w, XmNdeleteResponse, XmDO_NOTHING, NULL);
3494     WM_DELETE_WINDOW = XmInternAtom(disp, "WM_DELETE_WINDOW", False);
3495     XmAddProtocolCallback(w,
3496         XM_WM_PROTOCOL_ATOM(w), WM_DELETE_WINDOW,
3497         (w == app_shell) ? wm_exit_cb : destroy_dialog, w);
3498 
3499     savewidget(w);
3500 }
3501 
3502 /*
3503  * Manage and raise
3504  */
RaiseWindow(Widget w)3505 void RaiseWindow(Widget w)
3506 {
3507     XtManageChild(w);
3508     XMapRaised(XtDisplay(w), XtWindow(w));
3509 }
3510 
3511 
3512 static Widget *savewidgets = NULL;
3513 static int nsavedwidgets = 0;
3514 
savewidget(Widget w)3515 void savewidget(Widget w)
3516 {
3517     int i;
3518 
3519     for (i = 0; i < nsavedwidgets; i++) {
3520         if (w == savewidgets[i]) {
3521             return;
3522         }
3523     }
3524 
3525     savewidgets = xrealloc(savewidgets, (nsavedwidgets + 1)*sizeof(Widget));
3526     savewidgets[nsavedwidgets] = w;
3527     nsavedwidgets++;
3528 }
3529 
deletewidget(Widget w)3530 void deletewidget(Widget w)
3531 {
3532     int i;
3533 
3534     for (i = 0; i < nsavedwidgets; i++) {
3535         if (w == savewidgets[i]) {
3536             nsavedwidgets--;
3537             for (; i <  nsavedwidgets; i++) {
3538                 savewidgets[i] = savewidgets[i + 1];
3539             }
3540             savewidgets = xrealloc(savewidgets, nsavedwidgets*sizeof(Widget));
3541             XtDestroyWidget(w);
3542             return;
3543         }
3544     }
3545 
3546 }
3547 
DefineDialogCursor(Cursor c)3548 void DefineDialogCursor(Cursor c)
3549 {
3550     int i;
3551 
3552     for (i = 0; i < nsavedwidgets; i++) {
3553 	XDefineCursor(disp, XtWindow(savewidgets[i]), c);
3554     }
3555     XFlush(disp);
3556 }
3557 
UndefineDialogCursor()3558 void UndefineDialogCursor()
3559 {
3560     int i;
3561 
3562     for (i = 0; i < nsavedwidgets; i++) {
3563 	XUndefineCursor(disp, XtWindow(savewidgets[i]));
3564     }
3565     XFlush(disp);
3566 }
3567 
CreateCommandButtonsNoDefault(Widget parent,int n,Widget * buts,char ** l)3568 Widget CreateCommandButtonsNoDefault(Widget parent, int n, Widget * buts, char **l)
3569 {
3570     int i;
3571     Widget form;
3572     Dimension h;
3573 
3574     form = XtVaCreateWidget("form", xmFormWidgetClass, parent,
3575 			    XmNfractionBase, n,
3576 			    NULL);
3577 
3578     for (i = 0; i < n; i++) {
3579 	buts[i] = XtVaCreateManagedWidget(l[i],
3580 					  xmPushButtonWidgetClass, form,
3581 					  XmNtopAttachment, XmATTACH_FORM,
3582 					  XmNbottomAttachment, XmATTACH_FORM,
3583 					  XmNleftAttachment, XmATTACH_POSITION,
3584 					  XmNleftPosition, i,
3585 					  XmNrightAttachment, XmATTACH_POSITION,
3586 					  XmNrightPosition, i + 1,
3587 					  XmNleftOffset, (i == 0) ? 2 : 0,
3588 					  XmNrightOffset, 3,
3589 					  XmNtopOffset, 2,
3590 					  XmNbottomOffset, 3,
3591 					  NULL);
3592     }
3593     XtManageChild(form);
3594     XtVaGetValues(buts[0], XmNheight, &h, NULL);
3595     XtVaSetValues(form, XmNpaneMaximum, h, XmNpaneMinimum, h, NULL);
3596 
3597     return form;
3598 }
3599 
CreateCommandButtons(Widget parent,int n,Widget * buts,char ** l)3600 Widget CreateCommandButtons(Widget parent, int n, Widget * buts, char **l)
3601 {
3602     int i;
3603     Widget form;
3604     Dimension h;
3605 
3606     form = XtVaCreateWidget("form", xmFormWidgetClass, parent,
3607 			    XmNfractionBase, n,
3608 			    NULL);
3609 
3610     for (i = 0; i < n; i++) {
3611 	buts[i] = XtVaCreateManagedWidget(l[i],
3612 					  xmPushButtonWidgetClass, form,
3613 					  XmNtopAttachment, XmATTACH_FORM,
3614 					  XmNbottomAttachment, XmATTACH_FORM,
3615 					  XmNleftAttachment, XmATTACH_POSITION,
3616 					  XmNleftPosition, i,
3617 					  XmNrightAttachment, XmATTACH_POSITION,
3618 					  XmNrightPosition, i + 1,
3619 					  XmNdefaultButtonShadowThickness, 1,
3620 					  XmNshowAsDefault, (i == 0) ? True : False,
3621 					  NULL);
3622     }
3623     XtManageChild(form);
3624     XtVaGetValues(buts[0], XmNheight, &h, NULL);
3625     XtVaSetValues(form, XmNpaneMaximum, h, XmNpaneMinimum, h, NULL);
3626 
3627     return form;
3628 }
3629 
3630 
3631 
3632 static SetChoiceItem *plist = NULL;
3633 static int nplist = 0;
3634 
CreateSetSelector(Widget parent,char * label,int type,int ff,int gtype,int stype)3635 SetChoiceItem CreateSetSelector(Widget parent,
3636 				char *label,
3637 				int type,
3638 				int ff,
3639 				int gtype,
3640 				int stype)
3641 {
3642     Arg args[3];
3643     Widget rc2, lab;
3644     SetChoiceItem sel;
3645 
3646     rc2 = XtVaCreateWidget("rc", xmRowColumnWidgetClass, parent,
3647 			      XmNorientation, XmVERTICAL, NULL);
3648     lab = XmCreateLabel(rc2, label, NULL, 0);
3649     XtManageChild(lab);
3650     XtSetArg(args[0], XmNlistSizePolicy, XmRESIZE_IF_POSSIBLE);
3651     XtSetArg(args[1], XmNvisibleItemCount, 6);
3652     sel.list = XmCreateScrolledList(rc2, "list", args, 2);
3653     if (stype == SELECTION_TYPE_MULTIPLE) {	/* multiple select */
3654 	XtVaSetValues(sel.list,
3655 		      XmNselectionPolicy, XmEXTENDED_SELECT,
3656 		      NULL);
3657     } else {			/* single select */
3658     	XtVaSetValues(sel.list,
3659 		      XmNselectionPolicy, XmSINGLE_SELECT,
3660 		      NULL);
3661     }
3662     sel.type = type;
3663     sel.gno = gtype;
3664     XtManageChild(sel.list);
3665     sel.indx = save_set_list(sel);
3666     update_set_list(gtype == GRAPH_SELECT_CURRENT ? get_cg():sel.gno, sel);
3667 
3668     XtManageChild(rc2);
3669     return sel;
3670 }
3671 
GetSelectedSet(SetChoiceItem l)3672 int GetSelectedSet(SetChoiceItem l)
3673 {
3674     int retval = SET_SELECT_ERROR;
3675     int *pos_list;
3676     int pos_cnt, cnt;
3677     char buf[256];
3678 
3679     if (XmListGetSelectedPos(l.list, &pos_list, &pos_cnt)) {
3680 	XmString *s, cs;
3681 	char *cstr;
3682 	XtVaGetValues(l.list,
3683 		      XmNselectedItemCount, &cnt,
3684 		      XmNselectedItems, &s,
3685 		      NULL);
3686 	cs = XmStringCopy(*s);
3687 	if ((cstr = GetStringSimple(cs))) {
3688 	    strcpy(buf, cstr);
3689 	    if (strcmp(buf, "New set") == 0) {
3690 		retval = SET_SELECT_NEXT;
3691 	    } else if (strcmp(buf, "All sets") == 0) {
3692 		retval = SET_SELECT_ALL;
3693 	    } else if (strcmp(buf, "Nearest set") == 0) {
3694 		retval = SET_SELECT_NEAREST;
3695 	    } else {
3696 		sscanf(buf, "S%d", &retval);
3697 	    }
3698 	    XtFree(cstr);
3699 	}
3700         XmStringFree(cs);
3701     }
3702 
3703     return retval;
3704 }
3705 
3706 /*
3707  * if the set selection type is multiple, then get a
3708  * list of sets, returns the number of selected sets.
3709  */
GetSelectedSets(SetChoiceItem l,int ** sets)3710 int GetSelectedSets(SetChoiceItem l, int **sets)
3711 {
3712     int i;
3713     int cnt = SET_SELECT_ERROR, retval = SET_SELECT_ERROR;
3714     int *ptr;
3715     int *pos_list;
3716     int pos_cnt, gno;
3717     if (XmListGetSelectedPos(l.list, &pos_list, &pos_cnt)) {
3718 	char buf[256];
3719 	char *cstr;
3720 	XmString *s, cs;
3721 
3722 	XtVaGetValues(l.list,
3723 		      XmNselectedItemCount, &cnt,
3724 		      XmNselectedItems, &s,
3725 		      NULL);
3726 	*sets = xmalloc(cnt * SIZEOF_INT);
3727 	ptr = *sets;
3728 	for (i = 0; i < cnt; i++) {
3729 	    cs = XmStringCopy(s[i]);
3730 	    if ((cstr = GetStringSimple(cs))) {
3731 		strcpy(buf, cstr);
3732 		if (strcmp(buf, "New set") == 0) {
3733 		    retval = SET_SELECT_NEXT;
3734 		    return retval;
3735 		} else if (strcmp(buf, "All sets") == 0) {
3736 		    int j, nsets = 0;
3737 		    retval = SET_SELECT_ALL;
3738 		    if (l.gno == GRAPH_SELECT_CURRENT) {
3739 			gno = get_cg();
3740 		    } else {
3741 			gno = l.gno;
3742 		    }
3743 		    retval = nactive(gno);
3744 		    *sets = xrealloc(*sets, retval * SIZEOF_INT);
3745 		    ptr = *sets;
3746 		    for (j = 0; j < number_of_sets(gno); j++) {
3747 			if (is_set_active(gno, j)) {
3748 			    ptr[nsets] = j;
3749 			    nsets++;
3750 			}
3751 		    }
3752 		    if (nsets != retval) {
3753 			errwin("Nsets != reval, can't happen!");
3754 		    }
3755 		    return retval;
3756 		} else {
3757 		    sscanf(buf, "S%d", &retval);
3758 		}
3759 		ptr[i] = retval;
3760 		XtFree(cstr);
3761 	    }
3762 	    XmStringFree(cs);
3763 	}
3764     }
3765     return cnt;
3766 }
3767 
save_set_list(SetChoiceItem l)3768 int save_set_list(SetChoiceItem l)
3769 {
3770     nplist++;
3771     plist = xrealloc(plist, nplist*sizeof(SetChoiceItem));
3772     plist[nplist - 1] = l;
3773     return nplist - 1;
3774 }
3775 
update_save_set_list(SetChoiceItem l,int newgr)3776 void update_save_set_list( SetChoiceItem l, int newgr )
3777 {
3778     plist[l.indx] = l;
3779     update_set_list( newgr, plist[l.indx] );
3780 }
3781 
update_set_list(int gno,SetChoiceItem l)3782 void update_set_list(int gno, SetChoiceItem l)
3783 {
3784     int i, cnt, scnt=0;
3785     char buf[1024];
3786     XmString *xms;
3787 
3788     XmListDeleteAllItems(l.list);
3789     for (i = 0; i < number_of_sets(gno); i++) {
3790 	if (is_set_active(gno, i)) {
3791 	    scnt++;
3792 	}
3793     }
3794 
3795     switch (l.type) {		/* TODO */
3796     case SET_SELECT_ACTIVE:
3797 	xms = xmalloc(sizeof(XmString) * scnt);
3798 	cnt = 0;
3799 	break;
3800     case SET_SELECT_ALL:
3801 	xms = xmalloc(sizeof(XmString) * (scnt + 1));
3802 	xms[0] = XmStringCreateLocalized("All sets");
3803 	cnt = 1;
3804 	break;
3805     case SET_SELECT_NEXT:
3806 	xms = xmalloc(sizeof(XmString) * (scnt + 1));
3807 	xms[0] = XmStringCreateLocalized("New set");
3808 	cnt = 1;
3809 	break;
3810     case SET_SELECT_NEAREST:
3811 	xms = xmalloc(sizeof(XmString) * (scnt + 1));
3812 	xms[0] = XmStringCreateLocalized("Nearest set");
3813 	cnt = 1;
3814 	break;
3815     default:
3816 	xms = xmalloc(sizeof(XmString) * scnt);
3817 	cnt = 0;
3818 	break;
3819     }
3820 
3821     for (i = 0; i < number_of_sets(gno); i++) {
3822         if (is_set_active(gno, i)) {
3823             sprintf(buf, "S%d (N=%d, %s)", i, getsetlength(gno, i), getcomment(gno, i));
3824             xms[cnt] = XmStringCreateLocalized(buf);
3825             cnt++;
3826         }
3827     }
3828     XmListAddItemsUnselected(l.list, xms, cnt, 0);
3829 
3830     /* automatically highlight if only 1 selection */
3831     if (scnt == 1) {
3832         XmListSelectItem(l.list, xms[cnt-1], True);
3833     }
3834 
3835     for (i = 0; i < cnt; i++) {
3836         XmStringFree(xms[i]);
3837     }
3838     xfree(xms);
3839 }
3840 
3841 
update_set_lists(int gno)3842 void update_set_lists(int gno)
3843 {
3844     int i;
3845 
3846     if (gno == GRAPH_SELECT_CURRENT) {
3847         update_set_selectors(get_cg());
3848         update_ss_editors(get_cg());
3849     } else {
3850         update_set_selectors(gno);
3851         update_ss_editors(gno);
3852     }
3853 
3854     if (inwin) {
3855         for (i = 0; i < nplist; i++) {
3856             if (plist[i].gno == gno ||
3857                 (gno == get_cg() && plist[i].gno == GRAPH_SELECT_CURRENT)) {
3858                 update_set_list(gno, plist[i]);
3859             }
3860         }
3861     }
3862 }
3863 
3864 
CreateSeparator(Widget parent)3865 Widget CreateSeparator(Widget parent)
3866 {
3867     Widget sep;
3868 
3869     sep = XmCreateSeparator(parent, "sep", NULL, 0);
3870     XtManageChild(sep);
3871     return sep;
3872 }
3873 
CreateMenuBar(Widget parent)3874 Widget CreateMenuBar(Widget parent)
3875 {
3876     Widget menubar;
3877 
3878     menubar = XmCreateMenuBar(parent, "menuBar", NULL, 0);
3879     return menubar;
3880 }
3881 
CreateMenu(Widget parent,char * label,char mnemonic,int help)3882 Widget CreateMenu(Widget parent, char *label, char mnemonic, int help)
3883 {
3884     Widget menupane, cascade;
3885     XmString str;
3886     char *name, ms[2];
3887 
3888     name = label_to_resname(label, "Menu");
3889     menupane = XmCreatePulldownMenu(parent, name, NULL, 0);
3890     xfree(name);
3891 
3892     ms[0] = mnemonic;
3893     ms[1] = '\0';
3894 
3895     str = XmStringCreateLocalized(label);
3896     cascade = XtVaCreateManagedWidget("cascade",
3897         xmCascadeButtonGadgetClass, parent,
3898     	XmNsubMenuId, menupane,
3899     	XmNlabelString, str,
3900     	XmNmnemonic, XStringToKeysym(ms),
3901     	NULL);
3902     XmStringFree(str);
3903 
3904     if (help) {
3905         XtVaSetValues(parent, XmNmenuHelpWidget, cascade, NULL);
3906         CreateMenuButton(menupane, "On context", 'x',
3907             ContextHelpCB, NULL);
3908         CreateSeparator(menupane);
3909     }
3910 
3911     return menupane;
3912 }
3913 
3914 
CreateMenuButton(Widget parent,char * label,char mnemonic,Button_CBProc cb,void * data)3915 Widget CreateMenuButton(Widget parent, char *label, char mnemonic,
3916 	Button_CBProc cb, void *data)
3917 {
3918     Widget button;
3919     XmString str;
3920     char *name, ms[2];
3921 
3922     ms[0] = mnemonic;
3923     ms[1] = '\0';
3924 
3925     str = XmStringCreateLocalized(label);
3926     name = label_to_resname(label, "Button");
3927     button = XtVaCreateManagedWidget(name,
3928         xmPushButtonWidgetClass, parent,
3929     	XmNlabelString, str,
3930     	XmNmnemonic, XStringToKeysym(ms),
3931     	NULL);
3932     xfree(name);
3933     XmStringFree(str);
3934 
3935     AddButtonCB(button, cb, data);
3936 
3937     return button;
3938 }
3939 
CreateMenuCloseButton(Widget parent,Widget form)3940 Widget CreateMenuCloseButton(Widget parent, Widget form)
3941 {
3942     Widget wbut;
3943     XmString str;
3944 
3945     wbut = CreateMenuButton(parent,
3946         "Close", 'C', destroy_dialog_cb, XtParent(form));
3947     str = XmStringCreateLocalized("Esc");
3948     XtVaSetValues(wbut, XmNacceleratorText, str, NULL);
3949     XmStringFree(str);
3950     XtVaSetValues(form, XmNcancelButton, wbut, NULL);
3951 
3952     return wbut;
3953 }
3954 
CreateMenuHelpButton(Widget parent,char * label,char mnemonic,Widget form,char * ha)3955 Widget CreateMenuHelpButton(Widget parent, char *label, char mnemonic,
3956     Widget form, char *ha)
3957 {
3958     Widget wbut;
3959 
3960     wbut = CreateMenuButton(parent, label, mnemonic, HelpCB, ha);
3961     AddHelpCB(form, ha);
3962 
3963     return wbut;
3964 }
3965 
CreateMenuToggle(Widget parent,char * label,char mnemonic,TB_CBProc cb,void * data)3966 Widget CreateMenuToggle(Widget parent, char *label, char mnemonic,
3967 	TB_CBProc cb, void *data)
3968 {
3969     Widget button;
3970     XmString str;
3971     char *name, ms[2];
3972 
3973     ms[0] = mnemonic;
3974     ms[1] = '\0';
3975 
3976     str = XmStringCreateLocalized(label);
3977     name = label_to_resname(label, NULL);
3978     button = XtVaCreateManagedWidget(name,
3979         xmToggleButtonWidgetClass, parent,
3980     	XmNlabelString, str,
3981     	XmNmnemonic, XStringToKeysym(ms),
3982     	XmNvisibleWhenOff, True,
3983     	XmNindicatorOn, True,
3984     	NULL);
3985     xfree(name);
3986     XmStringFree(str);
3987 
3988     if (cb) {
3989         AddToggleButtonCB(button, cb, data);
3990     }
3991 
3992     return button;
3993 }
3994 
CreateMenuLabel(Widget parent,char * name)3995 Widget CreateMenuLabel(Widget parent, char *name)
3996 {
3997     Widget lab;
3998 
3999     lab = XmCreateLabel(parent, name, NULL, 0);
4000     XtManageChild(lab);
4001     return lab;
4002 }
4003 
help_int_cb(Widget w,XtPointer client_data,XtPointer call_data)4004 static void help_int_cb(Widget w, XtPointer client_data, XtPointer call_data)
4005 {
4006     HelpCB(client_data);
4007 }
4008 
AddHelpCB(Widget w,char * ha)4009 void AddHelpCB(Widget w, char *ha)
4010 {
4011     if (XtHasCallbacks(w, XmNhelpCallback) == XtCallbackHasSome) {
4012         /* allow only one help callback */
4013         XtRemoveAllCallbacks(w, XmNhelpCallback);
4014     }
4015 
4016     XtAddCallback(w, XmNhelpCallback, help_int_cb, (XtPointer) ha);
4017 }
4018 
ContextHelpCB(void * data)4019 void ContextHelpCB(void *data)
4020 {
4021     Widget whelp;
4022     Cursor cursor;
4023     int ok = FALSE;
4024 
4025     cursor = XCreateFontCursor(disp, XC_question_arrow);
4026     whelp = XmTrackingLocate(app_shell, cursor, False);
4027     while (whelp != NULL) {
4028         if (XtHasCallbacks(whelp, XmNhelpCallback) == XtCallbackHasSome) {
4029             XtCallCallbacks(whelp, XmNhelpCallback, NULL);
4030             ok = TRUE;
4031             break;
4032         } else {
4033             whelp = GetParent(whelp);
4034         }
4035     }
4036     if (!ok) {
4037         HelpCB(NULL);
4038     }
4039     XFreeCursor(disp, cursor);
4040 }
4041 
4042 
4043 static int yesno_retval = 0;
4044 static Boolean keep_grab = True;
4045 
yesnoCB(Widget w,XtPointer client_data,XtPointer call_data)4046 void yesnoCB(Widget w, XtPointer client_data, XtPointer call_data)
4047 {
4048     XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
4049     int why = cbs->reason;
4050 
4051     keep_grab = False;
4052 
4053     XtRemoveGrab(XtParent(w));
4054     XtUnmanageChild(w);
4055     switch (why) {
4056     case XmCR_OK:
4057 	yesno_retval = 1;
4058 	/* process ok action */
4059 	break;
4060     case XmCR_CANCEL:
4061 	yesno_retval = 0;
4062 	/* process cancel action */
4063 	break;
4064     }
4065 }
4066 
update_yesno(Widget w,char * msg,char * ha)4067 static void update_yesno(Widget w, char *msg, char *ha)
4068 {
4069     Widget hb;
4070     XmString str;
4071 
4072     if (msg != NULL) {
4073         str = XmStringCreateLocalized(msg);
4074     } else {
4075         str = XmStringCreateLocalized("Warning");
4076     }
4077     XtVaSetValues(w, XmNmessageString, str, NULL);
4078     XmStringFree(str);
4079 
4080     hb = XtNameToWidget(w, "Help");
4081     if (ha) {
4082         AddButtonCB(hb, HelpCB, ha);
4083         XtSetSensitive(hb, True);
4084     } else {
4085         XtSetSensitive(hb, False);
4086     }
4087 }
4088 
yesnowin(char * msg,char * s1,char * s2,char * help_anchor)4089 int yesnowin(char *msg, char *s1, char *s2, char *help_anchor)
4090 {
4091     static Widget yesno_popup = NULL;
4092     XEvent event;
4093 
4094     keep_grab = True;
4095 
4096     if (yesno_popup == NULL) {
4097 	yesno_popup = XmCreateErrorDialog(app_shell, "warndlg", NULL, 0);
4098 
4099 	XtAddCallback(yesno_popup, XmNokCallback, yesnoCB, NULL);
4100 	XtAddCallback(yesno_popup, XmNcancelCallback, yesnoCB, NULL);
4101     }
4102     update_yesno(yesno_popup, msg, help_anchor);
4103     RaiseWindow(yesno_popup);
4104 
4105     XtAddGrab(XtParent(yesno_popup), True, False);
4106     while (keep_grab || XtAppPending(app_con)) {
4107 	XtAppNextEvent(app_con, &event);
4108 	XtDispatchEvent(&event);
4109     }
4110     return yesno_retval;
4111 }
4112 
4113 
CreateAACButtons(Widget parent,Widget form,Button_CBProc aac_cb)4114 Widget CreateAACButtons(Widget parent, Widget form, Button_CBProc aac_cb)
4115 {
4116     Widget w;
4117     Widget aacbut[3];
4118     static char *aaclab[3] = {"Apply", "Accept", "Close"};
4119 
4120     w = CreateCommandButtons(parent, 3, aacbut, aaclab);
4121     AddButtonCB(aacbut[0], aac_cb, (void *) AAC_APPLY);
4122     AddButtonCB(aacbut[1], aac_cb, (void *) AAC_ACCEPT);
4123     AddButtonCB(aacbut[2], aac_cb, (void *) AAC_CLOSE);
4124 
4125     if (form != NULL) {
4126         XtVaSetValues(form, XmNcancelButton, aacbut[2], NULL);
4127     }
4128 
4129     return w;
4130 }
4131 
SetLabel(Widget w,char * s)4132 void SetLabel(Widget w, char *s)
4133 {
4134     XmString str;
4135 
4136     str = XmStringCreateLocalized(s);
4137     XtVaSetValues(w, XmNlabelString, str, NULL);
4138     XmStringFree(str);
4139 }
4140 
SetFixedFont(Widget w)4141 void SetFixedFont(Widget w)
4142 {
4143     XFontStruct *f;
4144     XmFontList xmf;
4145 
4146     f = XLoadQueryFont(disp, "fixed");
4147     xmf = XmFontListCreate(f, charset);
4148     if (xmf == NULL) {
4149         errmsg("Can't load font \"fixed\"");
4150         return;
4151     } else {
4152         XtVaSetValues(w, XmNfontList, xmf, NULL);
4153         XmFontListFree(xmf);
4154     }
4155 }
4156 
GetStringSimple(XmString xms)4157 char *GetStringSimple(XmString xms)
4158 {
4159     char *s;
4160 
4161     if (XmStringGetLtoR(xms, charset, &s)) {
4162         return s;
4163     } else {
4164         return NULL;
4165     }
4166 }
4167 
4168 extern int ReqUpdateColorSel;
4169 
update_all(void)4170 void update_all(void)
4171 {
4172     int gno = get_cg();
4173 
4174     if (!inwin) {
4175         return;
4176     }
4177 
4178     update_set_lists(gno);
4179 
4180     update_set_selectors(ALL_GRAPHS);
4181     update_ss_editors(ALL_GRAPHS);
4182 
4183     if (ReqUpdateColorSel == TRUE) {
4184         update_color_selectors();
4185         ReqUpdateColorSel = FALSE;
4186     }
4187 
4188     update_ticks(gno);
4189     update_props_items();
4190     update_hotlinks();
4191     update_prune_frame();
4192     update_locator_items(gno);
4193     set_stack_message();
4194     set_left_footer(NULL);
4195 }
4196 
update_all_cb(void * data)4197 void update_all_cb(void *data)
4198 {
4199     update_all();
4200 }
4201