Callback.c revision 0568f49b
1444c061aSmrg/***********************************************************
2249c3046SmrgCopyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
31477040fSmrg
41477040fSmrgPermission is hereby granted, free of charge, to any person obtaining a
51477040fSmrgcopy of this software and associated documentation files (the "Software"),
61477040fSmrgto deal in the Software without restriction, including without limitation
71477040fSmrgthe rights to use, copy, modify, merge, publish, distribute, sublicense,
81477040fSmrgand/or sell copies of the Software, and to permit persons to whom the
91477040fSmrgSoftware is furnished to do so, subject to the following conditions:
101477040fSmrg
111477040fSmrgThe above copyright notice and this permission notice (including the next
121477040fSmrgparagraph) shall be included in all copies or substantial portions of the
131477040fSmrgSoftware.
141477040fSmrg
151477040fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161477040fSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171477040fSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181477040fSmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191477040fSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201477040fSmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211477040fSmrgDEALINGS IN THE SOFTWARE.
221477040fSmrg
231477040fSmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24444c061aSmrg
25444c061aSmrg                        All Rights Reserved
26444c061aSmrg
27444c061aSmrgPermission to use, copy, modify, and distribute this software and its
28444c061aSmrgdocumentation for any purpose and without fee is hereby granted,
29444c061aSmrgprovided that the above copyright notice appear in all copies and that
30444c061aSmrgboth that copyright notice and this permission notice appear in
311477040fSmrgsupporting documentation, and that the name of Digital not be
32444c061aSmrgused in advertising or publicity pertaining to distribution of the
33444c061aSmrgsoftware without specific, written prior permission.
34444c061aSmrg
35444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41444c061aSmrgSOFTWARE.
42444c061aSmrg
43444c061aSmrg******************************************************************/
44444c061aSmrg
45444c061aSmrg/*
46444c061aSmrg
47444c061aSmrgCopyright 1987, 1988, 1998  The Open Group
48444c061aSmrg
49444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its
50444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that
51444c061aSmrgthe above copyright notice appear in all copies and that both that
52444c061aSmrgcopyright notice and this permission notice appear in supporting
53444c061aSmrgdocumentation.
54444c061aSmrg
55444c061aSmrgThe above copyright notice and this permission notice shall be included in
56444c061aSmrgall copies or substantial portions of the Software.
57444c061aSmrg
58444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
61444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64444c061aSmrg
65444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be
66444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings
67444c061aSmrgin this Software without prior written authorization from The Open Group.
68444c061aSmrg
69444c061aSmrg*/
70444c061aSmrg
71444c061aSmrg#ifdef HAVE_CONFIG_H
72444c061aSmrg#include <config.h>
73444c061aSmrg#endif
74444c061aSmrg#include "IntrinsicI.h"
75444c061aSmrg
760568f49bSmrgstatic _Xconst _XtString XtNinvalidCallbackList = "invalidCallbackList";
770568f49bSmrgstatic _Xconst _XtString XtNxtAddCallback = "xtAddCallback";
780568f49bSmrgstatic _Xconst _XtString XtNxtRemoveCallback = "xtRemoveCallback";
790568f49bSmrgstatic _Xconst _XtString XtNxtRemoveAllCallback = "xtRemoveAllCallback";
800568f49bSmrgstatic _Xconst _XtString XtNxtCallCallback = "xtCallCallback";
81444c061aSmrg
82444c061aSmrg/* However it doesn't contain a final NULL record */
83444c061aSmrg#define ToList(p) ((XtCallbackList) ((p)+1))
84444c061aSmrg
85444c061aSmrgstatic InternalCallbackList* FetchInternalList(
86444c061aSmrg    Widget	widget,
87444c061aSmrg    _Xconst char *name)
88444c061aSmrg{
89444c061aSmrg    XrmQuark quark;
90444c061aSmrg    int n;
91444c061aSmrg    CallbackTable offsets;
92444c061aSmrg    InternalCallbackList* retval = NULL;
93444c061aSmrg
94444c061aSmrg    quark = StringToQuark(name);
95444c061aSmrg    LOCK_PROCESS;
96444c061aSmrg    offsets = (CallbackTable)
97444c061aSmrg	widget->core.widget_class->core_class.callback_private;
98444c061aSmrg
99444c061aSmrg    for (n = (int)(long) *(offsets++); --n >= 0; offsets++)
100444c061aSmrg	if (quark == (*offsets)->xrm_name) {
101444c061aSmrg	    retval = (InternalCallbackList *)
102444c061aSmrg		((char *) widget - (*offsets)->xrm_offset - 1);
103444c061aSmrg	    break;
104444c061aSmrg	}
105444c061aSmrg    UNLOCK_PROCESS;
106444c061aSmrg    return retval;
107444c061aSmrg}
108444c061aSmrg
109444c061aSmrg
110444c061aSmrgvoid _XtAddCallback(
111444c061aSmrg    InternalCallbackList*   callbacks,
112444c061aSmrg    XtCallbackProc	    callback,
113444c061aSmrg    XtPointer		    closure)
114444c061aSmrg{
115444c061aSmrg    register InternalCallbackList icl;
116444c061aSmrg    register XtCallbackList cl;
117444c061aSmrg    register int count;
118444c061aSmrg
119444c061aSmrg    icl = *callbacks;
120444c061aSmrg    count = icl ? icl->count : 0;
121444c061aSmrg
122444c061aSmrg    if (icl && icl->call_state) {
123444c061aSmrg	icl->call_state |= _XtCBFreeAfterCalling;
124444c061aSmrg	icl = (InternalCallbackList)
1250568f49bSmrg	    __XtMalloc((Cardinal) (sizeof(InternalCallbackRec) +
1260568f49bSmrg		     sizeof(XtCallbackRec) * (size_t) (count + 1)));
127444c061aSmrg	(void) memmove((char *)ToList(icl), (char *)ToList(*callbacks),
1280568f49bSmrg		       sizeof(XtCallbackRec) * (size_t) count);
129444c061aSmrg    } else {
130444c061aSmrg	icl = (InternalCallbackList)
1310568f49bSmrg	    XtRealloc((char *) icl, (Cardinal)(sizeof(InternalCallbackRec) +
1320568f49bSmrg		      sizeof(XtCallbackRec) * (size_t) (count + 1)));
133444c061aSmrg    }
134444c061aSmrg    *callbacks = icl;
1350568f49bSmrg    icl->count = (unsigned short) (count + 1);
136444c061aSmrg    icl->is_padded = 0;
137444c061aSmrg    icl->call_state = 0;
138444c061aSmrg    cl = ToList(icl) + count;
139444c061aSmrg    cl->callback = callback;
140444c061aSmrg    cl->closure = closure;
141444c061aSmrg} /* _XtAddCallback */
142444c061aSmrg
143444c061aSmrgvoid _XtAddCallbackOnce(
144444c061aSmrg    register InternalCallbackList*callbacks,
145444c061aSmrg    XtCallbackProc	    callback,
146444c061aSmrg    XtPointer		    closure)
147444c061aSmrg{
148444c061aSmrg    register XtCallbackList cl = ToList(*callbacks);
149444c061aSmrg    register int i;
150444c061aSmrg
151444c061aSmrg    for (i=(*callbacks)->count; --i >= 0; cl++)
152444c061aSmrg	if (cl->callback == callback && cl->closure == closure)
153444c061aSmrg	    return;
154444c061aSmrg
155444c061aSmrg    _XtAddCallback(callbacks, callback, closure);
156444c061aSmrg} /* _XtAddCallbackOnce */
157444c061aSmrg
158444c061aSmrgvoid XtAddCallback(
159444c061aSmrg    Widget	    widget,
160444c061aSmrg    _Xconst char*   name,
161444c061aSmrg    XtCallbackProc  callback,
162444c061aSmrg    XtPointer	    closure
163444c061aSmrg    )
164444c061aSmrg{
165444c061aSmrg    InternalCallbackList *callbacks;
166444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
167444c061aSmrg
168444c061aSmrg    LOCK_APP(app);
169444c061aSmrg    callbacks = FetchInternalList(widget, name);
170444c061aSmrg    if (!callbacks) {
171444c061aSmrg	XtAppWarningMsg(app,
172444c061aSmrg	       XtNinvalidCallbackList,XtNxtAddCallback,XtCXtToolkitError,
173444c061aSmrg              "Cannot find callback list in XtAddCallback",
1740568f49bSmrg	      NULL, NULL);
175444c061aSmrg	UNLOCK_APP(app);
176444c061aSmrg	return;
177444c061aSmrg    }
178444c061aSmrg    _XtAddCallback(callbacks, callback, closure);
179444c061aSmrg    if (!_XtIsHookObject(widget)) {
1800568f49bSmrg        Widget hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
181444c061aSmrg	if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
182444c061aSmrg	    XtChangeHookDataRec call_data;
183444c061aSmrg
184444c061aSmrg	    call_data.type = XtHaddCallback;
185444c061aSmrg	    call_data.widget = widget;
186444c061aSmrg	    call_data.event_data = (XtPointer) name;
187444c061aSmrg	    XtCallCallbackList(hookobj,
188444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
189444c061aSmrg		(XtPointer)&call_data);
190444c061aSmrg	}
191444c061aSmrg    }
192444c061aSmrg    UNLOCK_APP(app);
193444c061aSmrg} /* XtAddCallback */
194444c061aSmrg
195444c061aSmrg/* ARGSUSED */
196444c061aSmrgstatic void AddCallbacks(
197444c061aSmrg    Widget		    widget,
198444c061aSmrg    InternalCallbackList   *callbacks,
199444c061aSmrg    XtCallbackList	    newcallbacks)
200444c061aSmrg{
201444c061aSmrg    register InternalCallbackList icl;
202444c061aSmrg    register int i, j;
203444c061aSmrg    register XtCallbackList cl;
204444c061aSmrg
205444c061aSmrg    icl = *callbacks;
206444c061aSmrg    i = icl ? icl->count : 0;
207444c061aSmrg    for (j=0, cl = newcallbacks; cl->callback; cl++, j++);
208444c061aSmrg    if (icl && icl->call_state) {
209444c061aSmrg	icl->call_state |= _XtCBFreeAfterCalling;
2100568f49bSmrg	icl = (InternalCallbackList) __XtMalloc((Cardinal)(sizeof(InternalCallbackRec) +
2110568f49bSmrg					      sizeof(XtCallbackRec) * (size_t) (i+j)));
212444c061aSmrg	(void) memmove((char *)ToList(*callbacks), (char *)ToList(icl),
2130568f49bSmrg		       sizeof(XtCallbackRec) * (size_t) i);
214444c061aSmrg    } else {
215444c061aSmrg	icl = (InternalCallbackList) XtRealloc((char *) icl,
2160568f49bSmrg					       (Cardinal)(sizeof(InternalCallbackRec) +
2170568f49bSmrg					       sizeof(XtCallbackRec) * (size_t) (i+j)));
218444c061aSmrg    }
219444c061aSmrg    *callbacks = icl;
2200568f49bSmrg    icl->count = (unsigned short) (i+j);
221444c061aSmrg    icl->is_padded = 0;
222444c061aSmrg    icl->call_state = 0;
223444c061aSmrg    for (cl = ToList(icl) + i; --j >= 0; )
224444c061aSmrg	*cl++ = *newcallbacks++;
225444c061aSmrg} /* AddCallbacks */
226444c061aSmrg
227444c061aSmrgvoid XtAddCallbacks(
228444c061aSmrg    Widget	    widget,
229444c061aSmrg    _Xconst char*   name,
230444c061aSmrg    XtCallbackList  xtcallbacks
231444c061aSmrg    )
232444c061aSmrg{
233444c061aSmrg    InternalCallbackList* callbacks;
234444c061aSmrg    Widget hookobj;
235444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
236444c061aSmrg
237444c061aSmrg    LOCK_APP(app);
238444c061aSmrg    callbacks = FetchInternalList(widget, name);
239444c061aSmrg    if (!callbacks) {
240444c061aSmrg	XtAppWarningMsg(app,
241444c061aSmrg	       XtNinvalidCallbackList,XtNxtAddCallback,XtCXtToolkitError,
242444c061aSmrg              "Cannot find callback list in XtAddCallbacks",
2430568f49bSmrg	      NULL, NULL);
244444c061aSmrg	UNLOCK_APP(app);
245444c061aSmrg	return;
246444c061aSmrg    }
247444c061aSmrg    AddCallbacks(widget, callbacks, xtcallbacks);
248444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
249444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
250444c061aSmrg	XtChangeHookDataRec call_data;
251444c061aSmrg
252444c061aSmrg	call_data.type = XtHaddCallbacks;
253444c061aSmrg	call_data.widget = widget;
254444c061aSmrg	call_data.event_data = (XtPointer) name;
255444c061aSmrg	XtCallCallbackList(hookobj,
256444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
257444c061aSmrg		(XtPointer)&call_data);
258444c061aSmrg    }
259444c061aSmrg    UNLOCK_APP(app);
260444c061aSmrg} /* XtAddCallbacks */
261444c061aSmrg
262444c061aSmrgvoid _XtRemoveCallback (
263444c061aSmrg    InternalCallbackList   *callbacks,
264444c061aSmrg    XtCallbackProc	    callback,
265444c061aSmrg    XtPointer		    closure)
266444c061aSmrg{
267444c061aSmrg    register InternalCallbackList icl;
268444c061aSmrg    register int i, j;
269444c061aSmrg    register XtCallbackList cl, ncl, ocl;
270444c061aSmrg
271444c061aSmrg    icl = *callbacks;
272444c061aSmrg    if (!icl) return;
273444c061aSmrg
274444c061aSmrg    cl = ToList(icl);
275444c061aSmrg    for (i=icl->count; --i >= 0; cl++) {
276444c061aSmrg	if (cl->callback == callback && cl->closure == closure) {
277444c061aSmrg	    if (icl->call_state) {
278444c061aSmrg		icl->call_state |= _XtCBFreeAfterCalling;
279444c061aSmrg		if (icl->count == 1) {
280444c061aSmrg		    *callbacks = NULL;
281444c061aSmrg		} else {
282444c061aSmrg		    j = icl->count - i - 1;
283444c061aSmrg		    ocl = ToList(icl);
284444c061aSmrg		    icl = (InternalCallbackList)
2850568f49bSmrg			__XtMalloc((Cardinal) (sizeof(InternalCallbackRec) +
2860568f49bSmrg				 sizeof(XtCallbackRec) * (size_t) (i + j)));
2870568f49bSmrg		    icl->count = (unsigned short) (i + j);
288444c061aSmrg		    icl->is_padded = 0;
289444c061aSmrg		    icl->call_state = 0;
290444c061aSmrg		    ncl = ToList(icl);
291444c061aSmrg		    while (--j >= 0)
292444c061aSmrg			*ncl++ = *ocl++;
293444c061aSmrg		    while (--i >= 0)
294444c061aSmrg			*ncl++ = *++cl;
295444c061aSmrg		    *callbacks = icl;
296444c061aSmrg		}
297444c061aSmrg	    } else {
298444c061aSmrg		if (--icl->count) {
299444c061aSmrg		    ncl = cl + 1;
300444c061aSmrg		    while (--i >= 0)
301444c061aSmrg			*cl++ = *ncl++;
302444c061aSmrg		    icl = (InternalCallbackList)
3030568f49bSmrg			XtRealloc((char *) icl, (Cardinal) (sizeof(InternalCallbackRec)
3040568f49bSmrg				  + sizeof(XtCallbackRec) * icl->count));
305444c061aSmrg		    icl->is_padded = 0;
306444c061aSmrg		    *callbacks = icl;
307444c061aSmrg		} else {
308444c061aSmrg		    XtFree((char *) icl);
309444c061aSmrg		    *callbacks = NULL;
310444c061aSmrg		}
311444c061aSmrg	    }
312444c061aSmrg	    return;
313444c061aSmrg	}
314444c061aSmrg    }
315444c061aSmrg} /* _XtRemoveCallback */
316444c061aSmrg
317444c061aSmrgvoid XtRemoveCallback (
318444c061aSmrg    Widget	    widget,
319444c061aSmrg    _Xconst char*   name,
320444c061aSmrg    XtCallbackProc  callback,
321444c061aSmrg    XtPointer	    closure
322444c061aSmrg    )
323444c061aSmrg{
324444c061aSmrg    InternalCallbackList *callbacks;
325444c061aSmrg    Widget hookobj;
326444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
327444c061aSmrg
328444c061aSmrg    LOCK_APP(app);
329444c061aSmrg    callbacks = FetchInternalList(widget, name);
330444c061aSmrg    if (!callbacks) {
331444c061aSmrg	XtAppWarningMsg(app,
332444c061aSmrg	       XtNinvalidCallbackList,XtNxtRemoveCallback,XtCXtToolkitError,
333444c061aSmrg              "Cannot find callback list in XtRemoveCallback",
3340568f49bSmrg	      NULL, NULL);
335444c061aSmrg	UNLOCK_APP(app);
336444c061aSmrg	return;
337444c061aSmrg    }
338444c061aSmrg    _XtRemoveCallback(callbacks, callback, closure);
339444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
340444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
341444c061aSmrg	XtChangeHookDataRec call_data;
342444c061aSmrg
343444c061aSmrg	call_data.type = XtHremoveCallback;
344444c061aSmrg	call_data.widget = widget;
345444c061aSmrg	call_data.event_data = (XtPointer) name;
346444c061aSmrg	XtCallCallbackList(hookobj,
347444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
348444c061aSmrg		(XtPointer)&call_data);
349444c061aSmrg    }
350444c061aSmrg    UNLOCK_APP(app);
351444c061aSmrg} /* XtRemoveCallback */
352444c061aSmrg
353444c061aSmrg
354444c061aSmrgvoid XtRemoveCallbacks (
355444c061aSmrg    Widget	    widget,
356444c061aSmrg    _Xconst char*   name,
357444c061aSmrg    XtCallbackList  xtcallbacks)
358444c061aSmrg{
359444c061aSmrg    InternalCallbackList *callbacks;
360444c061aSmrg    Widget hookobj;
361444c061aSmrg    int i;
362444c061aSmrg    InternalCallbackList icl;
363444c061aSmrg    XtCallbackList cl, ccl, rcl;
364444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
365444c061aSmrg
366444c061aSmrg    LOCK_APP(app);
367444c061aSmrg    callbacks = FetchInternalList(widget, name);
368444c061aSmrg    if (!callbacks) {
369444c061aSmrg	XtAppWarningMsg(app,
370444c061aSmrg	       XtNinvalidCallbackList,XtNxtRemoveCallback,XtCXtToolkitError,
371444c061aSmrg              "Cannot find callback list in XtRemoveCallbacks",
3720568f49bSmrg	      NULL, NULL);
373444c061aSmrg	UNLOCK_APP(app);
374444c061aSmrg	return;
375444c061aSmrg    }
376444c061aSmrg
377444c061aSmrg    icl = *callbacks;
378444c061aSmrg    if (!icl) {
379444c061aSmrg	UNLOCK_APP(app);
380444c061aSmrg	return;
381444c061aSmrg    }
382444c061aSmrg
383444c061aSmrg    i = icl->count;
384444c061aSmrg    cl = ToList(icl);
385444c061aSmrg    if (icl->call_state) {
386444c061aSmrg	icl->call_state |= _XtCBFreeAfterCalling;
3870568f49bSmrg	icl = (InternalCallbackList)__XtMalloc((Cardinal)(sizeof(InternalCallbackRec) +
3880568f49bSmrg					     sizeof(XtCallbackRec) * (size_t) i));
3890568f49bSmrg	icl->count = (unsigned short) i;
390444c061aSmrg	icl->call_state = 0;
391444c061aSmrg    }
392444c061aSmrg    ccl = ToList(icl);
393444c061aSmrg    while (--i >= 0) {
394444c061aSmrg	*ccl++ = *cl;
395444c061aSmrg	for (rcl=xtcallbacks; rcl->callback; rcl++) {
396444c061aSmrg	    if (cl->callback == rcl->callback && cl->closure == rcl->closure) {
397444c061aSmrg		ccl--;
398444c061aSmrg		icl->count--;
399444c061aSmrg		break;
400444c061aSmrg	    }
401444c061aSmrg	}
402444c061aSmrg	cl++;
403444c061aSmrg    }
404444c061aSmrg    if (icl->count) {
405444c061aSmrg	icl = (InternalCallbackList)
4060568f49bSmrg	    XtRealloc((char *)icl, (Cardinal) (sizeof(InternalCallbackRec) +
407444c061aSmrg				    sizeof(XtCallbackRec) * icl->count));
408444c061aSmrg	icl->is_padded = 0;
409444c061aSmrg	*callbacks = icl;
410444c061aSmrg    } else {
411444c061aSmrg	XtFree((char *)icl);
412444c061aSmrg	*callbacks = NULL;
413444c061aSmrg    }
414444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
415444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
416444c061aSmrg	XtChangeHookDataRec call_data;
417444c061aSmrg
418444c061aSmrg	call_data.type = XtHremoveCallbacks;
419444c061aSmrg	call_data.widget = widget;
420444c061aSmrg	call_data.event_data = (XtPointer) name;
421444c061aSmrg	XtCallCallbackList(hookobj,
422444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
423444c061aSmrg		(XtPointer)&call_data);
424444c061aSmrg    }
425444c061aSmrg    UNLOCK_APP(app);
426444c061aSmrg} /* XtRemoveCallbacks */
427444c061aSmrg
428444c061aSmrg
429444c061aSmrgvoid _XtRemoveAllCallbacks (
430444c061aSmrg    InternalCallbackList *callbacks)
431444c061aSmrg{
432444c061aSmrg    register InternalCallbackList icl = *callbacks;
433444c061aSmrg
434444c061aSmrg    if (icl) {
435444c061aSmrg	if (icl->call_state)
436444c061aSmrg	    icl->call_state |= _XtCBFreeAfterCalling;
437444c061aSmrg	else
438444c061aSmrg	    XtFree((char *) icl);
439444c061aSmrg	*callbacks = NULL;
440444c061aSmrg    }
441444c061aSmrg} /* _XtRemoveAllCallbacks */
442444c061aSmrg
443444c061aSmrgvoid XtRemoveAllCallbacks(
444444c061aSmrg    Widget widget,
445444c061aSmrg    _Xconst char* name)
446444c061aSmrg{
447444c061aSmrg    InternalCallbackList *callbacks;
448444c061aSmrg    Widget hookobj;
449444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
450444c061aSmrg
451444c061aSmrg    LOCK_APP(app);
452444c061aSmrg    callbacks = FetchInternalList(widget, name);
453444c061aSmrg    if (!callbacks) {
454444c061aSmrg	XtAppWarningMsg(app,
455444c061aSmrg	       XtNinvalidCallbackList,XtNxtRemoveAllCallback,XtCXtToolkitError,
456444c061aSmrg              "Cannot find callback list in XtRemoveAllCallbacks",
4570568f49bSmrg	      NULL, NULL);
458444c061aSmrg	UNLOCK_APP(app);
459444c061aSmrg	return;
460444c061aSmrg    }
461444c061aSmrg    _XtRemoveAllCallbacks(callbacks);
462444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
463444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
464444c061aSmrg	XtChangeHookDataRec call_data;
465444c061aSmrg
466444c061aSmrg	call_data.type = XtHremoveAllCallbacks;
467444c061aSmrg	call_data.widget = widget;
468444c061aSmrg	call_data.event_data = (XtPointer) name;
469444c061aSmrg	XtCallCallbackList(hookobj,
470444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
471444c061aSmrg		(XtPointer)&call_data);
472444c061aSmrg    }
473444c061aSmrg    UNLOCK_APP(app);
474444c061aSmrg} /* XtRemoveAllCallbacks */
475444c061aSmrg
476444c061aSmrgInternalCallbackList _XtCompileCallbackList(
477444c061aSmrg    XtCallbackList xtcallbacks)
478444c061aSmrg{
479444c061aSmrg    register int n;
480444c061aSmrg    register XtCallbackList xtcl, cl;
481444c061aSmrg    register InternalCallbackList callbacks;
482444c061aSmrg
483444c061aSmrg    for (n=0, xtcl=xtcallbacks; xtcl->callback; n++, xtcl++) {};
484444c061aSmrg    if (n == 0) return (InternalCallbackList) NULL;
485444c061aSmrg
4860568f49bSmrg    callbacks = (InternalCallbackList) __XtMalloc((Cardinal) (sizeof(InternalCallbackRec) +
4870568f49bSmrg						sizeof(XtCallbackRec) * (size_t) n));
4880568f49bSmrg    callbacks->count = (unsigned short) n;
489444c061aSmrg    callbacks->is_padded = 0;
490444c061aSmrg    callbacks->call_state = 0;
491444c061aSmrg    cl = ToList(callbacks);
492444c061aSmrg    while (--n >= 0)
493444c061aSmrg	*cl++ = *xtcallbacks++;
494444c061aSmrg    return(callbacks);
495444c061aSmrg} /* _XtCompileCallbackList */
496444c061aSmrg
497444c061aSmrg
498444c061aSmrgXtCallbackList _XtGetCallbackList(
499444c061aSmrg    InternalCallbackList *callbacks)
500444c061aSmrg{
5010568f49bSmrg    int i;
5020568f49bSmrg    InternalCallbackList icl;
5030568f49bSmrg    XtCallbackList cl;
504444c061aSmrg
505444c061aSmrg    icl = *callbacks;
506444c061aSmrg    if (!icl) {
507444c061aSmrg	static XtCallbackRec emptyList[1] = { {NULL, NULL} };
508444c061aSmrg	return (XtCallbackList)emptyList;
509444c061aSmrg    }
510444c061aSmrg    if (icl->is_padded)
511444c061aSmrg	return ToList(icl);
512444c061aSmrg    i = icl->count;
513444c061aSmrg    if (icl->call_state) {
5140568f49bSmrg        XtCallbackList ocl;
515444c061aSmrg	icl->call_state |= _XtCBFreeAfterCalling;
516444c061aSmrg	ocl = ToList(icl);
5170568f49bSmrg	icl = (InternalCallbackList) __XtMalloc((Cardinal)(sizeof(InternalCallbackRec) +
5180568f49bSmrg					      sizeof(XtCallbackRec) * (size_t) (i+1)));
5190568f49bSmrg	icl->count = (unsigned short) i;
520444c061aSmrg	icl->call_state = 0;
521444c061aSmrg	cl = ToList(icl);
522444c061aSmrg	while (--i >= 0)
523444c061aSmrg	    *cl++ = *ocl++;
524444c061aSmrg    } else {
525444c061aSmrg	icl = (InternalCallbackList) XtRealloc((char *)icl,
5260568f49bSmrg					       (Cardinal)(sizeof(InternalCallbackRec) +
5270568f49bSmrg					       sizeof(XtCallbackRec) * (size_t)(i+1)));
528444c061aSmrg	cl = ToList(icl) + i;
529444c061aSmrg    }
530444c061aSmrg    icl->is_padded = 1;
531444c061aSmrg    cl->callback = (XtCallbackProc) NULL;
532444c061aSmrg    cl->closure = NULL;
533444c061aSmrg    *callbacks = icl;
534444c061aSmrg    return ToList(icl);
535444c061aSmrg}
536444c061aSmrg
537444c061aSmrgvoid XtCallCallbacks(
538444c061aSmrg    Widget   widget,
539444c061aSmrg    _Xconst char* name,
540444c061aSmrg    XtPointer call_data
541444c061aSmrg    )
542444c061aSmrg{
543444c061aSmrg    InternalCallbackList *callbacks;
544444c061aSmrg    InternalCallbackList icl;
545444c061aSmrg    XtCallbackList cl;
546444c061aSmrg    int i;
547444c061aSmrg    char ostate;
548444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
549444c061aSmrg
550444c061aSmrg    LOCK_APP(app);
551444c061aSmrg    callbacks = FetchInternalList(widget, name);
552444c061aSmrg    if (!callbacks) {
553444c061aSmrg	XtAppWarningMsg(app,
554444c061aSmrg	       XtNinvalidCallbackList,XtNxtCallCallback,XtCXtToolkitError,
555444c061aSmrg              "Cannot find callback list in XtCallCallbacks",
5560568f49bSmrg	      NULL, NULL);
557444c061aSmrg	UNLOCK_APP(app);
558444c061aSmrg	return;
559444c061aSmrg    }
560444c061aSmrg
561444c061aSmrg    icl = *callbacks;
562444c061aSmrg    if (!icl) {
563444c061aSmrg	UNLOCK_APP(app);
564444c061aSmrg	return;
565444c061aSmrg    }
566444c061aSmrg    cl = ToList(icl);
567444c061aSmrg    if (icl->count == 1) {
568444c061aSmrg	(*cl->callback) (widget, cl->closure, call_data);
569444c061aSmrg	UNLOCK_APP(app);
570444c061aSmrg	return;
571444c061aSmrg    }
572444c061aSmrg    ostate = icl->call_state;
573444c061aSmrg    icl->call_state = _XtCBCalling;
574444c061aSmrg    for (i = icl->count; --i >= 0; cl++)
575444c061aSmrg	(*cl->callback) (widget, cl->closure, call_data);
576444c061aSmrg    if (ostate)
577444c061aSmrg	icl->call_state |= ostate;
578444c061aSmrg    else if (icl->call_state & _XtCBFreeAfterCalling)
579444c061aSmrg	XtFree((char *)icl);
580444c061aSmrg    else
581444c061aSmrg	icl->call_state = ostate;
582444c061aSmrg    UNLOCK_APP(app);
583444c061aSmrg} /* XtCallCallbacks */
584444c061aSmrg
585444c061aSmrg
586444c061aSmrgXtCallbackStatus XtHasCallbacks(
587444c061aSmrg     Widget		widget,
588444c061aSmrg     _Xconst char*	callback_name
589444c061aSmrg     )
590444c061aSmrg{
591444c061aSmrg    InternalCallbackList *callbacks;
592444c061aSmrg    XtCallbackStatus retval = XtCallbackHasSome;
593444c061aSmrg    WIDGET_TO_APPCON(widget);
594444c061aSmrg
595444c061aSmrg    LOCK_APP(app);
596444c061aSmrg    callbacks = FetchInternalList(widget, callback_name);
597444c061aSmrg    if (!callbacks)
598444c061aSmrg	retval = XtCallbackNoList;
599444c061aSmrg    else if (!*callbacks)
600444c061aSmrg	retval = XtCallbackHasNone;
601444c061aSmrg    UNLOCK_APP(app);
602444c061aSmrg    return retval;
603444c061aSmrg} /* XtHasCallbacks */
604444c061aSmrg
605444c061aSmrg
606444c061aSmrgvoid XtCallCallbackList(
607444c061aSmrg    Widget widget,
608444c061aSmrg    XtCallbackList callbacks,
609444c061aSmrg    XtPointer call_data)
610444c061aSmrg{
611444c061aSmrg    register InternalCallbackList icl;
612444c061aSmrg    register XtCallbackList cl;
613444c061aSmrg    register int i;
614444c061aSmrg    char ostate;
615444c061aSmrg    WIDGET_TO_APPCON(widget);
616444c061aSmrg
617444c061aSmrg    LOCK_APP(app);
618444c061aSmrg    if (!callbacks) {
619444c061aSmrg	UNLOCK_APP(app);
620444c061aSmrg	return;
621444c061aSmrg    }
622444c061aSmrg    icl = (InternalCallbackList)callbacks;
623444c061aSmrg    cl = ToList(icl);
624444c061aSmrg    if (icl->count == 1) {
625444c061aSmrg	(*cl->callback) (widget, cl->closure, call_data);
626444c061aSmrg	UNLOCK_APP(app);
627444c061aSmrg	return;
628444c061aSmrg    }
629444c061aSmrg    ostate = icl->call_state;
630444c061aSmrg    icl->call_state = _XtCBCalling;
631444c061aSmrg    for (i = icl->count; --i >= 0; cl++)
632444c061aSmrg	(*cl->callback) (widget, cl->closure, call_data);
633444c061aSmrg    if (ostate)
634444c061aSmrg	icl->call_state |= ostate;
635444c061aSmrg    else if (icl->call_state & _XtCBFreeAfterCalling)
636444c061aSmrg	XtFree((char *)icl);
637444c061aSmrg    else
638444c061aSmrg	icl->call_state = 0;
639444c061aSmrg    UNLOCK_APP(app);
640444c061aSmrg} /* XtCallCallbackList */
641444c061aSmrg
642444c061aSmrgvoid _XtPeekCallback(
643444c061aSmrg    Widget widget,
644444c061aSmrg    XtCallbackList callbacks,
645444c061aSmrg    XtCallbackProc *callback,
646444c061aSmrg    XtPointer *closure)
647444c061aSmrg{
648444c061aSmrg    register InternalCallbackList icl = (InternalCallbackList) callbacks;
649444c061aSmrg    register XtCallbackList cl;
650444c061aSmrg
651444c061aSmrg    if (!callbacks) {
652444c061aSmrg	*callback = (XtCallbackProc) NULL;
653444c061aSmrg	return;
654444c061aSmrg    }
655444c061aSmrg    cl = ToList(icl);
656444c061aSmrg    *callback = cl->callback;
657444c061aSmrg    *closure = cl->closure;
658444c061aSmrg    return;
659444c061aSmrg}
660444c061aSmrg
661444c061aSmrgvoid _XtCallConditionalCallbackList(
662444c061aSmrg    Widget widget,
663444c061aSmrg    XtCallbackList callbacks,
664444c061aSmrg    XtPointer call_data,
665444c061aSmrg    _XtConditionProc cond_proc)
666444c061aSmrg{
667444c061aSmrg    register InternalCallbackList icl;
668444c061aSmrg    register XtCallbackList cl;
669444c061aSmrg    register int i;
670444c061aSmrg    char ostate;
671444c061aSmrg    WIDGET_TO_APPCON(widget);
672444c061aSmrg
673444c061aSmrg    LOCK_APP(app);
674444c061aSmrg    if (!callbacks) {
675444c061aSmrg	UNLOCK_APP(app);
676444c061aSmrg	return;
677444c061aSmrg    }
678444c061aSmrg    icl = (InternalCallbackList)callbacks;
679444c061aSmrg    cl = ToList(icl);
680444c061aSmrg    if (icl->count == 1) {
681444c061aSmrg	(*cl->callback) (widget, cl->closure, call_data);
682444c061aSmrg	(void) (*cond_proc)(call_data);
683444c061aSmrg	UNLOCK_APP(app);
684444c061aSmrg	return;
685444c061aSmrg    }
686444c061aSmrg    ostate = icl->call_state;
687444c061aSmrg    icl->call_state = _XtCBCalling;
688444c061aSmrg    for (i = icl->count; --i >= 0; cl++) {
689444c061aSmrg	(*cl->callback) (widget, cl->closure, call_data);
690444c061aSmrg	if (! (*cond_proc)(call_data))
691444c061aSmrg	    break;
692444c061aSmrg    }
693444c061aSmrg    if (ostate)
694444c061aSmrg	icl->call_state |= ostate;
695444c061aSmrg    else if (icl->call_state & _XtCBFreeAfterCalling)
696444c061aSmrg	XtFree((char *)icl);
697444c061aSmrg    else
698444c061aSmrg	icl->call_state = 0;
699444c061aSmrg    UNLOCK_APP(app);
700444c061aSmrg}
701