widgets.c revision ad47b356
1/*
2 *
3Copyright 1989, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in 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
58static Widget CreateTopArea ( Widget parent );
59static void CreateCommandMenu ( Widget parent, String toolkit );
60static void CreateTreeCommandMenu ( Widget parent, String toolkit );
61static void CreateResourceNameForm ( Widget parent, WNode * node );
62static void SetToggleGroupLeaders ( WNode * node );
63static void MakeBoxLookNice ( Widget dot, Widget star, Widget any,
64			      Widget single, Widget name, Widget class,
65			      int endbox );
66static void CreateLists ( Widget parent, WNode * node, char **names,
67			  char **cons_names );
68static void CreateValueWidget ( Widget parent, WNode * node );
69static void PopupOnNode ( WNode * node, Widget shell );
70static void FreeClientData ( Widget w, XtPointer ptr, XtPointer junk );
71static 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
84static Widget box = NULL;
85static 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
93static 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
136void
137RebuildMenusAndLabel(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
163void
164BuildWidgetTree(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
198static Widget
199CreateTopArea(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 */
237void
238SetEntriesSensitive(Widget *entries, int num, Boolean sensitive)
239{
240int 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
252static Widget cmenu = NULL, cbutton = NULL;
253/* at first most menu entries are insensitive */
254static Boolean CM_set_insensitive = True;
255Widget CM_entries[NUM_CM_ENTRIES];
256
257static void
258CreateCommandMenu(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
325struct tree_ops_menu {
326    char * name;
327    int type;
328    XtPointer data;
329};
330
331static Widget tmenu = NULL, tbutton = NULL;
332/* at first most menu entries are insensitive */
333static Boolean TM_set_insensitive = True;
334Widget TM_entries[NUM_TM_ENTRIES];
335
336static void
337CreateTreeCommandMenu(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
407static 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
415void
416PrepareToLayoutTree(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
437void
438LayoutTree(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
466void
467CreateResourceBoxWidgets(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
542static void
543CreateResourceNameForm(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
679static void
680SetToggleGroupLeaders(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
707static void
708MakeBoxLookNice(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
817static char* noneList[] = {"None"};
818
819static void
820CreateLists(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
876static void
877CreateValueWidget(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
919static void
920PopupOnNode(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 */
979static void
980FreeClientData(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 */
996static void
997FreeResBox(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