geometry.c revision 33c89af1
133c89af1Smrg/*
233c89af1Smrg * $Xorg: geometry.c,v 1.4 2001/02/09 02:05:29 xorgcvs Exp $
333c89af1Smrg *
433c89af1SmrgCopyright 1989, 1998  The Open Group
533c89af1Smrg
633c89af1SmrgPermission to use, copy, modify, distribute, and sell this software and its
733c89af1Smrgdocumentation for any purpose is hereby granted without fee, provided that
833c89af1Smrgthe above copyright notice appear in all copies and that both that
933c89af1Smrgcopyright notice and this permission notice appear in supporting
1033c89af1Smrgdocumentation.
1133c89af1Smrg
1233c89af1SmrgThe above copyright notice and this permission notice shall be included in
1333c89af1Smrgall copies or substantial portions of the Software.
1433c89af1Smrg
1533c89af1SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1633c89af1SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1733c89af1SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1833c89af1SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1933c89af1SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2033c89af1SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2133c89af1Smrg
2233c89af1SmrgExcept as contained in this notice, the name of The Open Group shall not be
2333c89af1Smrgused in advertising or otherwise to promote the sale, use or other dealings
2433c89af1Smrgin this Software without prior written authorization from The Open Group.
2533c89af1Smrg *
2633c89af1Smrg * Author:  Chris D. Peterson, MIT X Consortium
2733c89af1Smrg */
2833c89af1Smrg/* $XFree86: xc/programs/editres/geometry.c,v 1.4 2001/01/17 23:44:52 dawes Exp $ */
2933c89af1Smrg
3033c89af1Smrg#include <X11/Intrinsic.h>
3133c89af1Smrg#include <X11/StringDefs.h>
3233c89af1Smrg#include <X11/Shell.h>
3333c89af1Smrg#include <stdio.h>
3433c89af1Smrg
3533c89af1Smrg#include <X11/Xaw/Cardinals.h>
3633c89af1Smrg
3733c89af1Smrg#include "editresP.h"
3833c89af1Smrg
3933c89af1Smrg/*
4033c89af1Smrg * Local function definitions
4133c89af1Smrg */
4233c89af1Smrgstatic void AddToFlashList ( TreeInfo * tree_info, GetGeomInfo * geom_info,
4333c89af1Smrg			     char ** errors );
4433c89af1Smrgstatic void _AddToFlashList ( TreeInfo * tree_info, char ** errors,
4533c89af1Smrg			      WNode * node, int x, int y, unsigned int width,
4633c89af1Smrg			      unsigned int height );
4733c89af1Smrgstatic void CreateFlashWidget ( TreeInfo * tree_info, int x, int y,
4833c89af1Smrg				unsigned int width, unsigned int height );
4933c89af1Smrgstatic void FlashWidgets ( TreeInfo * tree_info );
5033c89af1Smrgstatic void FlashWidgetsOn ( XtPointer info_ptr, XtIntervalId * id );
5133c89af1Smrgstatic void FlashWidgetsOff ( XtPointer info_ptr, XtIntervalId * id );
5233c89af1Smrgstatic void FlashWidgetsCleanup ( XtPointer info_ptr, XtIntervalId * id );
5333c89af1Smrg
5433c89af1Smrg/*	Function Name: _FindWidget
5533c89af1Smrg *	Description: Finds a widget in the tree and shows it to the user.
5633c89af1Smrg *	Arguments: w - any widget in the application.
5733c89af1Smrg *	Returns: none.
5833c89af1Smrg */
5933c89af1Smrg
6033c89af1Smrgvoid
6133c89af1Smrg_FindWidget(w)
6233c89af1SmrgWidget w;
6333c89af1Smrg{
6433c89af1Smrg    char msg[BUFSIZ];
6533c89af1Smrg    WNode * node;
6633c89af1Smrg    Window win;
6733c89af1Smrg    int x, y;			/* location of event in root coordinates. */
6833c89af1Smrg
6933c89af1Smrg    sprintf(msg, res_labels[14]);
7033c89af1Smrg
7133c89af1Smrg    SetMessage(global_screen_data.info_label, msg);
7233c89af1Smrg
7333c89af1Smrg    if ( (win = GetClientWindow(w, &x, &y)) != None) {
7433c89af1Smrg	node = FindWidgetFromWindow(global_tree_info, win);
7533c89af1Smrg	if (node != NULL) {
7633c89af1Smrg	    ProtocolStream * stream = &(global_client.stream);
7733c89af1Smrg
7833c89af1Smrg	    _XEditResResetStream(stream);
7933c89af1Smrg	    InsertWidgetFromNode(stream, node);
8033c89af1Smrg	    _XEditResPut16(stream, (short) x);
8133c89af1Smrg	    _XEditResPut16(stream, (short) y);
8233c89af1Smrg	    SetCommand(w, LocalFindChild, NULL);
8333c89af1Smrg	    return;
8433c89af1Smrg	}
8533c89af1Smrg    }
8633c89af1Smrg
8733c89af1Smrg    SetMessage(global_screen_data.info_label,
8833c89af1Smrg      res_labels[15]);
8933c89af1Smrg}
9033c89af1Smrg
9133c89af1Smrg
9233c89af1Smrg/*	Function Name: DisplayChild
9333c89af1Smrg *	Description: Displays the child node returned by the client
9433c89af1Smrg *	Arguments: event - the event from the client.
9533c89af1Smrg *	Returns: none.
9633c89af1Smrg */
9733c89af1Smrg
9833c89af1Smrgvoid
9933c89af1SmrgDisplayChild(event)
10033c89af1SmrgEvent * event;
10133c89af1Smrg{
10233c89af1Smrg    FindChildEvent * find_event = (FindChildEvent *) event;
10333c89af1Smrg    WNode * node;
10433c89af1Smrg    char msg[BUFSIZ];
10533c89af1Smrg
10633c89af1Smrg    node = FindNode(global_tree_info->top_node, find_event->widgets.ids,
10733c89af1Smrg		    find_event->widgets.num_widgets);
10833c89af1Smrg
10933c89af1Smrg    if (node == NULL) {
11033c89af1Smrg	sprintf(msg, res_labels[13]);
11133c89af1Smrg	SetMessage(global_screen_data.info_label, msg);
11233c89af1Smrg	return;
11333c89af1Smrg    }
11433c89af1Smrg
11533c89af1Smrg    SetAndCenterTreeNode(node);
11633c89af1Smrg
11733c89af1Smrg    node = node->tree_info->top_node;
11833c89af1Smrg
11933c89af1Smrg    sprintf(msg, res_labels[12], node->name, node->class);
12033c89af1Smrg    SetMessage(global_screen_data.info_label, msg);
12133c89af1Smrg
12233c89af1Smrg    _FlashActiveWidgets(global_tree_info);
12333c89af1Smrg}
12433c89af1Smrg
12533c89af1Smrg/*	Function Name: _FlashActiveWidgets
12633c89af1Smrg *	Description: Highlights all active widgets in the tree.
12733c89af1Smrg *	Arguments: tree_info - information about the current tree.
12833c89af1Smrg *	Returns: none.
12933c89af1Smrg */
13033c89af1Smrg
13133c89af1Smrgvoid
13233c89af1Smrg_FlashActiveWidgets(tree_info)
13333c89af1SmrgTreeInfo * tree_info;
13433c89af1Smrg{
13533c89af1Smrg    int i;
13633c89af1Smrg    ProtocolStream * stream = &(global_client.stream);
13733c89af1Smrg
13833c89af1Smrg    if (tree_info == NULL) {
13933c89af1Smrg	SetMessage(global_screen_data.info_label,
14033c89af1Smrg		   res_labels[17]);
14133c89af1Smrg	return;
14233c89af1Smrg    }
14333c89af1Smrg
14433c89af1Smrg    if (tree_info->num_nodes == 0) {
14533c89af1Smrg	SetMessage(global_screen_data.info_label,res_labels[18]);
14633c89af1Smrg	return;
14733c89af1Smrg    }
14833c89af1Smrg
14933c89af1Smrg    _XEditResResetStream(stream);
15033c89af1Smrg    /*
15133c89af1Smrg     * Insert the number of widgets.
15233c89af1Smrg     */
15333c89af1Smrg    _XEditResPut16(stream, (unsigned short) tree_info->num_nodes);
15433c89af1Smrg
15533c89af1Smrg    for (i = 0; i < tree_info->num_nodes; i++)
15633c89af1Smrg	InsertWidgetFromNode(stream, global_tree_info->active_nodes[i]);
15733c89af1Smrg
15833c89af1Smrg    SetCommand(tree_info->tree_widget, LocalFlashWidget, NULL);
15933c89af1Smrg}
16033c89af1Smrg
16133c89af1Smrg/*	Function Name: HandleFlashWidget
16233c89af1Smrg *	Description: Is called when client has returned geometry of all widget
16333c89af1Smrg *                   to flash.
16433c89af1Smrg *	Arguments: event - the event containing the client info.
16533c89af1Smrg *	Returns: none.
16633c89af1Smrg */
16733c89af1Smrg
16833c89af1Smrgchar *
16933c89af1SmrgHandleFlashWidget(event)
17033c89af1SmrgEvent * event;
17133c89af1Smrg{
17233c89af1Smrg    GetGeomEvent * geom_event = (GetGeomEvent *) event;
17333c89af1Smrg    char * errors = NULL;
17433c89af1Smrg    int i;
17533c89af1Smrg
17633c89af1Smrg    for (i = 0; i < (int)geom_event->num_entries; i++)
17733c89af1Smrg	AddToFlashList(global_tree_info, geom_event->info + i, &errors);
17833c89af1Smrg
17933c89af1Smrg    FlashWidgets(global_tree_info);
18033c89af1Smrg
18133c89af1Smrg    return(errors);
18233c89af1Smrg}
18333c89af1Smrg
18433c89af1Smrg/*	Function Name: AddWidgetToFlashList
18533c89af1Smrg *	Description: Adds a widget to the list of widget to flash.
18633c89af1Smrg *	Arguments: tree_info - info about this tree.
18733c89af1Smrg *                 geom_info - the info from the client about this widget.
18833c89af1Smrg *                 errors - a string containing the errors.
18933c89af1Smrg *	Returns: none
19033c89af1Smrg */
19133c89af1Smrg
19233c89af1Smrgstatic void
19333c89af1SmrgAddToFlashList(tree_info, geom_info, errors)
19433c89af1SmrgTreeInfo * tree_info;
19533c89af1SmrgGetGeomInfo * geom_info;
19633c89af1Smrgchar ** errors;
19733c89af1Smrg{
19833c89af1Smrg    WNode * node;
19933c89af1Smrg    char buf[BUFSIZ];
20033c89af1Smrg
20133c89af1Smrg    node = FindNode(tree_info->top_node,
20233c89af1Smrg		    geom_info->widgets.ids, geom_info->widgets.num_widgets);
20333c89af1Smrg
20433c89af1Smrg    if (node == NULL) {
20533c89af1Smrg	sprintf(buf, "Editres Internal Error: Unable to FindNode.\n");
20633c89af1Smrg	AddString(errors, buf);
20733c89af1Smrg	return;
20833c89af1Smrg    }
20933c89af1Smrg
21033c89af1Smrg    if (geom_info->error) {
21133c89af1Smrg	AddString(errors, geom_info->message);
21233c89af1Smrg	return;
21333c89af1Smrg    }
21433c89af1Smrg
21533c89af1Smrg    if (!geom_info->visable) {
21633c89af1Smrg	sprintf(buf, "%s(0x%lx) - This widget is not mapped\n",
21733c89af1Smrg		node->name, node->id);
21833c89af1Smrg	AddString(errors, buf);
21933c89af1Smrg	return;
22033c89af1Smrg    }
22133c89af1Smrg
22233c89af1Smrg    _AddToFlashList(tree_info, errors, node,
22333c89af1Smrg		    geom_info->x, geom_info->y,
22433c89af1Smrg		    geom_info->width + geom_info->border_width,
22533c89af1Smrg		    geom_info->height + geom_info->border_width);
22633c89af1Smrg}
22733c89af1Smrg
22833c89af1Smrg/*	Function Name: _AddToFlashList
22933c89af1Smrg *	Description: adds the window to the current client's flash list.
23033c89af1Smrg *	Arguments: errors - a string to stuff any errors encountered.
23133c89af1Smrg *                 node - the node associated with this object.
23233c89af1Smrg *                 x, y - location of the flash widget in root coords.
23333c89af1Smrg *                 width, height - size of the flash widget.
23433c89af1Smrg *	Returns: none.
23533c89af1Smrg */
23633c89af1Smrg
23733c89af1Smrgstatic void
23833c89af1Smrg_AddToFlashList(tree_info, errors, node, x, y, width, height)
23933c89af1SmrgTreeInfo * tree_info;
24033c89af1Smrgchar ** errors;
24133c89af1SmrgWNode * node;
24233c89af1Smrgint x, y;
24333c89af1Smrgunsigned int width, height;
24433c89af1Smrg{
24533c89af1Smrg    Display * dpy = XtDisplay(tree_info->tree_widget);
24633c89af1Smrg    Window window = (Window) node->window;
24733c89af1Smrg    XWindowAttributes attrs;
24833c89af1Smrg
24933c89af1Smrg    if (window == EDITRES_IS_OBJECT)
25033c89af1Smrg	window = node->parent->window;
25133c89af1Smrg
25233c89af1Smrg    if (window == EDITRES_IS_UNREALIZED) {
25333c89af1Smrg	char buf[BUFSIZ];
25433c89af1Smrg
25533c89af1Smrg	if (node->window == EDITRES_IS_OBJECT)
25633c89af1Smrg	    sprintf(buf, "%s(0x%lx) - This object's parent is unrealized\n",
25733c89af1Smrg		    node->name, node->id);
25833c89af1Smrg	else
25933c89af1Smrg	    sprintf(buf, "%s(0x%lx) - This widget is unrealized\n",
26033c89af1Smrg		    node->name, node->id);
26133c89af1Smrg
26233c89af1Smrg	AddString(errors, buf);
26333c89af1Smrg	return;
26433c89af1Smrg    }
26533c89af1Smrg
26633c89af1Smrg    global_error_code = NO_ERROR;                 /* Reset Error code. */
26733c89af1Smrg    global_old_error_handler = XSetErrorHandler(HandleXErrors);
26833c89af1Smrg    global_serial_num = NextRequest(dpy);
26933c89af1Smrg
27033c89af1Smrg    XGetWindowAttributes(dpy, window, &attrs);
27133c89af1Smrg
27233c89af1Smrg    XSync(dpy, FALSE);
27333c89af1Smrg    XSetErrorHandler(global_old_error_handler);
27433c89af1Smrg    if (global_error_code == NO_WINDOW) {
27533c89af1Smrg	char buf[BUFSIZ];
27633c89af1Smrg
27733c89af1Smrg	sprintf(buf, "%s(0x%lx) - This widget's window no longer exists.\n",
27833c89af1Smrg		node->name, node->id);
27933c89af1Smrg	AddString(errors, buf);
28033c89af1Smrg	return;
28133c89af1Smrg    }
28233c89af1Smrg
28333c89af1Smrg    if (attrs.map_state != IsViewable) {
28433c89af1Smrg	char buf[BUFSIZ];
28533c89af1Smrg
28633c89af1Smrg	sprintf(buf, "%s(0x%lx) - This widget is not mapped.\n",
28733c89af1Smrg		node->name, node->id);
28833c89af1Smrg	AddString(errors, buf);
28933c89af1Smrg	return;
29033c89af1Smrg    }
29133c89af1Smrg
29233c89af1Smrg    CreateFlashWidget(tree_info, x, y, width, height);
29333c89af1Smrg}
29433c89af1Smrg
29533c89af1Smrg/*	Function Name: CreateFlashWidget
29633c89af1Smrg *	Description: Creates a widget of the size specified that
29733c89af1Smrg *                   will flash on the display, and adds it to the list
29833c89af1Smrg *                   of widgets to flash.
29933c89af1Smrg *	Arguments: tree_info - the tree information structure.
30033c89af1Smrg *                 x,y,width, height - size and location of the flash widget.
30133c89af1Smrg *	Returns: none.
30233c89af1Smrg */
30333c89af1Smrg
30433c89af1Smrg#define MORE_FLASH_WIDGETS 5
30533c89af1Smrg
30633c89af1Smrgstatic void
30733c89af1SmrgCreateFlashWidget(tree_info, x, y, width, height)
30833c89af1SmrgTreeInfo * tree_info;
30933c89af1Smrgint x, y;
31033c89af1Smrgunsigned int width, height;
31133c89af1Smrg{
31233c89af1Smrg    Widget shell;
31333c89af1Smrg    Arg args[3];
31433c89af1Smrg    Cardinal num = 0;
31533c89af1Smrg    Dimension bw;
31633c89af1Smrg
31733c89af1Smrg    XtSetArg(args[num], XtNx, x); num++;
31833c89af1Smrg    XtSetArg(args[num], XtNy, y); num++;
31933c89af1Smrg    XtSetArg(args[num], XtNbackground, global_resources.flash_color); num++;
32033c89af1Smrg
32133c89af1Smrg    shell = XtCreatePopupShell("flash", overrideShellWidgetClass,
32233c89af1Smrg			       tree_info->tree_widget, args, num);
32333c89af1Smrg
32433c89af1Smrg    num = 0;
32533c89af1Smrg    XtSetArg(args[num], XtNborderWidth, &bw); num++;
32633c89af1Smrg    XtGetValues(shell, args, num);
32733c89af1Smrg
32833c89af1Smrg    bw *= 2;
32933c89af1Smrg
33033c89af1Smrg    num = 0;
33133c89af1Smrg    XtSetArg(args[num], XtNwidth, (width - bw)); num++;
33233c89af1Smrg    XtSetArg(args[num], XtNheight, (height - bw)); num++;
33333c89af1Smrg    XtSetValues(shell, args, num);
33433c89af1Smrg
33533c89af1Smrg    if (tree_info->num_flash_widgets + 1 > tree_info->alloc_flash_widgets) {
33633c89af1Smrg	tree_info->alloc_flash_widgets += MORE_FLASH_WIDGETS;
33733c89af1Smrg	tree_info->flash_widgets =
33833c89af1Smrg	    (Widget *) XtRealloc((char *)tree_info->flash_widgets,
33933c89af1Smrg			      sizeof(Widget) * tree_info->alloc_flash_widgets);
34033c89af1Smrg    }
34133c89af1Smrg
34233c89af1Smrg    tree_info->flash_widgets[tree_info->num_flash_widgets] = shell;
34333c89af1Smrg    tree_info->num_flash_widgets++;
34433c89af1Smrg}
34533c89af1Smrg
34633c89af1Smrg/*	Function Name: FlashWidgets
34733c89af1Smrg *	Description: Starts the widgets flashing.
34833c89af1Smrg *	Arguments: tree_info - the info about the tree (contains flash list)
34933c89af1Smrg *	Returns: none
35033c89af1Smrg */
35133c89af1Smrg
35233c89af1Smrgstatic void
35333c89af1SmrgFlashWidgets(tree_info)
35433c89af1SmrgTreeInfo * tree_info;
35533c89af1Smrg{
35633c89af1Smrg    int i;
35733c89af1Smrg    unsigned long wait, half_flash;
35833c89af1Smrg    XtAppContext ac = XtWidgetToApplicationContext(tree_info->tree_widget);
35933c89af1Smrg
36033c89af1Smrg    if (tree_info->flash_widgets == NULL) /* no widgets to flash. */
36133c89af1Smrg	return;
36233c89af1Smrg
36333c89af1Smrg    wait = half_flash = global_resources.flash_time/2;
36433c89af1Smrg    for (i = 1; i < global_resources.num_flashes; i++) {
36533c89af1Smrg	XtAppAddTimeOut(ac, wait, FlashWidgetsOff,(XtPointer)tree_info);
36633c89af1Smrg	wait += half_flash;
36733c89af1Smrg	XtAppAddTimeOut(ac, wait, FlashWidgetsOn,(XtPointer)tree_info);
36833c89af1Smrg	wait += half_flash;
36933c89af1Smrg    }
37033c89af1Smrg
37133c89af1Smrg    wait += half_flash;
37233c89af1Smrg    XtAppAddTimeOut(ac, wait, FlashWidgetsCleanup, (XtPointer)tree_info);
37333c89af1Smrg
37433c89af1Smrg    FlashWidgetsOn((XtPointer) tree_info, (XtIntervalId *) NULL);
37533c89af1Smrg}
37633c89af1Smrg
37733c89af1Smrg/*	Function Name: FlashWidgetsOn
37833c89af1Smrg *	Description: Turns on all the Flash Widgets.
37933c89af1Smrg *	Arguments: info_ptr - pointer to the tree info.
38033c89af1Smrg *                 id - *** UNUSED ***.
38133c89af1Smrg *	Returns: none
38233c89af1Smrg */
38333c89af1Smrg
38433c89af1Smrg/* ARGSUSED */
38533c89af1Smrgstatic void
38633c89af1SmrgFlashWidgetsOn(info_ptr, id)
38733c89af1SmrgXtPointer info_ptr;
38833c89af1SmrgXtIntervalId * id;
38933c89af1Smrg{
39033c89af1Smrg
39133c89af1Smrg    int i;
39233c89af1Smrg    TreeInfo * tree_info = (TreeInfo *) info_ptr;
39333c89af1Smrg
39433c89af1Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++) {
39533c89af1Smrg	XtRealizeWidget(tree_info->flash_widgets[i]);
39633c89af1Smrg	XMapRaised(XtDisplay(tree_info->flash_widgets[i]),
39733c89af1Smrg		   XtWindow(tree_info->flash_widgets[i]));
39833c89af1Smrg    }
39933c89af1Smrg}
40033c89af1Smrg
40133c89af1Smrg/*	Function Name: FlashWidgetsOff
40233c89af1Smrg *	Description: Turns off all the Flash Widgets.
40333c89af1Smrg *	Arguments: info_ptr - pointer to the tree info.
40433c89af1Smrg *                 id - *** UNUSED ***.
40533c89af1Smrg *	Returns: none
40633c89af1Smrg */
40733c89af1Smrg
40833c89af1Smrg/* ARGSUSED */
40933c89af1Smrgstatic void
41033c89af1SmrgFlashWidgetsOff(info_ptr, id)
41133c89af1SmrgXtPointer info_ptr;
41233c89af1SmrgXtIntervalId * id;
41333c89af1Smrg{
41433c89af1Smrg    int i;
41533c89af1Smrg    TreeInfo * tree_info = (TreeInfo *) info_ptr;
41633c89af1Smrg
41733c89af1Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++)
41833c89af1Smrg	XtUnmapWidget(tree_info->flash_widgets[i]);
41933c89af1Smrg}
42033c89af1Smrg
42133c89af1Smrg/*	Function Name: FlashWidgetsCleanup
42233c89af1Smrg *	Description: Destroys all the Flash Widgets.
42333c89af1Smrg *	Arguments: info_ptr - pointer to the tree info.
42433c89af1Smrg *                 id - *** UNUSED ***.
42533c89af1Smrg *	Returns: none
42633c89af1Smrg */
42733c89af1Smrg
42833c89af1Smrg/* ARGSUSED */
42933c89af1Smrgstatic void
43033c89af1SmrgFlashWidgetsCleanup(info_ptr, id)
43133c89af1SmrgXtPointer info_ptr;
43233c89af1SmrgXtIntervalId * id;
43333c89af1Smrg{
43433c89af1Smrg    int i;
43533c89af1Smrg    TreeInfo * tree_info = (TreeInfo *) info_ptr;
43633c89af1Smrg
43733c89af1Smrg/*
43833c89af1Smrg * Unmap 'em first for consistency.
43933c89af1Smrg */
44033c89af1Smrg
44133c89af1Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++)
44233c89af1Smrg	XtUnmapWidget(tree_info->flash_widgets[i]);
44333c89af1Smrg
44433c89af1Smrg    XFlush(XtDisplay(tree_info->tree_widget));
44533c89af1Smrg
44633c89af1Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++)
44733c89af1Smrg	XtDestroyWidget(tree_info->flash_widgets[i]);
44833c89af1Smrg
44933c89af1Smrg    XtFree((char *)tree_info->flash_widgets);
45033c89af1Smrg    tree_info->flash_widgets = NULL;
45133c89af1Smrg    tree_info->num_flash_widgets = tree_info->alloc_flash_widgets = 0;
45233c89af1Smrg}
453