geometry.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 * Author:  Chris D. Peterson, MIT X Consortium
2633c89af1Smrg */
2733c89af1Smrg
2833c89af1Smrg#include <X11/Intrinsic.h>
2933c89af1Smrg#include <X11/StringDefs.h>
3033c89af1Smrg#include <X11/Shell.h>
3133c89af1Smrg#include <stdio.h>
3233c89af1Smrg
33ad47b356Smrg#include <X11/Xaw/Cardinals.h>
3433c89af1Smrg
3533c89af1Smrg#include "editresP.h"
3633c89af1Smrg
3733c89af1Smrg/*
38ad47b356Smrg * Local function definitions
3933c89af1Smrg */
40ad47b356Smrgstatic void AddToFlashList ( TreeInfo * tree_info, GetGeomInfo * geom_info,
4133c89af1Smrg			     char ** errors );
42ad47b356Smrgstatic void _AddToFlashList ( TreeInfo * tree_info, char ** errors,
43ad47b356Smrg			      WNode * node, int x, int y, unsigned int width,
4433c89af1Smrg			      unsigned int height );
45ad47b356Smrgstatic void CreateFlashWidget ( TreeInfo * tree_info, int x, int y,
4633c89af1Smrg				unsigned int width, unsigned int height );
4733c89af1Smrgstatic void FlashWidgets ( TreeInfo * tree_info );
4833c89af1Smrgstatic void FlashWidgetsOn ( XtPointer info_ptr, XtIntervalId * id );
4933c89af1Smrgstatic void FlashWidgetsOff ( XtPointer info_ptr, XtIntervalId * id );
5033c89af1Smrgstatic void FlashWidgetsCleanup ( XtPointer info_ptr, XtIntervalId * id );
5133c89af1Smrg
5233c89af1Smrg/*	Function Name: _FindWidget
5333c89af1Smrg *	Description: Finds a widget in the tree and shows it to the user.
5433c89af1Smrg *	Arguments: w - any widget in the application.
5533c89af1Smrg *	Returns: none.
5633c89af1Smrg */
5733c89af1Smrg
58ad47b356Smrgvoid
59278eca22Smrg_FindWidget(Widget w)
6033c89af1Smrg{
6133c89af1Smrg    char msg[BUFSIZ];
6233c89af1Smrg    WNode * node;
6333c89af1Smrg    Window win;
6433c89af1Smrg    int x, y;			/* location of event in root coordinates. */
6533c89af1Smrg
66ad47b356Smrg    snprintf(msg, sizeof(msg), res_labels[14]);
6733c89af1Smrg
6833c89af1Smrg    SetMessage(global_screen_data.info_label, msg);
6933c89af1Smrg
7033c89af1Smrg    if ( (win = GetClientWindow(w, &x, &y)) != None) {
7133c89af1Smrg	node = FindWidgetFromWindow(global_tree_info, win);
7233c89af1Smrg	if (node != NULL) {
73ad47b356Smrg	    ProtocolStream * stream = &(global_client.stream);
74ad47b356Smrg
7533c89af1Smrg	    _XEditResResetStream(stream);
7633c89af1Smrg	    InsertWidgetFromNode(stream, node);
7733c89af1Smrg	    _XEditResPut16(stream, (short) x);
7833c89af1Smrg	    _XEditResPut16(stream, (short) y);
7933c89af1Smrg	    SetCommand(w, LocalFindChild, NULL);
8033c89af1Smrg	    return;
8133c89af1Smrg	}
8233c89af1Smrg    }
8333c89af1Smrg
84ad47b356Smrg    SetMessage(global_screen_data.info_label,
8533c89af1Smrg      res_labels[15]);
8633c89af1Smrg}
8733c89af1Smrg
8833c89af1Smrg
8933c89af1Smrg/*	Function Name: DisplayChild
9033c89af1Smrg *	Description: Displays the child node returned by the client
9133c89af1Smrg *	Arguments: event - the event from the client.
9233c89af1Smrg *	Returns: none.
9333c89af1Smrg */
9433c89af1Smrg
9533c89af1Smrgvoid
96278eca22SmrgDisplayChild(Event *event)
9733c89af1Smrg{
9833c89af1Smrg    FindChildEvent * find_event = (FindChildEvent *) event;
9933c89af1Smrg    WNode * node;
10033c89af1Smrg    char msg[BUFSIZ];
10133c89af1Smrg
10233c89af1Smrg    node = FindNode(global_tree_info->top_node, find_event->widgets.ids,
10333c89af1Smrg		    find_event->widgets.num_widgets);
10433c89af1Smrg
10533c89af1Smrg    if (node == NULL) {
106ad47b356Smrg	snprintf(msg, sizeof(msg), res_labels[13]);
10733c89af1Smrg	SetMessage(global_screen_data.info_label, msg);
108ad47b356Smrg	return;
10933c89af1Smrg    }
11033c89af1Smrg
11133c89af1Smrg    SetAndCenterTreeNode(node);
11233c89af1Smrg
11333c89af1Smrg    node = node->tree_info->top_node;
11433c89af1Smrg
115ad47b356Smrg    snprintf(msg, sizeof(msg), res_labels[12], node->name, node->class);
11633c89af1Smrg    SetMessage(global_screen_data.info_label, msg);
11733c89af1Smrg
11833c89af1Smrg    _FlashActiveWidgets(global_tree_info);
11933c89af1Smrg}
12033c89af1Smrg
12133c89af1Smrg/*	Function Name: _FlashActiveWidgets
12233c89af1Smrg *	Description: Highlights all active widgets in the tree.
12333c89af1Smrg *	Arguments: tree_info - information about the current tree.
12433c89af1Smrg *	Returns: none.
12533c89af1Smrg */
12633c89af1Smrg
12733c89af1Smrgvoid
128278eca22Smrg_FlashActiveWidgets(TreeInfo *tree_info)
12933c89af1Smrg{
130ad47b356Smrg    Cardinal i;
13133c89af1Smrg    ProtocolStream * stream = &(global_client.stream);
13233c89af1Smrg
13333c89af1Smrg    if (tree_info == NULL) {
13433c89af1Smrg	SetMessage(global_screen_data.info_label,
13533c89af1Smrg		   res_labels[17]);
13633c89af1Smrg	return;
13733c89af1Smrg    }
13833c89af1Smrg
13933c89af1Smrg    if (tree_info->num_nodes == 0) {
14033c89af1Smrg	SetMessage(global_screen_data.info_label,res_labels[18]);
14133c89af1Smrg	return;
14233c89af1Smrg    }
143ad47b356Smrg
144ad47b356Smrg    _XEditResResetStream(stream);
14533c89af1Smrg    /*
146ad47b356Smrg     * Insert the number of widgets.
14733c89af1Smrg     */
14833c89af1Smrg    _XEditResPut16(stream, (unsigned short) tree_info->num_nodes);
14933c89af1Smrg
150ad47b356Smrg    for (i = 0; i < tree_info->num_nodes; i++)
15133c89af1Smrg	InsertWidgetFromNode(stream, global_tree_info->active_nodes[i]);
15233c89af1Smrg
15333c89af1Smrg    SetCommand(tree_info->tree_widget, LocalFlashWidget, NULL);
15433c89af1Smrg}
15533c89af1Smrg
15633c89af1Smrg/*	Function Name: HandleFlashWidget
15733c89af1Smrg *	Description: Is called when client has returned geometry of all widget
15833c89af1Smrg *                   to flash.
15933c89af1Smrg *	Arguments: event - the event containing the client info.
16033c89af1Smrg *	Returns: none.
16133c89af1Smrg */
16233c89af1Smrg
16333c89af1Smrgchar *
164278eca22SmrgHandleFlashWidget(Event *event)
16533c89af1Smrg{
16633c89af1Smrg    GetGeomEvent * geom_event = (GetGeomEvent *) event;
16733c89af1Smrg    char * errors = NULL;
16833c89af1Smrg    int i;
16933c89af1Smrg
170ad47b356Smrg    for (i = 0; i < (int)geom_event->num_entries; i++)
17133c89af1Smrg	AddToFlashList(global_tree_info, geom_event->info + i, &errors);
17233c89af1Smrg
17333c89af1Smrg    FlashWidgets(global_tree_info);
17433c89af1Smrg
17533c89af1Smrg    return(errors);
17633c89af1Smrg}
17733c89af1Smrg
17833c89af1Smrg/*	Function Name: AddWidgetToFlashList
17933c89af1Smrg *	Description: Adds a widget to the list of widget to flash.
18033c89af1Smrg *	Arguments: tree_info - info about this tree.
18133c89af1Smrg *                 geom_info - the info from the client about this widget.
18233c89af1Smrg *                 errors - a string containing the errors.
18333c89af1Smrg *	Returns: none
18433c89af1Smrg */
18533c89af1Smrg
18633c89af1Smrgstatic void
187278eca22SmrgAddToFlashList(TreeInfo *tree_info, GetGeomInfo *geom_info, char **errors)
18833c89af1Smrg{
18933c89af1Smrg    WNode * node;
19033c89af1Smrg    char buf[BUFSIZ];
19133c89af1Smrg
192ad47b356Smrg    node = FindNode(tree_info->top_node,
19333c89af1Smrg		    geom_info->widgets.ids, geom_info->widgets.num_widgets);
19433c89af1Smrg
19533c89af1Smrg    if (node == NULL) {
196ad47b356Smrg	snprintf(buf, sizeof(buf),
197ad47b356Smrg                 "Editres Internal Error: Unable to FindNode.\n");
198ad47b356Smrg	AddString(errors, buf);
199ad47b356Smrg	return;
20033c89af1Smrg    }
20133c89af1Smrg
20233c89af1Smrg    if (geom_info->error) {
203ad47b356Smrg	AddString(errors, geom_info->message);
204ad47b356Smrg	return;
20533c89af1Smrg    }
20633c89af1Smrg
207352bf44eSmrg    if (!geom_info->visible) {
208ad47b356Smrg	snprintf(buf, sizeof(buf), "%s(0x%lx) - This widget is not mapped\n",
20933c89af1Smrg		node->name, node->id);
210ad47b356Smrg	AddString(errors, buf);
21133c89af1Smrg	return;
21233c89af1Smrg    }
21333c89af1Smrg
214ad47b356Smrg    _AddToFlashList(tree_info, errors, node,
215ad47b356Smrg		    geom_info->x, geom_info->y,
216ad47b356Smrg		    geom_info->width + geom_info->border_width,
21733c89af1Smrg		    geom_info->height + geom_info->border_width);
21833c89af1Smrg}
21933c89af1Smrg
22033c89af1Smrg/*	Function Name: _AddToFlashList
22133c89af1Smrg *	Description: adds the window to the current client's flash list.
22233c89af1Smrg *	Arguments: errors - a string to stuff any errors encountered.
22333c89af1Smrg *                 node - the node associated with this object.
22433c89af1Smrg *                 x, y - location of the flash widget in root coords.
22533c89af1Smrg *                 width, height - size of the flash widget.
22633c89af1Smrg *	Returns: none.
22733c89af1Smrg */
22833c89af1Smrg
22933c89af1Smrgstatic void
230278eca22Smrg_AddToFlashList(TreeInfo *tree_info, char **errors, WNode *node,
231278eca22Smrg		int x, int y, unsigned int width, unsigned int height)
23233c89af1Smrg{
23333c89af1Smrg    Display * dpy = XtDisplay(tree_info->tree_widget);
23433c89af1Smrg    Window window = (Window) node->window;
23533c89af1Smrg    XWindowAttributes attrs;
23633c89af1Smrg
23733c89af1Smrg    if (window == EDITRES_IS_OBJECT)
23833c89af1Smrg	window = node->parent->window;
23933c89af1Smrg
24033c89af1Smrg    if (window == EDITRES_IS_UNREALIZED) {
24133c89af1Smrg	char buf[BUFSIZ];
24233c89af1Smrg
243ad47b356Smrg	if (node->window == EDITRES_IS_OBJECT)
244ad47b356Smrg	    snprintf(buf, sizeof(buf),
245ad47b356Smrg                     "%s(0x%lx) - This object's parent is unrealized\n",
246ad47b356Smrg                     node->name, node->id);
24733c89af1Smrg	else
248ad47b356Smrg	    snprintf(buf, sizeof(buf),
249ad47b356Smrg                     "%s(0x%lx) - This widget is unrealized\n",
250ad47b356Smrg                     node->name, node->id);
25133c89af1Smrg
252ad47b356Smrg	AddString(errors, buf);
25333c89af1Smrg	return;
25433c89af1Smrg    }
25533c89af1Smrg
25633c89af1Smrg    global_error_code = NO_ERROR;                 /* Reset Error code. */
25733c89af1Smrg    global_old_error_handler = XSetErrorHandler(HandleXErrors);
25833c89af1Smrg    global_serial_num = NextRequest(dpy);
25933c89af1Smrg
26033c89af1Smrg    XGetWindowAttributes(dpy, window, &attrs);
26133c89af1Smrg
26233c89af1Smrg    XSync(dpy, FALSE);
26333c89af1Smrg    XSetErrorHandler(global_old_error_handler);
26433c89af1Smrg    if (global_error_code == NO_WINDOW) {
26533c89af1Smrg	char buf[BUFSIZ];
26633c89af1Smrg
267ad47b356Smrg	snprintf(buf, sizeof(buf),
268ad47b356Smrg                 "%s(0x%lx) - This widget's window no longer exists.\n",
269ad47b356Smrg                 node->name, node->id);
270ad47b356Smrg	AddString(errors, buf);
27133c89af1Smrg	return;
272ad47b356Smrg    }
27333c89af1Smrg
27433c89af1Smrg    if (attrs.map_state != IsViewable) {
27533c89af1Smrg	char buf[BUFSIZ];
27633c89af1Smrg
277ad47b356Smrg	snprintf(buf, sizeof(buf), "%s(0x%lx) - This widget is not mapped.\n",
278ad47b356Smrg                 node->name, node->id);
279ad47b356Smrg	AddString(errors, buf);
28033c89af1Smrg	return;
281ad47b356Smrg    }
28233c89af1Smrg
28333c89af1Smrg    CreateFlashWidget(tree_info, x, y, width, height);
28433c89af1Smrg}
28533c89af1Smrg
28633c89af1Smrg/*	Function Name: CreateFlashWidget
28733c89af1Smrg *	Description: Creates a widget of the size specified that
28833c89af1Smrg *                   will flash on the display, and adds it to the list
28933c89af1Smrg *                   of widgets to flash.
29033c89af1Smrg *	Arguments: tree_info - the tree information structure.
29133c89af1Smrg *                 x,y,width, height - size and location of the flash widget.
29233c89af1Smrg *	Returns: none.
29333c89af1Smrg */
294ad47b356Smrg
29533c89af1Smrg#define MORE_FLASH_WIDGETS 5
29633c89af1Smrg
29733c89af1Smrgstatic void
298278eca22SmrgCreateFlashWidget(TreeInfo *tree_info, int x, int y,
299278eca22Smrg		  unsigned int width, unsigned int height)
30033c89af1Smrg{
30133c89af1Smrg    Widget shell;
30233c89af1Smrg    Arg args[3];
30333c89af1Smrg    Cardinal num = 0;
30433c89af1Smrg    Dimension bw;
30533c89af1Smrg
30633c89af1Smrg    XtSetArg(args[num], XtNx, x); num++;
30733c89af1Smrg    XtSetArg(args[num], XtNy, y); num++;
30833c89af1Smrg    XtSetArg(args[num], XtNbackground, global_resources.flash_color); num++;
30933c89af1Smrg
310ad47b356Smrg    shell = XtCreatePopupShell("flash", overrideShellWidgetClass,
31133c89af1Smrg			       tree_info->tree_widget, args, num);
31233c89af1Smrg
31333c89af1Smrg    num = 0;
31433c89af1Smrg    XtSetArg(args[num], XtNborderWidth, &bw); num++;
31533c89af1Smrg    XtGetValues(shell, args, num);
316ad47b356Smrg
31733c89af1Smrg    bw *= 2;
31833c89af1Smrg
31933c89af1Smrg    num = 0;
32033c89af1Smrg    XtSetArg(args[num], XtNwidth, (width - bw)); num++;
32133c89af1Smrg    XtSetArg(args[num], XtNheight, (height - bw)); num++;
322ad47b356Smrg    XtSetValues(shell, args, num);
323ad47b356Smrg
32433c89af1Smrg    if (tree_info->num_flash_widgets + 1 > tree_info->alloc_flash_widgets) {
32533c89af1Smrg	tree_info->alloc_flash_widgets += MORE_FLASH_WIDGETS;
32633c89af1Smrg	tree_info->flash_widgets =
32733c89af1Smrg	    (Widget *) XtRealloc((char *)tree_info->flash_widgets,
32833c89af1Smrg			      sizeof(Widget) * tree_info->alloc_flash_widgets);
32933c89af1Smrg    }
33033c89af1Smrg
33133c89af1Smrg    tree_info->flash_widgets[tree_info->num_flash_widgets] = shell;
33233c89af1Smrg    tree_info->num_flash_widgets++;
33333c89af1Smrg}
33433c89af1Smrg
33533c89af1Smrg/*	Function Name: FlashWidgets
33633c89af1Smrg *	Description: Starts the widgets flashing.
33733c89af1Smrg *	Arguments: tree_info - the info about the tree (contains flash list)
33833c89af1Smrg *	Returns: none
33933c89af1Smrg */
34033c89af1Smrg
34133c89af1Smrgstatic void
342278eca22SmrgFlashWidgets(TreeInfo *tree_info)
34333c89af1Smrg{
34433c89af1Smrg    int i;
34533c89af1Smrg    unsigned long wait, half_flash;
34633c89af1Smrg    XtAppContext ac = XtWidgetToApplicationContext(tree_info->tree_widget);
34733c89af1Smrg
34833c89af1Smrg    if (tree_info->flash_widgets == NULL) /* no widgets to flash. */
34933c89af1Smrg	return;
35033c89af1Smrg
35133c89af1Smrg    wait = half_flash = global_resources.flash_time/2;
35233c89af1Smrg    for (i = 1; i < global_resources.num_flashes; i++) {
35333c89af1Smrg	XtAppAddTimeOut(ac, wait, FlashWidgetsOff,(XtPointer)tree_info);
35433c89af1Smrg	wait += half_flash;
35533c89af1Smrg	XtAppAddTimeOut(ac, wait, FlashWidgetsOn,(XtPointer)tree_info);
35633c89af1Smrg	wait += half_flash;
35733c89af1Smrg    }
35833c89af1Smrg
35933c89af1Smrg    wait += half_flash;
36033c89af1Smrg    XtAppAddTimeOut(ac, wait, FlashWidgetsCleanup, (XtPointer)tree_info);
36133c89af1Smrg
36233c89af1Smrg    FlashWidgetsOn((XtPointer) tree_info, (XtIntervalId *) NULL);
36333c89af1Smrg}
364ad47b356Smrg
36533c89af1Smrg/*	Function Name: FlashWidgetsOn
36633c89af1Smrg *	Description: Turns on all the Flash Widgets.
36733c89af1Smrg *	Arguments: info_ptr - pointer to the tree info.
36833c89af1Smrg *                 id - *** UNUSED ***.
36933c89af1Smrg *	Returns: none
37033c89af1Smrg */
37133c89af1Smrg
37233c89af1Smrg/* ARGSUSED */
37333c89af1Smrgstatic void
374278eca22SmrgFlashWidgetsOn(XtPointer info_ptr, XtIntervalId *id)
37533c89af1Smrg{
37633c89af1Smrg
377ad47b356Smrg    Cardinal i;
37833c89af1Smrg    TreeInfo * tree_info = (TreeInfo *) info_ptr;
379ad47b356Smrg
38033c89af1Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++) {
38133c89af1Smrg	XtRealizeWidget(tree_info->flash_widgets[i]);
38233c89af1Smrg	XMapRaised(XtDisplay(tree_info->flash_widgets[i]),
38333c89af1Smrg		   XtWindow(tree_info->flash_widgets[i]));
38433c89af1Smrg    }
38533c89af1Smrg}
38633c89af1Smrg
38733c89af1Smrg/*	Function Name: FlashWidgetsOff
38833c89af1Smrg *	Description: Turns off all the Flash Widgets.
38933c89af1Smrg *	Arguments: info_ptr - pointer to the tree info.
39033c89af1Smrg *                 id - *** UNUSED ***.
39133c89af1Smrg *	Returns: none
39233c89af1Smrg */
39333c89af1Smrg
39433c89af1Smrg/* ARGSUSED */
39533c89af1Smrgstatic void
396278eca22SmrgFlashWidgetsOff(XtPointer info_ptr, XtIntervalId *id)
39733c89af1Smrg{
398ad47b356Smrg    Cardinal i;
39933c89af1Smrg    TreeInfo * tree_info = (TreeInfo *) info_ptr;
400ad47b356Smrg
40133c89af1Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++)
40233c89af1Smrg	XtUnmapWidget(tree_info->flash_widgets[i]);
40333c89af1Smrg}
40433c89af1Smrg
40533c89af1Smrg/*	Function Name: FlashWidgetsCleanup
40633c89af1Smrg *	Description: Destroys all the Flash Widgets.
40733c89af1Smrg *	Arguments: info_ptr - pointer to the tree info.
40833c89af1Smrg *                 id - *** UNUSED ***.
40933c89af1Smrg *	Returns: none
41033c89af1Smrg */
41133c89af1Smrg
41233c89af1Smrg/* ARGSUSED */
41333c89af1Smrgstatic void
414278eca22SmrgFlashWidgetsCleanup(XtPointer info_ptr, XtIntervalId *id)
41533c89af1Smrg{
416ad47b356Smrg    Cardinal i;
41733c89af1Smrg    TreeInfo * tree_info = (TreeInfo *) info_ptr;
41833c89af1Smrg
41933c89af1Smrg/*
42033c89af1Smrg * Unmap 'em first for consistency.
42133c89af1Smrg */
422ad47b356Smrg
42333c89af1Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++)
42433c89af1Smrg	XtUnmapWidget(tree_info->flash_widgets[i]);
42533c89af1Smrg
42633c89af1Smrg    XFlush(XtDisplay(tree_info->tree_widget));
42733c89af1Smrg
428ad47b356Smrg    for (i = 0; i < tree_info->num_flash_widgets; i++)
42933c89af1Smrg	XtDestroyWidget(tree_info->flash_widgets[i]);
43033c89af1Smrg
43133c89af1Smrg    XtFree((char *)tree_info->flash_widgets);
43233c89af1Smrg    tree_info->flash_widgets = NULL;
43333c89af1Smrg    tree_info->num_flash_widgets = tree_info->alloc_flash_widgets = 0;
43433c89af1Smrg}
435