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