geometry.c revision 352bf44e
1/* 2 * 3Copyright 1989, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in 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 */ 40static void AddToFlashList ( TreeInfo * tree_info, GetGeomInfo * geom_info, 41 char ** errors ); 42static void _AddToFlashList ( TreeInfo * tree_info, char ** errors, 43 WNode * node, int x, int y, unsigned int width, 44 unsigned int height ); 45static void CreateFlashWidget ( TreeInfo * tree_info, int x, int y, 46 unsigned int width, unsigned int height ); 47static void FlashWidgets ( TreeInfo * tree_info ); 48static void FlashWidgetsOn ( XtPointer info_ptr, XtIntervalId * id ); 49static void FlashWidgetsOff ( XtPointer info_ptr, XtIntervalId * id ); 50static 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 58void 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 95void 96DisplayChild(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 127void 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 163char * 164HandleFlashWidget(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 186static void 187AddToFlashList(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->visible) { 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 229static void 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 297static void 298CreateFlashWidget(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 341static void 342FlashWidgets(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 */ 373static void 374FlashWidgetsOn(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 */ 395static void 396FlashWidgetsOff(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 */ 413static void 414FlashWidgetsCleanup(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