handler.c revision 352bf44e
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 */
45352bf44eSmrgstatic String 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
219352bf44eSmrg *	Description: called to flash 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    /*
268352bf44eSmrg     * No resources, 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
372352bf44eSmrgstatic String
373278eca22SmrgGetResourceName(ResourceBoxInfo *res_box)
37433c89af1Smrg{
37533c89af1Smrg    XawListReturnStruct * list_info;
376352bf44eSmrg    String 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.
417352bf44eSmrg *                 node_ptr - pointer to widget node containing 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
492352bf44eSmrg *                   routine is essentially 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.
497352bf44eSmrg *                 node_ptr - pointer to widget node containing this res box.
49833c89af1Smrg *                 junk - UNUSED.
49933c89af1Smrg *	Returns: none
50033c89af1Smrg */
50133c89af1Smrg
50233c89af1Smrgvoid
503278eca22SmrgResourceListCallback(Widget list, XtPointer node_ptr, XtPointer junk)
50433c89af1Smrg{
50533c89af1Smrg    Widget o_list;
50633c89af1Smrg    WNode * node = (WNode *) node_ptr;
50733c89af1Smrg    ResourceBoxInfo * res_box = node->resources->res_box;
50833c89af1Smrg
509ad47b356Smrg    if (list == res_box->norm_list)
51033c89af1Smrg	o_list = res_box->cons_list;
51133c89af1Smrg    else
51233c89af1Smrg	o_list = res_box->norm_list;
51333c89af1Smrg
51433c89af1Smrg    if (o_list != NULL)
51533c89af1Smrg	XawListUnhighlight(o_list);
51633c89af1Smrg
51733c89af1Smrg    SetResourceString(list, node_ptr, junk);
51833c89af1Smrg
51933c89af1Smrg    /* get the resource value from the application */
52033c89af1Smrg    if (global_effective_protocol_version >=
52133c89af1Smrg	PROTOCOL_VERSION_ONE_POINT_ONE && do_get_values) {
52233c89af1Smrg      ObtainResource(node_ptr);
52333c89af1Smrg      do_get_values = False;
52433c89af1Smrg    }
52533c89af1Smrg}
52633c89af1Smrg
52733c89af1Smrg/*	Function Name: PopdownResBox
52833c89af1Smrg *	Description: Pops down the resource box.
52933c89af1Smrg *	Arguments: w - UNUSED
53033c89af1Smrg *                 shell_ptr - pointer to the shell to pop down.
53133c89af1Smrg *                 junk - UNUSED.
53233c89af1Smrg *	Returns: none
53333c89af1Smrg */
53433c89af1Smrg
53533c89af1Smrg/* ARGSUSED */
53633c89af1Smrgvoid
537278eca22SmrgPopdownResBox(Widget w, XtPointer shell_ptr, XtPointer junk)
53833c89af1Smrg{
53933c89af1Smrg    Widget shell = (Widget) shell_ptr;
54033c89af1Smrg
54133c89af1Smrg    XtPopdown(shell);
54233c89af1Smrg    XtDestroyWidget(shell);
54333c89af1Smrg}
54433c89af1Smrg
54533c89af1Smrg/* ARGSUSED */
54633c89af1Smrgstatic void
547278eca22Smrg_AppendResourceString(Widget w, XtPointer res_box_ptr, XtPointer filename_ptr)
54833c89af1Smrg{
54933c89af1Smrg    Arg args[1];
55033c89af1Smrg    FILE * fp;
55133c89af1Smrg    char buf[BUFSIZ], * resource_string, *filename = (char *) filename_ptr;
55233c89af1Smrg    ResourceBoxInfo * res_box = (ResourceBoxInfo *) res_box_ptr;
55333c89af1Smrg    char *value_ptr;
55433c89af1Smrg
55533c89af1Smrg    if (filename != NULL) {
556ad47b356Smrg	if (global_resources.allocated_save_resources_file)
55733c89af1Smrg	    XtFree(global_resources.save_resources_file);
55833c89af1Smrg	else
55933c89af1Smrg	    global_resources.allocated_save_resources_file = TRUE;
560ad47b356Smrg
56133c89af1Smrg	global_resources.save_resources_file = XtNewString(filename);
56233c89af1Smrg    }
56333c89af1Smrg
56433c89af1Smrg    if ((fp = fopen(global_resources.save_resources_file, "a+")) == NULL) {
565ad47b356Smrg	snprintf(buf, sizeof(buf), "%s",
566ad47b356Smrg                 "Unable to open this file for writing, would "
567ad47b356Smrg                 "you like To try again?");
56833c89af1Smrg	_PopupFileDialog(global_toplevel ,buf,
56933c89af1Smrg			global_resources.save_resources_file,
57033c89af1Smrg			_AppendResourceString, res_box_ptr);
57133c89af1Smrg	return;
57233c89af1Smrg    }
57333c89af1Smrg
57433c89af1Smrg    XtSetArg(args[0], XtNlabel, &resource_string);
57533c89af1Smrg    XtGetValues(res_box->res_label, args, ONE);
57633c89af1Smrg
57733c89af1Smrg    XtSetArg(args[0], XtNstring, &value_ptr);
57833c89af1Smrg    XtGetValues(res_box->value_wid, args, ONE);
57933c89af1Smrg
58033c89af1Smrg    fprintf(fp, "%s %s\n", resource_string, value_ptr);
58133c89af1Smrg
58233c89af1Smrg    fclose(fp);
58333c89af1Smrg}
58433c89af1Smrg
58533c89af1Smrg/*	Function Name: SaveResource
58633c89af1Smrg *	Description: Save the current resource to your resource file
58733c89af1Smrg *	Arguments: w - any widget in the application.
58833c89af1Smrg *                 res_box_ptr - the resource box info.
58933c89af1Smrg *                 junk - UNUSED.
59033c89af1Smrg *	Returns: none
59133c89af1Smrg */
59233c89af1Smrg
59333c89af1Smrg/* ARGSUSED */
59433c89af1Smrgvoid
595278eca22SmrgSaveResource(Widget w, XtPointer res_box_ptr, XtPointer junk)
59633c89af1Smrg{
597ad47b356Smrg    /*
59833c89af1Smrg     * If there is no filename the ask for one, otherwise just save to
59933c89af1Smrg     * current file.
60033c89af1Smrg     */
60133c89af1Smrg
60233c89af1Smrg    if (streq(global_resources.save_resources_file, ""))
60333c89af1Smrg	_PopupFileDialog(XtParent(w), "Enter file to dump resources into:",
60433c89af1Smrg			 global_resources.save_resources_file,
60533c89af1Smrg			 _AppendResourceString, res_box_ptr);
60633c89af1Smrg    else
60733c89af1Smrg	_AppendResourceString(w, res_box_ptr, NULL);
60833c89af1Smrg}
60933c89af1Smrg
61033c89af1Smrg/*	Function Name: _SetResourcesFile
61133c89af1Smrg *	Description: Sets the filename of the file to save the resources to.
61233c89af1Smrg *	Arguments: w - UNUSED
61333c89af1Smrg *                 junk - UNUSED
61433c89af1Smrg *                 filename_ptr - a pointer to the filename;
61533c89af1Smrg *	Returns: none
61633c89af1Smrg */
61733c89af1Smrg
61833c89af1Smrg/* ARGSUSED */
61933c89af1Smrgstatic void
620278eca22Smrg_SetResourcesFile(Widget w, XtPointer junk, XtPointer filename_ptr)
62133c89af1Smrg{
62233c89af1Smrg    char *filename = (char *) filename_ptr;
62333c89af1Smrg
624ad47b356Smrg    if (global_resources.allocated_save_resources_file)
62533c89af1Smrg	XtFree(global_resources.save_resources_file);
62633c89af1Smrg    else
62733c89af1Smrg	global_resources.allocated_save_resources_file = TRUE;
62833c89af1Smrg
62933c89af1Smrg    global_resources.save_resources_file = XtNewString(filename);
63033c89af1Smrg}
63133c89af1Smrg
63233c89af1Smrg/*	Function Name: SetFile
63333c89af1Smrg *	Description: Changes the current save file
63433c89af1Smrg *	Arguments: w - UNUSED.
63533c89af1Smrg *                 res_box_ptr - UNUSED.
63633c89af1Smrg *                 junk - UNUSED.
63733c89af1Smrg *	Returns: none
63833c89af1Smrg */
63933c89af1Smrg
64033c89af1Smrg/* ARGSUSED */
64133c89af1Smrgvoid
642278eca22SmrgSetFile(Widget w, XtPointer junk, XtPointer garbage)
64333c89af1Smrg{
644ad47b356Smrg    /*
64533c89af1Smrg     * If there is no filename the ask for one, otherwise just save to
64633c89af1Smrg     * current file.
64733c89af1Smrg     */
64833c89af1Smrg
64933c89af1Smrg    _PopupFileDialog(XtParent(w), "Enter file to dump resources into:",
65033c89af1Smrg		     global_resources.save_resources_file,
65133c89af1Smrg		     _SetResourcesFile, NULL);
65233c89af1Smrg}
65333c89af1Smrg
65433c89af1Smrg/*	Function Name: ApplyResource
65533c89af1Smrg *	Description: Apply the current resource to the running application.
65633c89af1Smrg *	Arguments: w - any widget in the application.
657ad47b356Smrg *                 node_ptr - a pointer to the node containing
658352bf44eSmrg *                            the current resource box.
65933c89af1Smrg *                 junk - UNUSED.
66033c89af1Smrg *	Returns: none
66133c89af1Smrg */
66233c89af1Smrg
66333c89af1Smrg/* ARGSUSED */
66433c89af1Smrgvoid
665278eca22SmrgApplyResource(Widget w, XtPointer node_ptr, XtPointer junk)
66633c89af1Smrg{
66733c89af1Smrg    ProtocolStream * stream = &(global_client.stream);
66833c89af1Smrg    ApplyResourcesInfo info;
669ad47b356Smrg    WNode * node = (WNode *) node_ptr;
67033c89af1Smrg    char * value;
67133c89af1Smrg    unsigned short size, i;
67233c89af1Smrg    long len;
67333c89af1Smrg    Arg args[1];
67433c89af1Smrg
67533c89af1Smrg    info.name = GetResourceName(node->resources->res_box);
67633c89af1Smrg    info.class = "IGNORE_ME";	/* Not currently used.  */
67733c89af1Smrg    info.stream = stream;
67833c89af1Smrg    info.count = 0;
67933c89af1Smrg
68033c89af1Smrg    XtSetArg(args[0], XtNlabel, &value);
68133c89af1Smrg    XtGetValues(node->resources->res_box->res_label, args, ONE);
68233c89af1Smrg
68333c89af1Smrg    info.database = NULL;
68433c89af1Smrg    XrmPutLineResource(&(info.database), value);
68533c89af1Smrg
68633c89af1Smrg
68733c89af1Smrg    _XEditResResetStream(stream);
68833c89af1Smrg    _XEditResPutString8(stream, info.name); /* Insert name */
68933c89af1Smrg    _XEditResPutString8(stream, XtRString); /* insert type */
69033c89af1Smrg
69133c89af1Smrg    /*
69233c89af1Smrg     * Insert value.
69333c89af1Smrg     */
69433c89af1Smrg
69533c89af1Smrg    value = GetResourceValueForSetValues(node, &size);
696ad47b356Smrg    _XEditResPut16(stream, size);
697ad47b356Smrg    for (i = 0; i < size; i++)
69833c89af1Smrg	_XEditResPut8(stream, value[i]);
69933c89af1Smrg    XtFree(value);
70033c89af1Smrg    len = stream->current - stream->top;
70133c89af1Smrg
702ad47b356Smrg    /*
703352bf44eSmrg     * Insert the widget count, overridden later.
70433c89af1Smrg     */
70533c89af1Smrg
706ad47b356Smrg    _XEditResPut16(stream, 0);
70733c89af1Smrg
70833c89af1Smrg    ExecuteOverAllNodes(node->tree_info->top_node,
70933c89af1Smrg			CreateSetValuesCommand, (XtPointer) &info);
710ad47b356Smrg
71133c89af1Smrg    if (info.count > 0) {
71233c89af1Smrg	*(stream->top + len++) = info.count >> XER_NBBY; /* Set the correct */
71333c89af1Smrg	*(stream->top + len) = info.count;               /* count. */
71433c89af1Smrg
71533c89af1Smrg	SetCommand(node->tree_info->tree_widget, LocalSetValues, NULL);
71633c89af1Smrg    }
717ad47b356Smrg    else
71833c89af1Smrg	SetMessage(global_screen_data.info_label,
71933c89af1Smrg		   res_labels[20]);
720ad47b356Smrg
72133c89af1Smrg    XrmDestroyDatabase(info.database);
72233c89af1Smrg}
72333c89af1Smrg
72433c89af1Smrg/*	Function Name: ObtainResource
72533c89af1Smrg *	Description: Obtain the current resource from the running application.
726ad47b356Smrg *	Arguments: node_ptr - a pointer to the node containing
727352bf44eSmrg *                            the current resource box.
72833c89af1Smrg *	Returns: none
72933c89af1Smrg */
73033c89af1Smrg
73133c89af1Smrg/* ARGSUSED */
73233c89af1Smrgstatic void
733278eca22SmrgObtainResource(XtPointer node_ptr)
73433c89af1Smrg{
73533c89af1Smrg    ProtocolStream * stream = &(global_client.stream);
73633c89af1Smrg    ObtainResourcesInfo info;
737ad47b356Smrg    WNode * node = (WNode *) node_ptr;
73833c89af1Smrg    char * value;
73933c89af1Smrg    Arg args[1];
74033c89af1Smrg
74133c89af1Smrg    info.name = GetResourceName(node->resources->res_box);
74233c89af1Smrg    info.class = "IGNORE_ME";	/* Not currently used.  */
74333c89af1Smrg    info.stream = stream;
74433c89af1Smrg    info.count = 1;
74533c89af1Smrg
74633c89af1Smrg    XtSetArg(args[0], XtNlabel, &value);
74733c89af1Smrg    XtGetValues(node->resources->res_box->res_label, args, ONE);
74833c89af1Smrg
74933c89af1Smrg    info.database = NULL;
75033c89af1Smrg    XrmPutLineResource(&(info.database), value);
75133c89af1Smrg
75233c89af1Smrg    _XEditResResetStream(stream);
75333c89af1Smrg    _XEditResPutString8(stream, info.name); /* insert name */
75433c89af1Smrg
755ad47b356Smrg    /*
75633c89af1Smrg     * Insert the widget count, always 1
75733c89af1Smrg     */
75833c89af1Smrg
759ad47b356Smrg    _XEditResPut16(stream, 1);
76033c89af1Smrg
76133c89af1Smrg    /*CreateGetValuesCommand(node, (XtPointer)&info);  Inserts widget */
76233c89af1Smrg
76333c89af1Smrg    /* Insert widget */
76433c89af1Smrg    InsertWidgetFromNode(stream, node);
76533c89af1Smrg
76633c89af1Smrg    SetCommand(node->tree_info->tree_widget, LocalGetValues, NULL);
76733c89af1Smrg}
76833c89af1Smrg
76933c89af1Smrg/*	Function Name: CreateSetValuesCommand
77033c89af1Smrg *	Description: Creates the SetValues command if this widget
77133c89af1Smrg *                   matches the resource string in the database.
77233c89af1Smrg *	Arguments: node - the current node.
77333c89af1Smrg *                 info_ptr - the pointer to the apply info.
77433c89af1Smrg *	Returns: none
77533c89af1Smrg */
77633c89af1Smrg
77733c89af1Smrgstatic void
778278eca22SmrgCreateSetValuesCommand(WNode *node, XtPointer info_ptr)
77933c89af1Smrg{
78033c89af1Smrg    ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
78133c89af1Smrg    XrmNameList name_quarks;
78233c89af1Smrg    XrmClassList class_quarks;
78333c89af1Smrg    char ** names, **classes;
78433c89af1Smrg
78533c89af1Smrg    GetNamesAndClasses(node, &names, &classes);
78633c89af1Smrg    name_quarks = (XrmNameList) Quarkify(names, info->name);
78733c89af1Smrg    class_quarks = (XrmNameList) Quarkify(classes, info->class);
78833c89af1Smrg
78933c89af1Smrg    if (CheckDatabase(info->database, name_quarks, class_quarks)) {
79033c89af1Smrg	InsertWidgetFromNode(info->stream, node);
79133c89af1Smrg	info->count++;
79233c89af1Smrg    }
79333c89af1Smrg
79433c89af1Smrg    XtFree((char *)names);
79533c89af1Smrg    XtFree((char *)classes);
79633c89af1Smrg    XtFree((char *)name_quarks);
79733c89af1Smrg    XtFree((char *)class_quarks);
79833c89af1Smrg}
79933c89af1Smrg
80033c89af1Smrg/*	Function Name: CreateGetValuesCommand
80133c89af1Smrg *	Description: Creates the GetValues command.
80233c89af1Smrg *	Arguments: node - the current node.
80333c89af1Smrg *                 info_ptr - the pointer to the apply info.
80433c89af1Smrg *	Returns: none
80533c89af1Smrg */
80633c89af1Smrg
80733c89af1Smrg/*****
80833c89af1Smrg
80933c89af1Smrgstatic void
810278eca22SmrgCreateGetValuesCommand(WNode *node, XtPointer info_ptr)
81133c89af1Smrg{
81233c89af1Smrg    ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
81333c89af1Smrg    XrmNameList name_quarks;
81433c89af1Smrg    XrmClassList class_quarks;
81533c89af1Smrg    char ** names, **classes;
81633c89af1Smrg
81733c89af1Smrg    GetNamesAndClasses(node, &names, &classes);
81833c89af1Smrg    name_quarks = (XrmNameList) Quarkify(names, info->name);
81933c89af1Smrg    class_quarks = (XrmNameList) Quarkify(classes, info->class);
82033c89af1Smrg
82133c89af1Smrg    if (CheckDatabase(info->database, name_quarks, class_quarks)) {
82233c89af1Smrg	InsertWidgetFromNode(info->stream, node);
82333c89af1Smrg	info->count++;
82433c89af1Smrg    }
82533c89af1Smrg
82633c89af1Smrg    XtFree((char *)names);
82733c89af1Smrg    XtFree((char *)classes);
82833c89af1Smrg    XtFree((char *)name_quarks);
82933c89af1Smrg    XtFree((char *)class_quarks);
83033c89af1Smrg}
83133c89af1Smrg
83233c89af1Smrg*****/
83333c89af1Smrg
83433c89af1Smrg/*	Function Name: ActivateResourceWidgets
83533c89af1Smrg *	Description: Activates all widgets that match this resource.
83633c89af1Smrg *	Arguments: w - UNUSED.
83733c89af1Smrg *                 node_ptr - the node that owns this resource box.
838ad47b356Smrg *                 junk - UNUSED.
83933c89af1Smrg *	Returns: none.
84033c89af1Smrg */
84133c89af1Smrg
84233c89af1Smrg/* ARGSUSED */
84333c89af1Smrgvoid
844278eca22SmrgActivateResourceWidgets(Widget w, XtPointer node_ptr, XtPointer junk)
84533c89af1Smrg{
846ad47b356Smrg    WNode * node = (WNode *) node_ptr;
84733c89af1Smrg    ApplyResourcesInfo info;
84833c89af1Smrg    char * line;
84933c89af1Smrg    Arg args[1];
85033c89af1Smrg
85133c89af1Smrg    info.name = GetResourceName(node->resources->res_box);
85233c89af1Smrg    info.class = "IGNORE_ME";	/* Not currently used.  */
85333c89af1Smrg
854ad47b356Smrg    /*
85533c89af1Smrg     * Unused fields.
85633c89af1Smrg     */
85733c89af1Smrg
85833c89af1Smrg    info.count = 0;
85933c89af1Smrg    info.stream = NULL;
86033c89af1Smrg
86133c89af1Smrg    XtSetArg(args[0], XtNlabel, &line);
86233c89af1Smrg    XtGetValues(node->resources->res_box->res_label, args, ONE);
86333c89af1Smrg
86433c89af1Smrg    info.database = NULL;
86533c89af1Smrg    XrmPutLineResource(&(info.database), line);
86633c89af1Smrg
86733c89af1Smrg
86833c89af1Smrg    ExecuteOverAllNodes(node->tree_info->top_node,
86933c89af1Smrg			SetOnlyMatchingWidgets, (XtPointer) &info);
870ad47b356Smrg
87133c89af1Smrg    XrmDestroyDatabase(info.database);
87233c89af1Smrg}
87333c89af1Smrg
87433c89af1Smrg/*	Function Name: SetOnlyMatchingWidgets
87533c89af1Smrg *	Description: Activates all widgets in the tree that match this
876352bf44eSmrg *                   resource specification.
87733c89af1Smrg *	Arguments: node - the current node.
87833c89af1Smrg *                 info_ptr - the pointer to the apply info.
87933c89af1Smrg *	Returns: none
88033c89af1Smrg */
88133c89af1Smrg
88233c89af1Smrgstatic void
883278eca22SmrgSetOnlyMatchingWidgets(WNode *node, XtPointer info_ptr)
88433c89af1Smrg{
88533c89af1Smrg    ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
88633c89af1Smrg    XrmNameList name_quarks;
88733c89af1Smrg    XrmClassList class_quarks;
88833c89af1Smrg    char ** names, **classes;
88933c89af1Smrg    Boolean state;
89033c89af1Smrg    Arg args[1];
89133c89af1Smrg
89233c89af1Smrg    GetNamesAndClasses(node, &names, &classes);
89333c89af1Smrg    name_quarks = (XrmNameList) Quarkify(names, info->name);
89433c89af1Smrg    class_quarks = (XrmNameList) Quarkify(classes, info->class);
89533c89af1Smrg
89633c89af1Smrg    state = CheckDatabase(info->database, name_quarks, class_quarks);
89733c89af1Smrg
89833c89af1Smrg    XtSetArg(args[0], XtNstate, state);
89933c89af1Smrg    XtSetValues(node->widget, args, ONE);
90033c89af1Smrg    TreeToggle(node->widget, (XtPointer) node, (XtPointer)(long) state);
90133c89af1Smrg
90233c89af1Smrg    XtFree((char *)names);
90333c89af1Smrg    XtFree((char *)classes);
90433c89af1Smrg    XtFree((char *)name_quarks);
90533c89af1Smrg    XtFree((char *)class_quarks);
90633c89af1Smrg}
907