1 /***********************************************************
2 Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files (the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice (including the next
12 paragraph) shall be included in all copies or substantial portions of the
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 DEALINGS IN THE SOFTWARE.
23 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
27 Permission to use, copy, modify, and distribute this software and its
28 documentation for any purpose and without fee is hereby granted,
29 provided that the above copyright notice appear in all copies and that
30 both that copyright notice and this permission notice appear in
31 supporting documentation, and that the name of Digital not be
32 used in advertising or publicity pertaining to distribution of the
33 software without specific, written prior permission.
35 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43 ******************************************************************/
47 Copyright 1987, 1988, 1998 The Open Group
49 Permission to use, copy, modify, distribute, and sell this software and its
50 documentation for any purpose is hereby granted without fee, provided that
51 the above copyright notice appear in all copies and that both that
52 copyright notice and this permission notice appear in supporting
55 The above copyright notice and this permission notice shall be included in
56 all copies or substantial portions of the Software.
58 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
61 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
65 Except as contained in this notice, the name of The Open Group shall not be
66 used in advertising or otherwise to promote the sale, use or other dealings
67 in this Software without prior written authorization from The Open Group.
74 #include "IntrinsicI.h"
75 #include "StringDefs.h"
76 #include "Intrinsic.h"
78 /* Conversion procedure hash table */
80 #define CONVERTHASHSIZE ((unsigned)256)
81 #define CONVERTHASHMASK 255
82 #define ProcHash(from_type, to_type) (2 * (from_type) + to_type)
84 typedef struct _ConverterRec *ConverterPtr;
85 typedef struct _ConverterRec {
87 XrmRepresentation from, to;
88 XtTypeConverter converter;
89 XtDestructor destructor;
90 unsigned short num_args;
91 unsigned int do_ref_count:1;
92 unsigned int new_style:1;
93 unsigned int global:1;
97 #define ConvertArgs(p) ((XtConvertArgList)((p)+1))
99 /* used for old-style type converter cache only */
100 static Heap globalHeap = {NULL, NULL, 0};
102 void _XtSetDefaultConverterTable(
103 ConverterTable *table)
105 register ConverterTable globalConverterTable;
108 globalConverterTable = _XtGetProcessContext()->globalConverterTable;
110 *table = (ConverterTable)
111 __XtCalloc(CONVERTHASHSIZE, (unsigned)sizeof(ConverterPtr));
112 _XtAddDefaultConverters(*table);
114 if (globalConverterTable) {
117 XtCacheType cache_type;
118 for (i = CONVERTHASHSIZE; --i >= 0; ) {
119 for (rec = *globalConverterTable++; rec; rec = rec->next) {
120 cache_type = rec->cache_type;
121 if (rec->do_ref_count)
122 cache_type |= XtCacheRefCount;
123 _XtTableAddConverter(*table, rec->from, rec->to, rec->converter,
124 ConvertArgs(rec), rec->num_args,
125 rec->new_style, cache_type,
126 rec->destructor, True);
133 void _XtFreeConverterTable(
134 ConverterTable table)
137 register ConverterPtr p;
139 for (i = 0; i < CONVERTHASHSIZE; i++) {
140 for (p = table[i]; p; ) {
141 register ConverterPtr next = p->next;
146 XtFree((char*)table);
149 /* Data cache hash table */
151 typedef struct _CacheRec *CachePtr;
153 typedef struct _CacheRec {
157 XtTypeConverter converter;
158 unsigned short num_args;
159 unsigned int conversion_succeeded:1;
160 unsigned int has_ext:1;
161 unsigned int is_refcounted:1;
162 unsigned int must_be_freed:1;
163 unsigned int from_is_value:1;
164 unsigned int to_is_value:1;
169 typedef struct _CacheRecExt {
171 XtDestructor destructor;
176 #define CEXT(p) ((CacheRecExt *)((p)+1))
177 #define CARGS(p) ((p)->has_ext ? (XrmValue *)(CEXT(p)+1) : (XrmValue *)((p)+1))
179 #define CACHEHASHSIZE 256
180 #define CACHEHASHMASK 255
181 typedef CachePtr CacheHashTable[CACHEHASHSIZE];
183 static CacheHashTable cacheHashTable;
185 void _XtTableAddConverter(
186 ConverterTable table,
187 XrmRepresentation from_type,
188 XrmRepresentation to_type,
189 XtTypeConverter converter,
190 XtConvertArgList convert_args,
192 _XtBoolean new_style,
193 XtCacheType cache_type,
194 XtDestructor destructor,
197 register ConverterPtr *pp;
198 register ConverterPtr p;
199 XtConvertArgList args;
201 pp= &table[ProcHash(from_type, to_type) & CONVERTHASHMASK];
202 while ((p = *pp) && (p->from != from_type || p->to != to_type))
210 p = (ConverterPtr) __XtMalloc(sizeof(ConverterRec) +
211 sizeof(XtConvertArgRec) * num_args);
216 p->converter = converter;
217 p->destructor = destructor;
218 p->num_args = num_args;
220 args = ConvertArgs(p);
222 *args++ = *convert_args++;
223 p->new_style = new_style;
224 p->do_ref_count = False;
225 if (destructor || (cache_type & 0xff)) {
226 p->cache_type = cache_type & 0xff;
227 if (cache_type & XtCacheRefCount)
228 p->do_ref_count = True;
230 p->cache_type = XtCacheNone;
234 void XtSetTypeConverter(
235 register _Xconst char* from_type,
236 register _Xconst char* to_type,
237 XtTypeConverter converter,
238 XtConvertArgList convert_args,
240 XtCacheType cache_type,
241 XtDestructor destructor
244 ProcessContext process;
246 XrmRepresentation from;
247 XrmRepresentation to;
250 process = _XtGetProcessContext();
251 app = process->appContextList;
252 from = XrmStringToRepresentation(from_type);
253 to = XrmStringToRepresentation(to_type);
255 if (!process->globalConverterTable) {
256 process->globalConverterTable = (ConverterTable)
257 __XtCalloc(CONVERTHASHSIZE, (unsigned)sizeof(ConverterPtr));
259 _XtTableAddConverter(process->globalConverterTable, from, to,
260 converter, convert_args,
261 num_args, True, cache_type, destructor, True);
263 _XtTableAddConverter(app->converterTable, from, to,
264 converter, convert_args,
265 num_args, True, cache_type, destructor, True);
271 void XtAppSetTypeConverter(
273 register _Xconst char* from_type,
274 register _Xconst char* to_type,
275 XtTypeConverter converter,
276 XtConvertArgList convert_args,
278 XtCacheType cache_type,
279 XtDestructor destructor
283 _XtTableAddConverter(app->converterTable,
284 XrmStringToRepresentation(from_type),
285 XrmStringToRepresentation(to_type),
286 converter, convert_args, num_args,
287 True, cache_type, destructor, False);
293 register _Xconst char* from_type,
294 register _Xconst char* to_type,
295 XtConverter converter,
296 XtConvertArgList convert_args,
300 ProcessContext process;
302 XrmRepresentation from;
303 XrmRepresentation to;
306 process = _XtGetProcessContext();
307 app = process->appContextList;
308 from = XrmStringToRepresentation(from_type);
309 to = XrmStringToRepresentation(to_type);
311 if (!process->globalConverterTable) {
312 process->globalConverterTable = (ConverterTable)
313 __XtCalloc(CONVERTHASHSIZE, (unsigned)sizeof(ConverterPtr));
315 _XtTableAddConverter(process->globalConverterTable, from, to,
316 (XtTypeConverter)converter, convert_args, num_args,
317 False, XtCacheAll, (XtDestructor)NULL, True);
319 _XtTableAddConverter(app->converterTable, from, to,
320 (XtTypeConverter)converter, convert_args,
321 num_args, False, XtCacheAll, (XtDestructor)NULL,
329 void XtAppAddConverter(
331 register _Xconst char* from_type,
332 register _Xconst char* to_type,
333 XtConverter converter,
334 XtConvertArgList convert_args,
339 _XtTableAddConverter(app->converterTable,
340 XrmStringToRepresentation(from_type),
341 XrmStringToRepresentation(to_type),
342 (XtTypeConverter)converter, convert_args, num_args,
343 False, XtCacheAll, (XtDestructor)NULL, False);
350 register XtTypeConverter converter,
351 register XrmValuePtr args,
359 XtDestructor destructor,
362 register CachePtr *pHashEntry;
367 pHashEntry = &cacheHashTable[hash & CACHEHASHMASK];
369 if ((succeeded && destructor) || do_ref) {
370 p = (CachePtr) _XtHeapAlloc(heap, (sizeof(CacheRec) +
371 sizeof(CacheRecExt) +
372 num_args * sizeof(XrmValue)));
373 CEXT(p)->prev = pHashEntry;
374 CEXT(p)->destructor = succeeded ? destructor : NULL;
375 CEXT(p)->closure = closure;
376 CEXT(p)->ref_count = 1;
380 p = (CachePtr)_XtHeapAlloc(heap, (sizeof(CacheRec) +
381 num_args * sizeof(XrmValue)));
386 p->conversion_succeeded = succeeded;
387 p->is_refcounted = do_ref;
388 p->must_be_freed = do_free;
389 p->next = *pHashEntry;
390 if (p->next && p->next->has_ext)
391 CEXT(p->next)->prev = &p->next;
394 p->tag = (XtPointer)heap;
396 p->converter = converter;
397 p->from.size = from->size;
398 if (from->size <= sizeof(p->from.addr)) {
399 p->from_is_value = True;
400 XtMemmove(&p->from.addr, from->addr, from->size);
402 p->from_is_value = False;
403 p->from.addr = (XPointer)_XtHeapAlloc(heap, from->size);
404 (void) memmove((char *)p->from.addr, (char *)from->addr, from->size);
406 p->num_args = num_args;
408 XrmValue *pargs = CARGS(p);
409 for (i = 0; i < num_args; i++) {
410 pargs[i].size = args[i].size;
411 pargs[i].addr = (XPointer)_XtHeapAlloc(heap, args[i].size);
412 XtMemmove(pargs[i].addr, args[i].addr, args[i].size);
415 p->to.size = to->size;
417 p->to_is_value = False;
419 } else if (to->size <= sizeof(p->to.addr)) {
420 p->to_is_value = True;
421 XtMemmove(&p->to.addr, to->addr, to->size);
423 p->to_is_value = False;
424 p->to.addr = (XPointer)_XtHeapAlloc(heap, to->size);
425 (void) memmove((char *)p->to.addr, (char *)to->addr, to->size);
431 static void FreeCacheRec(
438 if (CEXT(p)->destructor) {
439 Cardinal num_args = p->num_args;
440 XrmValue *args = NULL;
444 toc.size = p->to.size;
446 toc.addr = (XPointer)&p->to.addr;
448 toc.addr = p->to.addr;
449 (*CEXT(p)->destructor) (app, &toc, CEXT(p)->closure, args,
452 *(CEXT(p)->prev) = p->next;
453 if (p->next && p->next->has_ext)
454 CEXT(p->next)->prev = CEXT(p)->prev;
457 if (p->next && p->next->has_ext)
458 CEXT(p->next)->prev = prev;
460 if (p->must_be_freed) {
462 if (!p->from_is_value)
463 XtFree(p->from.addr);
464 if ((i = p->num_args)) {
465 XrmValue *pargs = CARGS(p);
467 XtFree(pargs[i].addr);
473 /* else on private heap; will free entire heap later */
478 void _XtCacheFlushTag(
483 register CachePtr *prev;
484 register CachePtr rec;
487 for (i = CACHEHASHSIZE; --i >= 0;) {
488 prev = &cacheHashTable[i];
489 while ((rec = *prev)) {
491 FreeCacheRec(app, rec, prev);
502 void _XtConverterCacheStats(void)
506 register Cardinal entries;
509 for (i = 0; i < CACHEHASHSIZE; i++) {
510 p = cacheHashTable[i];
512 for (entries = 0; p; p = p->next) {
515 (void) fprintf(stdout, "Index: %4d Entries: %d\n", i, entries);
516 for (p = cacheHashTable[i]; p; p = p->next) {
517 (void) fprintf(stdout, " Size: %3d Refs: %3d '",
519 p->has_ext ? CEXT(p)->ref_count : 0);
520 (void) fprintf(stdout, "'\n");
522 (void) fprintf(stdout, "\n");
529 static Boolean ResourceQuarkToOffset(
530 WidgetClass widget_class,
534 register WidgetClass wc;
536 register XrmResourceList res, *resources;
538 for (wc = widget_class; wc; wc = wc->core_class.superclass) {
539 resources = (XrmResourceList*) wc->core_class.resources;
540 for (i = 0; i < wc->core_class.num_resources; i++, resources++) {
542 if (res->xrm_name == name) {
543 *offset = -res->xrm_offset - 1;
546 } /* for i in resources */
547 } /* for wc in widget classes */
553 static void ComputeArgs(
555 XtConvertArgList convert_args,
562 Cardinal num_params = 1;
563 Widget ancestor = NULL;
565 for (i = 0; i < num_args; i++) {
566 args[i].size = convert_args[i].size;
567 switch (convert_args[i].address_mode) {
569 args[i].addr = convert_args[i].address_id;
574 (XPointer)((char *)widget + (long)convert_args[i].address_id);
577 case XtWidgetBaseOffset:
579 if (XtIsWidget(widget))
582 ancestor = _XtWindowedAncestor(widget);
586 (XPointer)((char *)ancestor + (long)convert_args[i].address_id);
590 args[i].addr = (XPointer) &(convert_args[i].address_id);
594 (*(XtConvertArgProc)convert_args[i].address_id)
595 (widget, &convert_args[i].size, &args[i]);
598 case XtResourceString:
599 /* Convert in place for next usage */
600 convert_args[i].address_mode = XtResourceQuark;
601 convert_args[i].address_id =
602 (XtPointer)(long)XrmStringToQuark((String)convert_args[i].address_id);
605 case XtResourceQuark:
606 if (! ResourceQuarkToOffset(widget->core.widget_class,
607 (XrmQuark)(long) convert_args[i].address_id, &offset)) {
609 XrmQuarkToString((XrmQuark)(long) convert_args[i].address_id);
610 XtAppWarningMsg(XtWidgetToApplicationContext(widget),
611 "invalidResourceName","computeArgs",XtCXtToolkitError,
612 "Cannot find resource name %s as argument to conversion",
616 args[i].addr = (XPointer)((char *)widget + offset);
619 params[0] = XtName(widget);
620 XtAppWarningMsg(XtWidgetToApplicationContext(widget),
621 "invalidAddressMode", "computeArgs", XtCXtToolkitError,
622 "Conversion arguments for widget '%s' contain an unsupported address mode",
630 void XtDirectConvert(
631 XtConverter converter,
634 register XrmValuePtr from,
642 /* Try to find cache entry for conversion */
643 hash = ((long) converter >> 2) + from->size + *((char *) from->addr);
644 if (from->size > 1) hash += ((char *) from->addr)[1];
646 for (p = cacheHashTable[hash & CACHEHASHMASK]; p; p = p->next) {
647 if ((p->hash == hash)
648 && (p->converter == (XtTypeConverter)converter)
649 && (p->from.size == from->size)
650 && !(p->from_is_value ?
651 XtMemcmp(&p->from.addr, from->addr, from->size) :
652 memcmp((char *)p->from.addr, (char *)from->addr, from->size))
653 && (p->num_args == num_args)) {
654 if ((i = num_args)) {
655 XrmValue *pargs = CARGS(p);
656 /* Are all args the same data ? */
658 i--; /* do not move to while test, broken compilers */
659 if (pargs[i].size != args[i].size ||
660 XtMemcmp(pargs[i].addr, args[i].addr, args[i].size)) {
668 to->size = p->to.size;
670 to->addr = (XPointer)&p->to.addr;
672 to->addr = p->to.addr;
679 /* Didn't find it, call converter procedure and entry result in cache */
682 (*converter)(args, &num_args, from, to);
683 /* This memory can never be freed since we don't know the Display
684 * or app context from which to compute the persistance */
686 CacheEnter(&globalHeap, (XtTypeConverter)converter, args, num_args,
687 from, to, (to->addr != NULL), hash, False, False,
688 (XtDestructor)NULL, NULL);
694 static ConverterPtr GetConverterEntry(
696 XtTypeConverter converter)
699 register ConverterPtr cP;
700 ConverterTable converterTable;
703 converterTable = app->converterTable;
705 for (entry = 0; (entry < CONVERTHASHSIZE) && !cP; entry++) {
706 cP = converterTable[entry];
707 while (cP && (cP->converter != converter)) cP = cP->next;
717 XtTypeConverter converter,
720 register XrmValuePtr from,
722 XtCacheRef *cache_ref_return,
723 register ConverterPtr cP)
730 if (!cP || ((cP->cache_type == XtCacheNone) && !cP->destructor)) {
732 if (cache_ref_return) *cache_ref_return = NULL;
733 retval = (*(XtTypeConverter)converter)
734 (dpy, args, &num_args, from, to, &closure);
739 /* Try to find cache entry for conversion */
740 hash = ((long)(converter) >> 2) + from->size + *((char *) from->addr);
741 if (from->size > 1) hash += ((char *) from->addr)[1];
743 if (cP->cache_type != XtCacheNone) {
744 for (p = cacheHashTable[hash & CACHEHASHMASK]; p; p = p->next){
745 if ((p->hash == hash)
746 && (p->converter == converter)
747 && (p->from.size == from->size)
748 && !(p->from_is_value ?
749 XtMemcmp(&p->from.addr, from->addr, from->size) :
750 memcmp((char *)p->from.addr, (char *)from->addr, from->size))
751 && (p->num_args == num_args)) {
752 if ((i = num_args)) {
753 XrmValue *pargs = CARGS(p);
754 /* Are all args the same data ? */
756 i--; /* do not move to while test, broken compilers */
757 if (pargs[i].size != args[i].size ||
758 XtMemcmp(pargs[i].addr, args[i].addr, args[i].size)){
766 if (p->conversion_succeeded) {
767 if (to->addr) { /* new-style call */
768 if (to->size < p->to.size) {
769 to->size = p->to.size;
773 to->size = p->to.size;
774 if (p->to_is_value) {
775 XtMemmove(to->addr, &p->to.addr,
778 (void) memmove((char *)to->addr,
779 (char *)p->to.addr, to->size);
781 } else { /* old-style call */
782 to->size = p->to.size;
784 to->addr = (XPointer)&p->to.addr;
786 to->addr = p->to.addr;
789 if (p->is_refcounted) {
790 CEXT(p)->ref_count++;
791 if (cache_ref_return)
792 *cache_ref_return = (XtCacheRef)p;
794 p->is_refcounted = False;
797 if (cache_ref_return)
798 *cache_ref_return = NULL;
800 retval = (p->conversion_succeeded);
808 /* No cache entry, call converter procedure and enter result in cache */
811 XtPointer closure = NULL;
812 unsigned int supplied_size = to->size;
813 Boolean do_ref = cP->do_ref_count && cache_ref_return;
814 Boolean do_free = False;
816 (*(XtTypeConverter)converter)(dpy, args, &num_args, from, to, &closure);
818 if (retval == False && supplied_size < to->size) {
819 /* programmer error: caller must allocate sufficient storage */
820 if (cache_ref_return)
821 *cache_ref_return = NULL;
826 if ((cP->cache_type == XtCacheNone) || do_ref) {
830 else if (cP->cache_type == XtCacheByDisplay)
831 heap = &_XtGetPerDisplay(dpy)->heap;
835 heap = &XtDisplayToApplicationContext(dpy)->heap;
837 p = CacheEnter(heap, converter, args, num_args, from, to, retval,
838 hash, do_ref, do_free, cP->destructor, closure);
840 *cache_ref_return = (XtCacheRef)p;
841 else if (cache_ref_return)
842 *cache_ref_return = NULL;
851 XtTypeConverter converter,
854 register XrmValuePtr from,
856 XtCacheRef *cache_ref_return)
860 XtAppContext app = XtDisplayToApplicationContext(dpy);
863 if ((cP = GetConverterEntry(app, converter)) == NULL) {
864 XtAppSetTypeConverter(XtDisplayToApplicationContext(dpy),
865 "_XtUnk1", "_XtUnk2",
868 cP = GetConverterEntry(app, converter);
870 retval = CallConverter(dpy, converter, args, num_args, from, to,
871 cache_ref_return, cP);
878 register XrmRepresentation from_type,
880 register XrmRepresentation to_type,
881 register XrmValuePtr to,
882 XtCacheRef *cache_ref_return)
884 XtAppContext app = XtWidgetToApplicationContext(widget);
885 register ConverterPtr p;
889 /* Look for type converter */
891 p = app->converterTable[ProcHash(from_type, to_type) & CONVERTHASHMASK];
892 for (; p; p = p->next) {
893 if (from_type == p->from && to_type == p->to) {
894 Boolean retval = False;
895 /* Compute actual arguments from widget and arg descriptor */
896 num_args = p->num_args;
899 ALLOCATE_LOCAL( num_args * sizeof (XrmValue) );
900 if (!args) _XtAllocError("alloca");
901 ComputeArgs(widget, ConvertArgs(p), num_args, args);
905 CallConverter(XtDisplayOfObject(widget),
906 p->converter, args, num_args,
907 from, to, cache_ref_return, p);
909 else { /* is old-style (non-display) converter */
911 XtDirectConvert((XtConverter)p->converter, args, num_args,
913 if (cache_ref_return)
914 *cache_ref_return = NULL;
916 if (to->addr) { /* new-style caller */
917 if (to->size >= tempTo.size) {
918 if (to_type == _XtQString)
919 *(String*)(to->addr) = tempTo.addr;
921 XtMemmove(to->addr, tempTo.addr,
926 to->size = tempTo.size;
927 } else { /* old-style caller */
933 if (args) DEALLOCATE_LOCAL( (XtPointer)args );
941 Cardinal num_params = 2;
942 params[0] = XrmRepresentationToString(from_type);
943 params[1] = XrmRepresentationToString(to_type);
944 XtAppWarningMsg(app, "typeConversionError", "noConverter", XtCXtToolkitError,
945 "No type converter registered for '%s' to '%s' conversion.",
946 params, &num_params);
954 _Xconst char* from_type_str,
956 _Xconst char* to_type_str,
959 XrmQuark from_type, to_type;
960 WIDGET_TO_APPCON(widget);
963 from_type = XrmStringToRepresentation(from_type_str);
964 to_type = XrmStringToRepresentation(to_type_str);
965 if (from_type != to_type) {
966 /* It's not safe to ref count these resources, 'cause we
967 don't know what older clients may have assumed about
968 the resource lifetimes.
973 _XtConvert(widget, from_type, from, to_type, to, /*&ref*/ NULL);
976 XtAddCallback( widget, XtNdestroyCallback,
977 XtCallbackReleaseCacheRef, (XtPointer)ref );
986 Boolean XtConvertAndStore(
988 _Xconst char* from_type_str,
990 _Xconst char* to_type_str,
993 XrmQuark from_type, to_type;
994 WIDGET_TO_APPCON(object);
998 from_type = XrmStringToRepresentation(from_type_str);
999 to_type = XrmStringToRepresentation(to_type_str);
1000 if (from_type != to_type) {
1001 static XtPointer local_valueP = NULL;
1002 static Cardinal local_valueS = 128;
1004 Boolean local = False;
1008 local_valueP = _XtHeapAlloc(&globalHeap, local_valueS);
1009 to->addr = local_valueP;
1010 to->size = local_valueS;
1013 if (!_XtConvert(object, from_type, from, to_type, to, &ref)) {
1014 if (local && (to->size > local_valueS)) {
1016 local_valueP = _XtHeapAlloc(&globalHeap, to->size);
1017 local_valueS = to->size;
1030 XtAddCallback( object, XtNdestroyCallback,
1031 XtCallbackReleaseCacheRef, (XtPointer)ref );
1036 } while (local /* && local_valueS < to->size */);
1039 if (to->size < from->size) {
1040 to->size = from->size;
1045 (void) memmove(to->addr, from->addr, from->size );
1046 to->size = from->size;
1047 } else /* from_type == to_type */
1054 void XtAppReleaseCacheRefs(
1058 register CachePtr *r;
1059 register CachePtr p;
1063 for (r = (CachePtr*)refs; (p = *r); r++) {
1064 if (p->is_refcounted && --(CEXT(p)->ref_count) == 0) {
1065 FreeCacheRec(app, p, NULL);
1074 void XtCallbackReleaseCacheRefList(
1075 Widget widget, /* unused */
1077 XtPointer call_data) /* unused */
1079 XtAppReleaseCacheRefs( XtWidgetToApplicationContext(widget),
1080 (XtCacheRef*)closure );
1086 void XtCallbackReleaseCacheRef(
1087 Widget widget, /* unused */
1089 XtPointer call_data) /* unused */
1091 XtCacheRef cache_refs[2];
1092 cache_refs[0] = (XtCacheRef)closure;
1093 cache_refs[1] = NULL;
1094 XtAppReleaseCacheRefs( XtWidgetToApplicationContext(widget), cache_refs );