handler.c revision ad47b356
133c89af1Smrg/*
233c89af1Smrg *
333c89af1SmrgCopyright 1989, 1998  The Open Group
433c89af1Smrg
533c89af1SmrgPermission to use, copy, modify, distribute, and sell this software and its
633c89af1Smrgdocumentation for any purpose is hereby granted without fee, provided that
733c89af1Smrgthe above copyright notice appear in all copies and that both that
833c89af1Smrgcopyright notice and this permission notice appear in supporting
933c89af1Smrgdocumentation.
1033c89af1Smrg
1133c89af1SmrgThe above copyright notice and this permission notice shall be included in
1233c89af1Smrgall copies or substantial portions of the Software.
1333c89af1Smrg
1433c89af1SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1533c89af1SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1633c89af1SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1733c89af1SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1833c89af1SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1933c89af1SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2033c89af1Smrg
2133c89af1SmrgExcept as contained in this notice, the name of The Open Group shall not be
2233c89af1Smrgused in advertising or otherwise to promote the sale, use or other dealings
2333c89af1Smrgin this Software without prior written authorization from The Open Group.
2433c89af1Smrg */
2533c89af1Smrg
2633c89af1Smrg
2733c89af1Smrg#include <X11/Intrinsic.h>
2833c89af1Smrg#include <X11/StringDefs.h>
2933c89af1Smrg
3033c89af1Smrg#include <X11/Xaw/Cardinals.h>
3133c89af1Smrg#include <X11/Xaw/List.h>
3233c89af1Smrg#include <X11/Xaw/Panner.h>
3333c89af1Smrg#include <X11/Xaw/Toggle.h>
3433c89af1Smrg#include <X11/Xfuncs.h>
3533c89af1Smrg#include <X11/Xos.h>		/* for W_OK def */
3633c89af1Smrg
3733c89af1Smrg#include <stdio.h>
3833c89af1Smrg#include <stdlib.h>
3933c89af1Smrg
4033c89af1Smrg#include "editresP.h"
4133c89af1Smrg
42ad47b356Smrg/*
4333c89af1Smrg * Local function definitions.
4433c89af1Smrg */
4533c89af1Smrgstatic char * GetResourceName ( ResourceBoxInfo * res_box );
46ad47b356Smrgstatic void _AppendResourceString ( Widget w, XtPointer res_box_ptr,
4733c89af1Smrg				    XtPointer filename_ptr );
48ad47b356Smrgstatic void _SetResourcesFile ( Widget w, XtPointer junk,
4933c89af1Smrg				XtPointer filename_ptr );
5033c89af1Smrgstatic void ObtainResource ( XtPointer node_ptr );
5133c89af1Smrgstatic void CreateSetValuesCommand ( WNode * node, XtPointer info_ptr );
5233c89af1Smrgstatic void SetOnlyMatchingWidgets ( WNode * node, XtPointer info_ptr );
5333c89af1Smrg
5433c89af1Smrg/*	Function Name: Quit
5533c89af1Smrg *	Description: This function prints a message to stdout.
5633c89af1Smrg *	Arguments: w - ** UNUSED **
5733c89af1Smrg *                 call_data - ** UNUSED **
5833c89af1Smrg *                 client_data - ** UNUSED **
5933c89af1Smrg *	Returns: none
6033c89af1Smrg */
6133c89af1Smrg
6233c89af1Smrg/* ARGSUSED */
6333c89af1Smrgvoid
64278eca22SmrgQuit(Widget w, XtPointer client_data, XtPointer call_data)
6533c89af1Smrg{
6633c89af1Smrg    XtDestroyApplicationContext(XtWidgetToApplicationContext(w));
6733c89af1Smrg    exit(0);
6833c89af1Smrg}
6933c89af1Smrg
7033c89af1Smrg/*	Function Name: SendTree
7133c89af1Smrg *	Description: This function initiates the client communication.
7233c89af1Smrg *                   by getting the resource tree.
7333c89af1Smrg *	Arguments: w - the widget that made the selection.
7433c89af1Smrg *                 value - a boolean value stored as a pointer.
7533c89af1Smrg *                         if True then get a new client, otherwise
7633c89af1Smrg *                         refresh the current client.
7733c89af1Smrg *                 call_data - ** UNUSED **
7833c89af1Smrg *	Returns: none
7933c89af1Smrg */
8033c89af1Smrg
8133c89af1Smrg/* ARGSUSED */
8233c89af1Smrgvoid
83278eca22SmrgSendTree(Widget w, XtPointer value, XtPointer call_data)
8433c89af1Smrg{
8533c89af1Smrg    if ((Boolean)(long) value)
8633c89af1Smrg	global_client.window = None;
8733c89af1Smrg
8833c89af1Smrg    if (!XtIsWidget(w))     /* Make sure that we use a "Real" widget here. */
8933c89af1Smrg	w = XtParent(w);
9033c89af1Smrg
9133c89af1Smrg    _XEditResResetStream(&(global_client.stream)); /* an empty message. */
92ad47b356Smrg
93ad47b356Smrg    SetCommand(w, LocalSendWidgetTree, NULL);
9433c89af1Smrg}
9533c89af1Smrg
9633c89af1Smrg/*	Function Name: FindWidget
9733c89af1Smrg *	Description: Maps a widget in the client to one in the currently
9833c89af1Smrg *                   displayed widget tree.
9933c89af1Smrg *	Arguments: w - the widget that invoked this action.
10033c89af1Smrg *                 call_data, client_data ** UNUSED **
10133c89af1Smrg *	Returns: none
10233c89af1Smrg */
10333c89af1Smrg
10433c89af1Smrg/* ARGSUSED */
10533c89af1Smrgvoid
106278eca22SmrgFindWidget(Widget w, XtPointer client_data, XtPointer call_data)
10733c89af1Smrg{
10833c89af1Smrg
10933c89af1Smrg    _FindWidget(XtParent(w));	/* Use parent since it is a "real"
11033c89af1Smrg				   widget not a rect_obj. */
11133c89af1Smrg}
11233c89af1Smrg
11333c89af1Smrg/*	Function Name: InitSetValues
11433c89af1Smrg *	Description: This function pops up the setvalues dialog
11533c89af1Smrg *	Arguments: w - the widget caused this action.
11633c89af1Smrg *                 call_data - ** UNUSED **
11733c89af1Smrg *                 client_data - ** UNUSED **
11833c89af1Smrg *	Returns: none
11933c89af1Smrg */
12033c89af1Smrg
12133c89af1Smrg/* ARGSUSED */
12233c89af1Smrgvoid
123278eca22SmrgInitSetValues(Widget w, XtPointer client_data, XtPointer call_data)
12433c89af1Smrg{
12533c89af1Smrg    if (!XtIsWidget(w))     /* Make sure that we use a "Real" widget here. */
12633c89af1Smrg	w = XtParent(w);
12733c89af1Smrg
12833c89af1Smrg    PopupSetValues(w, NULL);
12933c89af1Smrg}
13033c89af1Smrg
13133c89af1Smrg/*	Function Name: TreeSelect
13233c89af1Smrg *	Description: Selects all widgets.
13333c89af1Smrg *	Arguments: w - the widget caused this action.
13433c89af1Smrg *                 call_data - ** UNUSED **
13533c89af1Smrg *                 client_data - The type of thing to select.
13633c89af1Smrg *	Returns: none
13733c89af1Smrg */
13833c89af1Smrg
13933c89af1Smrg/* ARGSUSED */
14033c89af1Smrgvoid
141278eca22SmrgTreeSelect(Widget w, XtPointer client_data, XtPointer call_data)
14233c89af1Smrg{
14333c89af1Smrg    SelectTypes type = (SelectTypes) (unsigned long) client_data;
14433c89af1Smrg
14533c89af1Smrg    _TreeSelect(global_tree_info, type);
14633c89af1Smrg}
14733c89af1Smrg
14833c89af1Smrg/*	Function Name: TreeRelabel
14933c89af1Smrg *	Description: Relabels a tree to the type specified.
15033c89af1Smrg *	Arguments: w - the widget caused this action.
15133c89af1Smrg *                 call_data - ** UNUSED **
15233c89af1Smrg *                 client_data - the type of label to assign to each node.
15333c89af1Smrg *	Returns: none
15433c89af1Smrg */
15533c89af1Smrg
15633c89af1Smrg/* ARGSUSED */
15733c89af1Smrgvoid
158278eca22SmrgTreeRelabel(Widget w, XtPointer client_data, XtPointer call_data)
15933c89af1Smrg{
16033c89af1Smrg    LabelTypes type = (LabelTypes) (unsigned long) client_data;
16133c89af1Smrg
16233c89af1Smrg    _TreeRelabel(global_tree_info, type);
16333c89af1Smrg}
16433c89af1Smrg
16533c89af1Smrg/*	Function Name: PannerCallback
16633c89af1Smrg *	Description: called when the panner has moved.
16733c89af1Smrg *	Arguments: panner - the panner widget.
16833c89af1Smrg *                 closure - *** NOT USED ***.
16933c89af1Smrg *                 report_ptr - the panner record.
17033c89af1Smrg *	Returns: none.
17133c89af1Smrg */
17233c89af1Smrg
17333c89af1Smrg/* ARGSUSED */
174ad47b356Smrgvoid
175278eca22SmrgPannerCallback(Widget w, XtPointer closure, XtPointer report_ptr)
17633c89af1Smrg{
17733c89af1Smrg    Arg args[2];
17833c89af1Smrg    XawPannerReport *report = (XawPannerReport *) report_ptr;
17933c89af1Smrg
180ad47b356Smrg    if (global_tree_info == NULL)
18133c89af1Smrg	return;
18233c89af1Smrg
18333c89af1Smrg    XtSetArg (args[0], XtNx, -report->slider_x);
18433c89af1Smrg    XtSetArg (args[1], XtNy, -report->slider_y);
18533c89af1Smrg
18633c89af1Smrg    XtSetValues(global_tree_info->tree_widget, args, TWO);
18733c89af1Smrg}
18833c89af1Smrg
18933c89af1Smrg/*	Function Name: PortholeCallback
19033c89af1Smrg *	Description: called when the porthole or its child has
191ad47b356Smrg *                   changed
19233c89af1Smrg *	Arguments: porthole - the porthole widget.
19333c89af1Smrg *                 panner_ptr - the panner widget.
19433c89af1Smrg *                 report_ptr - the porthole record.
19533c89af1Smrg *	Returns: none.
19633c89af1Smrg */
19733c89af1Smrg
19833c89af1Smrg/* ARGSUSED */
199ad47b356Smrgvoid
200278eca22SmrgPortholeCallback(Widget w, XtPointer panner_ptr, XtPointer report_ptr)
20133c89af1Smrg{
20233c89af1Smrg    Arg args[10];
20333c89af1Smrg    Cardinal n = 0;
20433c89af1Smrg    XawPannerReport *report = (XawPannerReport *) report_ptr;
20533c89af1Smrg    Widget panner = (Widget) panner_ptr;
20633c89af1Smrg
20733c89af1Smrg    XtSetArg (args[n], XtNsliderX, report->slider_x); n++;
20833c89af1Smrg    XtSetArg (args[n], XtNsliderY, report->slider_y); n++;
20933c89af1Smrg    if (report->changed != (XawPRSliderX | XawPRSliderY)) {
21033c89af1Smrg	XtSetArg (args[n], XtNsliderWidth, report->slider_width); n++;
21133c89af1Smrg	XtSetArg (args[n], XtNsliderHeight, report->slider_height); n++;
21233c89af1Smrg	XtSetArg (args[n], XtNcanvasWidth, report->canvas_width); n++;
21333c89af1Smrg	XtSetArg (args[n], XtNcanvasHeight, report->canvas_height); n++;
21433c89af1Smrg    }
21533c89af1Smrg    XtSetValues (panner, args, n);
21633c89af1Smrg}
21733c89af1Smrg
21833c89af1Smrg/*	Function Name: FlashActiveWidgets
21933c89af1Smrg *	Description: called to flass all active widgets in the display.
22033c89af1Smrg *	Arguments: *** NOT USED ***
22133c89af1Smrg *	Returns: none.
22233c89af1Smrg */
22333c89af1Smrg
22433c89af1Smrg/* ARGSUSED */
225ad47b356Smrgvoid
226278eca22SmrgFlashActiveWidgets(Widget w, XtPointer junk, XtPointer garbage)
22733c89af1Smrg{
22833c89af1Smrg    _FlashActiveWidgets(global_tree_info);
22933c89af1Smrg}
23033c89af1Smrg
23133c89af1Smrg/*	Function Name: GetResourceList
23233c89af1Smrg *	Description: Gets the resources lists of all active widgets.
23333c89af1Smrg *	Arguments: ** NOT USED **
23433c89af1Smrg *	Returns: none
23533c89af1Smrg */
23633c89af1Smrg
23733c89af1Smrg/* ARGSUSED */
23833c89af1Smrgvoid
239278eca22SmrgGetResourceList(Widget w, XtPointer junk, XtPointer garbage)
24033c89af1Smrg{
24133c89af1Smrg    WNode * node;
24233c89af1Smrg    ProtocolStream * stream = &(global_client.stream);
24333c89af1Smrg
24433c89af1Smrg    if (global_tree_info == NULL) {
24533c89af1Smrg	SetMessage(global_screen_data.info_label,
24633c89af1Smrg		   res_labels[17]);
24733c89af1Smrg	return;
24833c89af1Smrg    }
24933c89af1Smrg
25033c89af1Smrg    if (global_tree_info->num_nodes != 1) {
25133c89af1Smrg	SetMessage(global_screen_data.info_label,
25233c89af1Smrg	      res_labels[19]);
25333c89af1Smrg	return;
25433c89af1Smrg    }
25533c89af1Smrg
25633c89af1Smrg    node = global_tree_info->active_nodes[0];
25733c89af1Smrg    if (node->resources != NULL) {
25833c89af1Smrg	char * errors = NULL;
25933c89af1Smrg	CreateResourceBox(node, &errors);
26033c89af1Smrg	if (errors != NULL) {
26133c89af1Smrg	    SetMessage(global_screen_data.info_label, errors);
26233c89af1Smrg	    XtFree(errors);
26333c89af1Smrg	}
26433c89af1Smrg	return;
26533c89af1Smrg    }
26633c89af1Smrg
26733c89af1Smrg    /*
26833c89af1Smrg     * No resoruces, fetch them from the client.
26933c89af1Smrg     */
27033c89af1Smrg
271ad47b356Smrg    _XEditResResetStream(stream);
27233c89af1Smrg    _XEditResPut16(stream, (unsigned short) 1);
27333c89af1Smrg    InsertWidgetFromNode(stream, node);
27433c89af1Smrg    SetCommand(global_tree_info->tree_widget, LocalGetResources, NULL);
27533c89af1Smrg}
27633c89af1Smrg
27733c89af1Smrg/*	Function Name: DumpTreeToFile
27833c89af1Smrg *	Description: Dumps all widgets in the tree to a file.
27933c89af1Smrg *	Arguments: w - the widget that activated this callback.
28033c89af1Smrg *                 junk, garbage - ** NOT USED **.
28133c89af1Smrg *	Returns: none.
28233c89af1Smrg */
28333c89af1Smrg
28433c89af1Smrg/* ARGSUSED */
285ad47b356Smrgvoid
286278eca22SmrgDumpTreeToFile(Widget w, XtPointer junk, XtPointer garbage)
28733c89af1Smrg{
28833c89af1Smrg    _PopupFileDialog(XtParent(w), "Enter the filename:", "",
28933c89af1Smrg		     _DumpTreeToFile, (XtPointer) global_tree_info);
29033c89af1Smrg}
29133c89af1Smrg
29233c89af1Smrg/************************************************************
293ad47b356Smrg *
29433c89af1Smrg * Callbacks for the Resource Box.
29533c89af1Smrg *
29633c89af1Smrg ************************************************************/
29733c89af1Smrg
29833c89af1Smrg
29933c89af1Smrg/*	Function Name: AnyChosen
300ad47b356Smrg *	Description: Callback that is called when the "any" widget
30133c89af1Smrg *                   is activated.
30233c89af1Smrg *	Arguments: w - the "any" widget that activated this callback.
303ad47b356Smrg *                 any_info_ptr - pointer to struct containing
30433c89af1Smrg *                                dot and star widgets to lock.
30533c89af1Smrg *                 state_ptr - state of the any toggle.
30633c89af1Smrg *	Returns: none.
30733c89af1Smrg */
30833c89af1Smrg
30933c89af1Smrg/* ARGSUSED */
310ad47b356Smrgvoid
311278eca22SmrgAnyChosen(Widget w, XtPointer any_info_ptr, XtPointer state_ptr)
31233c89af1Smrg{
31333c89af1Smrg    AnyInfo * any_info = (AnyInfo *) any_info_ptr;
31433c89af1Smrg    Boolean state = (Boolean)(long) state_ptr;
31533c89af1Smrg    Arg args[1];
31633c89af1Smrg
31733c89af1Smrg    if (state) {
31833c89af1Smrg
31933c89af1Smrg	if (any_info->left_count == 0) {
32033c89af1Smrg	    XtSetSensitive(any_info->left_dot, FALSE);
32133c89af1Smrg	    XtSetSensitive(any_info->left_star, FALSE);
32233c89af1Smrg
32333c89af1Smrg	    XtSetArg(args[0], XtNstate, TRUE);
32433c89af1Smrg	    XtSetValues(any_info->left_star, args, ONE);
32533c89af1Smrg	}
32633c89af1Smrg
32733c89af1Smrg	if ((any_info->right_count == NULL)||(*any_info->right_count == 0)) {
32833c89af1Smrg	    XtSetSensitive(any_info->right_dot, FALSE);
32933c89af1Smrg	    XtSetSensitive(any_info->right_star, FALSE);
33033c89af1Smrg
33133c89af1Smrg	    XtSetArg(args[0], XtNstate, TRUE);
33233c89af1Smrg	    XtSetValues(any_info->right_star, args, ONE);
33333c89af1Smrg	}
33433c89af1Smrg	any_info->left_count++;
33533c89af1Smrg
33633c89af1Smrg	if (any_info->right_count != NULL)
33733c89af1Smrg	    (*any_info->right_count)++;
33833c89af1Smrg    }
33933c89af1Smrg    else {			/* state == 0 */
340ad47b356Smrg	if (any_info->left_count > 0)
34133c89af1Smrg	    any_info->left_count--;
342ad47b356Smrg	if ((any_info->right_count != NULL)&&(*any_info->right_count > 0))
34333c89af1Smrg	    (*any_info->right_count)--;
34433c89af1Smrg
34533c89af1Smrg	if (any_info->left_count == 0) {
34633c89af1Smrg	    XtSetSensitive(any_info->left_dot, TRUE);
34733c89af1Smrg	    XtSetSensitive(any_info->left_star, TRUE);
34833c89af1Smrg
34933c89af1Smrg	    XtSetArg(args[0], XtNstate, TRUE);
35033c89af1Smrg	    XtSetValues(any_info->left_dot, args, ONE);
35133c89af1Smrg	}
35233c89af1Smrg
35333c89af1Smrg	if ((any_info->right_count == NULL)||(*any_info->right_count == 0)) {
35433c89af1Smrg	    XtSetSensitive(any_info->right_dot, TRUE);
35533c89af1Smrg	    XtSetSensitive(any_info->right_star, TRUE);
35633c89af1Smrg
35733c89af1Smrg	    XtSetArg(args[0], XtNstate, TRUE);
35833c89af1Smrg	    XtSetValues(any_info->right_dot, args, ONE);
35933c89af1Smrg	}
36033c89af1Smrg    }
36133c89af1Smrg    SetResourceString(NULL, (XtPointer) any_info->node, NULL);
36233c89af1Smrg    ActivateResourceWidgets(NULL, (XtPointer) any_info->node, NULL);
36333c89af1Smrg}
36433c89af1Smrg
36533c89af1Smrg/*	Function Name: GetResourceName
36633c89af1Smrg *	Description: Gets the name of the current resource.
36733c89af1Smrg *	Arguments: res_box - the resource box.
36833c89af1Smrg *	Returns: the name of the currently selected resource.
36933c89af1Smrg */
37033c89af1Smrg
37133c89af1Smrg
37233c89af1Smrgstatic char *
373278eca22SmrgGetResourceName(ResourceBoxInfo *res_box)
37433c89af1Smrg{
37533c89af1Smrg    XawListReturnStruct * list_info;
37633c89af1Smrg    char * result;
377ad47b356Smrg
37833c89af1Smrg    list_info = XawListShowCurrent(res_box->norm_list);
379ad47b356Smrg    if ((list_info->list_index == XAW_LIST_NONE) &&
38033c89af1Smrg	(res_box->cons_list != NULL)) {
38133c89af1Smrg	list_info = XawListShowCurrent(res_box->cons_list);
38233c89af1Smrg    }
38333c89af1Smrg
384ad47b356Smrg    if (list_info->list_index == XAW_LIST_NONE)
38533c89af1Smrg	result = "unknown";
38633c89af1Smrg    else
387ad47b356Smrg	result = list_info->string;
38833c89af1Smrg
38933c89af1Smrg    return(result);
39033c89af1Smrg}
39133c89af1Smrg
39233c89af1Smrg
39333c89af1Smrg/*	Function Name: ActivateWidgetsAndSetResourceString
39433c89af1Smrg *	Description: Sets the new resources string, then
39533c89af1Smrg *                   activates all widgets that match this resource,
39633c89af1Smrg *	Arguments: w - the widget that activated this.
39733c89af1Smrg *                 node_ptr - the node that owns this resource box.
39833c89af1Smrg *                 call_data - passed on to other callbacks.
39933c89af1Smrg *	Returns: none.
40033c89af1Smrg *
40133c89af1Smrg * NOTE: I cannot just have two callback routines, since I care which
40233c89af1Smrg *       order that these are executed in, sigh...
40333c89af1Smrg */
40433c89af1Smrg
40533c89af1Smrgvoid
406278eca22SmrgActivateWidgetsAndSetResourceString(Widget w,
407278eca22Smrg				    XtPointer node_ptr, XtPointer call_data)
40833c89af1Smrg{
40933c89af1Smrg    SetResourceString(w, node_ptr, call_data);
41033c89af1Smrg    ActivateResourceWidgets(w, node_ptr, call_data);
41133c89af1Smrg}
41233c89af1Smrg
41333c89af1Smrg/*	Function Name: SetResourceString
41433c89af1Smrg *	Description: Sets the resource label to correspond to the currently
41533c89af1Smrg *                   chosen string.
41633c89af1Smrg *	Arguments: w - The widget that invoked this callback, or NULL.
41733c89af1Smrg *                 node_ptr - pointer to widget node contating this res box.
41833c89af1Smrg *                 call_data - The call data for the action that invoked
41933c89af1Smrg *                             this callback.
42033c89af1Smrg *	Returns: none.
42133c89af1Smrg */
42233c89af1Smrg
42333c89af1Smrgvoid
424278eca22SmrgSetResourceString(Widget w, XtPointer node_ptr, XtPointer junk)
42533c89af1Smrg{
42633c89af1Smrg    static char * malloc_string; /* These are both inited to zero. */
42733c89af1Smrg    static Cardinal malloc_size;
42833c89af1Smrg
42933c89af1Smrg    WNode * node = (WNode *) node_ptr;
43033c89af1Smrg    ResourceBoxInfo * res_box = node->resources->res_box;
43133c89af1Smrg    char * temp, buf[BUFSIZ * 10];	/* here's hoping it's big enough. */
43233c89af1Smrg    NameInfo * name_node = res_box->name_info;
43333c89af1Smrg    Arg args[1];
434ad47b356Smrg    Cardinal len;
43533c89af1Smrg
43633c89af1Smrg    if ((w != NULL) && XtIsSubclass(w, toggleWidgetClass)) {
43733c89af1Smrg	/*
43833c89af1Smrg	 * Only set resources when toggles are activated, not when they are
439ad47b356Smrg	 * deactivated.
44033c89af1Smrg	 */
44133c89af1Smrg	if (!((Boolean)(long) junk))
44233c89af1Smrg	    return;
44333c89af1Smrg    }
44433c89af1Smrg
44533c89af1Smrg    buf[0] = '\0';		/* clear out string. */
44633c89af1Smrg
44733c89af1Smrg    /*
44833c89af1Smrg     * Get the widget name/class info.
44933c89af1Smrg     */
45033c89af1Smrg
45133c89af1Smrg    if ((temp = (char *) XawToggleGetCurrent(name_node->sep_leader)) != NULL)
45233c89af1Smrg	strcat(buf, temp);
45333c89af1Smrg
45433c89af1Smrg    for ( ; name_node->next != NULL ; name_node = name_node->next) {
45533c89af1Smrg	temp = (char *) XawToggleGetCurrent(name_node->name_leader);
45633c89af1Smrg	if ( (temp != NULL) && !streq(temp, ANY_RADIO_DATA) ) {
45733c89af1Smrg	    strcat(buf, temp);
45833c89af1Smrg	    temp = (char *) XawToggleGetCurrent(name_node->next->sep_leader);
459ad47b356Smrg	    if (temp == NULL)
46033c89af1Smrg		strcat(buf, "!");
46133c89af1Smrg	    else
46233c89af1Smrg		strcat(buf, temp);
46333c89af1Smrg	}
46433c89af1Smrg    }
465ad47b356Smrg
46633c89af1Smrg    strcat(buf, GetResourceName(res_box));
46733c89af1Smrg    len = strlen(buf) + 2; /* Leave space for ':' and '\0' */
46833c89af1Smrg
46933c89af1Smrg#ifdef notdef
47033c89af1Smrg    XtSetArg(args[0], XtNstring, &temp);
47133c89af1Smrg    XtGetValues(res_box->value_wid, args, ONE);
47233c89af1Smrg    len += strlen(temp);
47333c89af1Smrg#endif
47433c89af1Smrg
47533c89af1Smrg    if (len > malloc_size) {
47633c89af1Smrg	malloc_string = XtRealloc(malloc_string, sizeof(char) * len);
47733c89af1Smrg	malloc_size = len;
47833c89af1Smrg    }
479ad47b356Smrg
48033c89af1Smrg    strcpy(malloc_string, buf);
48133c89af1Smrg    strcat(malloc_string, ":");
48233c89af1Smrg#ifdef notdef
48333c89af1Smrg    strcat(malloc_string, temp);
48433c89af1Smrg#endif
48533c89af1Smrg
48633c89af1Smrg    XtSetArg(args[0], XtNlabel, malloc_string);
48733c89af1Smrg    XtSetValues(res_box->res_label, args, ONE);
48833c89af1Smrg}
489ad47b356Smrg
49033c89af1Smrg/*	Function Name: ResourceListCallback
491ad47b356Smrg *	Description: Callback functions for the resource lists.  This
49233c89af1Smrg *                   routine is essentialy called by the list widgets
49333c89af1Smrg *                   Notify action.  If action EnableGetVal has been
49433c89af1Smrg *                   invoked,  ResourceListCallback will perform a
49533c89af1Smrg *                   GetValues protocol request.
49633c89af1Smrg *	Arguments: list - the list widget that we are dealing with.
49733c89af1Smrg *                 node_ptr - pointer to widget node contating this res box.
49833c89af1Smrg *                 junk - UNUSED.
49933c89af1Smrg *	Returns: none
50033c89af1Smrg */
50133c89af1Smrg
50233c89af1Smrgextern Boolean do_get_values;
50333c89af1Smrg
50433c89af1Smrgvoid
505278eca22SmrgResourceListCallback(Widget list, XtPointer node_ptr, XtPointer junk)
50633c89af1Smrg{
50733c89af1Smrg    Widget o_list;
50833c89af1Smrg    WNode * node = (WNode *) node_ptr;
50933c89af1Smrg    ResourceBoxInfo * res_box = node->resources->res_box;
51033c89af1Smrg
511ad47b356Smrg    if (list == res_box->norm_list)
51233c89af1Smrg	o_list = res_box->cons_list;
51333c89af1Smrg    else
51433c89af1Smrg	o_list = res_box->norm_list;
51533c89af1Smrg
51633c89af1Smrg    if (o_list != NULL)
51733c89af1Smrg	XawListUnhighlight(o_list);
51833c89af1Smrg
51933c89af1Smrg    SetResourceString(list, node_ptr, junk);
52033c89af1Smrg
52133c89af1Smrg    /* get the resource value from the application */
52233c89af1Smrg    if (global_effective_protocol_version >=
52333c89af1Smrg	PROTOCOL_VERSION_ONE_POINT_ONE && do_get_values) {
52433c89af1Smrg      ObtainResource(node_ptr);
52533c89af1Smrg      do_get_values = False;
52633c89af1Smrg    }
52733c89af1Smrg}
52833c89af1Smrg
52933c89af1Smrg/*	Function Name: PopdownResBox
53033c89af1Smrg *	Description: Pops down the resource box.
53133c89af1Smrg *	Arguments: w - UNUSED
53233c89af1Smrg *                 shell_ptr - pointer to the shell to pop down.
53333c89af1Smrg *                 junk - UNUSED.
53433c89af1Smrg *	Returns: none
53533c89af1Smrg */
53633c89af1Smrg
53733c89af1Smrg/* ARGSUSED */
53833c89af1Smrgvoid
539278eca22SmrgPopdownResBox(Widget w, XtPointer shell_ptr, XtPointer junk)
54033c89af1Smrg{
54133c89af1Smrg    Widget shell = (Widget) shell_ptr;
54233c89af1Smrg
54333c89af1Smrg    XtPopdown(shell);
54433c89af1Smrg    XtDestroyWidget(shell);
54533c89af1Smrg}
54633c89af1Smrg
54733c89af1Smrg/* ARGSUSED */
54833c89af1Smrgstatic void
549278eca22Smrg_AppendResourceString(Widget w, XtPointer res_box_ptr, XtPointer filename_ptr)
55033c89af1Smrg{
55133c89af1Smrg    Arg args[1];
55233c89af1Smrg    FILE * fp;
55333c89af1Smrg    char buf[BUFSIZ], * resource_string, *filename = (char *) filename_ptr;
55433c89af1Smrg    ResourceBoxInfo * res_box = (ResourceBoxInfo *) res_box_ptr;
55533c89af1Smrg    char *value_ptr;
55633c89af1Smrg
55733c89af1Smrg    if (filename != NULL) {
558ad47b356Smrg	if (global_resources.allocated_save_resources_file)
55933c89af1Smrg	    XtFree(global_resources.save_resources_file);
56033c89af1Smrg	else
56133c89af1Smrg	    global_resources.allocated_save_resources_file = TRUE;
562ad47b356Smrg
56333c89af1Smrg	global_resources.save_resources_file = XtNewString(filename);
56433c89af1Smrg    }
56533c89af1Smrg
56633c89af1Smrg    if ((fp = fopen(global_resources.save_resources_file, "a+")) == NULL) {
567ad47b356Smrg	snprintf(buf, sizeof(buf), "%s",
568ad47b356Smrg                 "Unable to open this file for writing, would "
569ad47b356Smrg                 "you like To try again?");
57033c89af1Smrg	_PopupFileDialog(global_toplevel ,buf,
57133c89af1Smrg			global_resources.save_resources_file,
57233c89af1Smrg			_AppendResourceString, res_box_ptr);
57333c89af1Smrg	return;
57433c89af1Smrg    }
57533c89af1Smrg
57633c89af1Smrg    XtSetArg(args[0], XtNlabel, &resource_string);
57733c89af1Smrg    XtGetValues(res_box->res_label, args, ONE);
57833c89af1Smrg
57933c89af1Smrg    XtSetArg(args[0], XtNstring, &value_ptr);
58033c89af1Smrg    XtGetValues(res_box->value_wid, args, ONE);
58133c89af1Smrg
58233c89af1Smrg    fprintf(fp, "%s %s\n", resource_string, value_ptr);
58333c89af1Smrg
58433c89af1Smrg    fclose(fp);
58533c89af1Smrg}
58633c89af1Smrg
58733c89af1Smrg/*	Function Name: SaveResource
58833c89af1Smrg *	Description: Save the current resource to your resource file
58933c89af1Smrg *	Arguments: w - any widget in the application.
59033c89af1Smrg *                 res_box_ptr - the resource box info.
59133c89af1Smrg *                 junk - UNUSED.
59233c89af1Smrg *	Returns: none
59333c89af1Smrg */
59433c89af1Smrg
59533c89af1Smrg/* ARGSUSED */
59633c89af1Smrgvoid
597278eca22SmrgSaveResource(Widget w, XtPointer res_box_ptr, XtPointer junk)
59833c89af1Smrg{
599ad47b356Smrg    /*
60033c89af1Smrg     * If there is no filename the ask for one, otherwise just save to
60133c89af1Smrg     * current file.
60233c89af1Smrg     */
60333c89af1Smrg
60433c89af1Smrg    if (streq(global_resources.save_resources_file, ""))
60533c89af1Smrg	_PopupFileDialog(XtParent(w), "Enter file to dump resources into:",
60633c89af1Smrg			 global_resources.save_resources_file,
60733c89af1Smrg			 _AppendResourceString, res_box_ptr);
60833c89af1Smrg    else
60933c89af1Smrg	_AppendResourceString(w, res_box_ptr, NULL);
61033c89af1Smrg}
61133c89af1Smrg
61233c89af1Smrg/*	Function Name: _SetResourcesFile
61333c89af1Smrg *	Description: Sets the filename of the file to save the resources to.
61433c89af1Smrg *	Arguments: w - UNUSED
61533c89af1Smrg *                 junk - UNUSED
61633c89af1Smrg *                 filename_ptr - a pointer to the filename;
61733c89af1Smrg *	Returns: none
61833c89af1Smrg */
61933c89af1Smrg
62033c89af1Smrg/* ARGSUSED */
62133c89af1Smrgstatic void
622278eca22Smrg_SetResourcesFile(Widget w, XtPointer junk, XtPointer filename_ptr)
62333c89af1Smrg{
62433c89af1Smrg    char *filename = (char *) filename_ptr;
62533c89af1Smrg
626ad47b356Smrg    if (global_resources.allocated_save_resources_file)
62733c89af1Smrg	XtFree(global_resources.save_resources_file);
62833c89af1Smrg    else
62933c89af1Smrg	global_resources.allocated_save_resources_file = TRUE;
63033c89af1Smrg
63133c89af1Smrg    global_resources.save_resources_file = XtNewString(filename);
63233c89af1Smrg}
63333c89af1Smrg
63433c89af1Smrg/*	Function Name: SetFile
63533c89af1Smrg *	Description: Changes the current save file
63633c89af1Smrg *	Arguments: w - UNUSED.
63733c89af1Smrg *                 res_box_ptr - UNUSED.
63833c89af1Smrg *                 junk - UNUSED.
63933c89af1Smrg *	Returns: none
64033c89af1Smrg */
64133c89af1Smrg
64233c89af1Smrg/* ARGSUSED */
64333c89af1Smrgvoid
644278eca22SmrgSetFile(Widget w, XtPointer junk, XtPointer garbage)
64533c89af1Smrg{
646ad47b356Smrg    /*
64733c89af1Smrg     * If there is no filename the ask for one, otherwise just save to
64833c89af1Smrg     * current file.
64933c89af1Smrg     */
65033c89af1Smrg
65133c89af1Smrg    _PopupFileDialog(XtParent(w), "Enter file to dump resources into:",
65233c89af1Smrg		     global_resources.save_resources_file,
65333c89af1Smrg		     _SetResourcesFile, NULL);
65433c89af1Smrg}
65533c89af1Smrg
65633c89af1Smrg/*	Function Name: ApplyResource
65733c89af1Smrg *	Description: Apply the current resource to the running application.
65833c89af1Smrg *	Arguments: w - any widget in the application.
659ad47b356Smrg *                 node_ptr - a pointer to the node containing
66033c89af1Smrg *                            the current resouce box.
66133c89af1Smrg *                 junk - UNUSED.
66233c89af1Smrg *	Returns: none
66333c89af1Smrg */
66433c89af1Smrg
66533c89af1Smrg/* ARGSUSED */
66633c89af1Smrgvoid
667278eca22SmrgApplyResource(Widget w, XtPointer node_ptr, XtPointer junk)
66833c89af1Smrg{
66933c89af1Smrg    ProtocolStream * stream = &(global_client.stream);
67033c89af1Smrg    ApplyResourcesInfo info;
671ad47b356Smrg    WNode * node = (WNode *) node_ptr;
67233c89af1Smrg    char * value;
67333c89af1Smrg    unsigned short size, i;
67433c89af1Smrg    long len;
67533c89af1Smrg    Arg args[1];
67633c89af1Smrg
67733c89af1Smrg    info.name = GetResourceName(node->resources->res_box);
67833c89af1Smrg    info.class = "IGNORE_ME";	/* Not currently used.  */
67933c89af1Smrg    info.stream = stream;
68033c89af1Smrg    info.count = 0;
68133c89af1Smrg
68233c89af1Smrg    XtSetArg(args[0], XtNlabel, &value);
68333c89af1Smrg    XtGetValues(node->resources->res_box->res_label, args, ONE);
68433c89af1Smrg
68533c89af1Smrg    info.database = NULL;
68633c89af1Smrg    XrmPutLineResource(&(info.database), value);
68733c89af1Smrg
68833c89af1Smrg
68933c89af1Smrg    _XEditResResetStream(stream);
69033c89af1Smrg    _XEditResPutString8(stream, info.name); /* Insert name */
69133c89af1Smrg    _XEditResPutString8(stream, XtRString); /* insert type */
69233c89af1Smrg
69333c89af1Smrg    /*
69433c89af1Smrg     * Insert value.
69533c89af1Smrg     */
69633c89af1Smrg
69733c89af1Smrg    value = GetResourceValueForSetValues(node, &size);
698ad47b356Smrg    _XEditResPut16(stream, size);
699ad47b356Smrg    for (i = 0; i < size; i++)
70033c89af1Smrg	_XEditResPut8(stream, value[i]);
70133c89af1Smrg    XtFree(value);
70233c89af1Smrg    len = stream->current - stream->top;
70333c89af1Smrg
704ad47b356Smrg    /*
705ad47b356Smrg     * Insert the widget count, overriden later.
70633c89af1Smrg     */
70733c89af1Smrg
708ad47b356Smrg    _XEditResPut16(stream, 0);
70933c89af1Smrg
71033c89af1Smrg    ExecuteOverAllNodes(node->tree_info->top_node,
71133c89af1Smrg			CreateSetValuesCommand, (XtPointer) &info);
712ad47b356Smrg
71333c89af1Smrg    if (info.count > 0) {
71433c89af1Smrg	*(stream->top + len++) = info.count >> XER_NBBY; /* Set the correct */
71533c89af1Smrg	*(stream->top + len) = info.count;               /* count. */
71633c89af1Smrg
71733c89af1Smrg	SetCommand(node->tree_info->tree_widget, LocalSetValues, NULL);
71833c89af1Smrg    }
719ad47b356Smrg    else
72033c89af1Smrg	SetMessage(global_screen_data.info_label,
72133c89af1Smrg		   res_labels[20]);
722ad47b356Smrg
72333c89af1Smrg    XrmDestroyDatabase(info.database);
72433c89af1Smrg}
72533c89af1Smrg
72633c89af1Smrg/*	Function Name: ObtainResource
72733c89af1Smrg *	Description: Obtain the current resource from the running application.
728ad47b356Smrg *	Arguments: node_ptr - a pointer to the node containing
72933c89af1Smrg *                            the current resouce box.
73033c89af1Smrg *	Returns: none
73133c89af1Smrg */
73233c89af1Smrg
73333c89af1Smrg/* ARGSUSED */
73433c89af1Smrgstatic void
735278eca22SmrgObtainResource(XtPointer node_ptr)
73633c89af1Smrg{
73733c89af1Smrg    ProtocolStream * stream = &(global_client.stream);
73833c89af1Smrg    ObtainResourcesInfo info;
739ad47b356Smrg    WNode * node = (WNode *) node_ptr;
74033c89af1Smrg    char * value;
74133c89af1Smrg    Arg args[1];
74233c89af1Smrg
74333c89af1Smrg    info.name = GetResourceName(node->resources->res_box);
74433c89af1Smrg    info.class = "IGNORE_ME";	/* Not currently used.  */
74533c89af1Smrg    info.stream = stream;
74633c89af1Smrg    info.count = 1;
74733c89af1Smrg
74833c89af1Smrg    XtSetArg(args[0], XtNlabel, &value);
74933c89af1Smrg    XtGetValues(node->resources->res_box->res_label, args, ONE);
75033c89af1Smrg
75133c89af1Smrg    info.database = NULL;
75233c89af1Smrg    XrmPutLineResource(&(info.database), value);
75333c89af1Smrg
75433c89af1Smrg    _XEditResResetStream(stream);
75533c89af1Smrg    _XEditResPutString8(stream, info.name); /* insert name */
75633c89af1Smrg
757ad47b356Smrg    /*
75833c89af1Smrg     * Insert the widget count, always 1
75933c89af1Smrg     */
76033c89af1Smrg
761ad47b356Smrg    _XEditResPut16(stream, 1);
76233c89af1Smrg
76333c89af1Smrg    /*CreateGetValuesCommand(node, (XtPointer)&info);  Inserts widget */
76433c89af1Smrg
76533c89af1Smrg    /* Insert widget */
76633c89af1Smrg    InsertWidgetFromNode(stream, node);
76733c89af1Smrg
76833c89af1Smrg    SetCommand(node->tree_info->tree_widget, LocalGetValues, NULL);
76933c89af1Smrg}
77033c89af1Smrg
77133c89af1Smrg/*	Function Name: CreateSetValuesCommand
77233c89af1Smrg *	Description: Creates the SetValues command if this widget
77333c89af1Smrg *                   matches the resource string in the database.
77433c89af1Smrg *	Arguments: node - the current node.
77533c89af1Smrg *                 info_ptr - the pointer to the apply info.
77633c89af1Smrg *	Returns: none
77733c89af1Smrg */
77833c89af1Smrg
77933c89af1Smrgstatic void
780278eca22SmrgCreateSetValuesCommand(WNode *node, XtPointer info_ptr)
78133c89af1Smrg{
78233c89af1Smrg    ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
78333c89af1Smrg    XrmNameList name_quarks;
78433c89af1Smrg    XrmClassList class_quarks;
78533c89af1Smrg    char ** names, **classes;
78633c89af1Smrg
78733c89af1Smrg    GetNamesAndClasses(node, &names, &classes);
78833c89af1Smrg    name_quarks = (XrmNameList) Quarkify(names, info->name);
78933c89af1Smrg    class_quarks = (XrmNameList) Quarkify(classes, info->class);
79033c89af1Smrg
79133c89af1Smrg    if (CheckDatabase(info->database, name_quarks, class_quarks)) {
79233c89af1Smrg	InsertWidgetFromNode(info->stream, node);
79333c89af1Smrg	info->count++;
79433c89af1Smrg    }
79533c89af1Smrg
79633c89af1Smrg    XtFree((char *)names);
79733c89af1Smrg    XtFree((char *)classes);
79833c89af1Smrg    XtFree((char *)name_quarks);
79933c89af1Smrg    XtFree((char *)class_quarks);
80033c89af1Smrg}
80133c89af1Smrg
80233c89af1Smrg/*	Function Name: CreateGetValuesCommand
80333c89af1Smrg *	Description: Creates the GetValues command.
80433c89af1Smrg *	Arguments: node - the current node.
80533c89af1Smrg *                 info_ptr - the pointer to the apply info.
80633c89af1Smrg *	Returns: none
80733c89af1Smrg */
80833c89af1Smrg
80933c89af1Smrg/*****
81033c89af1Smrg
81133c89af1Smrgstatic void
812278eca22SmrgCreateGetValuesCommand(WNode *node, XtPointer info_ptr)
81333c89af1Smrg{
81433c89af1Smrg    ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
81533c89af1Smrg    XrmNameList name_quarks;
81633c89af1Smrg    XrmClassList class_quarks;
81733c89af1Smrg    char ** names, **classes;
81833c89af1Smrg
81933c89af1Smrg    GetNamesAndClasses(node, &names, &classes);
82033c89af1Smrg    name_quarks = (XrmNameList) Quarkify(names, info->name);
82133c89af1Smrg    class_quarks = (XrmNameList) Quarkify(classes, info->class);
82233c89af1Smrg
82333c89af1Smrg    if (CheckDatabase(info->database, name_quarks, class_quarks)) {
82433c89af1Smrg	InsertWidgetFromNode(info->stream, node);
82533c89af1Smrg	info->count++;
82633c89af1Smrg    }
82733c89af1Smrg
82833c89af1Smrg    XtFree((char *)names);
82933c89af1Smrg    XtFree((char *)classes);
83033c89af1Smrg    XtFree((char *)name_quarks);
83133c89af1Smrg    XtFree((char *)class_quarks);
83233c89af1Smrg}
83333c89af1Smrg
83433c89af1Smrg*****/
83533c89af1Smrg
83633c89af1Smrg/*	Function Name: ActivateResourceWidgets
83733c89af1Smrg *	Description: Activates all widgets that match this resource.
83833c89af1Smrg *	Arguments: w - UNUSED.
83933c89af1Smrg *                 node_ptr - the node that owns this resource box.
840ad47b356Smrg *                 junk - UNUSED.
84133c89af1Smrg *	Returns: none.
84233c89af1Smrg */
84333c89af1Smrg
84433c89af1Smrg/* ARGSUSED */
84533c89af1Smrgvoid
846278eca22SmrgActivateResourceWidgets(Widget w, XtPointer node_ptr, XtPointer junk)
84733c89af1Smrg{
848ad47b356Smrg    WNode * node = (WNode *) node_ptr;
84933c89af1Smrg    ApplyResourcesInfo info;
85033c89af1Smrg    char * line;
85133c89af1Smrg    Arg args[1];
85233c89af1Smrg
85333c89af1Smrg    info.name = GetResourceName(node->resources->res_box);
85433c89af1Smrg    info.class = "IGNORE_ME";	/* Not currently used.  */
85533c89af1Smrg
856ad47b356Smrg    /*
85733c89af1Smrg     * Unused fields.
85833c89af1Smrg     */
85933c89af1Smrg
86033c89af1Smrg    info.count = 0;
86133c89af1Smrg    info.stream = NULL;
86233c89af1Smrg
86333c89af1Smrg    XtSetArg(args[0], XtNlabel, &line);
86433c89af1Smrg    XtGetValues(node->resources->res_box->res_label, args, ONE);
86533c89af1Smrg
86633c89af1Smrg    info.database = NULL;
86733c89af1Smrg    XrmPutLineResource(&(info.database), line);
86833c89af1Smrg
86933c89af1Smrg
87033c89af1Smrg    ExecuteOverAllNodes(node->tree_info->top_node,
87133c89af1Smrg			SetOnlyMatchingWidgets, (XtPointer) &info);
872ad47b356Smrg
87333c89af1Smrg    XrmDestroyDatabase(info.database);
87433c89af1Smrg}
87533c89af1Smrg
87633c89af1Smrg/*	Function Name: SetOnlyMatchingWidgets
87733c89af1Smrg *	Description: Activates all widgets in the tree that match this
87833c89af1Smrg *                   resource specifiction.
87933c89af1Smrg *	Arguments: node - the current node.
88033c89af1Smrg *                 info_ptr - the pointer to the apply info.
88133c89af1Smrg *	Returns: none
88233c89af1Smrg */
88333c89af1Smrg
88433c89af1Smrgstatic void
885278eca22SmrgSetOnlyMatchingWidgets(WNode *node, XtPointer info_ptr)
88633c89af1Smrg{
88733c89af1Smrg    ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
88833c89af1Smrg    XrmNameList name_quarks;
88933c89af1Smrg    XrmClassList class_quarks;
89033c89af1Smrg    char ** names, **classes;
89133c89af1Smrg    Boolean state;
89233c89af1Smrg    Arg args[1];
89333c89af1Smrg
89433c89af1Smrg    GetNamesAndClasses(node, &names, &classes);
89533c89af1Smrg    name_quarks = (XrmNameList) Quarkify(names, info->name);
89633c89af1Smrg    class_quarks = (XrmNameList) Quarkify(classes, info->class);
89733c89af1Smrg
89833c89af1Smrg    state = CheckDatabase(info->database, name_quarks, class_quarks);
89933c89af1Smrg
90033c89af1Smrg    XtSetArg(args[0], XtNstate, state);
90133c89af1Smrg    XtSetValues(node->widget, args, ONE);
90233c89af1Smrg    TreeToggle(node->widget, (XtPointer) node, (XtPointer)(long) state);
90333c89af1Smrg
90433c89af1Smrg    XtFree((char *)names);
90533c89af1Smrg    XtFree((char *)classes);
90633c89af1Smrg    XtFree((char *)name_quarks);
90733c89af1Smrg    XtFree((char *)class_quarks);
90833c89af1Smrg}
909