Resources.c revision a3bd7f05
1/*********************************************************** 2Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved. 3 4Permission is hereby granted, free of charge, to any person obtaining a 5copy of this software and associated documentation files (the "Software"), 6to deal in the Software without restriction, including without limitation 7the rights to use, copy, modify, merge, publish, distribute, sublicense, 8and/or sell copies of the Software, and to permit persons to whom the 9Software is furnished to do so, subject to the following conditions: 10 11The above copyright notice and this permission notice (including the next 12paragraph) shall be included in all copies or substantial portions of the 13Software. 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 18THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21DEALINGS IN THE SOFTWARE. 22 23Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 24 25 All Rights Reserved 26 27Permission to use, copy, modify, and distribute this software and its 28documentation for any purpose and without fee is hereby granted, 29provided that the above copyright notice appear in all copies and that 30both that copyright notice and this permission notice appear in 31supporting documentation, and that the name of Digital not be 32used in advertising or publicity pertaining to distribution of the 33software without specific, written prior permission. 34 35DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 36ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 37DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 38ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 39WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 40ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 41SOFTWARE. 42 43******************************************************************/ 44 45/* 46 47Copyright 1987, 1988, 1994, 1998 The Open Group 48 49Permission to use, copy, modify, distribute, and sell this software and its 50documentation for any purpose is hereby granted without fee, provided that 51the above copyright notice appear in all copies and that both that 52copyright notice and this permission notice appear in supporting 53documentation. 54 55The above copyright notice and this permission notice shall be included in 56all copies or substantial portions of the Software. 57 58THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 59IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 60FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 61OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 62AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 63CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 64 65Except as contained in this notice, the name of The Open Group shall not be 66used in advertising or otherwise to promote the sale, use or other dealings 67in this Software without prior written authorization from The Open Group. 68 69*/ 70 71#ifdef HAVE_CONFIG_H 72#include <config.h> 73#endif 74#include "IntrinsicI.h" 75#include "VarargsI.h" 76#include "Shell.h" 77#include "ShellP.h" 78#include "StringDefs.h" 79#include <stdio.h> 80 81static XrmClass QBoolean, QString, QCallProc, QImmediate; 82static XrmName QinitialResourcesPersistent, QInitialResourcesPersistent; 83static XrmClass QTranslations, QTranslationTable; 84static XrmName Qtranslations, QbaseTranslations; 85static XrmName Qscreen; 86static XrmClass QScreen; 87 88void 89_XtCopyFromParent(Widget widget, int offset, XrmValue *value) 90{ 91 if (widget->core.parent == NULL) { 92 XtAppWarningMsg(XtWidgetToApplicationContext(widget), 93 "invalidParent", "xtCopyFromParent", XtCXtToolkitError, 94 "CopyFromParent must have non-NULL parent", NULL, NULL); 95 value->addr = NULL; 96 return; 97 } 98 value->addr = (XPointer) (((char *) widget->core.parent) + offset); 99} /* _XtCopyFromParent */ 100 101void 102_XtCopyFromArg(XtArgVal src, char *dst, register unsigned int size) 103{ 104 if (size > sizeof(XtArgVal)) 105 (void) memmove((char *) dst, (char *) src, (size_t) size); 106 else { 107 union { 108 long longval; 109#ifdef LONG64 110 int intval; 111#endif 112 short shortval; 113 char charval; 114 char *charptr; 115 XtPointer ptr; 116 } u; 117 char *p = (char *) &u; 118 119 if (size == sizeof(long)) 120 u.longval = (long) src; 121#ifdef LONG64 122 else if (size == sizeof(int)) 123 u.intval = (int) src; 124#endif 125 else if (size == sizeof(short)) 126 u.shortval = (short) src; 127 else if (size == sizeof(char)) 128 u.charval = (char) src; 129 else if (size == sizeof(XtPointer)) 130 u.ptr = (XtPointer) src; 131 else if (size == sizeof(char *)) 132 u.charptr = (char *) src; 133 else 134 p = (char *) &src; 135 136 (void) memmove(dst, p, (size_t) size); 137 } 138} /* _XtCopyFromArg */ 139 140void 141_XtCopyToArg(char *src, XtArgVal *dst, register unsigned int size) 142{ 143 if (!*dst) { 144#ifdef GETVALUES_BUG 145 /* old GetValues semantics (storing directly into arglists) are bad, 146 * but preserve for compatibility as long as arglist contains NULL. 147 */ 148 union { 149 long longval; 150#ifdef LONG64 151 int intval; 152#endif 153 short shortval; 154 char charval; 155 char *charptr; 156 XtPointer ptr; 157 } u; 158 159 if (size <= sizeof(XtArgVal)) { 160 (void) memmove((char *) &u, (char *) src, (size_t) size); 161 if (size == sizeof(long)) 162 *dst = (XtArgVal) u.longval; 163#ifdef LONG64 164 else if (size == sizeof(int)) 165 *dst = (XtArgVal) u.intval; 166#endif 167 else if (size == sizeof(short)) 168 *dst = (XtArgVal) u.shortval; 169 else if (size == sizeof(char)) 170 *dst = (XtArgVal) u.charval; 171 else if (size == sizeof(char *)) 172 *dst = (XtArgVal) u.charptr; 173 else if (size == sizeof(XtPointer)) 174 *dst = (XtArgVal) u.ptr; 175 else 176 (void) memmove((char *) dst, (char *) src, (size_t) size); 177 } 178 else 179 (void) memmove((char *) dst, (char *) src, (size_t) size); 180#else 181 XtErrorMsg("invalidGetValues", "xtGetValues", XtCXtToolkitError, 182 "NULL ArgVal in XtGetValues", NULL, NULL); 183#endif 184 } 185 else { 186 /* proper GetValues semantics: argval is pointer to destination */ 187 (void) memmove((char *) *dst, (char *) src, (size_t) size); 188 } 189} /* _XtCopyToArg */ 190 191static void 192CopyToArg(char *src, XtArgVal *dst, register unsigned int size) 193{ 194 if (!*dst) { 195 /* old GetValues semantics (storing directly into arglists) are bad, 196 * but preserve for compatibility as long as arglist contains NULL. 197 */ 198 union { 199 long longval; 200#ifdef LONG64 201 int intval; 202#endif 203 short shortval; 204 char charval; 205 char *charptr; 206 XtPointer ptr; 207 } u; 208 209 if (size <= sizeof(XtArgVal)) { 210 (void) memmove((char *) &u, (char *) src, (size_t) size); 211 if (size == sizeof(long)) 212 *dst = (XtArgVal) u.longval; 213#ifdef LONG64 214 else if (size == sizeof(int)) 215 *dst = (XtArgVal) u.intval; 216#endif 217 else if (size == sizeof(short)) 218 *dst = (XtArgVal) u.shortval; 219 else if (size == sizeof(char)) 220 *dst = (XtArgVal) u.charval; 221 else if (size == sizeof(char *)) 222 *dst = (XtArgVal) u.charptr; 223 else if (size == sizeof(XtPointer)) 224 *dst = (XtArgVal) u.ptr; 225 else 226 (void) memmove((char *) dst, (char *) src, (size_t) size); 227 } 228 else 229 (void) memmove((char *) dst, (char *) src, (size_t) size); 230 } 231 else { 232 /* proper GetValues semantics: argval is pointer to destination */ 233 (void) memmove((char *) *dst, (char *) src, (size_t) size); 234 } 235} /* CopyToArg */ 236 237static Cardinal 238CountTreeDepth(Widget w) 239{ 240 Cardinal count; 241 242 for (count = 1; w != NULL; w = (Widget) w->core.parent) 243 count++; 244 245 return count; 246} 247 248static void 249GetNamesAndClasses(register Widget w, 250 register XrmNameList names, 251 register XrmClassList classes) 252{ 253 register Cardinal length, j; 254 register XrmQuark t; 255 WidgetClass class; 256 257 /* Return null-terminated quark arrays, with length the number of 258 quarks (not including NULL) */ 259 260 LOCK_PROCESS; 261 for (length = 0; w != NULL; w = (Widget) w->core.parent) { 262 names[length] = w->core.xrm_name; 263 class = XtClass(w); 264 /* KLUDGE KLUDGE KLUDGE KLUDGE */ 265 if (w->core.parent == NULL && XtIsApplicationShell(w)) { 266 classes[length] = 267 ((ApplicationShellWidget) w)->application.xrm_class; 268 } 269 else 270 classes[length] = class->core_class.xrm_class; 271 length++; 272 } 273 UNLOCK_PROCESS; 274 /* They're in backwards order, flop them around */ 275 for (j = 0; j < length / 2; j++) { 276 t = names[j]; 277 names[j] = names[length - j - 1]; 278 names[length - j - 1] = t; 279 t = classes[j]; 280 classes[j] = classes[length - j - 1]; 281 classes[length - j - 1] = t; 282 } 283 names[length] = NULLQUARK; 284 classes[length] = NULLQUARK; 285} /* GetNamesAndClasses */ 286 287/* Spiffy fast compiled form of resource list. */ 288/* XtResourceLists are compiled in-place into XrmResourceLists */ 289/* All atoms are replaced by quarks, and offsets are -offset-1 to */ 290/* indicate that this list has been compiled already */ 291 292void 293_XtCompileResourceList(register XtResourceList resources, 294 Cardinal num_resources) 295{ 296 register Cardinal count; 297 298#define xrmres ((XrmResourceList) resources) 299#define PSToQ XrmPermStringToQuark 300 301 for (count = 0; count < num_resources; resources++, count++) { 302 xrmres->xrm_name = PSToQ(resources->resource_name); 303 xrmres->xrm_class = PSToQ(resources->resource_class); 304 xrmres->xrm_type = PSToQ(resources->resource_type); 305 xrmres->xrm_offset = (int) 306 (-(int) resources->resource_offset - 1); 307 xrmres->xrm_default_type = PSToQ(resources->default_type); 308 } 309#undef PSToQ 310#undef xrmres 311} /* _XtCompileResourceList */ 312 313/* Like _XtCompileResourceList, but strings are not permanent */ 314static void 315XrmCompileResourceListEphem(register XtResourceList resources, 316 Cardinal num_resources) 317{ 318 register Cardinal count; 319 320#define xrmres ((XrmResourceList) resources) 321 322 for (count = 0; count < num_resources; resources++, count++) { 323 xrmres->xrm_name = StringToName(resources->resource_name); 324 xrmres->xrm_class = StringToClass(resources->resource_class); 325 xrmres->xrm_type = StringToQuark(resources->resource_type); 326 xrmres->xrm_offset = (int) 327 (-(int) resources->resource_offset - 1); 328 xrmres->xrm_default_type = StringToQuark(resources->default_type); 329 } 330#undef xrmres 331} /* XrmCompileResourceListEphem */ 332 333static void 334BadSize(Cardinal size, XrmQuark name) 335{ 336 String params[2]; 337 Cardinal num_params = 2; 338 339 params[0] = (String) (long) size; 340 params[1] = XrmQuarkToString(name); 341 XtWarningMsg("invalidSizeOverride", "xtDependencies", XtCXtToolkitError, 342 "Representation size %d must match superclass's to override %s", 343 params, &num_params); 344} /* BadType */ 345 346/* 347 * Create a new resource list, with the class resources following the 348 * superclass's resources. If a resource in the class list overrides 349 * a superclass resource, then just replace the superclass entry in place. 350 * 351 * At the same time, add a level of indirection to the XtResourceList to 352 * create and XrmResourceList. 353 */ 354void 355_XtDependencies(XtResourceList *class_resp, /* VAR */ 356 Cardinal *class_num_resp, /* VAR */ 357 XrmResourceList *super_res, 358 Cardinal super_num_res, 359 Cardinal super_widget_size) 360{ 361 register XrmResourceList *new_res; 362 Cardinal new_num_res; 363 XrmResourceList class_res = (XrmResourceList) *class_resp; 364 Cardinal class_num_res = *class_num_resp; 365 register Cardinal i, j; 366 Cardinal new_next; 367 368 if (class_num_res == 0) { 369 /* Just point to superclass resource list */ 370 *class_resp = (XtResourceList) super_res; 371 *class_num_resp = super_num_res; 372 return; 373 } 374 375 /* Allocate and initialize new_res with superclass resource pointers */ 376 new_num_res = super_num_res + class_num_res; 377 new_res = (XrmResourceList *) 378 __XtMalloc((Cardinal) (new_num_res * sizeof(XrmResourceList))); 379 if (super_num_res > 0) 380 XtMemmove(new_res, super_res, super_num_res * sizeof(XrmResourceList)); 381 382 /* Put pointers to class resource entries into new_res */ 383 new_next = super_num_res; 384 for (i = 0; i < class_num_res; i++) { 385 if ((Cardinal) (-class_res[i].xrm_offset - 1) < super_widget_size) { 386 /* Probably an override of superclass resources--look for overlap */ 387 for (j = 0; j < super_num_res; j++) { 388 if (class_res[i].xrm_offset == new_res[j]->xrm_offset) { 389 /* Spec is silent on what fields subclass can override. 390 * The only two of real concern are type & size. 391 * Although allowing type to be over-ridden introduces 392 * the possibility of errors, it's at present the only 393 * reasonable way to allow a subclass to force a private 394 * converter to be invoked for a subset of fields. 395 */ 396 /* We do insist that size be identical to superclass */ 397 if (class_res[i].xrm_size != new_res[j]->xrm_size) { 398 BadSize(class_res[i].xrm_size, 399 (XrmQuark) class_res[i].xrm_name); 400 class_res[i].xrm_size = new_res[j]->xrm_size; 401 } 402 new_res[j] = &(class_res[i]); 403 new_num_res--; 404 goto NextResource; 405 } 406 } /* for j */ 407 } 408 /* Not an overlap, add an entry to new_res */ 409 new_res[new_next++] = &(class_res[i]); 410 NextResource:; 411 } /* for i */ 412 413 /* Okay, stuff new resources back into class record */ 414 *class_resp = (XtResourceList) new_res; 415 *class_num_resp = new_num_res; 416} /* _XtDependencies */ 417 418void 419_XtResourceDependencies(WidgetClass wc) 420{ 421 WidgetClass sc; 422 423 sc = wc->core_class.superclass; 424 if (sc == NULL) { 425 _XtDependencies(&(wc->core_class.resources), 426 &(wc->core_class.num_resources), 427 (XrmResourceList *) NULL, (unsigned) 0, (unsigned) 0); 428 } 429 else { 430 _XtDependencies(&(wc->core_class.resources), 431 &(wc->core_class.num_resources), 432 (XrmResourceList *) sc->core_class.resources, 433 sc->core_class.num_resources, 434 sc->core_class.widget_size); 435 } 436} /* _XtResourceDependencies */ 437 438void 439_XtConstraintResDependencies(ConstraintWidgetClass wc) 440{ 441 if (wc == (ConstraintWidgetClass) constraintWidgetClass) { 442 _XtDependencies(&(wc->constraint_class.resources), 443 &(wc->constraint_class.num_resources), 444 (XrmResourceList *) NULL, (unsigned) 0, (unsigned) 0); 445 } 446 else { 447 ConstraintWidgetClass sc; 448 449 sc = (ConstraintWidgetClass) wc->core_class.superclass; 450 _XtDependencies(&(wc->constraint_class.resources), 451 &(wc->constraint_class.num_resources), 452 (XrmResourceList *) sc->constraint_class.resources, 453 sc->constraint_class.num_resources, 454 sc->constraint_class.constraint_size); 455 } 456} /* _XtConstraintResDependencies */ 457 458XrmResourceList * 459_XtCreateIndirectionTable(XtResourceList resources, Cardinal num_resources) 460{ 461 register Cardinal idx; 462 XrmResourceList *table; 463 464 table = (XrmResourceList *) 465 __XtMalloc((Cardinal) (num_resources * sizeof(XrmResourceList))); 466 for (idx = 0; idx < num_resources; idx++) 467 table[idx] = (XrmResourceList) (&(resources[idx])); 468 return table; 469} 470 471static XtCacheRef * 472GetResources(Widget widget, /* Widget resources are associated with */ 473 char *base, /* Base address of memory to write to */ 474 XrmNameList names, /* Full inheritance name of widget */ 475 XrmClassList classes, /* Full inheritance class of widget */ 476 XrmResourceList *table, /* The list of resources required. */ 477 unsigned num_resources, /* number of items in resource list */ 478 XrmQuarkList quark_args, /* Arg names quarkified */ 479 ArgList args, /* ArgList to override resources */ 480 unsigned num_args, /* number of items in arg list */ 481 XtTypedArgList typed_args, /* Typed arg list to override resources */ 482 Cardinal *pNumTypedArgs, /* number of items in typed arg list */ 483 Boolean tm_hack) /* do baseTranslations */ 484{ 485/* 486 * assert: *pNumTypedArgs == 0 if num_args > 0 487 * assert: num_args == 0 if *pNumTypedArgs > 0 488 */ 489#define SEARCHLISTLEN 100 490#define MAXRESOURCES 400 491 492 XrmValue value; 493 XrmQuark rawType; 494 XrmValue convValue; 495 XrmHashTable stackSearchList[SEARCHLISTLEN]; 496 XrmHashTable *searchList = stackSearchList; 497 unsigned int searchListSize = SEARCHLISTLEN; 498 Boolean found[MAXRESOURCES]; 499 int typed[MAXRESOURCES]; 500 XtCacheRef cache_ref[MAXRESOURCES]; 501 XtCacheRef *cache_ptr, *cache_base; 502 Boolean persistent_resources = True; 503 Boolean found_persistence = False; 504 int num_typed_args = (int) *pNumTypedArgs; 505 XrmDatabase db; 506 Boolean do_tm_hack = False; 507 508 if ((args == NULL) && (num_args != 0)) { 509 XtAppWarningMsg(XtWidgetToApplicationContext(widget), 510 "invalidArgCount", "getResources", XtCXtToolkitError, 511 "argument count > 0 on NULL argument list", NULL, NULL); 512 num_args = 0; 513 } 514 if (num_resources == 0) { 515 return NULL; 516 } 517 else if (num_resources >= MAXRESOURCES) { 518 XtAppWarningMsg(XtWidgetToApplicationContext(widget), 519 "invalidResourceCount", "getResources", 520 XtCXtToolkitError, "too many resources", NULL, NULL); 521 return NULL; 522 } 523 else if (table == NULL) { 524 XtAppWarningMsg(XtWidgetToApplicationContext(widget), 525 "invalidResourceCount", "getResources", 526 XtCXtToolkitError, 527 "resource count > 0 on NULL resource list", NULL, NULL); 528 return NULL; 529 } 530 531 /* Mark each resource as not found on arg list */ 532 memset((void *) found, 0, (size_t) (num_resources * sizeof(Boolean))); 533 memset((void *) typed, 0, (size_t) (num_resources * sizeof(int))); 534 535 /* Copy the args into the resources, mark each as found */ 536 { 537 register ArgList arg; 538 register XtTypedArgList typed_arg; 539 register XrmName argName; 540 register Cardinal j; 541 register int i; 542 register XrmResourceList rx; 543 register XrmResourceList *res; 544 545 for (arg = args, i = 0; (Cardinal) i < num_args; i++, arg++) { 546 argName = quark_args[i]; 547 if (argName == QinitialResourcesPersistent) { 548 persistent_resources = (Boolean) arg->value; 549 found_persistence = True; 550 continue; 551 } 552 for (j = 0, res = table; j < num_resources; j++, res++) { 553 rx = *res; 554 if (argName == rx->xrm_name) { 555 _XtCopyFromArg(arg->value, 556 base - rx->xrm_offset - 1, rx->xrm_size); 557 found[j] = TRUE; 558 break; 559 } 560 } 561 } 562 for (typed_arg = typed_args, i = 0; i < num_typed_args; 563 i++, typed_arg++) { 564 register XrmRepresentation argType; 565 566 argName = quark_args[i]; 567 argType = (typed_arg->type == NULL) ? NULLQUARK 568 : XrmStringToRepresentation(typed_arg->type); 569 if (argName == QinitialResourcesPersistent) { 570 persistent_resources = (Boolean) typed_arg->value; 571 found_persistence = True; 572 break; 573 } 574 for (j = 0, res = table; j < num_resources; j++, res++) { 575 rx = *res; 576 if (argName == rx->xrm_name) { 577 if (argType != NULLQUARK && argType != rx->xrm_type) { 578 typed[j] = i + 1; 579 } 580 else { 581 _XtCopyFromArg(typed_arg->value, 582 base - rx->xrm_offset - 1, rx->xrm_size); 583 } 584 found[j] = TRUE; 585 break; 586 } 587 } 588 } 589 } 590 591 /* Ask resource manager for a list of database levels that we can 592 do a single-level search on each resource */ 593 594 db = XtScreenDatabase(XtScreenOfObject(widget)); 595 while (!XrmQGetSearchList(db, names, classes, 596 searchList, (int) searchListSize)) { 597 if (searchList == stackSearchList) 598 searchList = NULL; 599 searchList = (XrmHashTable *) XtRealloc((char *) searchList, 600 (Cardinal) (sizeof(XrmHashTable) 601 * (searchListSize *= 602 2))); 603 } 604 605 if (persistent_resources) 606 cache_base = NULL; 607 else 608 cache_base = cache_ref; 609 /* geez, this is an ugly mess */ 610 if (XtIsShell(widget)) { 611 register XrmResourceList *res; 612 register Cardinal j; 613 Screen *oldscreen = widget->core.screen; 614 615 /* look up screen resource first, since real rdb depends on it */ 616 for (res = table, j = 0; j < num_resources; j++, res++) { 617 if ((*res)->xrm_name != Qscreen) 618 continue; 619 if (typed[j]) { 620 register XtTypedArg *arg = typed_args + typed[j] - 1; 621 XrmQuark from_type; 622 XrmValue from_val, to_val; 623 624 from_type = StringToQuark(arg->type); 625 from_val.size = (Cardinal) arg->size; 626 if ((from_type == QString) || 627 ((unsigned) arg->size > sizeof(XtArgVal))) 628 from_val.addr = (XPointer) arg->value; 629 else 630 from_val.addr = (XPointer) &arg->value; 631 to_val.size = sizeof(Screen *); 632 to_val.addr = (XPointer) &widget->core.screen; 633 found[j] = _XtConvert(widget, from_type, &from_val, 634 QScreen, &to_val, cache_base); 635 if (cache_base && *cache_base) 636 cache_base++; 637 } 638 if (!found[j]) { 639 if (XrmQGetSearchResource(searchList, Qscreen, QScreen, 640 &rawType, &value)) { 641 if (rawType != QScreen) { 642 convValue.size = sizeof(Screen *); 643 convValue.addr = (XPointer) &widget->core.screen; 644 (void) _XtConvert(widget, rawType, &value, 645 QScreen, &convValue, cache_base); 646 if (cache_base && *cache_base) 647 cache_base++; 648 } 649 else { 650 widget->core.screen = *((Screen **) value.addr); 651 } 652 } 653 } 654 break; 655 } 656 /* now get the database to use for the rest of the resources */ 657 if (widget->core.screen != oldscreen) { 658 db = XtScreenDatabase(widget->core.screen); 659 while (!XrmQGetSearchList(db, names, classes, 660 searchList, (int) searchListSize)) { 661 if (searchList == stackSearchList) 662 searchList = NULL; 663 searchList = (XrmHashTable *) XtRealloc((char *) searchList, 664 (Cardinal) (sizeof 665 (XrmHashTable) 666 * 667 (searchListSize 668 *= 2))); 669 } 670 } 671 } 672 673 /* go to the resource manager for those resources not found yet */ 674 /* if it's not in the resource database use the default value */ 675 676 { 677 register XrmResourceList rx; 678 register XrmResourceList *res; 679 register Cardinal j; 680 register XrmRepresentation xrm_type; 681 register XrmRepresentation xrm_default_type; 682 char char_val; 683 short short_val; 684 int int_val; 685 long long_val; 686 char *char_ptr; 687 688 if (!found_persistence) { 689 if (XrmQGetSearchResource(searchList, QinitialResourcesPersistent, 690 QInitialResourcesPersistent, &rawType, 691 &value)) { 692 if (rawType != QBoolean) { 693 convValue.size = sizeof(Boolean); 694 convValue.addr = (XPointer) &persistent_resources; 695 (void) _XtConvert(widget, rawType, &value, QBoolean, 696 &convValue, NULL); 697 } 698 else 699 persistent_resources = *(Boolean *) value.addr; 700 } 701 } 702 if (persistent_resources) 703 cache_ptr = NULL; 704 else if (cache_base) 705 cache_ptr = cache_base; 706 else 707 cache_ptr = cache_ref; 708 709 for (res = table, j = 0; j < num_resources; j++, res++) { 710 rx = *res; 711 xrm_type = (XrmRepresentation) rx->xrm_type; 712 if (typed[j]) { 713 register XtTypedArg *arg = typed_args + typed[j] - 1; 714 715 /* 716 * This resource value has been specified as a typed arg and 717 * has to be converted. Typed arg conversions are done here 718 * to correctly interpose them with normal resource conversions. 719 */ 720 XrmQuark from_type; 721 XrmValue from_val, to_val; 722 Boolean converted; 723 724 from_type = StringToQuark(arg->type); 725 from_val.size = (Cardinal) arg->size; 726 if ((from_type == QString) || 727 ((unsigned) arg->size > sizeof(XtArgVal))) 728 from_val.addr = (XPointer) arg->value; 729 else 730 from_val.addr = (XPointer) &arg->value; 731 to_val.size = rx->xrm_size; 732 to_val.addr = base - rx->xrm_offset - 1; 733 converted = _XtConvert(widget, from_type, &from_val, 734 xrm_type, &to_val, cache_ptr); 735 if (converted) { 736 737 /* Copy the converted value back into the typed argument. 738 * normally the data should be <= sizeof(XtArgVal) and 739 * is stored directly into the 'value' field .... BUT 740 * if the resource size is greater than sizeof(XtArgVal) 741 * then we dynamically alloc a block of store to hold the 742 * data and zap a copy in there !!! .... freeing it later 743 * the size field in the typed arg is negated to indicate 744 * that the store pointed to by the value field is 745 * dynamic ....... 746 * "freeing" happens in the case of _XtCreate after the 747 * CallInitialize ..... other clients of GetResources 748 * using typed args should be aware of the need to free 749 * this store ..... 750 */ 751 752 if (rx->xrm_size > sizeof(XtArgVal)) { 753 arg->value = 754 (XtArgVal) (void *) __XtMalloc(rx->xrm_size); 755 arg->size = -(arg->size); 756 } 757 else { /* will fit - copy directly into value field */ 758 arg->value = (XtArgVal) NULL; 759 } 760 CopyToArg((char *) (base - rx->xrm_offset - 1), 761 &arg->value, rx->xrm_size); 762 763 } 764 else { 765 /* Conversion failed. Get default value. */ 766 found[j] = False; 767 } 768 769 if (cache_ptr && *cache_ptr) 770 cache_ptr++; 771 } 772 773 if (!found[j]) { 774 Boolean already_copied = False; 775 Boolean have_value = False; 776 777 if (XrmQGetSearchResource(searchList, 778 (XrmName) rx->xrm_name, 779 (XrmClass) rx->xrm_class, &rawType, 780 &value)) { 781 if (rawType != xrm_type) { 782 convValue.size = rx->xrm_size; 783 convValue.addr = (XPointer) (base - rx->xrm_offset - 1); 784 already_copied = have_value = 785 _XtConvert(widget, rawType, &value, 786 xrm_type, &convValue, cache_ptr); 787 if (cache_ptr && *cache_ptr) 788 cache_ptr++; 789 } 790 else 791 have_value = True; 792 if (have_value && rx->xrm_name == Qtranslations) 793 do_tm_hack = True; 794 } 795 LOCK_PROCESS; 796 if (!have_value && ((rx->xrm_default_type == QImmediate) 797 || (rx->xrm_default_type == xrm_type) 798 || (rx->xrm_default_addr != NULL))) { 799 /* Convert default value to proper type */ 800 xrm_default_type = (XrmRepresentation) rx->xrm_default_type; 801 if (xrm_default_type == QCallProc) { 802 (*(XtResourceDefaultProc) (rx->xrm_default_addr)) 803 (widget, -(rx->xrm_offset + 1), &value); 804 805 } 806 else if (xrm_default_type == QImmediate) { 807 /* XtRImmediate == XtRString for type XtRString */ 808 if (xrm_type == QString) { 809 value.addr = rx->xrm_default_addr; 810 } 811 else if (rx->xrm_size == sizeof(int)) { 812 int_val = (int) (long) rx->xrm_default_addr; 813 value.addr = (XPointer) &int_val; 814 } 815 else if (rx->xrm_size == sizeof(short)) { 816 short_val = (short) (long) rx->xrm_default_addr; 817 value.addr = (XPointer) &short_val; 818 } 819 else if (rx->xrm_size == sizeof(char)) { 820 char_val = (char) (long) rx->xrm_default_addr; 821 value.addr = (XPointer) &char_val; 822 } 823 else if (rx->xrm_size == sizeof(long)) { 824 long_val = (long) rx->xrm_default_addr; 825 value.addr = (XPointer) &long_val; 826 } 827 else if (rx->xrm_size == sizeof(char *)) { 828 char_ptr = (char *) rx->xrm_default_addr; 829 value.addr = (XPointer) &char_ptr; 830 } 831 else { 832 value.addr = (XPointer) &(rx->xrm_default_addr); 833 } 834 } 835 else if (xrm_default_type == xrm_type) { 836 value.addr = rx->xrm_default_addr; 837 } 838 else { 839 value.addr = rx->xrm_default_addr; 840 if (xrm_default_type == QString) { 841 value.size = 842 (unsigned) strlen((char *) value.addr) + 1; 843 } 844 else { 845 value.size = sizeof(XtPointer); 846 } 847 convValue.size = rx->xrm_size; 848 convValue.addr = (XPointer) (base - rx->xrm_offset - 1); 849 already_copied = 850 _XtConvert(widget, xrm_default_type, &value, 851 xrm_type, &convValue, cache_ptr); 852 if (!already_copied) 853 value.addr = NULL; 854 if (cache_ptr && *cache_ptr) 855 cache_ptr++; 856 } 857 } 858 if (!already_copied) { 859 if (xrm_type == QString) { 860 *((String *) (base - rx->xrm_offset - 1)) = value.addr; 861 } 862 else { 863 if (value.addr != NULL) { 864 XtMemmove(base - rx->xrm_offset - 1, 865 value.addr, rx->xrm_size); 866 } 867 else { 868 /* didn't get value, initialize to NULL... */ 869 XtBZero(base - rx->xrm_offset - 1, rx->xrm_size); 870 } 871 } 872 } 873 UNLOCK_PROCESS; 874 } 875 } 876 for (res = table, j = 0; j < num_resources; j++, res++) { 877 if (!found[j] && typed[j]) { 878 /* 879 * This resource value was specified as a typed arg. 880 * However, the default value is being used here since 881 * type type conversion failed, so we compress the list. 882 */ 883 register XtTypedArg *arg = typed_args + typed[j] - 1; 884 register int i; 885 886 for (i = num_typed_args - typed[j]; i > 0; i--, arg++) { 887 *arg = *(arg + 1); 888 } 889 num_typed_args--; 890 } 891 } 892 if (tm_hack) 893 widget->core.tm.current_state = NULL; 894 if (tm_hack && 895 (!widget->core.tm.translations || 896 (do_tm_hack && 897 widget->core.tm.translations->operation != XtTableReplace)) && 898 XrmQGetSearchResource(searchList, QbaseTranslations, 899 QTranslations, &rawType, &value)) { 900 if (rawType != QTranslationTable) { 901 convValue.size = sizeof(XtTranslations); 902 convValue.addr = (XPointer) &widget->core.tm.current_state; 903 (void) _XtConvert(widget, rawType, &value, 904 QTranslationTable, &convValue, cache_ptr); 905 if (cache_ptr && *cache_ptr) 906 cache_ptr++; 907 } 908 else { 909 /* value.addr can be NULL see: !already_copied */ 910 if (value.addr) 911 *((XtTranslations *) &widget->core.tm.current_state) = 912 *((XtTranslations *) value.addr); 913 } 914 } 915 } 916 if ((Cardinal) num_typed_args != *pNumTypedArgs) 917 *pNumTypedArgs = (Cardinal) num_typed_args; 918 if (searchList != stackSearchList) 919 XtFree((char *) searchList); 920 if (!cache_ptr) 921 cache_ptr = cache_base; 922 if (cache_ptr && cache_ptr != cache_ref) { 923 int cache_ref_size = (int) (cache_ptr - cache_ref); 924 XtCacheRef *refs = (XtCacheRef *) 925 __XtMalloc((Cardinal) 926 (sizeof(XtCacheRef) * (size_t) (cache_ref_size + 1))); 927 928 (void) memmove(refs, cache_ref, 929 sizeof(XtCacheRef) * (size_t) cache_ref_size); 930 refs[cache_ref_size] = NULL; 931 return refs; 932 } 933 return (XtCacheRef *) NULL; 934} 935 936static void 937CacheArgs(ArgList args, 938 Cardinal num_args, 939 XtTypedArgList typed_args, 940 Cardinal num_typed_args, 941 XrmQuarkList quark_cache, 942 Cardinal num_quarks, 943 XrmQuarkList *pQuarks) /* RETURN */ 944{ 945 register XrmQuarkList quarks; 946 register Cardinal i; 947 register Cardinal count; 948 949 count = (args != NULL) ? num_args : num_typed_args; 950 951 if (num_quarks < count) { 952 quarks = 953 (XrmQuarkList) __XtMalloc((Cardinal) (count * sizeof(XrmQuark))); 954 } 955 else { 956 quarks = quark_cache; 957 } 958 *pQuarks = quarks; 959 960 if (args != NULL) { 961 for (i = count; i; i--) 962 *quarks++ = StringToQuark((args++)->name); 963 } 964 else { 965 for (i = count; i; i--) 966 *quarks++ = StringToQuark((typed_args++)->name); 967 } 968} 969 970#define FreeCache(cache, pointer) \ 971 if (cache != pointer) XtFree((char *)pointer) 972 973XtCacheRef * 974_XtGetResources(register Widget w, 975 ArgList args, 976 Cardinal num_args, 977 XtTypedArgList typed_args, 978 Cardinal *num_typed_args) 979{ 980 XrmName *names, names_s[50]; 981 XrmClass *classes, classes_s[50]; 982 XrmQuark quark_cache[100]; 983 XrmQuarkList quark_args; 984 WidgetClass wc; 985 XtCacheRef *cache_refs = NULL; 986 Cardinal count; 987 988 wc = XtClass(w); 989 990 count = CountTreeDepth(w); 991 names = (XrmName *) XtStackAlloc(count * sizeof(XrmName), names_s); 992 classes = (XrmClass *) XtStackAlloc(count * sizeof(XrmClass), classes_s); 993 if (names == NULL || classes == NULL) { 994 _XtAllocError(NULL); 995 } 996 else { 997 998 /* Get names, classes for widget and ancestors */ 999 GetNamesAndClasses(w, names, classes); 1000 1001 /* Compile arg list into quarks */ 1002 CacheArgs(args, num_args, typed_args, *num_typed_args, quark_cache, 1003 XtNumber(quark_cache), &quark_args); 1004 1005 /* Get normal resources */ 1006 LOCK_PROCESS; 1007 cache_refs = GetResources(w, (char *) w, names, classes, 1008 (XrmResourceList *) wc->core_class.resources, 1009 wc->core_class.num_resources, quark_args, 1010 args, num_args, typed_args, num_typed_args, 1011 XtIsWidget(w)); 1012 1013 if (w->core.constraints != NULL) { 1014 ConstraintWidgetClass cwc; 1015 XtCacheRef *cache_refs_core; 1016 1017 cwc = (ConstraintWidgetClass) XtClass(w->core.parent); 1018 cache_refs_core = 1019 GetResources(w, (char *) w->core.constraints, names, classes, 1020 (XrmResourceList *) cwc->constraint_class. 1021 resources, cwc->constraint_class.num_resources, 1022 quark_args, args, num_args, typed_args, 1023 num_typed_args, False); 1024 XtFree((char *) cache_refs_core); 1025 } 1026 FreeCache(quark_cache, quark_args); 1027 UNLOCK_PROCESS; 1028 XtStackFree((XtPointer) names, names_s); 1029 XtStackFree((XtPointer) classes, classes_s); 1030 } 1031 return cache_refs; 1032} /* _XtGetResources */ 1033 1034void 1035_XtGetSubresources(Widget w, /* Widget "parent" of subobject */ 1036 XtPointer base, /* Base address to write to */ 1037 const char *name, /* name of subobject */ 1038 const char *class, /* class of subobject */ 1039 XtResourceList resources, /* resource list for subobject */ 1040 Cardinal num_resources, 1041 ArgList args, /* arg list to override resources */ 1042 Cardinal num_args, 1043 XtTypedArgList typed_args, 1044 Cardinal num_typed_args) 1045{ 1046 XrmName *names, names_s[50]; 1047 XrmClass *classes, classes_s[50]; 1048 XrmQuark quark_cache[100]; 1049 XrmQuarkList quark_args; 1050 XrmResourceList *table; 1051 Cardinal count, ntyped_args = num_typed_args; 1052 XtCacheRef *Resrc = NULL; 1053 1054 WIDGET_TO_APPCON(w); 1055 1056 if (num_resources == 0) 1057 return; 1058 1059 LOCK_APP(app); 1060 count = CountTreeDepth(w); 1061 count++; /* make sure there's enough room for name and class */ 1062 names = (XrmName *) XtStackAlloc(count * sizeof(XrmName), names_s); 1063 classes = (XrmClass *) XtStackAlloc(count * sizeof(XrmClass), classes_s); 1064 if (names == NULL || classes == NULL) { 1065 _XtAllocError(NULL); 1066 } 1067 else { 1068 /* Get full name, class of subobject */ 1069 GetNamesAndClasses(w, names, classes); 1070 count -= 2; 1071 names[count] = StringToName(name); 1072 classes[count] = StringToClass(class); 1073 count++; 1074 names[count] = NULLQUARK; 1075 classes[count] = NULLQUARK; 1076 1077 /* Compile arg list into quarks */ 1078 CacheArgs(args, num_args, typed_args, num_typed_args, 1079 quark_cache, XtNumber(quark_cache), &quark_args); 1080 1081 /* Compile resource list if needed */ 1082 if (((int) resources->resource_offset) >= 0) { 1083 XrmCompileResourceListEphem(resources, num_resources); 1084 } 1085 table = _XtCreateIndirectionTable(resources, num_resources); 1086 Resrc = 1087 GetResources(w, (char *) base, names, classes, table, num_resources, 1088 quark_args, args, num_args, typed_args, &ntyped_args, 1089 False); 1090 FreeCache(quark_cache, quark_args); 1091 XtFree((char *) table); 1092 XtFree((char *) Resrc); 1093 XtStackFree((XtPointer) names, names_s); 1094 XtStackFree((XtPointer) classes, classes_s); 1095 UNLOCK_APP(app); 1096 } 1097} 1098 1099void 1100XtGetSubresources(Widget w, /* Widget "parent" of subobject */ 1101 XtPointer base, /* Base address to write to */ 1102 _Xconst char *name, /* name of subobject */ 1103 _Xconst char *class, /* class of subobject */ 1104 XtResourceList resources, /* resource list for subobject */ 1105 Cardinal num_resources, 1106 ArgList args, /* arg list to override resources */ 1107 Cardinal num_args) 1108{ 1109 _XtGetSubresources(w, base, name, class, resources, num_resources, args, 1110 num_args, NULL, 0); 1111} 1112 1113void 1114_XtGetApplicationResources(Widget w, /* Application shell widget */ 1115 XtPointer base, /* Base address to write to */ 1116 XtResourceList resources, /* resource list for subobject */ 1117 Cardinal num_resources, 1118 ArgList args, /* arg list to override resources */ 1119 Cardinal num_args, 1120 XtTypedArgList typed_args, 1121 Cardinal num_typed_args) 1122{ 1123 XrmName *names, names_s[50]; 1124 XrmClass *classes, classes_s[50]; 1125 XrmQuark quark_cache[100]; 1126 XrmQuarkList quark_args; 1127 XrmResourceList *table; 1128 Cardinal ntyped_args = num_typed_args; 1129 1130#ifdef XTHREADS 1131 XtAppContext app; 1132#endif 1133 XtCacheRef *Resrc = NULL; 1134 1135 if (num_resources == 0) 1136 return; 1137 1138#ifdef XTHREADS 1139 if (w == NULL) 1140 app = _XtDefaultAppContext(); 1141 else 1142 app = XtWidgetToApplicationContext(w); 1143#endif 1144 1145 LOCK_APP(app); 1146 /* Get full name, class of application */ 1147 if (w == NULL) { 1148 /* hack for R2 compatibility */ 1149 XtPerDisplay pd = _XtGetPerDisplay(_XtDefaultAppContext()->list[0]); 1150 1151 names = (XrmName *) XtStackAlloc(2 * sizeof(XrmName), names_s); 1152 classes = (XrmClass *) XtStackAlloc(2 * sizeof(XrmClass), classes_s); 1153 if (names == NULL || classes == NULL) { 1154 _XtAllocError(NULL); 1155 } 1156 else { 1157 names[0] = pd->name; 1158 names[1] = NULLQUARK; 1159 classes[0] = pd->class; 1160 classes[1] = NULLQUARK; 1161 } 1162 } 1163 else { 1164 Cardinal count = CountTreeDepth(w); 1165 1166 names = (XrmName *) XtStackAlloc(count * sizeof(XrmName), names_s); 1167 classes = 1168 (XrmClass *) XtStackAlloc(count * sizeof(XrmClass), classes_s); 1169 if (names == NULL || classes == NULL) { 1170 _XtAllocError(NULL); 1171 } 1172 else { 1173 GetNamesAndClasses(w, names, classes); 1174 } 1175 } 1176 1177 /* Compile arg list into quarks */ 1178 CacheArgs(args, num_args, typed_args, num_typed_args, quark_cache, 1179 XtNumber(quark_cache), &quark_args); 1180 /* Compile resource list if needed */ 1181 if (((int) resources->resource_offset) >= 0) { 1182 XrmCompileResourceListEphem(resources, num_resources); 1183 } 1184 table = _XtCreateIndirectionTable(resources, num_resources); 1185 1186 Resrc = GetResources(w, (char *) base, names, classes, table, num_resources, 1187 quark_args, args, num_args, 1188 typed_args, &ntyped_args, False); 1189 FreeCache(quark_cache, quark_args); 1190 XtFree((char *) table); 1191 XtFree((char *) Resrc); 1192 if (w != NULL) { 1193 XtStackFree((XtPointer) names, names_s); 1194 XtStackFree((XtPointer) classes, classes_s); 1195 } 1196 UNLOCK_APP(app); 1197} 1198 1199void 1200XtGetApplicationResources(Widget w, /* Application shell widget */ 1201 XtPointer base, /* Base address to write to */ 1202 XtResourceList resources, /* resource list for subobject */ 1203 Cardinal num_resources, 1204 ArgList args, /* arg list to override resources */ 1205 Cardinal num_args) 1206{ 1207 _XtGetApplicationResources(w, base, resources, num_resources, args, 1208 num_args, NULL, 0); 1209} 1210 1211static Boolean initialized = FALSE; 1212 1213void 1214_XtResourceListInitialize(void) 1215{ 1216 LOCK_PROCESS; 1217 if (initialized) { 1218 XtWarningMsg("initializationError", "xtInitialize", XtCXtToolkitError, 1219 "Initializing Resource Lists twice", NULL, NULL); 1220 UNLOCK_PROCESS; 1221 return; 1222 } 1223 initialized = TRUE; 1224 UNLOCK_PROCESS; 1225 1226 QBoolean = XrmPermStringToQuark(XtCBoolean); 1227 QString = XrmPermStringToQuark(XtCString); 1228 QCallProc = XrmPermStringToQuark(XtRCallProc); 1229 QImmediate = XrmPermStringToQuark(XtRImmediate); 1230 QinitialResourcesPersistent = 1231 XrmPermStringToQuark(XtNinitialResourcesPersistent); 1232 QInitialResourcesPersistent = 1233 XrmPermStringToQuark(XtCInitialResourcesPersistent); 1234 Qtranslations = XrmPermStringToQuark(XtNtranslations); 1235 QbaseTranslations = XrmPermStringToQuark("baseTranslations"); 1236 QTranslations = XrmPermStringToQuark(XtCTranslations); 1237 QTranslationTable = XrmPermStringToQuark(XtRTranslationTable); 1238 Qscreen = XrmPermStringToQuark(XtNscreen); 1239 QScreen = XrmPermStringToQuark(XtCScreen); 1240} 1241