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