Object.c revision 2265a131
1/* $Xorg: Object.c,v 1.4 2001/02/09 02:03:56 xorgcvs Exp $ */
2
3/***********************************************************
4Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
5Copyright 1993 by Sun Microsystems, Inc. Mountain View, CA.
6
7                        All Rights Reserved
8
9Permission to use, copy, modify, and distribute this software and its
10documentation for any purpose and without fee is hereby granted,
11provided that the above copyright notice appear in all copies and that
12both that copyright notice and this permission notice appear in
13supporting documentation, and that the names of Digital or Sun not be
14used in advertising or publicity pertaining to distribution of the
15software without specific, written prior permission.
16
17DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
19DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
20ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
23SOFTWARE.
24
25SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
26INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
27NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
28ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
29ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
30PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
31OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
32THE USE OR PERFORMANCE OF THIS SOFTWARE.
33
34******************************************************************/
35
36/*
37
38Copyright 1987, 1988, 1994, 1998  The Open Group
39
40Permission to use, copy, modify, distribute, and sell this software and its
41documentation for any purpose is hereby granted without fee, provided that
42the above copyright notice appear in all copies and that both that
43copyright notice and this permission notice appear in supporting
44documentation.
45
46The above copyright notice and this permission notice shall be included in
47all copies or substantial portions of the Software.
48
49THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
52OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
53AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
54CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
55
56Except as contained in this notice, the name of The Open Group shall not be
57used in advertising or otherwise to promote the sale, use or other dealings
58in this Software without prior written authorization from The Open Group.
59
60*/
61/* $XFree86: xc/lib/Xt/Object.c,v 1.5 2001/01/17 19:43:06 dawes Exp $ */
62
63#ifdef HAVE_CONFIG_H
64#include <config.h>
65#endif
66#include "IntrinsicI.h"
67#include "StringDefs.h"
68
69static XtResource resources[] = {
70        {XtNdestroyCallback, XtCCallback, XtRCallback,sizeof(XtPointer),
71         XtOffsetOf(ObjectRec,object.destroy_callbacks),
72	 XtRCallback, (XtPointer)NULL}
73    };
74
75static void ObjectClassPartInitialize(WidgetClass);
76static Boolean ObjectSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
77static void ObjectDestroy(Widget);
78
79externaldef(objectclassrec) ObjectClassRec objectClassRec = {
80  {
81    /* superclass	  */	NULL,
82    /* class_name	  */	"Object",
83    /* widget_size	  */	sizeof(ObjectRec),
84    /* class_initialize   */    NULL,
85    /* class_part_initialize*/	ObjectClassPartInitialize,
86    /* class_inited       */	FALSE,
87    /* initialize	  */	NULL,
88    /* initialize_hook    */	NULL,
89    /* pad                */    NULL,
90    /* pad		  */	NULL,
91    /* pad       	  */	0,
92    /* resources	  */	resources,
93    /* num_resources	  */    XtNumber(resources),
94    /* xrm_class	  */	NULLQUARK,
95    /* pad                */    FALSE,
96    /* pad                */    FALSE,
97    /* pad                */    FALSE,
98    /* pad                */    FALSE,
99    /* destroy		  */	ObjectDestroy,
100    /* pad		  */	NULL,
101    /* pad		  */	NULL,
102    /* set_values	  */	ObjectSetValues,
103    /* set_values_hook    */	NULL,
104    /* pad                */    NULL,
105    /* get_values_hook    */	NULL,
106    /* pad                */    NULL,
107    /* version		  */	XtVersion,
108    /* callback_offsets   */    NULL,
109    /* pad                */    NULL,
110    /* pad                */    NULL,
111    /* pad                */    NULL,
112    /* extension	    */  NULL
113}
114};
115
116externaldef(objectClass) WidgetClass objectClass
117                          = (WidgetClass)&objectClassRec;
118
119/*
120 * Start of object routines.
121 */
122
123
124static void ConstructCallbackOffsets(
125    WidgetClass widgetClass)
126{
127    static XrmQuark QCallback = NULLQUARK;
128    register int i;
129    register int tableSize;
130    register CallbackTable newTable;
131    register CallbackTable superTable;
132    register XrmResourceList resourceList;
133    ObjectClass objectClass = (ObjectClass)widgetClass;
134
135    /*
136      This function builds an array of pointers to the resource
137      structures which describe the callbacks for this widget class.
138      This array is special in that the 0th entry is the number of
139      callback pointers.
140     */
141
142    if (QCallback == NULLQUARK)
143	QCallback = XrmPermStringToQuark(XtRCallback);
144
145    if (objectClass->object_class.superclass != NULL) {
146	superTable = (CallbackTable)
147	    ((ObjectClass) objectClass->object_class.superclass)->
148		object_class.callback_private;
149	tableSize = (int)(long) superTable[0];
150    } else {
151	superTable = (CallbackTable) NULL;
152	tableSize = 0;
153    }
154
155    /* Count the number of callbacks */
156    resourceList = (XrmResourceList) objectClass->object_class.resources;
157    for (i = objectClass->object_class.num_resources; --i >= 0; resourceList++)
158	if (resourceList->xrm_type == QCallback)
159	    tableSize++;
160
161    /*
162     * Allocate and load the table.  Make sure that the new callback
163     * offsets occur in the table ahead of the superclass callback
164     * offsets so that resource overrides work.
165     */
166    newTable = (CallbackTable)
167	__XtMalloc(sizeof(XrmResource *) * (tableSize + 1));
168
169    newTable[0] = (XrmResource *)(long) tableSize;
170
171    if (superTable)
172	tableSize -= (int)(long) superTable[0];
173    resourceList = (XrmResourceList) objectClass->object_class.resources;
174    for (i=1; tableSize > 0; resourceList++)
175	if (resourceList->xrm_type == QCallback) {
176	    newTable[i++] = resourceList;
177	    tableSize--;
178	}
179
180    if (superTable)
181	for (tableSize = (int)(long) *superTable++;
182	    --tableSize >= 0; superTable++)
183	    newTable[i++] = *superTable;
184
185    objectClass->object_class.callback_private = (XtPointer) newTable;
186}
187
188static void InheritObjectExtensionMethods(
189    WidgetClass widget_class)
190{
191    ObjectClass oc = (ObjectClass) widget_class;
192    ObjectClassExtension ext, super_ext = NULL;
193
194    ext = (ObjectClassExtension)
195	XtGetClassExtension(widget_class,
196		    XtOffsetOf(ObjectClassRec, object_class.extension),
197			    NULLQUARK, XtObjectExtensionVersion,
198			    sizeof(ObjectClassExtensionRec));
199
200    if (oc->object_class.superclass)
201	super_ext = (ObjectClassExtension)
202	    XtGetClassExtension(oc->object_class.superclass,
203			XtOffsetOf(ObjectClassRec, object_class.extension),
204				NULLQUARK, XtObjectExtensionVersion,
205				sizeof(ObjectClassExtensionRec));
206    LOCK_PROCESS;
207    if (ext) {
208	if (ext->allocate == XtInheritAllocate)
209	    ext->allocate = (super_ext ? super_ext->allocate : NULL);
210	if (ext->deallocate == XtInheritDeallocate)
211	    ext->deallocate = (super_ext ? super_ext->deallocate : NULL);
212    } else if (super_ext) {
213	/* Be careful to inherit only what is appropriate */
214	ext = (ObjectClassExtension)
215	    __XtCalloc(1, sizeof(ObjectClassExtensionRec));
216	ext->next_extension = oc->object_class.extension;
217	ext->record_type = NULLQUARK;
218	ext->version = XtObjectExtensionVersion;
219	ext->record_size = sizeof(ObjectClassExtensionRec);
220	ext->allocate = super_ext->allocate;
221	ext->deallocate = super_ext->deallocate;
222	oc->object_class.extension = (XtPointer) ext;
223    }
224    UNLOCK_PROCESS;
225}
226
227static void ObjectClassPartInitialize(
228    register WidgetClass wc)
229{
230   ObjectClass oc = (ObjectClass)wc;
231
232   oc->object_class.xrm_class =
233       XrmPermStringToQuark(oc->object_class.class_name);
234
235   if (oc->object_class.resources)
236       _XtCompileResourceList(oc->object_class.resources,
237			      oc->object_class.num_resources);
238
239   ConstructCallbackOffsets(wc);
240   _XtResourceDependencies(wc);
241   InheritObjectExtensionMethods(wc);
242}
243
244
245/*ARGSUSED*/
246static Boolean ObjectSetValues(
247    Widget	old,
248    Widget	request,
249    Widget	widget,
250    ArgList	args,
251    Cardinal *	num_args)
252{
253    register CallbackTable offsets;
254    register int i;
255    register InternalCallbackList *ol, *nl;
256
257    LOCK_PROCESS;
258    /* Compile any callback lists into internal form */
259    offsets = (CallbackTable) XtClass(widget)->core_class.callback_private;
260
261    for (i= (int)(long) *(offsets++); --i >= 0; offsets++) {
262	ol = (InternalCallbackList *)
263	    ((char *) old - (*offsets)->xrm_offset - 1);
264	nl = (InternalCallbackList *)
265	    ((char *) widget - (*offsets)->xrm_offset - 1);
266	if (*ol != *nl) {
267	    if (*ol != NULL)
268		XtFree((char *) *ol);
269	    if (*nl != NULL)
270		*nl = _XtCompileCallbackList((XtCallbackList) *nl);
271	}
272    }
273    UNLOCK_PROCESS;
274    return False;
275}
276
277
278static void ObjectDestroy (
279    register Widget    widget)
280{
281    register CallbackTable offsets;
282    register int i;
283    register InternalCallbackList cl;
284
285    /* Remove all callbacks associated with widget */
286    LOCK_PROCESS;
287    offsets = (CallbackTable)
288	widget->core.widget_class->core_class.callback_private;
289
290    for (i = (int)(long) *(offsets++); --i >= 0; offsets++) {
291	cl = *(InternalCallbackList *)
292	    ((char *) widget - (*offsets)->xrm_offset - 1);
293	if (cl) XtFree((char *) cl);
294    }
295    UNLOCK_PROCESS;
296} /* ObjectDestroy */
297