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