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