1 /*
2  *
3 Copyright 1989, 1998  The Open Group
4 
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
24  */
25 
26 /*
27  * Code for creating all widgets used by EditRes.
28  */
29 
30 #include <stdio.h>
31 #include <X11/Intrinsic.h>
32 #include <X11/StringDefs.h>	/* Get standard string definations. */
33 
34 #include <X11/Xaw/AsciiText.h>
35 #include <X11/Xaw/Box.h>
36 #include <X11/Xaw/Cardinals.h>
37 #include <X11/Xaw/Label.h>
38 #include <X11/Xaw/List.h>
39 #include <X11/Xaw/MenuButton.h>
40 #include <X11/Xaw/Paned.h>
41 #include <X11/Xaw/Panner.h>
42 #include <X11/Xaw/Porthole.h>
43 #include <X11/Xaw/SmeBSB.h>
44 #include <X11/Xaw/SmeLine.h>
45 #include <X11/Xaw/SimpleMenu.h>
46 #include <X11/Xaw/Toggle.h>
47 #include <X11/Xaw/Tree.h>
48 #include <X11/Xaw/Viewport.h>
49 
50 #include "editresP.h"
51 
52 
53 
54 /*
55  * functions.
56  */
57 
58 static Widget CreateTopArea ( Widget parent );
59 static void CreateCommandMenu ( Widget parent, String toolkit );
60 static void CreateTreeCommandMenu ( Widget parent, String toolkit );
61 static void CreateResourceNameForm ( Widget parent, WNode * node );
62 static void SetToggleGroupLeaders ( WNode * node );
63 static void MakeBoxLookNice ( Widget dot, Widget star, Widget any,
64 			      Widget single, Widget name, Widget class,
65 			      int endbox );
66 static void CreateLists ( Widget parent, WNode * node, char **names,
67 			  char **cons_names );
68 static void CreateValueWidget ( Widget parent, WNode * node );
69 static void PopupOnNode ( WNode * node, Widget shell );
70 static void FreeClientData ( Widget w, XtPointer ptr, XtPointer junk );
71 static void FreeResBox ( Widget w, XtPointer ptr, XtPointer junk );
72 
73 
74 
75 /*      Function Name: RebuildMenusAndLabel
76  *      Description: Determins if the user has selected an application
77  *                   which uses a different toolkit.  Xt is the default.
78  *                   If this is so, destroys and recreates the menus and
79  *                   information label at the top of the application.
80  *      Arguments: toolkit - name of the toolkit.
81  *      Returns: none.
82  */
83 
84 static Widget box = NULL;
85 static Widget hPane = NULL;
86 
87 #define Offset(index) sizeof(String) * index
88 
89 #define res_entry(index, name, class) \
90   {name, class, XtRString, sizeof(String), \
91      Offset(index), XtRString, (XtPointer)NULL}
92 
93 static XtResource resources[] = {
94   res_entry(0, "label0", "Label0"),
95   res_entry(1, "label1", "Label1"),
96   res_entry(2, "label2", "Label2"),
97   res_entry(3, "label3", "Label3"),
98   res_entry(4, "label4", "Label4"),
99   res_entry(5, "label5", "Label5"),
100   res_entry(6, "label6", "Label6"),
101   res_entry(7, "label7", "Label7"),
102   res_entry(8, "label8", "Label8"),
103   res_entry(9, "label9", "Label9"),
104   res_entry(11, "label11", "Label11"),
105   res_entry(12, "label12", "Label12"),
106   res_entry(13, "label13", "Label13"),
107   res_entry(14, "label14", "Label14"),
108   res_entry(15, "label15", "Label15"),
109   res_entry(16, "label16", "Label16"),
110   res_entry(17, "label17", "Label17"),
111   res_entry(18, "label18", "Label18"),
112   res_entry(19, "label19", "Label19"),
113   res_entry(20, "label20", "Label20"),
114   res_entry(21, "label21", "Label21"),
115   res_entry(22, "label22", "Label22"),
116   res_entry(23, "label23", "Label23"),
117   res_entry(24, "label24", "Label24"),
118   res_entry(25, "label25", "Label25"),
119   res_entry(26, "label26", "Label26"),
120   res_entry(27, "label27", "Label27"),
121   res_entry(28, "label28", "Label28"),
122   res_entry(29, "label29", "Label29"),
123   res_entry(30, "label30", "Label30"),
124   res_entry(31, "label31", "Label31"),
125   res_entry(32, "label32", "Label32"),
126   res_entry(33, "label33", "Label33"),
127   res_entry(34, "label34", "Label34"),
128   res_entry(35, "label35", "Label35"),
129   res_entry(36, "label36", "Label36")
130 };
131 
132 #undef res_entry
133 
134 #undef Offset
135 
136 void
RebuildMenusAndLabel(String toolkit)137 RebuildMenusAndLabel(String toolkit)
138 {
139   if (strcmp(global_effective_toolkit, toolkit)) {
140     CreateCommandMenu(box, toolkit);
141     CreateTreeCommandMenu(box, toolkit);
142     XtDestroyWidget(global_screen_data.info_label);
143     global_screen_data.info_label = XtCreateManagedWidget(toolkit,
144 							  labelWidgetClass,
145 							  hPane, NULL, ZERO);
146     /* get the new toolkit label application resources for info_label */
147     XtGetApplicationResources(global_screen_data.info_label,
148 			      res_labels, resources,
149 			      XtNumber(resources), NULL, 0);
150 
151     global_effective_toolkit = toolkit;
152   }
153 }
154 
155 
156 
157 /*      Function Name: BuildWidgetTree
158  *      Description: Creates all widgets for Editres.
159  *      Arguments: parent - the shell to put them into.
160  *      Returns: none.
161  */
162 
163 void
BuildWidgetTree(Widget parent)164 BuildWidgetTree(Widget parent)
165 {
166     Widget paned, porthole, panner;
167 
168     paned = XtCreateManagedWidget("paned", panedWidgetClass, parent,
169                                   NULL, ZERO);
170 
171     panner = CreateTopArea(paned);
172 
173     porthole = XtCreateManagedWidget("porthole", portholeWidgetClass,
174                                      paned, NULL, ZERO);
175 
176 /*
177  * Allow the panner and porthole to talk to each other.
178  */
179 
180     XtAddCallback(porthole,
181                   XtNreportCallback, PortholeCallback, (XtPointer) panner);
182     XtAddCallback(panner,
183                   XtNreportCallback, PannerCallback, (XtPointer) porthole);
184 
185     global_tree_parent = porthole;
186 }
187 
188 
189 
190 
191 /*	Function Name: CreateTopArea
192  *	Description: Creates the top part of the display
193  *	Arguments: parent - widget to put this menu bar into.
194  *	Returns: none.
195  */
196 
197 
198 static Widget
CreateTopArea(Widget parent)199 CreateTopArea(Widget parent)
200 {
201     Widget panner;
202 
203     box = XtCreateManagedWidget("box", boxWidgetClass, parent, NULL, ZERO);
204 
205     CreateCommandMenu(box, "xt");
206     CreateTreeCommandMenu(box, "xt");
207 
208     hPane = XtCreateManagedWidget("hPane",panedWidgetClass, parent, NULL,ZERO);
209 
210     {
211 	panner = XtCreateManagedWidget("panner", pannerWidgetClass,
212 				       hPane, NULL, ZERO);
213 
214 	global_screen_data.info_label = XtCreateManagedWidget("xt",
215 							     labelWidgetClass,
216 							     hPane, NULL,ZERO);
217 
218 	/* get the "xt label" application resources for info_label */
219 	XtGetApplicationResources(global_screen_data.info_label,
220 				  res_labels, resources,
221 				  XtNumber(resources), NULL, 0);
222 
223     }
224 
225     return(panner);
226 }
227 
228 
229 
230 /*	Function Name: SetEntriesInsensitive
231  *	Description: Make menu entries unusable.
232  *	Arguments: entries - address of widget array.
233  *                 num - number of widgets.
234  *                 sensitive - whether to sensitize or desensitize.
235  *	Returns: none.
236  */
237 void
SetEntriesSensitive(Widget * entries,int num,Boolean sensitive)238 SetEntriesSensitive(Widget *entries, int num, Boolean sensitive)
239 {
240 int i; for (i=0; i<num; i++) XtSetSensitive(entries[i], sensitive);
241 }
242 
243 
244 
245 /*	Function Name: CreateCommandMenu
246  *	Description: Creates the command menu.
247  *	Arguments: parent - widget to put this menu into.
248  *                 toolkit - name given to the SimpleMenu widget.
249  *	Returns: none.
250  */
251 
252 static Widget cmenu = NULL, cbutton = NULL;
253 /* at first most menu entries are insensitive */
254 static Boolean CM_set_insensitive = True;
255 Widget CM_entries[NUM_CM_ENTRIES];
256 
257 static void
CreateCommandMenu(Widget parent,String toolkit)258 CreateCommandMenu(Widget parent, String toolkit)
259 {
260     Arg args[1];
261 
262     if (cmenu) { XtDestroyWidget(cmenu); CM_set_insensitive = False; }
263     else
264       cbutton = XtCreateManagedWidget("commands", menuButtonWidgetClass,
265 				      parent, NULL, ZERO);
266 
267     /* set the menu name to the toolkit name */
268     XtSetArg(args[0], XtNmenuName, toolkit);
269     XtSetValues(cbutton, args, ONE);
270 
271     cmenu = XtCreatePopupShell(toolkit, simpleMenuWidgetClass, cbutton,
272 			       NULL, ZERO);
273 
274     CM_entries[0] = XtCreateManagedWidget("sendTree", smeBSBObjectClass,cmenu,
275 					   NULL, ZERO);
276     XtAddCallback(CM_entries[0], XtNcallback, SendTree, (XtPointer) TRUE);
277 
278     CM_entries[1]=XtCreateManagedWidget("refreshTree",smeBSBObjectClass,cmenu,
279 					 NULL, ZERO);
280     XtAddCallback(CM_entries[1], XtNcallback, SendTree, (XtPointer) FALSE);
281 
282     CM_entries[2] = XtCreateManagedWidget("dumpTreeToFile",
283 					   smeBSBObjectClass,cmenu,
284 					   NULL, ZERO);
285     XtAddCallback(CM_entries[2], XtNcallback, DumpTreeToFile, NULL);
286 
287     CM_entries[3] = XtCreateManagedWidget("line", smeLineObjectClass, cmenu,
288 				  NULL, ZERO);
289     CM_entries[4]= XtCreateManagedWidget("getResourceList",
290 					  smeBSBObjectClass,cmenu,
291 					  NULL, ZERO);
292     XtAddCallback(CM_entries[4], XtNcallback, GetResourceList, NULL);
293 
294     CM_entries[5] = XtCreateManagedWidget("setValues", smeBSBObjectClass,
295 					   cmenu,
296 					   NULL, ZERO);
297     XtAddCallback(CM_entries[5], XtNcallback, InitSetValues, NULL);
298 
299     CM_entries[6] = XtCreateManagedWidget("line", smeLineObjectClass, cmenu,
300 					   NULL, ZERO);
301 
302     CM_entries[7] = XtCreateManagedWidget("quit", smeBSBObjectClass, cmenu,
303 					   NULL, ZERO);
304     XtAddCallback(CM_entries[7], XtNcallback, Quit, NULL);
305 
306     if (CM_set_insensitive)
307       SetEntriesSensitive(&CM_entries[CM_OFFSET], CM_NUM, False);
308 }
309 
310 
311 
312 /*	Function Name: CreateTreeCommandMenu
313  *	Description: Creats the command menu.
314  *	Arguments: parent - widget to put this menu into.
315  *	Returns: none.
316  */
317 
318 #define SELECT 0
319 #define ACTIVATE 1
320 #define LABEL 2
321 #define LINE 3
322 #define FIND 4
323 #define FLASH 5
324 
325 struct tree_ops_menu {
326     char * name;
327     int type;
328     XtPointer data;
329 };
330 
331 static Widget tmenu = NULL, tbutton = NULL;
332 /* at first most menu entries are insensitive */
333 static Boolean TM_set_insensitive = True;
334 Widget TM_entries[NUM_TM_ENTRIES];
335 
336 static void
CreateTreeCommandMenu(Widget parent,String toolkit)337 CreateTreeCommandMenu(Widget parent, String toolkit)
338 {
339     int i, number;
340     static struct tree_ops_menu tree_menu[] = {
341 	{ "showClientWidget", FIND, (XtPointer) NULL },
342         { "selectAll", SELECT, (XtPointer) SelectAll },
343 	{ "unselectAll", SELECT, (XtPointer) SelectNone },
344 	{ "invertAll", SELECT, (XtPointer) SelectInvert },
345 	{ "line", LINE, (XtPointer) NULL },
346 	{ "selectChildren", SELECT, (XtPointer) SelectChildren },
347         { "selectParent", SELECT, (XtPointer) SelectParent },
348 	{ "selectDescendants", SELECT, (XtPointer) SelectDescendants },
349         { "selectAncestors", SELECT, (XtPointer) SelectAncestors },
350         { "line", LINE, (XtPointer) NULL },
351         { "showWidgetNames", LABEL, (XtPointer) NameLabel },
352         { "showClassNames", LABEL, (XtPointer) ClassLabel },
353         { "showWidgetIDs", LABEL, (XtPointer) IDLabel},
354         { "showWidgetWindows", LABEL, (XtPointer) WindowLabel },
355         { "line", LINE, (XtPointer) NULL },
356 	{ "flashActiveWidgets", FLASH, (XtPointer) NULL }
357     };
358     Arg args[1];
359 
360     if (tmenu) { XtDestroyWidget(tmenu); TM_set_insensitive = False; }
361     else
362       tbutton = XtCreateManagedWidget("treeCommands", menuButtonWidgetClass,
363 				      parent, NULL, ZERO);
364 
365     XtSetArg(args[0], XtNmenuName, toolkit);
366     XtSetValues(tbutton, args, ONE);
367 
368     tmenu = XtCreatePopupShell(toolkit, simpleMenuWidgetClass, tbutton,
369 			      NULL, ZERO);
370 
371     for ( i = 0, number = XtNumber(tree_menu) ; i < number ; i++) {
372 	XtCallbackProc func;
373 	WidgetClass class = smeBSBObjectClass;
374 
375 	switch (tree_menu[i].type) {
376 	case SELECT:
377 	    func = TreeSelect;
378 	    break;
379 	case LABEL:
380 	    func = TreeRelabel;
381 	    break;
382 	case LINE:
383 	    func = NULL;
384 	    class = smeLineObjectClass;
385 	    break;
386 	case FIND:
387 	    func = FindWidget;
388 	    break;
389 	case FLASH:
390 	    func = FlashActiveWidgets;
391 	    break;
392 	default:
393 	    continue;
394 	}
395 
396 	TM_entries[i] = XtCreateManagedWidget(tree_menu[i].name, class, tmenu,
397 				      NULL, ZERO);
398 	if (func != NULL)
399 	    XtAddCallback(TM_entries[i], XtNcallback, func,tree_menu[i].data);
400     }
401     if (TM_set_insensitive) SetEntriesSensitive(&TM_entries[TM_OFFSET],
402 						 TM_NUM, False);
403 }
404 
405 
406 
407 static Pixmap old_pixmap;
408 
409 /*	Function Name: PrepareToLayoutTree
410  *	Description: prepares the Tree widget to be layed out.
411  *	Arguments: tree - the Tree widget.
412  *	Returns: none
413  */
414 
415 void
PrepareToLayoutTree(Widget tree)416 PrepareToLayoutTree(Widget tree)
417 {
418     Arg args[1];
419 
420     XtSetArg(args[0], XtNbackgroundPixmap, &old_pixmap);
421     XtGetValues(XtParent(tree), args, ONE);
422 
423     XtSetArg(args[0], XtNbackgroundPixmap, None);
424     XtSetValues(XtParent(tree), args, ONE);
425 
426     XtUnmapWidget(tree);
427 }
428 
429 
430 
431 /*	Function Name: LayoutTree
432  *	Description: Laysout the tree widget.
433  *	Arguments: tree - the widget tree.
434  *	Returns: none.
435  */
436 
437 void
LayoutTree(Widget tree)438 LayoutTree(Widget tree)
439 {
440     Arg args[1];
441 
442     XawTreeForceLayout(tree);
443     XtMapWidget(tree);
444 
445     XtSetArg(args[0], XtNbackgroundPixmap, old_pixmap);
446     XtSetValues(XtParent(tree), args, ONE);
447 }
448 
449 
450 
451 /************************************************************
452  *
453  * Functions for creating the Resource Box.
454  *
455  ************************************************************/
456 
457 /*	Function Name: CreateResourceBoxWidgets
458  *	Description: Creates the widgets that make up the resource box.
459  *	Arguments: node - the widget node.
460  *                 names - the list of names that make up the normal resources.
461  *                 cons_names - the list of names that make up
462  *                              the constraint resources.
463  *	Returns: none.
464  */
465 
466 void
CreateResourceBoxWidgets(WNode * node,char ** names,char ** cons_names)467 CreateResourceBoxWidgets(WNode *node, char **names, char **cons_names)
468 {
469     Widget pane, box, button, viewport, pane_child;
470     ResourceBoxInfo * res_box;
471     Dimension max_width = WidthOfScreen(XtScreen(node->widget)) - 20;
472     Dimension max_height = HeightOfScreen(XtScreen(node->widget)) - 40;
473 
474     res_box = (ResourceBoxInfo *) XtMalloc(sizeof(ResourceBoxInfo));
475     node->resources->res_box = res_box;
476 
477     res_box->shell = XtVaCreatePopupShell(global_effective_toolkit,
478 					  /*RESOURCE_BOX,*/
479 					  transientShellWidgetClass,
480 					  node->widget,
481 					  XtNmaxWidth, max_width,
482 					  XtNmaxHeight, max_height, NULL);
483     XtAddCallback(res_box->shell, XtNdestroyCallback,
484 		  FreeResBox, (XtPointer) node);
485 
486     pane = XtCreateManagedWidget("pane", panedWidgetClass,
487 				 res_box->shell, NULL, ZERO);
488 
489     viewport = XtCreateManagedWidget("mainViewport", viewportWidgetClass,
490 				     pane, NULL, 0);
491     pane_child = XtCreateManagedWidget("pane", panedWidgetClass,
492 				       viewport, NULL, ZERO);
493 
494     res_box->res_label = XtCreateManagedWidget("resourceLabel",
495 					       labelWidgetClass,
496 					       pane_child, NULL, ZERO);
497 
498     CreateResourceNameForm(pane_child, node);
499     CreateLists(pane_child, node, names, cons_names);
500     CreateValueWidget(pane, node);
501 
502     XtSetKeyboardFocus(pane, res_box->value_wid); /* send keyboard to value. */
503 
504     box = XtCreateManagedWidget("commandBox", boxWidgetClass,
505 				 pane, NULL, ZERO);
506 
507     button = XtCreateManagedWidget("setFile", commandWidgetClass,
508 				   box, NULL, ZERO);
509     XtAddCallback(button, XtNcallback, SetFile, NULL);
510 
511     button = XtCreateManagedWidget("save", commandWidgetClass,
512 				   box, NULL, ZERO);
513     XtAddCallback(button, XtNcallback, SaveResource,(XtPointer) res_box);
514 
515     button = XtCreateManagedWidget("apply", commandWidgetClass,
516 				   box, NULL, ZERO);
517     XtAddCallback(button, XtNcallback, ApplyResource,(XtPointer) node);
518 
519     button = XtCreateManagedWidget("saveAndApply", commandWidgetClass,
520 				   box, NULL, ZERO);
521     XtAddCallback(button, XtNcallback, SaveResource,(XtPointer) res_box);
522     XtAddCallback(button, XtNcallback, ApplyResource,(XtPointer) node);
523 
524     button = XtCreateManagedWidget("cancel", commandWidgetClass,
525 				   box, NULL, ZERO);
526     XtAddCallback(button,XtNcallback,PopdownResBox,(XtPointer)res_box->shell);
527 
528     SetToggleGroupLeaders(node);
529     PopupOnNode(node, res_box->shell);
530 }
531 
532 
533 
534 /*	Function Name: CreateResourceNameForm
535  *	Description: Creates the Form widget with children that represent
536  *                   the full resource name for this object.
537  *	Arguments: parent - parent of the form.
538  *                 node - the node corrosponding to this object.
539  *	Returns: none
540  */
541 
542 static void
CreateResourceNameForm(Widget parent,WNode * node)543 CreateResourceNameForm(Widget parent, WNode *node)
544 {
545     ResourceBoxInfo * res_box = node->resources->res_box;
546     AnyInfo *new_info = NULL, *old_info;
547     char **names, **classes;
548     Widget form;
549     NameInfo * name_info = NULL;
550     Cardinal num_args;
551     Arg args[10];
552     int i;
553     Widget dot, star, name, class, single, any;
554 
555     GetNamesAndClasses(node, &names, &classes);
556 
557     form = XtCreateManagedWidget("namesAndClasses", formWidgetClass,
558 				 parent, NULL, ZERO);
559 
560     name = class = any = NULL;
561     i = 0;
562     old_info = NULL;
563     while (TRUE) {
564 
565 	num_args = 0;
566 	XtSetArg(args[num_args], XtNfromHoriz, name); num_args++;
567 	XtSetArg(args[num_args], XtNradioData, "."); num_args++;
568 	dot = XtCreateManagedWidget("dot", toggleWidgetClass,
569 				    form, args, num_args);
570 	XtAddCallback(dot, XtNcallback,
571 		      ActivateWidgetsAndSetResourceString,(XtPointer) node);
572 
573 	num_args = 0;
574 	XtSetArg(args[num_args], XtNfromHoriz, class); num_args++;
575 	XtSetArg(args[num_args], XtNfromVert, dot); num_args++;
576 	XtSetArg(args[num_args], XtNradioGroup, dot); num_args++;
577 	XtSetArg(args[num_args], XtNradioData, "*"); num_args++;
578 	star = XtCreateManagedWidget("star", toggleWidgetClass,
579 				     form, args, num_args);
580 	XtAddCallback(star,XtNcallback,
581 		      ActivateWidgetsAndSetResourceString, (XtPointer) node);
582 
583 	if (name_info != NULL) {
584 	    name_info->next = (NameInfo *) XtMalloc(sizeof(NameInfo));
585 	    name_info = name_info->next;
586 	}
587 	else
588 	    res_box->name_info =
589 		     name_info = (NameInfo *) XtMalloc(sizeof(NameInfo));
590 
591 	name_info->sep_leader = dot;
592 	name_info->name_leader = NULL;
593 
594 	if (names[i] != NULL) {
595 	    new_info = (AnyInfo *) XtMalloc(sizeof(AnyInfo));
596 	    new_info->node = node;
597 	    new_info->left_dot = dot;
598 	    new_info->left_star = star;
599 	    new_info->left_count = 0;
600 	    if (old_info != NULL)
601 		old_info->right_count = &(new_info->left_count);
602 	}
603 	else if (old_info != NULL)
604 	    old_info->right_count = NULL;
605 
606 	if (old_info != NULL) {
607 	    old_info->right_dot = dot;
608 	    old_info->right_star = star;
609 
610 	    XtAddCallback(any, XtNcallback, AnyChosen, (XtPointer) old_info);
611 	    XtAddCallback(any, XtNdestroyCallback,
612 			  FreeClientData, (XtPointer) old_info);
613 	}
614 
615 	if ( names[i] == NULL) /* no more name and class boxes. */
616 	    break;
617 
618 	old_info = new_info;
619 
620 	num_args = 0;
621 	XtSetArg(args[num_args], XtNfromHoriz, dot); num_args++;
622 	XtSetArg(args[num_args], XtNlabel, names[i]); num_args++;
623 	XtSetArg(args[num_args], XtNradioData, names[i]); num_args++;
624 	name = XtCreateManagedWidget("name", toggleWidgetClass,
625 				     form, args, num_args);
626 	XtAddCallback(name,XtNcallback,
627 		      ActivateWidgetsAndSetResourceString,(XtPointer) node);
628 
629 	num_args = 0;
630 	XtSetArg(args[num_args], XtNfromHoriz, star); num_args++;
631 	XtSetArg(args[num_args], XtNfromVert, name); num_args++;
632 	XtSetArg(args[num_args], XtNlabel, classes[i]); num_args++;
633 	XtSetArg(args[num_args], XtNradioGroup, name); num_args++;
634 	XtSetArg(args[num_args], XtNradioData, classes[i]); num_args++;
635 	class = XtCreateManagedWidget("class", toggleWidgetClass,
636 				      form,args,num_args);
637 	XtAddCallback(class, XtNcallback,
638 		      ActivateWidgetsAndSetResourceString,(XtPointer) node);
639 
640 	num_args = 0;
641 	XtSetArg(args[num_args], XtNfromHoriz, star); num_args++;
642 	XtSetArg(args[num_args], XtNfromVert, class); num_args++;
643 	XtSetArg(args[num_args], XtNradioData, "?"); num_args++;
644 	XtSetArg(args[num_args], XtNradioGroup, name); num_args++;
645 	single = XtCreateManagedWidget("single", toggleWidgetClass,
646 				       form, args, num_args);
647 	XtAddCallback(single,XtNcallback,
648 		      ActivateWidgetsAndSetResourceString,(XtPointer) node);
649 
650 	num_args = 0;
651 	XtSetArg(args[num_args], XtNfromHoriz, any); num_args++;
652 	XtSetArg(args[num_args], XtNfromVert, single); num_args++;
653 	XtSetArg(args[num_args], XtNradioGroup, name); num_args++;
654 	XtSetArg(args[num_args], XtNradioData, ANY_RADIO_DATA); num_args++;
655 	any = XtCreateManagedWidget("any", toggleWidgetClass,
656 				    form, args, num_args);
657 
658 	name_info->name_leader = name;
659 
660 	MakeBoxLookNice(dot, star, any, single, name, class,
661 			(i == 0 ? -1 : (names[i + 1] ? 0 : 1)));
662 
663 	i++;
664     }
665 
666     name_info->next = NULL;
667     XtFree((char *)names);		/* Free what you allocate... */
668     XtFree((char *)classes);
669 }
670 
671 
672 
673 /*	Function Name: SetToggleGroupLeaders
674  *	Description: Sets the leaders of each toggle group.
675  *                 node - The widget node containing this res box.
676  *	Returns: none
677  */
678 
679 static void
SetToggleGroupLeaders(WNode * node)680 SetToggleGroupLeaders(WNode *node)
681 {
682     NameInfo *name;
683     ResourceBoxInfo * res_box = node->resources->res_box;
684     static Arg args[] = {
685 	{XtNstate, (XtArgVal) TRUE}
686     };
687 
688     for (name  = res_box->name_info; name != NULL; name = name->next) {
689 	XtSetValues(name->sep_leader, args, XtNumber(args));
690 	if (name->name_leader != NULL)
691 	    XtSetValues(name->name_leader, args, XtNumber(args));
692     }
693     SetResourceString(NULL, (XtPointer) node, NULL);
694 }
695 
696 
697 
698 /*	Function Name: MakeBoxLookNice
699  *	Description: Resizes the box that contains the resource names
700  *                   to look a bit nicer.
701  *	Arguments: dot, star - the widgets containing the separator types.
702  *                 any, single, name, class - the widgets that contain the
703  *                                     name and class of this object.
704  *	Returns: none.
705  */
706 
707 static void
MakeBoxLookNice(Widget dot,Widget star,Widget any,Widget single,Widget name,Widget class,int endbox)708 MakeBoxLookNice(Widget dot, Widget star, Widget any, Widget single,
709 		Widget name, Widget class, int endbox)
710 {
711 
712 #define MAX_HDIST 3
713 
714     Arg args[10];
715     Cardinal num_args;
716     Dimension any_width, name_class_width, dot_star_width;
717     Dimension width_1, width_2;
718     int h_dist[MAX_HDIST];
719     int i;
720 
721     /*
722      * Make sure that the dot and star widgets are the same size.
723      */
724 
725     num_args = 0;
726     XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[0])); num_args++;
727     XtSetArg(args[num_args], XtNwidth, &width_1); num_args++;
728     XtGetValues(dot, args, num_args);
729 
730     num_args = 0;
731     XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[1])); num_args++;
732     XtSetArg(args[num_args], XtNwidth, &width_2); num_args++;
733     XtGetValues(star, args, num_args);
734 
735     num_args = 0;
736     XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[2])); num_args++;
737     XtSetArg(args[num_args], XtNwidth, &any_width); num_args++;
738     XtGetValues(any, args, num_args);
739 
740     dot_star_width = (width_1 > width_2) ? width_1 : width_2;
741     for (i = 1 ; i < MAX_HDIST; i++) {
742 	if (h_dist[i] > h_dist[0]) h_dist[0] = h_dist[i];
743     }
744 
745     num_args = 0;
746     XtSetArg(args[num_args], XtNhorizDistance, h_dist[0]); num_args++;
747     XtSetValues(any, args, num_args);
748 
749     /*
750      * Add a new arg, and continue...
751      */
752     XtSetArg(args[num_args], XtNwidth, dot_star_width); num_args++;
753     XtSetValues(star, args, num_args);
754     XtSetValues(dot, args, num_args);
755 
756 
757     /*
758      * Now make sure that the Any Widget is as wide as the longest
759      * of the name and class widgets, plus space for the dot and star widgets.
760      * Don't forget the Form widget's internal space.
761      */
762 
763     num_args = 0;
764     XtSetArg(args[num_args], XtNwidth, &width_1); num_args++;
765     XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[0])); num_args++;
766     XtGetValues(name, args, num_args);
767 
768     num_args = 0;
769     XtSetArg(args[num_args], XtNwidth, &width_2); num_args++;
770     XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[1])); num_args++;
771     XtGetValues(class, args, num_args);
772 
773     if (width_2 > width_1) width_1 = width_2;
774     if (h_dist[1] > h_dist[0]) h_dist[0] = h_dist[1];
775 
776     num_args = 0;
777     XtSetArg(args[num_args], XtNwidth, &width_2); num_args++;
778     XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[1])); num_args++;
779     XtGetValues(single, args, num_args);
780 
781     name_class_width = (width_1 > width_2) ? width_1 : width_2;
782     if (h_dist[1] > h_dist[0]) h_dist[0] = h_dist[1];
783     if (any_width > name_class_width)
784 	name_class_width = any_width;
785     any_width = dot_star_width + h_dist[0] + name_class_width;
786 
787     num_args = 0;
788     if (endbox < 0) {
789 	any_width -= dot_star_width & 1;
790 	XtSetArg(args[num_args], XtNhorizDistance,
791 		 h_dist[2] + (dot_star_width >> 1) + (dot_star_width & 1));
792 	++num_args;
793     }
794 
795     XtSetArg(args[num_args], XtNwidth, any_width); num_args++;
796     XtSetValues(any, args, num_args);
797 
798     num_args = 0;
799     XtSetArg(args[num_args], XtNwidth, name_class_width); num_args++;
800     XtSetArg(args[num_args], XtNhorizDistance, h_dist[0]); num_args++;
801     XtSetValues(name, args, num_args);
802     XtSetValues(class, args, num_args);
803     XtSetValues(single, args, num_args);
804 }
805 
806 
807 
808 /*	Function Name: CreateLists
809  *	Description: Creates the list widgets for the normal and constraint
810  *                   resources
811  *	Arguments: parent - parent of the lists.
812  *                 node - The widget node containing this res box.
813  *                 names, cons_names - lists for norm and cons resource boxes.
814  *	Returns: none
815  */
816 
817 static char* noneList[] = {"None"};
818 
819 static void
CreateLists(Widget parent,WNode * node,char ** names,char ** cons_names)820 CreateLists(Widget parent, WNode *node, char **names, char **cons_names)
821 {
822     Widget viewport;
823     Cardinal num_args;
824     ResourceBoxInfo * res_box = node->resources->res_box;
825     Arg args[3];
826 
827     (void) XtCreateManagedWidget("namesLabel", labelWidgetClass,
828 				 parent, NULL, ZERO);
829 
830     num_args = 0;
831     /* if the first list item is the widget name we want an empty
832      * list.
833      */
834     if (!names) {
835         XtSetArg(args[num_args], XtNlist, noneList); num_args++;
836         XtSetArg(args[num_args], XtNnumberStrings, 1); num_args++;
837         XtSetArg(args[num_args], XtNsensitive, False); num_args++;
838     }
839     else { XtSetArg(args[num_args], XtNlist, names); num_args++; }
840     viewport = XtCreateManagedWidget("normalViewport", viewportWidgetClass,
841 				     parent, NULL, 0);
842     res_box->norm_list = XtCreateManagedWidget("namesList", listWidgetClass,
843 				      viewport, args, num_args);
844     XtAddCallback(res_box->norm_list, XtNcallback,
845 		  ResourceListCallback, (XtPointer) node);
846     XtAddCallback(res_box->norm_list, XtNdestroyCallback,
847 		  FreeClientData, (XtPointer) names);
848 
849     if (cons_names != NULL) {
850 	(void) XtCreateManagedWidget("constraintLabel", labelWidgetClass,
851 				     parent, NULL, ZERO);
852 
853 	num_args = 0;
854 	XtSetArg(args[num_args], XtNlist, cons_names); num_args++;
855 	viewport = XtCreateManagedWidget("constraintViewport", viewportWidgetClass,
856 					 parent, NULL, 0);
857 	res_box->cons_list = XtCreateManagedWidget("constraintList",
858 						   listWidgetClass,
859 						   viewport, args, num_args);
860 	XtAddCallback(res_box->cons_list, XtNcallback,
861 		      ResourceListCallback, (XtPointer) node);
862 	XtAddCallback(res_box->cons_list, XtNdestroyCallback,
863 		      FreeClientData, (XtPointer) cons_names);
864     }
865     else
866 	res_box->cons_list = NULL;
867 }
868 
869 /*	Function Name: CreateValueWidget
870  *	Description: Creates the value widget for entering the resources value.
871  *	Arguments: parent - parent of this widget.
872  *                 res_box - the resource box info.
873  *	Returns: none.
874  */
875 
876 static void
CreateValueWidget(Widget parent,WNode * node)877 CreateValueWidget(Widget parent, WNode *node)
878 {
879     Widget form, label;
880     Cardinal num_args;
881     Arg args[10];
882     ResourceBoxInfo * res_box = node->resources->res_box;
883 
884     form = XtCreateManagedWidget("valueForm", formWidgetClass,
885 				 parent, NULL, ZERO);
886 
887     num_args = 0;
888     XtSetArg(args[num_args], XtNleft, XawChainLeft); num_args++;
889     XtSetArg(args[num_args], XtNright, XawChainLeft); num_args++;
890     XtSetArg(args[num_args], XtNtop, XawChainTop); num_args++;
891     XtSetArg(args[num_args], XtNbottom, XawChainBottom); num_args++;
892     label = XtCreateManagedWidget("valueLabel", labelWidgetClass,
893 				 form, args, num_args);
894 
895     num_args = 0;
896     XtSetArg(args[num_args], XtNfromHoriz, label); num_args++;
897     XtSetArg(args[num_args], XtNleft, XawChainLeft); num_args++;
898     XtSetArg(args[num_args], XtNright, XawChainRight); num_args++;
899     XtSetArg(args[num_args], XtNtop, XawChainTop); num_args++;
900     XtSetArg(args[num_args], XtNbottom, XawChainBottom); num_args++;
901     res_box->value_wid = XtCreateManagedWidget("valueText",
902 					       asciiTextWidgetClass,
903 					       form, args, num_args);
904 #ifdef notdef
905     XtAddCallback(XawTextGetSource(res_box->value_wid), XtNcallback,
906 		  SetResourceString, (XtPointer) node);
907 #endif
908 }
909 
910 
911 
912 /*	Function Name: PopupOnNode
913  *	Description: Pops a shell widget up centered on the node specified.
914  *	Arguments: node - the node.
915  *                 shell - the shell to popup.
916  *	Returns: none.
917  */
918 
919 static void
PopupOnNode(WNode * node,Widget shell)920 PopupOnNode(WNode *node, Widget shell)
921 {
922     Arg args[3];
923     Cardinal num_args;
924     Position x, y, max_loc;
925     Dimension width, height, bw;
926 
927     num_args = 0;
928     XtSetArg(args[num_args], XtNwidth, &width); num_args++;
929     XtSetArg(args[num_args], XtNheight, &height); num_args++;
930     XtSetArg(args[num_args], XtNborderWidth, &bw); num_args++;
931     XtGetValues(node->widget, args, num_args);
932     XtTranslateCoords(node->widget,
933 		      (Position) (width/2 + bw), (Position) (height/2 + bw),
934 		      &x, &y);
935 
936     XtOverrideTranslations
937       (shell, XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()"));
938     XtRealizeWidget(shell);
939     wm_delete_window = XInternAtom(XtDisplay(shell), "WM_DELETE_WINDOW",
940 				   False);
941     (void) XSetWMProtocols (XtDisplay(shell), XtWindow(shell),
942                             &wm_delete_window, 1);
943     XtGetValues(shell, args, num_args);	/* use same arg_list. */
944 
945     x -= (Position) (width/2 + bw);
946     y -= (Position) (height/2 + bw);
947 
948     max_loc = WidthOfScreen(XtScreen(shell)) - (Position) (width + 2 * bw);
949     if (x > max_loc)
950 	x = max_loc;
951     if (x < 0)
952 	x = 0;
953 
954     max_loc = HeightOfScreen(XtScreen(shell)) - (Position) (height + 2 * bw);
955     if (y > max_loc)
956 	y = max_loc;
957     if (y < 0)
958 	y = 0;
959 
960     num_args = 0;
961     XtSetArg(args[num_args], XtNx, x); num_args++;
962     XtSetArg(args[num_args], XtNy, y); num_args++;
963     XtSetValues(shell, args, num_args);
964 
965     XtPopup(shell, XtGrabNone);
966 }
967 
968 
969 
970 /*	Function Name: FreeClientData
971  *	Description: Frees the client data passed to this function.
972  *	Arguments: w - UNUSED.
973  *                 list_ptr - pointer to the list to check.
974  *                 junk - UNUSED.
975  *	Returns: none
976  */
977 
978 /* ARGSUSED */
979 static void
FreeClientData(Widget w,XtPointer ptr,XtPointer junk)980 FreeClientData(Widget w, XtPointer ptr, XtPointer junk)
981 {
982     XtFree(ptr);
983 }
984 
985 
986 
987 /*	Function Name: FreeResBox.
988  *	Description: Frees resource box allocated memory.
989  *	Arguments: w - UNUSED.
990  *                 ptr - pointer to the node that has this resources box.
991  *                 junk - UNUSED.
992  *	Returns: none
993  */
994 
995 /* ARGSUSED */
996 static void
FreeResBox(Widget w,XtPointer ptr,XtPointer junk)997 FreeResBox(Widget w, XtPointer ptr, XtPointer junk)
998 {
999     WNode * node = (WNode *) ptr;
1000     NameInfo *old_name, *name = node->resources->res_box->name_info;
1001 
1002     global_resource_box_up = FALSE;
1003 
1004     XtFree((XtPointer) node->resources->res_box);
1005     node->resources->res_box = NULL;
1006 
1007     while (name != NULL) {
1008 	old_name = name;
1009 	name = name->next;
1010 	XtFree((XtPointer) old_name);
1011     }
1012 }
1013 
1014 
1015 
1016