| File: | src/ResConfig.c |
| Location: | line 122, column 9 |
| Description: | Dereference of null pointer |
| 1 | /* | |||||
| 2 | ||||||
| 3 | Copyright 1987, 1988, 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 | */ | |||||
| 26 | /***************************************************************** | |||||
| 27 | ||||||
| 28 | (C) COPYRIGHT International Business Machines Corp. 1992,1997 | |||||
| 29 | All Rights Reserved | |||||
| 30 | ||||||
| 31 | Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
| 32 | of this software and associated documentation files (the "Software"), to deal | |||||
| 33 | in the Software without restriction, including without limitation the rights | |||||
| 34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
| 35 | copies of the Software. | |||||
| 36 | ||||||
| 37 | The above copyright notice and this permission notice shall be included in | |||||
| 38 | all copies or substantial portions of the Software. | |||||
| 39 | ||||||
| 40 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| 41 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| 42 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
| 43 | THE IBM CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, | |||||
| 44 | BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, | |||||
| 45 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR | |||||
| 46 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
| 47 | ||||||
| 48 | Except as contained in this notice, the name of the IBM Corporation shall | |||||
| 49 | not be used in advertising or otherwise to promote the sale, use or other | |||||
| 50 | dealings in this Software without prior written authorization from the IBM | |||||
| 51 | Corporation. | |||||
| 52 | ||||||
| 53 | ******************************************************************/ | |||||
| 54 | ||||||
| 55 | #ifdef HAVE_CONFIG_H1 | |||||
| 56 | #include <config.h> | |||||
| 57 | #endif | |||||
| 58 | #include "Intrinsic.h" | |||||
| 59 | #include "IntrinsicI.h" | |||||
| 60 | #include "Core.h" | |||||
| 61 | #include "CoreP.h" | |||||
| 62 | #include "ShellP.h" | |||||
| 63 | #include "StringDefs.h" | |||||
| 64 | #include "ResConfigP.h" | |||||
| 65 | #include <X11/Xatom.h> | |||||
| 66 | #include <stdio.h> | |||||
| 67 | #include <stdlib.h> | |||||
| 68 | ||||||
| 69 | #define MAX_BUFFER512 512 | |||||
| 70 | ||||||
| 71 | static void _search_child(Widget, char *, char *, char *, char *, char, char *); | |||||
| 72 | static void _set_and_search(Widget, char *, char *, char *, char *, char , char *); | |||||
| 73 | static int _locate_children(Widget, Widget **); | |||||
| 74 | ||||||
| 75 | /* | |||||
| 76 | * NAME: _set_resource_values | |||||
| 77 | * | |||||
| 78 | * FUNCTION: | |||||
| 79 | * This function sets the value on the widget. It must first determine | |||||
| 80 | * if the last part is a valid resource for that widget. (eg. | |||||
| 81 | * labelString is a valid resource for label but not for bulletin board) | |||||
| 82 | * It must also add the resource to the application's resource database | |||||
| 83 | * and then query it out using specific resource strings that it builds | |||||
| 84 | * from the widget information. This ensures that a customizing tool | |||||
| 85 | * on-the-fly paradigm is followed: an application that is | |||||
| 86 | * instantaneously updated should look the same as one that is restarted | |||||
| 87 | * and uses the .Xdefaults file. | |||||
| 88 | * | |||||
| 89 | * PARAMETERS: | |||||
| 90 | * w the widget to match | |||||
| 91 | * resource the resource string to be matched | |||||
| 92 | * value the value to be set | |||||
| 93 | * last_part the last resource part (e.g. *background) | |||||
| 94 | * | |||||
| 95 | * RETURN VALUES: void | |||||
| 96 | * | |||||
| 97 | * ERRORS: none | |||||
| 98 | */ | |||||
| 99 | static void | |||||
| 100 | _set_resource_values ( | |||||
| 101 | Widget w, | |||||
| 102 | char *resource, | |||||
| 103 | char *value, | |||||
| 104 | char *last_part) | |||||
| 105 | { | |||||
| 106 | XrmDatabase db = NULL((void*)0); | |||||
| 107 | char *resource_name = NULL((void*)0); | |||||
| 108 | char *resource_class = NULL((void*)0); | |||||
| 109 | char *return_type; | |||||
| 110 | XrmValue return_value; | |||||
| 111 | char *resource_value; | |||||
| 112 | Widget cur = w; | |||||
| 113 | char *temp; | |||||
| 114 | XtResourceList resources_return = NULL((void*)0); | |||||
| 115 | Cardinal num_resources_return = 0; | |||||
| 116 | Cardinal res_index; | |||||
| 117 | Boolean found_resource = False0; | |||||
| 118 | Display *dpy; | |||||
| 119 | XrmDatabase tmp_db; | |||||
| 120 | ||||||
| 121 | if (!XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x04)) | |||||
| 122 | dpy = XtDisplay (w->core.parent)(((w->core.parent)->core.screen)->display); | |||||
| ||||||
| 123 | else | |||||
| 124 | dpy = XtDisplay (w)(((w)->core.screen)->display); | |||||
| 125 | tmp_db = XtDatabase(dpy); | |||||
| 126 | ||||||
| 127 | /* | |||||
| 128 | * get a list of all the valid resources for this widget | |||||
| 129 | */ | |||||
| 130 | XtGetResourceList (w->core.widget_class, | |||||
| 131 | &resources_return, &num_resources_return); | |||||
| 132 | ||||||
| 133 | /* | |||||
| 134 | * try to match the last_part of the resource string with | |||||
| 135 | * a resource in this resource list | |||||
| 136 | */ | |||||
| 137 | for (res_index=0; res_index<num_resources_return; res_index++) { | |||||
| 138 | if ((strcmp (last_part, | |||||
| 139 | resources_return[res_index].resource_name) == 0) || | |||||
| 140 | (strcmp (last_part, | |||||
| 141 | resources_return[res_index].resource_class) == 0)) { | |||||
| 142 | found_resource = True1; | |||||
| 143 | break; | |||||
| 144 | } | |||||
| 145 | } | |||||
| 146 | ||||||
| 147 | /* | |||||
| 148 | * if resource is not a valid resource for this widget | |||||
| 149 | * or the resource name or class are NULL | |||||
| 150 | * then exit this function | |||||
| 151 | */ | |||||
| 152 | if (!found_resource | |||||
| 153 | || !resources_return[res_index].resource_name | |||||
| 154 | || !resources_return[res_index].resource_class) { | |||||
| 155 | XtFree ((char *) resources_return); | |||||
| 156 | return; | |||||
| 157 | } | |||||
| 158 | ||||||
| 159 | /* | |||||
| 160 | * build the full resource name and class specifications so | |||||
| 161 | * that you can query the resource database | |||||
| 162 | * eg: .app.button1.foreground | |||||
| 163 | * .App.XmPushButton.Foreground | |||||
| 164 | */ | |||||
| 165 | while (cur != NULL((void*)0)) { | |||||
| 166 | /* | |||||
| 167 | * create resource name string | |||||
| 168 | */ | |||||
| 169 | if (resource_name) { | |||||
| 170 | XtAsprintf (&temp, ".%s%s", cur->core.name, resource_name); | |||||
| 171 | XtFree (resource_name); | |||||
| 172 | } else if (!XtIsWidget (cur)(((Object)(cur))->object.widget_class->core_class.class_inited & 0x04) || !cur->core.name) { | |||||
| 173 | cur = XtParent(cur)((cur)->core.parent); | |||||
| 174 | continue; | |||||
| 175 | } else { | |||||
| 176 | XtAsprintf (&temp, ".%s", cur->core.name); | |||||
| 177 | } | |||||
| 178 | resource_name = temp; | |||||
| 179 | ||||||
| 180 | /* | |||||
| 181 | * create resource class string | |||||
| 182 | */ | |||||
| 183 | if ((XtIsTopLevelShell (cur)(((Object)(cur))->object.widget_class->core_class.class_inited & 0x80)) && (XtParent (cur)((cur)->core.parent) == NULL((void*)0))) { | |||||
| 184 | ApplicationShellWidget top = | |||||
| 185 | (ApplicationShellWidget) (cur); | |||||
| 186 | ||||||
| 187 | if (resource_class) { | |||||
| 188 | XtAsprintf (&temp, ".%s%s", | |||||
| 189 | top->application.class, resource_class); | |||||
| 190 | } else { | |||||
| 191 | XtAsprintf (&temp, ".%s", | |||||
| 192 | top->application.class); | |||||
| 193 | } | |||||
| 194 | } else { | |||||
| 195 | if (resource_class) { | |||||
| 196 | XtAsprintf (&temp, ".%s%s", | |||||
| 197 | cur->core.widget_class->core_class.class_name, | |||||
| 198 | resource_class); | |||||
| 199 | } else { | |||||
| 200 | XtAsprintf (&temp, ".%s", | |||||
| 201 | cur->core.widget_class->core_class.class_name); | |||||
| 202 | } | |||||
| 203 | } | |||||
| 204 | if (resource_class != NULL((void*)0)) | |||||
| 205 | XtFree (resource_class); | |||||
| 206 | resource_class = temp; | |||||
| 207 | ||||||
| 208 | cur = XtParent(cur)((cur)->core.parent); | |||||
| 209 | } | |||||
| 210 | ||||||
| 211 | /* | |||||
| 212 | * add the resource name to the end of the resource name string | |||||
| 213 | */ | |||||
| 214 | XtAsprintf (&temp, "%s.%s", resource_name, | |||||
| 215 | resources_return[res_index].resource_name); | |||||
| 216 | if (resource_name != NULL((void*)0)) | |||||
| 217 | XtFree (resource_name); | |||||
| 218 | resource_name = temp; | |||||
| 219 | ||||||
| 220 | /* | |||||
| 221 | * add the resource class to the end of the resource class string | |||||
| 222 | */ | |||||
| 223 | XtAsprintf (&temp, "%s.%s", resource_class, | |||||
| 224 | resources_return[res_index].resource_class); | |||||
| 225 | if (resource_class != NULL((void*)0)) | |||||
| 226 | XtFree (resource_class); | |||||
| 227 | resource_class = temp; | |||||
| 228 | ||||||
| 229 | #ifdef DEBUG | |||||
| 230 | fprintf (stderr__stderrp, "resource_name = %s\n", resource_name); | |||||
| 231 | fprintf (stderr__stderrp, "resource_class = %s\n", resource_class); | |||||
| 232 | #endif | |||||
| 233 | ||||||
| 234 | /* | |||||
| 235 | * put the resource and its value in a resource database and | |||||
| 236 | * then query it back out again using the specific name and | |||||
| 237 | * class resource strings that were built above. This is | |||||
| 238 | * necessary to maintain a precedence similar to the .Xdefaults | |||||
| 239 | * file | |||||
| 240 | */ | |||||
| 241 | XrmPutStringResource (&db, resource, value); | |||||
| 242 | XrmMergeDatabases (db, &tmp_db); | |||||
| 243 | XrmGetResource (tmp_db, resource_name, resource_class, | |||||
| 244 | &return_type, &return_value); | |||||
| 245 | if (return_type) | |||||
| 246 | resource_value = XtNewString (return_value.addr)((return_value.addr) != ((void*)0) ? (__builtin___strcpy_chk ( XtMalloc((unsigned)strlen(return_value.addr) + 1), return_value .addr, __builtin_object_size (XtMalloc((unsigned)strlen(return_value .addr) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||||
| 247 | else | |||||
| 248 | resource_value = XtNewString (value)((value) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned )strlen(value) + 1), value, __builtin_object_size (XtMalloc(( unsigned)strlen(value) + 1), 2 > 1 ? 1 : 0))) : ((void*)0) ); | |||||
| 249 | ||||||
| 250 | #ifdef DEBUG | |||||
| 251 | fprintf (stderr__stderrp, | |||||
| 252 | "Apply:\n\twidget = %s\n\tlast_part = %s\n\tvalue = %s\n", | |||||
| 253 | (w->core.name == NULL((void*)0)) ? "NULL" : w->core.name, | |||||
| 254 | resources_return[res_index].resource_name, | |||||
| 255 | resource_value); | |||||
| 256 | #endif | |||||
| 257 | /* | |||||
| 258 | * use XtVaSetValues with XtVaTypedArg to convert the value of | |||||
| 259 | * type String the the same type as the resource (last_part). | |||||
| 260 | * Then set the value. | |||||
| 261 | */ | |||||
| 262 | XtVaSetValues (w, | |||||
| 263 | XtVaTypedArg"XtVaTypedArg", resources_return[res_index].resource_name, | |||||
| 264 | XtRString((char*)&XtStrings[1797]), resource_value, | |||||
| 265 | strlen (resource_value) + 1, | |||||
| 266 | NULL((void*)0)); | |||||
| 267 | ||||||
| 268 | XtFree ((char *) resources_return); | |||||
| 269 | XtFree (resource_name); | |||||
| 270 | XtFree (resource_class); | |||||
| 271 | XtFree (resource_value); | |||||
| 272 | } | |||||
| 273 | ||||||
| 274 | /* | |||||
| 275 | * NAME: _apply_values_to_children | |||||
| 276 | * | |||||
| 277 | * FUNCTION: | |||||
| 278 | * Once the resource string matches the value must be applied to | |||||
| 279 | * all children if applicable. (eg. App*Form.background must apply | |||||
| 280 | * background to all children of the Form widget) | |||||
| 281 | * | |||||
| 282 | * PARAMETERS: | |||||
| 283 | * w the widget to match | |||||
| 284 | * remainder the part of the resource string left over | |||||
| 285 | * resource the resource string to be matched | |||||
| 286 | * value the value to be set | |||||
| 287 | * last_token the last * or . before the final resoruce part | |||||
| 288 | * last_part the last resource part (e.g. *background) | |||||
| 289 | * | |||||
| 290 | * RETURN VALUES: void | |||||
| 291 | * | |||||
| 292 | * ERRORS: none | |||||
| 293 | */ | |||||
| 294 | static void | |||||
| 295 | _apply_values_to_children ( | |||||
| 296 | Widget w, | |||||
| 297 | char *remainder, | |||||
| 298 | char *resource, | |||||
| 299 | char *value, | |||||
| 300 | char last_token, | |||||
| 301 | char *last_part) | |||||
| 302 | { | |||||
| 303 | int i; | |||||
| 304 | int num_children; | |||||
| 305 | Widget *children; | |||||
| 306 | ||||||
| 307 | /* | |||||
| 308 | * Recursively search through the children | |||||
| 309 | */ | |||||
| 310 | num_children = _locate_children (w, &children); | |||||
| 311 | ||||||
| 312 | for (i=0; i<num_children; i++) { | |||||
| 313 | ||||||
| 314 | #ifdef DEBUG | |||||
| 315 | if (XtIsWidget (children[i])(((Object)(children[i]))->object.widget_class->core_class .class_inited & 0x04) && XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x04)) | |||||
| 316 | fprintf (stderr__stderrp, "searching child %s of parent %s\n", | |||||
| 317 | children[i]->core.name, w->core.name); | |||||
| 318 | else | |||||
| 319 | fprintf (stderr__stderrp,"searching child (NULL) of parent %s\n", | |||||
| 320 | w->core.name); | |||||
| 321 | if (!XtIsWidget (children[i])(((Object)(children[i]))->object.widget_class->core_class .class_inited & 0x04)) | |||||
| 322 | fprintf (stderr__stderrp, "children[%d] is NOT a widget\n", i); | |||||
| 323 | if (!XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x04)) | |||||
| 324 | fprintf (stderr__stderrp, "w is NOT a widget\n"); | |||||
| 325 | #endif | |||||
| 326 | ||||||
| 327 | _set_resource_values (children[i], resource, value, last_part); | |||||
| 328 | _apply_values_to_children (children[i], remainder, | |||||
| 329 | resource, value, last_token, last_part); | |||||
| 330 | } | |||||
| 331 | ||||||
| 332 | XtFree ((char *)children); | |||||
| 333 | } | |||||
| 334 | ||||||
| 335 | /* | |||||
| 336 | * NAME: _search_child | |||||
| 337 | * | |||||
| 338 | * FUNCTION: | |||||
| 339 | * descends through each child of the tree | |||||
| 340 | * | |||||
| 341 | * PARAMETERS: | |||||
| 342 | * w the widget whose children are to be searched | |||||
| 343 | * indx index into the resource string | |||||
| 344 | * remainder the remaining part of the resource string | |||||
| 345 | * resource the resource string to be matched | |||||
| 346 | * value the value to be applied | |||||
| 347 | * last_token the last * or . before the final resoruce part | |||||
| 348 | * last_part the last resource part (e.g. *background) | |||||
| 349 | * | |||||
| 350 | * RETURN VALUES: none | |||||
| 351 | * | |||||
| 352 | * ERRORS: none | |||||
| 353 | */ | |||||
| 354 | static void | |||||
| 355 | _search_child ( | |||||
| 356 | Widget w, | |||||
| 357 | char *indx, | |||||
| 358 | char *remainder, | |||||
| 359 | char *resource, | |||||
| 360 | char *value, | |||||
| 361 | char last_token, | |||||
| 362 | char *last_part) | |||||
| 363 | { | |||||
| 364 | int i; | |||||
| 365 | int num_children; | |||||
| 366 | Widget *children; | |||||
| 367 | ||||||
| 368 | /* | |||||
| 369 | * Recursively search through the children | |||||
| 370 | */ | |||||
| 371 | num_children = _locate_children (w, &children); | |||||
| 372 | for (i=0; i<num_children; i++) { | |||||
| 373 | _set_and_search (children[i], indx, remainder, resource, | |||||
| 374 | value, last_token, last_part); | |||||
| 375 | } | |||||
| 376 | ||||||
| 377 | XtFree ((char *)children); | |||||
| 378 | } | |||||
| 379 | ||||||
| 380 | /* | |||||
| 381 | * NAME: _get_part | |||||
| 382 | * | |||||
| 383 | * FUNCTION: | |||||
| 384 | * This routine will return the token and following part of the resource | |||||
| 385 | * when given the current index it will update the index accordingly | |||||
| 386 | * | |||||
| 387 | * PARAMETERS: | |||||
| 388 | * remainder the part of the resource string left over | |||||
| 389 | * indx the index into the resource string | |||||
| 390 | * part the parsed off part of the resource string | |||||
| 391 | * | |||||
| 392 | * RETURN VALUES: | |||||
| 393 | * char the token (* or . or ?) preceding the resource part | |||||
| 394 | * indx the index into the resource string | |||||
| 395 | * part the parsed off part of the resource string | |||||
| 396 | * | |||||
| 397 | * ERRORS: none | |||||
| 398 | */ | |||||
| 399 | /* ARGSUSED */ | |||||
| 400 | static char | |||||
| 401 | _get_part ( | |||||
| 402 | char *remainder, | |||||
| 403 | char **indx, | |||||
| 404 | char **part) | |||||
| 405 | { | |||||
| 406 | char buffer[MAX_BUFFER512]; | |||||
| 407 | char *buf_ptr; | |||||
| 408 | char token = **indx; | |||||
| 409 | int i = 0; | |||||
| 410 | ||||||
| 411 | /* | |||||
| 412 | * copy the remainder part into the buffer | |||||
| 413 | */ | |||||
| 414 | buf_ptr = buffer; | |||||
| 415 | (*indx)++; /* get rid of the token */ | |||||
| 416 | while (**indx && (**indx != '.') && (**indx != '*')) { | |||||
| 417 | *buf_ptr++ = *(*indx)++; | |||||
| 418 | if (++i >= MAX_BUFFER512 - 1) | |||||
| 419 | break; | |||||
| 420 | } | |||||
| 421 | *buf_ptr = '\0'; | |||||
| 422 | ||||||
| 423 | *part = XtNewString (buffer)((buffer) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc(( unsigned)strlen(buffer) + 1), buffer, __builtin_object_size ( XtMalloc((unsigned)strlen(buffer) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); /* return a new string to part */ | |||||
| 424 | ||||||
| 425 | if (strcmp (*indx, "") == 0) | |||||
| 426 | *indx = NULL((void*)0); | |||||
| 427 | ||||||
| 428 | return (token); /* return the token */ | |||||
| 429 | } | |||||
| 430 | ||||||
| 431 | /* | |||||
| 432 | * NAME: _match_resource_to_widget | |||||
| 433 | * | |||||
| 434 | * FUNCTION: | |||||
| 435 | * This function matches the resource part to the widget name or class | |||||
| 436 | * | |||||
| 437 | * PARAMETERS: | |||||
| 438 | * w the widget to match | |||||
| 439 | * part the parsed off part of the resource string | |||||
| 440 | * | |||||
| 441 | * RETURN VALUES: | |||||
| 442 | * Boolean true if a match occurs | |||||
| 443 | * | |||||
| 444 | * ERRORS: none | |||||
| 445 | */ | |||||
| 446 | static Boolean | |||||
| 447 | _match_resource_to_widget ( | |||||
| 448 | Widget w, | |||||
| 449 | char *part) | |||||
| 450 | { | |||||
| 451 | /* | |||||
| 452 | * Match any widget at this level if the ? is used | |||||
| 453 | */ | |||||
| 454 | if (strcmp (part, "?") == 0) | |||||
| 455 | return (True1); | |||||
| 456 | ||||||
| 457 | /* | |||||
| 458 | * if the object is really a widget then its name can be matched | |||||
| 459 | * otherwise only use its class. Note that if you try to reference | |||||
| 460 | * a widget name when the object is not a widget, you may get a | |||||
| 461 | * core dump from an invalid pointer reference. | |||||
| 462 | */ | |||||
| 463 | if (XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x04)) { | |||||
| 464 | if ((strcmp (w->core.name, part) == 0) || | |||||
| 465 | (strcmp (w->core.widget_class->core_class.class_name, | |||||
| 466 | part) == 0)) | |||||
| 467 | return (True1); | |||||
| 468 | else | |||||
| 469 | return (False0); | |||||
| 470 | } else { | |||||
| 471 | if ((strcmp (w->core.widget_class->core_class.class_name, | |||||
| 472 | part) == 0)) | |||||
| 473 | return (True1); | |||||
| 474 | else | |||||
| 475 | return (False0); | |||||
| 476 | } | |||||
| 477 | } | |||||
| 478 | ||||||
| 479 | /* | |||||
| 480 | * NAME: _set_and_search | |||||
| 481 | * | |||||
| 482 | * FUNCTION: | |||||
| 483 | * The algorithm to search the widget tree and apply a resource string | |||||
| 484 | * | |||||
| 485 | * PARAMETERS: | |||||
| 486 | * w the widget to match | |||||
| 487 | * indx the index into the resource string | |||||
| 488 | * remainder the part of the resource string left over | |||||
| 489 | * resource the resource string to be matched | |||||
| 490 | * value the value to be set | |||||
| 491 | * last_token the last * or . before the final resoruce part | |||||
| 492 | * last_part the last resource part (e.g. *background) | |||||
| 493 | * | |||||
| 494 | * RETURN VALUES: none | |||||
| 495 | * | |||||
| 496 | * ERRORS: none | |||||
| 497 | * | |||||
| 498 | * ALGORITHM: | |||||
| 499 | * loop (look at all children) | |||||
| 500 | * if (resource segment and current widget match) | |||||
| 501 | * if '.' | |||||
| 502 | * if at end of resource string | |||||
| 503 | * set values ( .=over all children | |||||
| 504 | * *=this widget only) | |||||
| 505 | * else | |||||
| 506 | * descend the widget tree | |||||
| 507 | * and parse off resource segment | |||||
| 508 | * exit the loop | |||||
| 509 | * if '*' | |||||
| 510 | * if at end of resource string | |||||
| 511 | * set values ( .=over all children | |||||
| 512 | * *=this widget only) | |||||
| 513 | * descend and parse | |||||
| 514 | * else | |||||
| 515 | * if '.' | |||||
| 516 | * continue looping | |||||
| 517 | * if '*' | |||||
| 518 | * descend but don't parse | |||||
| 519 | * continue looping | |||||
| 520 | * end loop | |||||
| 521 | * | |||||
| 522 | * NOTE: the _set_resource_values routine will not allow a value to be | |||||
| 523 | * set on a resource against the rules of the resource database manager | |||||
| 524 | */ | |||||
| 525 | static void | |||||
| 526 | _set_and_search ( | |||||
| 527 | Widget w, | |||||
| 528 | char *indx, | |||||
| 529 | char *remainder, | |||||
| 530 | char *resource, | |||||
| 531 | char *value, | |||||
| 532 | char last_token, | |||||
| 533 | char *last_part) | |||||
| 534 | { | |||||
| 535 | char *part; | |||||
| 536 | char *local_index = indx; | |||||
| 537 | char token; | |||||
| 538 | ||||||
| 539 | /* | |||||
| 540 | * parse off one part, return token and the new index | |||||
| 541 | */ | |||||
| 542 | token = _get_part (remainder, &local_index, &part); | |||||
| 543 | ||||||
| 544 | if (_match_resource_to_widget (w, part)) { | |||||
| 545 | if (token == '.') { | |||||
| 546 | if (local_index == NULL((void*)0)) { | |||||
| 547 | if (last_token == '.') { | |||||
| 548 | _set_resource_values (w, resource, | |||||
| 549 | value, last_part); | |||||
| 550 | } else if (last_token == '*') { | |||||
| 551 | _set_resource_values (w, resource, | |||||
| 552 | value, last_part); | |||||
| 553 | _apply_values_to_children (w, | |||||
| 554 | remainder, resource, value, | |||||
| 555 | last_token, last_part); | |||||
| 556 | } | |||||
| 557 | } else | |||||
| 558 | _search_child (w, local_index, remainder, | |||||
| 559 | resource, value, last_token, last_part); | |||||
| 560 | return; | |||||
| 561 | } | |||||
| 562 | if (token == '*') { | |||||
| 563 | if (local_index == NULL((void*)0)) { | |||||
| 564 | if (last_token == '.') { | |||||
| 565 | _set_resource_values (w, resource, | |||||
| 566 | value, last_part); | |||||
| 567 | } else if (last_token == '*') { | |||||
| 568 | _set_resource_values (w, resource, | |||||
| 569 | value, last_part); | |||||
| 570 | _apply_values_to_children ( w, | |||||
| 571 | remainder, resource, value, | |||||
| 572 | last_token, last_part); | |||||
| 573 | } | |||||
| 574 | } else | |||||
| 575 | _search_child (w, local_index, remainder, | |||||
| 576 | resource, value, last_token, last_part); | |||||
| 577 | } | |||||
| 578 | } else {/* if the widget name and class don't match the part */ | |||||
| 579 | /* if (token == '.') just continue looping */ | |||||
| 580 | ||||||
| 581 | if (token == '*') { | |||||
| 582 | _search_child (w, indx, remainder, resource, value, | |||||
| 583 | last_token, last_part); | |||||
| 584 | } | |||||
| 585 | } | |||||
| 586 | ||||||
| 587 | XtFree (part); | |||||
| 588 | } | |||||
| 589 | ||||||
| 590 | /* | |||||
| 591 | * NAME: _get_last_part | |||||
| 592 | * | |||||
| 593 | * FUNCTION: | |||||
| 594 | * This routine will parse off the last segment of a resource string | |||||
| 595 | * and its token and return them. the remainder of resource is also | |||||
| 596 | * returned. strcoll is used to guarantee no problems with | |||||
| 597 | * international strings. | |||||
| 598 | * | |||||
| 599 | * PARAMETERS: | |||||
| 600 | * remainder the part of the resource string left over | |||||
| 601 | * part the parsed off part of the resource string | |||||
| 602 | * | |||||
| 603 | * RETURN VALUES: | |||||
| 604 | * char the token (* or . or ?) preceding the resource part | |||||
| 605 | * remainder the part of the resource string left over | |||||
| 606 | * part the parsed off part of the resource string | |||||
| 607 | * | |||||
| 608 | * ERRORS: none | |||||
| 609 | */ | |||||
| 610 | static char | |||||
| 611 | _get_last_part ( | |||||
| 612 | char *remainder, | |||||
| 613 | char **part) | |||||
| 614 | { | |||||
| 615 | char *loose, *tight; | |||||
| 616 | ||||||
| 617 | loose = strrchr (remainder, '*'); | |||||
| 618 | tight = strrchr (remainder, '.'); | |||||
| 619 | ||||||
| 620 | if ((loose == NULL((void*)0)) && (tight == NULL((void*)0))) { | |||||
| 621 | *part = XtNewString (remainder)((remainder) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc ((unsigned)strlen(remainder) + 1), remainder, __builtin_object_size (XtMalloc((unsigned)strlen(remainder) + 1), 2 > 1 ? 1 : 0 ))) : ((void*)0)); | |||||
| 622 | return ('.'); | |||||
| 623 | } | |||||
| 624 | if ((loose == NULL((void*)0)) || (tight && (strcoll (loose, tight) < 0))) { | |||||
| 625 | *tight++ = '\0'; /* shorten the remainder string */ | |||||
| 626 | *part = XtNewString (tight)((tight) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned )strlen(tight) + 1), tight, __builtin_object_size (XtMalloc(( unsigned)strlen(tight) + 1), 2 > 1 ? 1 : 0))) : ((void*)0) ); | |||||
| 627 | return ('.'); | |||||
| 628 | } | |||||
| 629 | if ((tight == NULL((void*)0)) || (loose && (strcoll (tight, loose) < 0))) { | |||||
| 630 | *loose++ = '\0'; | |||||
| 631 | *part = XtNewString (loose)((loose) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned )strlen(loose) + 1), loose, __builtin_object_size (XtMalloc(( unsigned)strlen(loose) + 1), 2 > 1 ? 1 : 0))) : ((void*)0) ); | |||||
| 632 | return ('*'); | |||||
| 633 | } | |||||
| 634 | *part = NULL((void*)0); | |||||
| 635 | ||||||
| 636 | return ('0'); /* error - return 0 */ | |||||
| 637 | } | |||||
| 638 | ||||||
| 639 | /* | |||||
| 640 | * NAME: _search_widget_tree | |||||
| 641 | * | |||||
| 642 | * FUNCTION: | |||||
| 643 | * This function tries to match a resource string to the widgets | |||||
| 644 | * it applies to. The functions it invokes to do this then set | |||||
| 645 | * the value for that resource to each widget. | |||||
| 646 | * | |||||
| 647 | * The resource string has to be parsed into the following format: | |||||
| 648 | * resource = App*Form*button1.background | |||||
| 649 | * remainder = *Form*button1 | |||||
| 650 | * last_part = background last_token = . | |||||
| 651 | * As the widget tree is recursively descended, these variables are | |||||
| 652 | * passed. The remainder is parsed at each level in the widget | |||||
| 653 | * tree as the _set_and_search function attempts to match | |||||
| 654 | * the resource part (eg. part = Form token = *) to a widget. When | |||||
| 655 | * the entire resource string has been matched, the _set_resource_values | |||||
| 656 | * functions is called to apply the value to the widget or widgets. | |||||
| 657 | * | |||||
| 658 | * PARAMETERS: | |||||
| 659 | * w a widget from whose toplevel shell ancestor | |||||
| 660 | * the search will start | |||||
| 661 | * resource the resource string to match | |||||
| 662 | * value the value to apply | |||||
| 663 | * | |||||
| 664 | * RETURN VALUES: none | |||||
| 665 | * | |||||
| 666 | * ERRORS: none | |||||
| 667 | */ | |||||
| 668 | static void | |||||
| 669 | _search_widget_tree ( | |||||
| 670 | Widget w, | |||||
| 671 | char *resource, | |||||
| 672 | char *value) | |||||
| 673 | { | |||||
| 674 | Widget parent = w; | |||||
| 675 | char *last_part; | |||||
| 676 | char *remainder = NULL((void*)0); | |||||
| 677 | char last_token; | |||||
| 678 | char *indx, *copy; | |||||
| 679 | char *loose, *tight; | |||||
| 680 | int loose_len, tight_len; | |||||
| 681 | ||||||
| 682 | /* | |||||
| 683 | * Find the root of the tree given any widget | |||||
| 684 | */ | |||||
| 685 | while (XtParent(parent)((parent)->core.parent) != NULL((void*)0)) { | |||||
| 686 | parent = XtParent(parent)((parent)->core.parent); | |||||
| 687 | } | |||||
| 688 | #ifdef DEBUG | |||||
| 689 | if (XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x04) && XtIsWidget (parent)(((Object)(parent))->object.widget_class->core_class.class_inited & 0x04)) | |||||
| 690 | fprintf (stderr__stderrp, "widget = %s parent = %s\n", | |||||
| 691 | w->core.name, parent->core.name); | |||||
| 692 | else | |||||
| 693 | fprintf (stderr__stderrp, "widget = NULL parent = NULL\n"); | |||||
| 694 | #endif | |||||
| 695 | ||||||
| 696 | /* | |||||
| 697 | * parse off the Class name that was prepended to this string in | |||||
| 698 | * a customizing tool | |||||
| 699 | */ | |||||
| 700 | loose = strchr (resource, '*'); | |||||
| 701 | tight = strchr (resource, '.'); | |||||
| 702 | if ((loose == NULL((void*)0)) && (tight == NULL((void*)0))) | |||||
| 703 | return; | |||||
| 704 | ||||||
| 705 | loose_len = (loose) ? strlen (loose) : 0; | |||||
| 706 | tight_len = (tight) ? strlen (tight) : 0; | |||||
| 707 | ||||||
| 708 | if ((loose == NULL((void*)0)) || (tight_len > loose_len)) | |||||
| 709 | remainder = XtNewString (tight)((tight) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned )strlen(tight) + 1), tight, __builtin_object_size (XtMalloc(( unsigned)strlen(tight) + 1), 2 > 1 ? 1 : 0))) : ((void*)0) ); | |||||
| 710 | else if ((tight == NULL((void*)0)) || (loose_len > tight_len)) | |||||
| 711 | remainder = XtNewString (loose)((loose) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned )strlen(loose) + 1), loose, __builtin_object_size (XtMalloc(( unsigned)strlen(loose) + 1), 2 > 1 ? 1 : 0))) : ((void*)0) ); | |||||
| 712 | ||||||
| 713 | /* | |||||
| 714 | * Parse last segment off of resource string, (eg. background, font, | |||||
| 715 | * etc.) | |||||
| 716 | */ | |||||
| 717 | last_token = _get_last_part (remainder, &last_part); | |||||
| 718 | /* | |||||
| 719 | * this case covers resources of only one level (eg. *background) | |||||
| 720 | */ | |||||
| 721 | if (remainder[0] == 0) { | |||||
| 722 | _set_resource_values (w, resource, value, last_part); | |||||
| 723 | if (last_token == '*') | |||||
| 724 | _apply_values_to_children (parent, remainder, resource, | |||||
| 725 | value, last_token, last_part); | |||||
| 726 | /* | |||||
| 727 | * all other resource strings are recursively applied to the widget tree. | |||||
| 728 | * Prepend a '.' to the remainder string if there is no leading token. | |||||
| 729 | */ | |||||
| 730 | } else { | |||||
| 731 | if (remainder[0] != '*' && remainder[0] != '.') { | |||||
| 732 | XtAsprintf (©, ".%s", remainder); | |||||
| 733 | XtFree (remainder); | |||||
| 734 | remainder = copy; | |||||
| 735 | } | |||||
| 736 | indx = remainder; | |||||
| 737 | _set_and_search (parent, indx, remainder, resource, value, | |||||
| 738 | last_token, last_part); | |||||
| 739 | } | |||||
| 740 | ||||||
| 741 | XtFree (remainder); | |||||
| 742 | XtFree (last_part); | |||||
| 743 | } | |||||
| 744 | ||||||
| 745 | /* | |||||
| 746 | * NAME: _locate_children | |||||
| 747 | * | |||||
| 748 | * FUNCTION: | |||||
| 749 | * returns a list of all of a widget's children | |||||
| 750 | * | |||||
| 751 | * PARAMETERS: | |||||
| 752 | * w the parent to search for its children | |||||
| 753 | * children the list of children that is created | |||||
| 754 | * normal flag for normal children | |||||
| 755 | * popup flag for popup children | |||||
| 756 | * | |||||
| 757 | * RETURN VALUES: | |||||
| 758 | * int the number of children | |||||
| 759 | * children the list of children found | |||||
| 760 | * | |||||
| 761 | * ERRORS: none | |||||
| 762 | */ | |||||
| 763 | static int | |||||
| 764 | _locate_children ( | |||||
| 765 | Widget parent, | |||||
| 766 | Widget **children) | |||||
| 767 | { | |||||
| 768 | CompositeWidget comp = (CompositeWidget) parent; | |||||
| 769 | Cardinal i; | |||||
| 770 | int num_children = 0; | |||||
| 771 | int current = 0; | |||||
| 772 | ||||||
| 773 | /* | |||||
| 774 | * count the number of children | |||||
| 775 | */ | |||||
| 776 | if (XtIsWidget (parent)(((Object)(parent))->object.widget_class->core_class.class_inited & 0x04)) | |||||
| 777 | num_children += parent->core.num_popups; | |||||
| 778 | if (XtIsComposite (parent)(((Object)(parent))->object.widget_class->core_class.class_inited & 0x08)) | |||||
| 779 | num_children += comp->composite.num_children; | |||||
| 780 | if (num_children == 0) { | |||||
| 781 | *children = NULL((void*)0); | |||||
| 782 | return (0); | |||||
| 783 | } | |||||
| 784 | ||||||
| 785 | *children = (Widget *) | |||||
| 786 | XtMalloc ((Cardinal) sizeof(Widget) * num_children); | |||||
| 787 | ||||||
| 788 | if (XtIsComposite (parent)(((Object)(parent))->object.widget_class->core_class.class_inited & 0x08)) { | |||||
| 789 | for (i=0; i<comp->composite.num_children; i++) { | |||||
| 790 | (*children)[current] = comp->composite.children[i]; | |||||
| 791 | current++; | |||||
| 792 | } | |||||
| 793 | } | |||||
| 794 | ||||||
| 795 | if (XtIsWidget (parent)(((Object)(parent))->object.widget_class->core_class.class_inited & 0x04)) { | |||||
| 796 | for (i=0; i<parent->core.num_popups; i++) { | |||||
| 797 | (*children)[current] = comp->core.popup_list[i]; | |||||
| 798 | current++; | |||||
| 799 | } | |||||
| 800 | } | |||||
| 801 | ||||||
| 802 | return (num_children); | |||||
| 803 | } | |||||
| 804 | ||||||
| 805 | #ifdef DEBUG | |||||
| 806 | /* | |||||
| 807 | * NAME: dump_widget_tree | |||||
| 808 | * | |||||
| 809 | * FUNCTION: | |||||
| 810 | * recursively printout entire widget tree | |||||
| 811 | * | |||||
| 812 | * PARAMETERS: | |||||
| 813 | * w the widget to match | |||||
| 814 | * indent the amount to indent each line | |||||
| 815 | * | |||||
| 816 | * RETURN VALUES: void | |||||
| 817 | * | |||||
| 818 | * ERRORS: none | |||||
| 819 | */ | |||||
| 820 | static void | |||||
| 821 | dump_widget_tree ( | |||||
| 822 | Widget w, | |||||
| 823 | int indent) | |||||
| 824 | { | |||||
| 825 | int i,j; | |||||
| 826 | int num_children; | |||||
| 827 | Widget *children; | |||||
| 828 | ||||||
| 829 | /* | |||||
| 830 | * Recursively search through the children | |||||
| 831 | */ | |||||
| 832 | num_children = _locate_children (w, &children); | |||||
| 833 | indent += 2; | |||||
| 834 | for (i=0; i<num_children; i++) { | |||||
| 835 | if (children[i] != NULL((void*)0)) { | |||||
| 836 | for (j=0; j<indent; j++) | |||||
| 837 | fprintf (stderr__stderrp, " "); | |||||
| 838 | if (XtIsWidget (children[i])(((Object)(children[i]))->object.widget_class->core_class .class_inited & 0x04)) { | |||||
| 839 | fprintf (stderr__stderrp, "(%s)\t",children[i]->core.name); | |||||
| 840 | fprintf (stderr__stderrp, "(%s)\n", | |||||
| 841 | children[i]->core.widget_class->core_class.class_name); | |||||
| 842 | } else { | |||||
| 843 | fprintf (stderr__stderrp, "(NULL)\t"); | |||||
| 844 | fprintf (stderr__stderrp, "(%s)\n", | |||||
| 845 | children[i]->core.widget_class->core_class.class_name); | |||||
| 846 | } | |||||
| 847 | } | |||||
| 848 | dump_widget_tree (children[i], indent); | |||||
| 849 | } | |||||
| 850 | ||||||
| 851 | XtFree ((char *)children); | |||||
| 852 | } | |||||
| 853 | #endif | |||||
| 854 | ||||||
| 855 | /* | |||||
| 856 | * NAME: _XtResourceConfiguationEH | |||||
| 857 | * | |||||
| 858 | * FUNCTION: | |||||
| 859 | * This function is the event handler for the on-the-fly communication | |||||
| 860 | * with a resource customization tool. This event handler must be | |||||
| 861 | * registered for the toplevel shell of each app. This is best done | |||||
| 862 | * in the _XtCreatePopupShell and _XtAppCreateShell functions in Xt's | |||||
| 863 | * Create.c source file. | |||||
| 864 | * | |||||
| 865 | * The property used to communicate with a customizing tool is | |||||
| 866 | * placed on the toplevel shell window of the application. The | |||||
| 867 | * customizing tool places a property on this window which causes | |||||
| 868 | * this event handler to be invoked via the PropertyNotify event. | |||||
| 869 | * This event handler reads the property and then deletes it from | |||||
| 870 | * the server. The contents of the property are a resource string | |||||
| 871 | * and value. The event handler then calls functions to walk the | |||||
| 872 | * applications widget tree, determining which widgets are affected | |||||
| 873 | * by the resource string, and then applying the value with XtSetValues. | |||||
| 874 | * | |||||
| 875 | * PARAMETERS: | |||||
| 876 | * w the widget that invoked this event handler | |||||
| 877 | * client_data not used | |||||
| 878 | * event the event structure | |||||
| 879 | * | |||||
| 880 | * RETURN VALUES: none | |||||
| 881 | * | |||||
| 882 | * ERRORS: none | |||||
| 883 | */ | |||||
| 884 | /* ARGSUSED */ | |||||
| 885 | void | |||||
| 886 | _XtResourceConfigurationEH ( | |||||
| 887 | Widget w, | |||||
| 888 | XtPointer client_data, | |||||
| 889 | XEvent *event) | |||||
| 890 | { | |||||
| 891 | Atom actual_type; | |||||
| 892 | int actual_format; | |||||
| 893 | unsigned long nitems; | |||||
| 894 | unsigned long leftover; | |||||
| 895 | char *data = NULL((void*)0); | |||||
| 896 | unsigned long resource_len; | |||||
| 897 | char *data_ptr; | |||||
| 898 | char *resource; | |||||
| 899 | char *value; | |||||
| 900 | #ifdef DEBUG | |||||
| 901 | int indent = 0; | |||||
| 902 | #endif | |||||
| 903 | XtPerDisplay pd; | |||||
| 904 | ||||||
| 905 | #ifdef DEBUG | |||||
| 906 | fprintf (stderr__stderrp, "in _XtResourceConfiguationEH atom = %d\n",event->xproperty.atom); | |||||
| 907 | fprintf (stderr__stderrp, " window = %x\n", XtWindow (w)((w)->core.window)); | |||||
| 908 | if (XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x04)) | |||||
| 909 | fprintf (stderr__stderrp, " widget = %x name = %s\n", w, w->core.name); | |||||
| 910 | #endif | |||||
| 911 | ||||||
| 912 | pd = _XtGetPerDisplay (XtDisplay (w)(((w)->core.screen)->display)); | |||||
| 913 | ||||||
| 914 | /* | |||||
| 915 | * The window on which a customizing tool places the property | |||||
| 916 | * is determined at this point. It should be the applications | |||||
| 917 | * toplevel shell window. | |||||
| 918 | * | |||||
| 919 | * A customizing tool sends a "ping" to the application on | |||||
| 920 | * the RCM_INIT property. The application answers the ping | |||||
| 921 | * by deleting the property. | |||||
| 922 | */ | |||||
| 923 | if (event->xproperty.atom == pd->rcm_init) { | |||||
| ||||||
| 924 | XDeleteProperty (XtDisplay(w)(((w)->core.screen)->display), XtWindow (w)((w)->core.window), pd->rcm_init); | |||||
| 925 | ||||||
| 926 | #ifdef DEBUG | |||||
| 927 | if (XtIsWidget (w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x04)) | |||||
| 928 | fprintf (stderr__stderrp, "%s\n", w->core.name); | |||||
| 929 | else | |||||
| 930 | fprintf (stderr__stderrp, "NULL name\n"); | |||||
| 931 | dump_widget_tree(w, indent); | |||||
| 932 | ||||||
| 933 | fprintf (stderr__stderrp, "answer ping\n"); | |||||
| 934 | #endif | |||||
| 935 | } | |||||
| 936 | ||||||
| 937 | /* | |||||
| 938 | * This event handler ignores any property notify events that | |||||
| 939 | * are not RCM_INIT or RCM_DATA | |||||
| 940 | */ | |||||
| 941 | if (event->xproperty.atom != pd->rcm_data) | |||||
| 942 | return; | |||||
| 943 | ||||||
| 944 | /* | |||||
| 945 | * Retrieve the data from the property | |||||
| 946 | */ | |||||
| 947 | #ifdef DEBUG | |||||
| 948 | fprintf (stderr__stderrp, "receiving RCM_DATA property\n"); | |||||
| 949 | #endif | |||||
| 950 | if (XGetWindowProperty (XtDisplay(w)(((w)->core.screen)->display), | |||||
| 951 | XtWindow (w)((w)->core.window), | |||||
| 952 | pd->rcm_data, 0L, 8192L, | |||||
| 953 | TRUE1, XA_STRING((Atom) 31), | |||||
| 954 | &actual_type, &actual_format, &nitems, &leftover, | |||||
| 955 | (unsigned char **)&data ) == Success0 && actual_type == XA_STRING((Atom) 31) | |||||
| 956 | && actual_format == 8) { | |||||
| 957 | /* | |||||
| 958 | * data format is: | |||||
| 959 | * | |||||
| 960 | * resource_length, resource, value | |||||
| 961 | * | |||||
| 962 | * convert the resource_length to a long, skip over it, put a | |||||
| 963 | * zero byte at the end of the resource, and pick off the | |||||
| 964 | * resource and value fields. | |||||
| 965 | */ | |||||
| 966 | if (data) { | |||||
| 967 | char *data_end = data + nitems; | |||||
| 968 | char *data_value; | |||||
| 969 | ||||||
| 970 | resource_len = strtoul (data, &data_ptr, 10); | |||||
| 971 | ||||||
| 972 | if (data_ptr != (char *) data) { | |||||
| 973 | data_ptr++; | |||||
| 974 | data_value = data_ptr + resource_len; | |||||
| 975 | } else /* strtoul failed to convert a number */ | |||||
| 976 | data_ptr = data_value = NULL((void*)0); | |||||
| 977 | ||||||
| 978 | if (data_value > data_ptr && data_value < data_end) { | |||||
| 979 | *data_value++ = '\0'; | |||||
| 980 | ||||||
| 981 | resource = XtNewString (data_ptr)((data_ptr) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc ((unsigned)strlen(data_ptr) + 1), data_ptr, __builtin_object_size (XtMalloc((unsigned)strlen(data_ptr) + 1), 2 > 1 ? 1 : 0) )) : ((void*)0)); | |||||
| 982 | value = XtNewString (data_value)((data_value) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc ((unsigned)strlen(data_value) + 1), data_value, __builtin_object_size (XtMalloc((unsigned)strlen(data_value) + 1), 2 > 1 ? 1 : 0 ))) : ((void*)0)); | |||||
| 983 | #ifdef DEBUG | |||||
| 984 | fprintf (stderr__stderrp, "resource_len=%d\n", | |||||
| 985 | resource_len); | |||||
| 986 | fprintf (stderr__stderrp, "resource = %s\t value = %s\n", | |||||
| 987 | resource, value); | |||||
| 988 | #endif | |||||
| 989 | /* | |||||
| 990 | * descend the application widget tree and | |||||
| 991 | * apply the value to the appropriate widgets | |||||
| 992 | */ | |||||
| 993 | _search_widget_tree (w, resource, value); | |||||
| 994 | ||||||
| 995 | XtFree (resource); | |||||
| 996 | XtFree (value); | |||||
| 997 | } | |||||
| 998 | } | |||||
| 999 | } | |||||
| 1000 | ||||||
| 1001 | if (data) | |||||
| 1002 | XFree ((char *)data); | |||||
| 1003 | } |