1 /***********************************************************
2 Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
3 
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:
10 
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
13 Software.
14 
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.
22 
23 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24 
25                         All Rights Reserved
26 
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.
34 
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
41 SOFTWARE.
42 
43 ******************************************************************/
44 
45 /*
46 
47 Copyright 1987, 1988, 1994, 1998  The Open Group
48 
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
53 documentation.
54 
55 The above copyright notice and this permission notice shall be included in
56 all copies or substantial portions of the Software.
57 
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.
64 
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.
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* */
78 static XtResource resources[] = {
79     {XtNdestroyCallback, XtCCallback, XtRCallback,sizeof(XtPointer),
80      XtOffsetOf(ObjectRec,object.destroy_callbacks),
81      XtRCallback, (XtPointer)NULL}
82 };
83 /* *INDENT-ON* */
84 
85 static void ObjectClassPartInitialize(WidgetClass);
86 static Boolean ObjectSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
87 static void ObjectDestroy(Widget);
88 
89 /* *INDENT-OFF* */
90 externaldef(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 
128 externaldef(objectClass)
129 WidgetClass objectClass = (WidgetClass) &objectClassRec;
130 
131 /*
132  * Start of object routines.
133  */
134 
135 static void
ConstructCallbackOffsets(WidgetClass myWidgetClass)136 ConstructCallbackOffsets(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 
202 static void
InheritObjectExtensionMethods(WidgetClass widget_class)203 InheritObjectExtensionMethods(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 
243 static void
ObjectClassPartInitialize(register WidgetClass wc)244 ObjectClassPartInitialize(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 
260 static Boolean
ObjectSetValues(Widget old,Widget request _X_UNUSED,Widget widget,ArgList args _X_UNUSED,Cardinal * num_args _X_UNUSED)261 ObjectSetValues(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 
292 static void
ObjectDestroy(register Widget widget)293 ObjectDestroy(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