geometry.c revision 278eca22
1/*
2 * $Xorg: geometry.c,v 1.4 2001/02/09 02:05:29 xorgcvs Exp $
3 *
4Copyright 1989, 1998  The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25 *
26 * Author:  Chris D. Peterson, MIT X Consortium
27 */
28/* $XFree86: xc/programs/editres/geometry.c,v 1.4 2001/01/17 23:44:52 dawes Exp $ */
29
30#include <X11/Intrinsic.h>
31#include <X11/StringDefs.h>
32#include <X11/Shell.h>
33#include <stdio.h>
34
35#include <X11/Xaw/Cardinals.h>
36
37#include "editresP.h"
38
39/*
40 * Local function definitions
41 */
42static void AddToFlashList ( TreeInfo * tree_info, GetGeomInfo * geom_info,
43			     char ** errors );
44static void _AddToFlashList ( TreeInfo * tree_info, char ** errors,
45			      WNode * node, int x, int y, unsigned int width,
46			      unsigned int height );
47static void CreateFlashWidget ( TreeInfo * tree_info, int x, int y,
48				unsigned int width, unsigned int height );
49static void FlashWidgets ( TreeInfo * tree_info );
50static void FlashWidgetsOn ( XtPointer info_ptr, XtIntervalId * id );
51static void FlashWidgetsOff ( XtPointer info_ptr, XtIntervalId * id );
52static void FlashWidgetsCleanup ( XtPointer info_ptr, XtIntervalId * id );
53
54/*	Function Name: _FindWidget
55 *	Description: Finds a widget in the tree and shows it to the user.
56 *	Arguments: w - any widget in the application.
57 *	Returns: none.
58 */
59
60void
61_FindWidget(Widget w)
62{
63    char msg[BUFSIZ];
64    WNode * node;
65    Window win;
66    int x, y;			/* location of event in root coordinates. */
67
68    sprintf(msg, res_labels[14]);
69
70    SetMessage(global_screen_data.info_label, msg);
71
72    if ( (win = GetClientWindow(w, &x, &y)) != None) {
73	node = FindWidgetFromWindow(global_tree_info, win);
74	if (node != NULL) {
75	    ProtocolStream * stream = &(global_client.stream);
76
77	    _XEditResResetStream(stream);
78	    InsertWidgetFromNode(stream, node);
79	    _XEditResPut16(stream, (short) x);
80	    _XEditResPut16(stream, (short) y);
81	    SetCommand(w, LocalFindChild, NULL);
82	    return;
83	}
84    }
85
86    SetMessage(global_screen_data.info_label,
87      res_labels[15]);
88}
89
90
91/*	Function Name: DisplayChild
92 *	Description: Displays the child node returned by the client
93 *	Arguments: event - the event from the client.
94 *	Returns: none.
95 */
96
97void
98DisplayChild(Event *event)
99{
100    FindChildEvent * find_event = (FindChildEvent *) event;
101    WNode * node;
102    char msg[BUFSIZ];
103
104    node = FindNode(global_tree_info->top_node, find_event->widgets.ids,
105		    find_event->widgets.num_widgets);
106
107    if (node == NULL) {
108	sprintf(msg, res_labels[13]);
109	SetMessage(global_screen_data.info_label, msg);
110	return;
111    }
112
113    SetAndCenterTreeNode(node);
114
115    node = node->tree_info->top_node;
116
117    sprintf(msg, res_labels[12], node->name, node->class);
118    SetMessage(global_screen_data.info_label, msg);
119
120    _FlashActiveWidgets(global_tree_info);
121}
122
123/*	Function Name: _FlashActiveWidgets
124 *	Description: Highlights all active widgets in the tree.
125 *	Arguments: tree_info - information about the current tree.
126 *	Returns: none.
127 */
128
129void
130_FlashActiveWidgets(TreeInfo *tree_info)
131{
132    int i;
133    ProtocolStream * stream = &(global_client.stream);
134
135    if (tree_info == NULL) {
136	SetMessage(global_screen_data.info_label,
137		   res_labels[17]);
138	return;
139    }
140
141    if (tree_info->num_nodes == 0) {
142	SetMessage(global_screen_data.info_label,res_labels[18]);
143	return;
144    }
145
146    _XEditResResetStream(stream);
147    /*
148     * Insert the number of widgets.
149     */
150    _XEditResPut16(stream, (unsigned short) tree_info->num_nodes);
151
152    for (i = 0; i < tree_info->num_nodes; i++)
153	InsertWidgetFromNode(stream, global_tree_info->active_nodes[i]);
154
155    SetCommand(tree_info->tree_widget, LocalFlashWidget, NULL);
156}
157
158/*	Function Name: HandleFlashWidget
159 *	Description: Is called when client has returned geometry of all widget
160 *                   to flash.
161 *	Arguments: event - the event containing the client info.
162 *	Returns: none.
163 */
164
165char *
166HandleFlashWidget(Event *event)
167{
168    GetGeomEvent * geom_event = (GetGeomEvent *) event;
169    char * errors = NULL;
170    int i;
171
172    for (i = 0; i < (int)geom_event->num_entries; i++)
173	AddToFlashList(global_tree_info, geom_event->info + i, &errors);
174
175    FlashWidgets(global_tree_info);
176
177    return(errors);
178}
179
180/*	Function Name: AddWidgetToFlashList
181 *	Description: Adds a widget to the list of widget to flash.
182 *	Arguments: tree_info - info about this tree.
183 *                 geom_info - the info from the client about this widget.
184 *                 errors - a string containing the errors.
185 *	Returns: none
186 */
187
188static void
189AddToFlashList(TreeInfo *tree_info, GetGeomInfo *geom_info, char **errors)
190{
191    WNode * node;
192    char buf[BUFSIZ];
193
194    node = FindNode(tree_info->top_node,
195		    geom_info->widgets.ids, geom_info->widgets.num_widgets);
196
197    if (node == NULL) {
198	sprintf(buf, "Editres Internal Error: Unable to FindNode.\n");
199	AddString(errors, buf);
200	return;
201    }
202
203    if (geom_info->error) {
204	AddString(errors, geom_info->message);
205	return;
206    }
207
208    if (!geom_info->visable) {
209	sprintf(buf, "%s(0x%lx) - This widget is not mapped\n",
210		node->name, node->id);
211	AddString(errors, buf);
212	return;
213    }
214
215    _AddToFlashList(tree_info, errors, node,
216		    geom_info->x, geom_info->y,
217		    geom_info->width + geom_info->border_width,
218		    geom_info->height + geom_info->border_width);
219}
220
221/*	Function Name: _AddToFlashList
222 *	Description: adds the window to the current client's flash list.
223 *	Arguments: errors - a string to stuff any errors encountered.
224 *                 node - the node associated with this object.
225 *                 x, y - location of the flash widget in root coords.
226 *                 width, height - size of the flash widget.
227 *	Returns: none.
228 */
229
230static void
231_AddToFlashList(TreeInfo *tree_info, char **errors, WNode *node,
232		int x, int y, unsigned int width, unsigned int height)
233{
234    Display * dpy = XtDisplay(tree_info->tree_widget);
235    Window window = (Window) node->window;
236    XWindowAttributes attrs;
237
238    if (window == EDITRES_IS_OBJECT)
239	window = node->parent->window;
240
241    if (window == EDITRES_IS_UNREALIZED) {
242	char buf[BUFSIZ];
243
244	if (node->window == EDITRES_IS_OBJECT)
245	    sprintf(buf, "%s(0x%lx) - This object's parent is unrealized\n",
246		    node->name, node->id);
247	else
248	    sprintf(buf, "%s(0x%lx) - This widget is unrealized\n",
249		    node->name, node->id);
250
251	AddString(errors, buf);
252	return;
253    }
254
255    global_error_code = NO_ERROR;                 /* Reset Error code. */
256    global_old_error_handler = XSetErrorHandler(HandleXErrors);
257    global_serial_num = NextRequest(dpy);
258
259    XGetWindowAttributes(dpy, window, &attrs);
260
261    XSync(dpy, FALSE);
262    XSetErrorHandler(global_old_error_handler);
263    if (global_error_code == NO_WINDOW) {
264	char buf[BUFSIZ];
265
266	sprintf(buf, "%s(0x%lx) - This widget's window no longer exists.\n",
267		node->name, node->id);
268	AddString(errors, buf);
269	return;
270    }
271
272    if (attrs.map_state != IsViewable) {
273	char buf[BUFSIZ];
274
275	sprintf(buf, "%s(0x%lx) - This widget is not mapped.\n",
276		node->name, node->id);
277	AddString(errors, buf);
278	return;
279    }
280
281    CreateFlashWidget(tree_info, x, y, width, height);
282}
283
284/*	Function Name: CreateFlashWidget
285 *	Description: Creates a widget of the size specified that
286 *                   will flash on the display, and adds it to the list
287 *                   of widgets to flash.
288 *	Arguments: tree_info - the tree information structure.
289 *                 x,y,width, height - size and location of the flash widget.
290 *	Returns: none.
291 */
292
293#define MORE_FLASH_WIDGETS 5
294
295static void
296CreateFlashWidget(TreeInfo *tree_info, int x, int y,
297		  unsigned int width, unsigned int height)
298{
299    Widget shell;
300    Arg args[3];
301    Cardinal num = 0;
302    Dimension bw;
303
304    XtSetArg(args[num], XtNx, x); num++;
305    XtSetArg(args[num], XtNy, y); num++;
306    XtSetArg(args[num], XtNbackground, global_resources.flash_color); num++;
307
308    shell = XtCreatePopupShell("flash", overrideShellWidgetClass,
309			       tree_info->tree_widget, args, num);
310
311    num = 0;
312    XtSetArg(args[num], XtNborderWidth, &bw); num++;
313    XtGetValues(shell, args, num);
314
315    bw *= 2;
316
317    num = 0;
318    XtSetArg(args[num], XtNwidth, (width - bw)); num++;
319    XtSetArg(args[num], XtNheight, (height - bw)); num++;
320    XtSetValues(shell, args, num);
321
322    if (tree_info->num_flash_widgets + 1 > tree_info->alloc_flash_widgets) {
323	tree_info->alloc_flash_widgets += MORE_FLASH_WIDGETS;
324	tree_info->flash_widgets =
325	    (Widget *) XtRealloc((char *)tree_info->flash_widgets,
326			      sizeof(Widget) * tree_info->alloc_flash_widgets);
327    }
328
329    tree_info->flash_widgets[tree_info->num_flash_widgets] = shell;
330    tree_info->num_flash_widgets++;
331}
332
333/*	Function Name: FlashWidgets
334 *	Description: Starts the widgets flashing.
335 *	Arguments: tree_info - the info about the tree (contains flash list)
336 *	Returns: none
337 */
338
339static void
340FlashWidgets(TreeInfo *tree_info)
341{
342    int i;
343    unsigned long wait, half_flash;
344    XtAppContext ac = XtWidgetToApplicationContext(tree_info->tree_widget);
345
346    if (tree_info->flash_widgets == NULL) /* no widgets to flash. */
347	return;
348
349    wait = half_flash = global_resources.flash_time/2;
350    for (i = 1; i < global_resources.num_flashes; i++) {
351	XtAppAddTimeOut(ac, wait, FlashWidgetsOff,(XtPointer)tree_info);
352	wait += half_flash;
353	XtAppAddTimeOut(ac, wait, FlashWidgetsOn,(XtPointer)tree_info);
354	wait += half_flash;
355    }
356
357    wait += half_flash;
358    XtAppAddTimeOut(ac, wait, FlashWidgetsCleanup, (XtPointer)tree_info);
359
360    FlashWidgetsOn((XtPointer) tree_info, (XtIntervalId *) NULL);
361}
362
363/*	Function Name: FlashWidgetsOn
364 *	Description: Turns on all the Flash Widgets.
365 *	Arguments: info_ptr - pointer to the tree info.
366 *                 id - *** UNUSED ***.
367 *	Returns: none
368 */
369
370/* ARGSUSED */
371static void
372FlashWidgetsOn(XtPointer info_ptr, XtIntervalId *id)
373{
374
375    int i;
376    TreeInfo * tree_info = (TreeInfo *) info_ptr;
377
378    for (i = 0; i < tree_info->num_flash_widgets; i++) {
379	XtRealizeWidget(tree_info->flash_widgets[i]);
380	XMapRaised(XtDisplay(tree_info->flash_widgets[i]),
381		   XtWindow(tree_info->flash_widgets[i]));
382    }
383}
384
385/*	Function Name: FlashWidgetsOff
386 *	Description: Turns off all the Flash Widgets.
387 *	Arguments: info_ptr - pointer to the tree info.
388 *                 id - *** UNUSED ***.
389 *	Returns: none
390 */
391
392/* ARGSUSED */
393static void
394FlashWidgetsOff(XtPointer info_ptr, XtIntervalId *id)
395{
396    int i;
397    TreeInfo * tree_info = (TreeInfo *) info_ptr;
398
399    for (i = 0; i < tree_info->num_flash_widgets; i++)
400	XtUnmapWidget(tree_info->flash_widgets[i]);
401}
402
403/*	Function Name: FlashWidgetsCleanup
404 *	Description: Destroys all the Flash Widgets.
405 *	Arguments: info_ptr - pointer to the tree info.
406 *                 id - *** UNUSED ***.
407 *	Returns: none
408 */
409
410/* ARGSUSED */
411static void
412FlashWidgetsCleanup(XtPointer info_ptr, XtIntervalId *id)
413{
414    int i;
415    TreeInfo * tree_info = (TreeInfo *) info_ptr;
416
417/*
418 * Unmap 'em first for consistency.
419 */
420
421    for (i = 0; i < tree_info->num_flash_widgets; i++)
422	XtUnmapWidget(tree_info->flash_widgets[i]);
423
424    XFlush(XtDisplay(tree_info->tree_widget));
425
426    for (i = 0; i < tree_info->num_flash_widgets; i++)
427	XtDestroyWidget(tree_info->flash_widgets[i]);
428
429    XtFree((char *)tree_info->flash_widgets);
430    tree_info->flash_widgets = NULL;
431    tree_info->num_flash_widgets = tree_info->alloc_flash_widgets = 0;
432}
433