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