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