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 * Author:  Chris D. Peterson, MIT X Consortium
2633c89af1Smrg */
2733c89af1Smrg
2838d718bdSmrg#ifdef HAVE_CONFIG_H
2938d718bdSmrg# include "config.h"
3038d718bdSmrg#endif
3138d718bdSmrg
3233c89af1Smrg#include <X11/Intrinsic.h>
3333c89af1Smrg#include <X11/StringDefs.h>
3433c89af1Smrg#include <X11/Shell.h>
3533c89af1Smrg#include <stdio.h>
3633c89af1Smrg
37ad47b356Smrg#include <X11/Xaw/Cardinals.h>
3833c89af1Smrg
3933c89af1Smrg#include "editresP.h"
4033c89af1Smrg
4133c89af1Smrg/*
42ad47b356Smrg * Local function definitions
4333c89af1Smrg */
44ad47b356Smrgstatic void AddToFlashList ( TreeInfo * tree_info, GetGeomInfo * geom_info,
4533c89af1Smrg			     char ** errors );
46ad47b356Smrgstatic void _AddToFlashList ( TreeInfo * tree_info, char ** errors,
47ad47b356Smrg			      WNode * node, int x, int y, unsigned int width,
4833c89af1Smrg			      unsigned int height );
49ad47b356Smrgstatic void CreateFlashWidget ( TreeInfo * tree_info, int x, int y,
5033c89af1Smrg				unsigned int width, unsigned int height );
5133c89af1Smrgstatic void FlashWidgets ( TreeInfo * tree_info );
5233c89af1Smrgstatic void FlashWidgetsOn ( XtPointer info_ptr, XtIntervalId * id );
5333c89af1Smrgstatic void FlashWidgetsOff ( XtPointer info_ptr, XtIntervalId * id );
5433c89af1Smrgstatic void FlashWidgetsCleanup ( XtPointer info_ptr, XtIntervalId * id );
5533c89af1Smrg
5633c89af1Smrg/*	Function Name: _FindWidget
5733c89af1Smrg *	Description: Finds a widget in the tree and shows it to the user.
5833c89af1Smrg *	Arguments: w - any widget in the application.
5933c89af1Smrg *	Returns: none.
6033c89af1Smrg */
6133c89af1Smrg
62ad47b356Smrgvoid
63278eca22Smrg_FindWidget(Widget w)
6433c89af1Smrg{
6533c89af1Smrg    char msg[BUFSIZ];
6633c89af1Smrg    WNode * node;
6733c89af1Smrg    Window win;
6833c89af1Smrg    int x, y;			/* location of event in root coordinates. */
6933c89af1Smrg
70ad47b356Smrg    snprintf(msg, sizeof(msg), res_labels[14]);
7133c89af1Smrg
7233c89af1Smrg    SetMessage(global_screen_data.info_label, msg);
7333c89af1Smrg
7433c89af1Smrg    if ( (win = GetClientWindow(w, &x, &y)) != None) {
7533c89af1Smrg	node = FindWidgetFromWindow(global_tree_info, win);
7633c89af1Smrg	if (node != NULL) {
77ad47b356Smrg	    ProtocolStream * stream = &(global_client.stream);
78ad47b356Smrg
7933c89af1Smrg	    _XEditResResetStream(stream);
8033c89af1Smrg	    InsertWidgetFromNode(stream, node);
8133c89af1Smrg	    _XEditResPut16(stream, (short) x);
8233c89af1Smrg	    _XEditResPut16(stream, (short) y);
8333c89af1Smrg	    SetCommand(w, LocalFindChild, NULL);
8433c89af1Smrg	    return;
8533c89af1Smrg	}
8633c89af1Smrg    }
8733c89af1Smrg
88ad47b356Smrg    SetMessage(global_screen_data.info_label,
8933c89af1Smrg      res_labels[15]);
9033c89af1Smrg}
9133c89af1Smrg
9233c89af1Smrg
9333c89af1Smrg/*	Function Name: DisplayChild
9433c89af1Smrg *	Description: Displays the child node returned by the client
9533c89af1Smrg *	Arguments: event - the event from the client.
9633c89af1Smrg *	Returns: none.
9733c89af1Smrg */
9833c89af1Smrg
9933c89af1Smrgvoid
100278eca22SmrgDisplayChild(Event *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) {
110ad47b356Smrg	snprintf(msg, sizeof(msg), res_labels[13]);
11133c89af1Smrg	SetMessage(global_screen_data.info_label, msg);
112ad47b356Smrg	return;
11333c89af1Smrg    }
11433c89af1Smrg
11533c89af1Smrg    SetAndCenterTreeNode(node);
11633c89af1Smrg
11733c89af1Smrg    node = node->tree_info->top_node;
11833c89af1Smrg
119ad47b356Smrg    snprintf(msg, sizeof(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
132278eca22Smrg_FlashActiveWidgets(TreeInfo *tree_info)
13333c89af1Smrg{
134ad47b356Smrg    Cardinal i;
13533c89af1Smrg    ProtocolStream * stream = &(global_client.stream);
13633c89af1Smrg
13733c89af1Smrg    if (tree_info == NULL) {
13833c89af1Smrg	SetMessage(global_screen_data.info_label,
13933c89af1Smrg		   res_labels[17]);
14033c89af1Smrg	return;
14133c89af1Smrg    }
14233c89af1Smrg
14333c89af1Smrg    if (tree_info->num_nodes == 0) {
14433c89af1Smrg	SetMessage(global_screen_data.info_label,res_labels[18]);
14533c89af1Smrg	return;
14633c89af1Smrg    }
147ad47b356Smrg
148ad47b356Smrg    _XEditResResetStream(stream);
14933c89af1Smrg    /*
150ad47b356Smrg     * Insert the number of widgets.
15133c89af1Smrg     */
15233c89af1Smrg    _XEditResPut16(stream, (unsigned short) tree_info->num_nodes);
15333c89af1Smrg
154ad47b356Smrg    for (i = 0; i < tree_info->num_nodes; i++)
15533c89af1Smrg	InsertWidgetFromNode(stream, global_tree_info->active_nodes[i]);
15633c89af1Smrg
15733c89af1Smrg    SetCommand(tree_info->tree_widget, LocalFlashWidget, NULL);
15833c89af1Smrg}
15933c89af1Smrg
16033c89af1Smrg/*	Function Name: HandleFlashWidget
16133c89af1Smrg *	Description: Is called when client has returned geometry of all widget
16233c89af1Smrg *                   to flash.
16333c89af1Smrg *	Arguments: event - the event containing the client info.
16433c89af1Smrg *	Returns: none.
16533c89af1Smrg */
16633c89af1Smrg
16733c89af1Smrgchar *
168278eca22SmrgHandleFlashWidget(Event *event)
16933c89af1Smrg{
17033c89af1Smrg    GetGeomEvent * geom_event = (GetGeomEvent *) event;
17133c89af1Smrg    char * errors = NULL;
17233c89af1Smrg    int i;
17333c89af1Smrg
174ad47b356Smrg    for (i = 0; i < (int)geom_event->num_entries; i++)
17533c89af1Smrg	AddToFlashList(global_tree_info, geom_event->info + i, &errors);
17633c89af1Smrg
17733c89af1Smrg    FlashWidgets(global_tree_info);
17833c89af1Smrg
17933c89af1Smrg    return(errors);
18033c89af1Smrg}
18133c89af1Smrg
18233c89af1Smrg/*	Function Name: AddWidgetToFlashList
18333c89af1Smrg *	Description: Adds a widget to the list of widget to flash.
18433c89af1Smrg *	Arguments: tree_info - info about this tree.
18533c89af1Smrg *                 geom_info - the info from the client about this widget.
18633c89af1Smrg *                 errors - a string containing the errors.
18733c89af1Smrg *	Returns: none
18833c89af1Smrg */
18933c89af1Smrg
19033c89af1Smrgstatic void
191278eca22SmrgAddToFlashList(TreeInfo *tree_info, GetGeomInfo *geom_info, char **errors)
19233c89af1Smrg{
19333c89af1Smrg    WNode * node;
19433c89af1Smrg    char buf[BUFSIZ];
19533c89af1Smrg
196ad47b356Smrg    node = FindNode(tree_info->top_node,
19733c89af1Smrg		    geom_info->widgets.ids, geom_info->widgets.num_widgets);
19833c89af1Smrg
19933c89af1Smrg    if (node == NULL) {
200ad47b356Smrg	snprintf(buf, sizeof(buf),
201ad47b356Smrg                 "Editres Internal Error: Unable to FindNode.\n");
202ad47b356Smrg	AddString(errors, buf);
203ad47b356Smrg	return;
20433c89af1Smrg    }
20533c89af1Smrg
20633c89af1Smrg    if (geom_info->error) {
207ad47b356Smrg	AddString(errors, geom_info->message);
208ad47b356Smrg	return;
20933c89af1Smrg    }
21033c89af1Smrg
211352bf44eSmrg    if (!geom_info->visible) {
212ad47b356Smrg	snprintf(buf, sizeof(buf), "%s(0x%lx) - This widget is not mapped\n",
21333c89af1Smrg		node->name, node->id);
214ad47b356Smrg	AddString(errors, buf);
21533c89af1Smrg	return;
21633c89af1Smrg    }
21733c89af1Smrg
218ad47b356Smrg    _AddToFlashList(tree_info, errors, node,
219ad47b356Smrg		    geom_info->x, geom_info->y,
220ad47b356Smrg		    geom_info->width + geom_info->border_width,
22133c89af1Smrg		    geom_info->height + geom_info->border_width);
22233c89af1Smrg}
22333c89af1Smrg
22433c89af1Smrg/*	Function Name: _AddToFlashList
22533c89af1Smrg *	Description: adds the window to the current client's flash list.
22633c89af1Smrg *	Arguments: errors - a string to stuff any errors encountered.
22733c89af1Smrg *                 node - the node associated with this object.
22833c89af1Smrg *                 x, y - location of the flash widget in root coords.
22933c89af1Smrg *                 width, height - size of the flash widget.
23033c89af1Smrg *	Returns: none.
23133c89af1Smrg */
23233c89af1Smrg
23333c89af1Smrgstatic void
234278eca22Smrg_AddToFlashList(TreeInfo *tree_info, char **errors, WNode *node,
235278eca22Smrg		int x, int y, unsigned int width, unsigned int height)
23633c89af1Smrg{
23733c89af1Smrg    Display * dpy = XtDisplay(tree_info->tree_widget);
23833c89af1Smrg    Window window = (Window) node->window;
23933c89af1Smrg    XWindowAttributes attrs;
24033c89af1Smrg
24133c89af1Smrg    if (window == EDITRES_IS_OBJECT)
24233c89af1Smrg	window = node->parent->window;
24333c89af1Smrg
24433c89af1Smrg    if (window == EDITRES_IS_UNREALIZED) {
24533c89af1Smrg	char buf[BUFSIZ];
24633c89af1Smrg
247ad47b356Smrg	if (node->window == EDITRES_IS_OBJECT)
248ad47b356Smrg	    snprintf(buf, sizeof(buf),
249ad47b356Smrg                     "%s(0x%lx) - This object's parent is unrealized\n",
250ad47b356Smrg                     node->name, node->id);
25133c89af1Smrg	else
252ad47b356Smrg	    snprintf(buf, sizeof(buf),
253ad47b356Smrg                     "%s(0x%lx) - This widget is unrealized\n",
254ad47b356Smrg                     node->name, node->id);
25533c89af1Smrg
256ad47b356Smrg	AddString(errors, buf);
25733c89af1Smrg	return;
25833c89af1Smrg    }
25933c89af1Smrg
26033c89af1Smrg    global_error_code = NO_ERROR;                 /* Reset Error code. */
26133c89af1Smrg    global_old_error_handler = XSetErrorHandler(HandleXErrors);
26233c89af1Smrg    global_serial_num = NextRequest(dpy);
26333c89af1Smrg
26433c89af1Smrg    XGetWindowAttributes(dpy, window, &attrs);
26533c89af1Smrg
26633c89af1Smrg    XSync(dpy, FALSE);
26733c89af1Smrg    XSetErrorHandler(global_old_error_handler);
26833c89af1Smrg    if (global_error_code == NO_WINDOW) {
26933c89af1Smrg	char buf[BUFSIZ];
27033c89af1Smrg
271ad47b356Smrg	snprintf(buf, sizeof(buf),
272ad47b356Smrg                 "%s(0x%lx) - This widget's window no longer exists.\n",
273ad47b356Smrg                 node->name, node->id);
274ad47b356Smrg	AddString(errors, buf);
27533c89af1Smrg	return;
276ad47b356Smrg    }
27733c89af1Smrg
27833c89af1Smrg    if (attrs.map_state != IsViewable) {
27933c89af1Smrg	char buf[BUFSIZ];
28033c89af1Smrg
281ad47b356Smrg	snprintf(buf, sizeof(buf), "%s(0x%lx) - This widget is not mapped.\n",
282ad47b356Smrg                 node->name, node->id);
283ad47b356Smrg	AddString(errors, buf);
28433c89af1Smrg	return;
285ad47b356Smrg    }
28633c89af1Smrg
28733c89af1Smrg    CreateFlashWidget(tree_info, x, y, width, height);
28833c89af1Smrg}
28933c89af1Smrg
29033c89af1Smrg/*	Function Name: CreateFlashWidget
29133c89af1Smrg *	Description: Creates a widget of the size specified that
29233c89af1Smrg *                   will flash on the display, and adds it to the list
29333c89af1Smrg *                   of widgets to flash.
29433c89af1Smrg *	Arguments: tree_info - the tree information structure.
29533c89af1Smrg *                 x,y,width, height - size and location of the flash widget.
29633c89af1Smrg *	Returns: none.
29733c89af1Smrg */
298ad47b356Smrg
29933c89af1Smrg#define MORE_FLASH_WIDGETS 5
30033c89af1Smrg
30133c89af1Smrgstatic void
302278eca22SmrgCreateFlashWidget(TreeInfo *tree_info, int x, int y,
303278eca22Smrg		  unsigned int width, unsigned int height)
30433c89af1Smrg{
30533c89af1Smrg    Widget shell;
30633c89af1Smrg    Arg args[3];
30733c89af1Smrg    Cardinal num = 0;
30833c89af1Smrg    Dimension bw;
30933c89af1Smrg
31033c89af1Smrg    XtSetArg(args[num], XtNx, x); num++;
31133c89af1Smrg    XtSetArg(args[num], XtNy, y); num++;
31233c89af1Smrg    XtSetArg(args[num], XtNbackground, global_resources.flash_color); num++;
31333c89af1Smrg
314ad47b356Smrg    shell = XtCreatePopupShell("flash", overrideShellWidgetClass,
31533c89af1Smrg			       tree_info->tree_widget, args, num);
31633c89af1Smrg
31733c89af1Smrg    num = 0;
31833c89af1Smrg    XtSetArg(args[num], XtNborderWidth, &bw); num++;
31933c89af1Smrg    XtGetValues(shell, args, num);
320ad47b356Smrg
32133c89af1Smrg    bw *= 2;
32233c89af1Smrg
32333c89af1Smrg    num = 0;
32433c89af1Smrg    XtSetArg(args[num], XtNwidth, (width - bw)); num++;
32533c89af1Smrg    XtSetArg(args[num], XtNheight, (height - bw)); num++;
326ad47b356Smrg    XtSetValues(shell, args, num);
327ad47b356Smrg
32833c89af1Smrg    if (tree_info->num_flash_widgets + 1 > tree_info->alloc_flash_widgets) {
32933c89af1Smrg	tree_info->alloc_flash_widgets += MORE_FLASH_WIDGETS;
33033c89af1Smrg	tree_info->flash_widgets =
33133c89af1Smrg	    (Widget *) XtRealloc((char *)tree_info->flash_widgets,
33233c89af1Smrg			      sizeof(Widget) * tree_info->alloc_flash_widgets);
33333c89af1Smrg    }
33433c89af1Smrg
33533c89af1Smrg    tree_info->flash_widgets[tree_info->num_flash_widgets] = shell;
33633c89af1Smrg    tree_info->num_flash_widgets++;
33733c89af1Smrg}
33833c89af1Smrg
33933c89af1Smrg/*	Function Name: FlashWidgets
34033c89af1Smrg *	Description: Starts the widgets flashing.
34133c89af1Smrg *	Arguments: tree_info - the info about the tree (contains flash list)
34233c89af1Smrg *	Returns: none
34333c89af1Smrg */
34433c89af1Smrg
34533c89af1Smrgstatic void
346278eca22SmrgFlashWidgets(TreeInfo *tree_info)
34733c89af1Smrg{
34833c89af1Smrg    int i;
34933c89af1Smrg    unsigned long wait, half_flash;
35033c89af1Smrg    XtAppContext ac = XtWidgetToApplicationContext(tree_info->tree_widget);
35133c89af1Smrg
35233c89af1Smrg    if (tree_info->flash_widgets == NULL) /* no widgets to flash. */
35333c89af1Smrg	return;
35433c89af1Smrg
35533c89af1Smrg    wait = half_flash = global_resources.flash_time/2;
35633c89af1Smrg    for (i = 1; i < global_resources.num_flashes; i++) {
35733c89af1Smrg	XtAppAddTimeOut(ac, wait, FlashWidgetsOff,(XtPointer)tree_info);
35833c89af1Smrg	wait += half_flash;
35933c89af1Smrg	XtAppAddTimeOut(ac, wait, FlashWidgetsOn,(XtPointer)tree_info);
36033c89af1Smrg	wait += half_flash;
36133c89af1Smrg    }
36233c89af1Smrg
36333c89af1Smrg    wait += half_flash;
36433c89af1Smrg    XtAppAddTimeOut(ac, wait, FlashWidgetsCleanup, (XtPointer)tree_info);
36533c89af1Smrg
36633c89af1Smrg    FlashWidgetsOn((XtPointer) tree_info, (XtIntervalId *) NULL);
36733c89af1Smrg}
368ad47b356Smrg
36933c89af1Smrg/*	Function Name: FlashWidgetsOn
37033c89af1Smrg *	Description: Turns on all the Flash Widgets.
37133c89af1Smrg *	Arguments: info_ptr - pointer to the tree info.
37233c89af1Smrg *                 id - *** UNUSED ***.
37333c89af1Smrg *	Returns: none
37433c89af1Smrg */
37533c89af1Smrg
37633c89af1Smrg/* ARGSUSED */
37733c89af1Smrgstatic void
378278eca22SmrgFlashWidgetsOn(XtPointer info_ptr, XtIntervalId *id)
37933c89af1Smrg{
38033c89af1Smrg
381ad47b356Smrg    Cardinal i;
38233c89af1Smrg    TreeInfo * tree_info = (TreeInfo *) info_ptr;
383ad47b356Smrg
38433c89af1Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++) {
38533c89af1Smrg	XtRealizeWidget(tree_info->flash_widgets[i]);
38633c89af1Smrg	XMapRaised(XtDisplay(tree_info->flash_widgets[i]),
38733c89af1Smrg		   XtWindow(tree_info->flash_widgets[i]));
38833c89af1Smrg    }
38933c89af1Smrg}
39033c89af1Smrg
39133c89af1Smrg/*	Function Name: FlashWidgetsOff
39233c89af1Smrg *	Description: Turns off all the Flash Widgets.
39333c89af1Smrg *	Arguments: info_ptr - pointer to the tree info.
39433c89af1Smrg *                 id - *** UNUSED ***.
39533c89af1Smrg *	Returns: none
39633c89af1Smrg */
39733c89af1Smrg
39833c89af1Smrg/* ARGSUSED */
39933c89af1Smrgstatic void
400278eca22SmrgFlashWidgetsOff(XtPointer info_ptr, XtIntervalId *id)
40133c89af1Smrg{
402ad47b356Smrg    Cardinal i;
40333c89af1Smrg    TreeInfo * tree_info = (TreeInfo *) info_ptr;
404ad47b356Smrg
40533c89af1Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++)
40633c89af1Smrg	XtUnmapWidget(tree_info->flash_widgets[i]);
40733c89af1Smrg}
40833c89af1Smrg
40933c89af1Smrg/*	Function Name: FlashWidgetsCleanup
41033c89af1Smrg *	Description: Destroys all the Flash Widgets.
41133c89af1Smrg *	Arguments: info_ptr - pointer to the tree info.
41233c89af1Smrg *                 id - *** UNUSED ***.
41333c89af1Smrg *	Returns: none
41433c89af1Smrg */
41533c89af1Smrg
41633c89af1Smrg/* ARGSUSED */
41733c89af1Smrgstatic void
418278eca22SmrgFlashWidgetsCleanup(XtPointer info_ptr, XtIntervalId *id)
41933c89af1Smrg{
420ad47b356Smrg    Cardinal i;
42133c89af1Smrg    TreeInfo * tree_info = (TreeInfo *) info_ptr;
42233c89af1Smrg
42333c89af1Smrg/*
42433c89af1Smrg * Unmap 'em first for consistency.
42533c89af1Smrg */
426ad47b356Smrg
42733c89af1Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++)
42833c89af1Smrg	XtUnmapWidget(tree_info->flash_widgets[i]);
42933c89af1Smrg
43033c89af1Smrg    XFlush(XtDisplay(tree_info->tree_widget));
43133c89af1Smrg
432ad47b356Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++)
43333c89af1Smrg	XtDestroyWidget(tree_info->flash_widgets[i]);
43433c89af1Smrg
43533c89af1Smrg    XtFree((char *)tree_info->flash_widgets);
43633c89af1Smrg    tree_info->flash_widgets = NULL;
43733c89af1Smrg    tree_info->num_flash_widgets = tree_info->alloc_flash_widgets = 0;
43833c89af1Smrg}
439