Object.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 "StringDefs.h" 76 77/* *INDENT-OFF* */ 78static XtResource resources[] = { 79 {XtNdestroyCallback, XtCCallback, XtRCallback,sizeof(XtPointer), 80 XtOffsetOf(ObjectRec,object.destroy_callbacks), 81 XtRCallback, (XtPointer)NULL} 82}; 83/* *INDENT-ON* */ 84 85static void ObjectClassPartInitialize(WidgetClass); 86static Boolean ObjectSetValues(Widget, Widget, Widget, ArgList, Cardinal *); 87static void ObjectDestroy(Widget); 88 89/* *INDENT-OFF* */ 90externaldef(objectclassrec) ObjectClassRec objectClassRec = { 91 { 92 /* superclass */ NULL, 93 /* class_name */ "Object", 94 /* widget_size */ sizeof(ObjectRec), 95 /* class_initialize */ NULL, 96 /* class_part_initialize */ ObjectClassPartInitialize, 97 /* class_inited */ FALSE, 98 /* initialize */ NULL, 99 /* initialize_hook */ NULL, 100 /* pad */ NULL, 101 /* pad */ NULL, 102 /* pad */ 0, 103 /* resources */ resources, 104 /* num_resources */ XtNumber(resources), 105 /* xrm_class */ NULLQUARK, 106 /* pad */ FALSE, 107 /* pad */ FALSE, 108 /* pad */ FALSE, 109 /* pad */ FALSE, 110 /* destroy */ ObjectDestroy, 111 /* pad */ NULL, 112 /* pad */ NULL, 113 /* set_values */ ObjectSetValues, 114 /* set_values_hook */ NULL, 115 /* pad */ NULL, 116 /* get_values_hook */ NULL, 117 /* pad */ NULL, 118 /* version */ XtVersion, 119 /* callback_offsets */ NULL, 120 /* pad */ NULL, 121 /* pad */ NULL, 122 /* pad */ NULL, 123 /* extension */ NULL 124 } 125}; 126/* *INDENT-ON* */ 127 128externaldef(objectClass) 129WidgetClass objectClass = (WidgetClass) &objectClassRec; 130 131/* 132 * Start of object routines. 133 */ 134 135static void 136ConstructCallbackOffsets(WidgetClass myWidgetClass) 137{ 138 static XrmQuark QCallback = NULLQUARK; 139 register int i; 140 register int tableSize; 141 register CallbackTable newTable; 142 register CallbackTable superTable; 143 register XrmResourceList resourceList; 144 ObjectClass myObjectClass = (ObjectClass) myWidgetClass; 145 146 /* 147 This function builds an array of pointers to the resource 148 structures which describe the callbacks for this widget class. 149 This array is special in that the 0th entry is the number of 150 callback pointers. 151 */ 152 153 if (QCallback == NULLQUARK) 154 QCallback = XrmPermStringToQuark(XtRCallback); 155 156 if (myObjectClass->object_class.superclass != NULL) { 157 superTable = (CallbackTable) 158 ((ObjectClass) myObjectClass->object_class. 159 superclass)->object_class.callback_private; 160 tableSize = (int) (long) superTable[0]; 161 } 162 else { 163 superTable = (CallbackTable) NULL; 164 tableSize = 0; 165 } 166 167 /* Count the number of callbacks */ 168 resourceList = (XrmResourceList) myObjectClass->object_class.resources; 169 for (i = (int) myObjectClass->object_class.num_resources; --i >= 0; 170 resourceList++) 171 if (resourceList->xrm_type == QCallback) 172 tableSize++; 173 174 /* 175 * Allocate and load the table. Make sure that the new callback 176 * offsets occur in the table ahead of the superclass callback 177 * offsets so that resource overrides work. 178 */ 179 newTable = (CallbackTable) 180 __XtMalloc((Cardinal) 181 (sizeof(XrmResource *) * (size_t) (tableSize + 1))); 182 183 newTable[0] = (XrmResource *) (long) tableSize; 184 185 if (superTable) 186 tableSize -= (int) (long) superTable[0]; 187 resourceList = (XrmResourceList) myObjectClass->object_class.resources; 188 for (i = 1; tableSize > 0; resourceList++) 189 if (resourceList->xrm_type == QCallback) { 190 newTable[i++] = resourceList; 191 tableSize--; 192 } 193 194 if (superTable) 195 for (tableSize = (int) (long) *superTable++; 196 --tableSize >= 0; superTable++) 197 newTable[i++] = *superTable; 198 199 myObjectClass->object_class.callback_private = (XtPointer) newTable; 200} 201 202static void 203InheritObjectExtensionMethods(WidgetClass widget_class) 204{ 205 ObjectClass oc = (ObjectClass) widget_class; 206 ObjectClassExtension ext, super_ext = NULL; 207 208 ext = (ObjectClassExtension) 209 XtGetClassExtension(widget_class, 210 XtOffsetOf(ObjectClassRec, object_class.extension), 211 NULLQUARK, XtObjectExtensionVersion, 212 sizeof(ObjectClassExtensionRec)); 213 214 if (oc->object_class.superclass) 215 super_ext = (ObjectClassExtension) 216 XtGetClassExtension(oc->object_class.superclass, 217 XtOffsetOf(ObjectClassRec, 218 object_class.extension), NULLQUARK, 219 XtObjectExtensionVersion, 220 sizeof(ObjectClassExtensionRec)); 221 LOCK_PROCESS; 222 if (ext) { 223 if (ext->allocate == XtInheritAllocate) 224 ext->allocate = (super_ext ? super_ext->allocate : NULL); 225 if (ext->deallocate == XtInheritDeallocate) 226 ext->deallocate = (super_ext ? super_ext->deallocate : NULL); 227 } 228 else if (super_ext) { 229 /* Be careful to inherit only what is appropriate */ 230 ext = (ObjectClassExtension) 231 __XtCalloc(1, sizeof(ObjectClassExtensionRec)); 232 ext->next_extension = oc->object_class.extension; 233 ext->record_type = NULLQUARK; 234 ext->version = XtObjectExtensionVersion; 235 ext->record_size = sizeof(ObjectClassExtensionRec); 236 ext->allocate = super_ext->allocate; 237 ext->deallocate = super_ext->deallocate; 238 oc->object_class.extension = (XtPointer) ext; 239 } 240 UNLOCK_PROCESS; 241} 242 243static void 244ObjectClassPartInitialize(register WidgetClass wc) 245{ 246 ObjectClass oc = (ObjectClass) wc; 247 248 oc->object_class.xrm_class = 249 XrmPermStringToQuark(oc->object_class.class_name); 250 251 if (oc->object_class.resources) 252 _XtCompileResourceList(oc->object_class.resources, 253 oc->object_class.num_resources); 254 255 ConstructCallbackOffsets(wc); 256 _XtResourceDependencies(wc); 257 InheritObjectExtensionMethods(wc); 258} 259 260static Boolean 261ObjectSetValues(Widget old, 262 Widget request _X_UNUSED, 263 Widget widget, 264 ArgList args _X_UNUSED, 265 Cardinal *num_args _X_UNUSED) 266{ 267 CallbackTable offsets; 268 int i; 269 270 LOCK_PROCESS; 271 /* Compile any callback lists into internal form */ 272 offsets = (CallbackTable) XtClass(widget)->core_class.callback_private; 273 274 for (i = (int) (long) *(offsets++); --i >= 0; offsets++) { 275 InternalCallbackList *ol, *nl; 276 277 ol = (InternalCallbackList *) 278 ((char *) old - (*offsets)->xrm_offset - 1); 279 nl = (InternalCallbackList *) 280 ((char *) widget - (*offsets)->xrm_offset - 1); 281 if (*ol != *nl) { 282 if (*ol != NULL) 283 XtFree((char *) *ol); 284 if (*nl != NULL) 285 *nl = _XtCompileCallbackList((XtCallbackList) *nl); 286 } 287 } 288 UNLOCK_PROCESS; 289 return False; 290} 291 292static void 293ObjectDestroy(register Widget widget) 294{ 295 CallbackTable offsets; 296 int i; 297 298 /* Remove all callbacks associated with widget */ 299 LOCK_PROCESS; 300 offsets = (CallbackTable) 301 widget->core.widget_class->core_class.callback_private; 302 303 for (i = (int) (long) *(offsets++); --i >= 0; offsets++) { 304 InternalCallbackList cl = *(InternalCallbackList *) 305 ((char *) widget - (*offsets)->xrm_offset - 1); 306 307 if (cl) 308 XtFree((char *) cl); 309 } 310 UNLOCK_PROCESS; 311} /* ObjectDestroy */ 312