Callback.c revision 249c3046
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
76444c061aSmrgstatic String XtNinvalidCallbackList = "invalidCallbackList";
77444c061aSmrgstatic String XtNxtAddCallback = "xtAddCallback";
78444c061aSmrgstatic String XtNxtRemoveCallback = "xtRemoveCallback";
79444c061aSmrgstatic String XtNxtRemoveAllCallback = "xtRemoveAllCallback";
80444c061aSmrgstatic String 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)
125444c061aSmrg	    __XtMalloc(sizeof(InternalCallbackRec) +
126444c061aSmrg		     sizeof(XtCallbackRec) * (count + 1));
127444c061aSmrg	(void) memmove((char *)ToList(icl), (char *)ToList(*callbacks),
128444c061aSmrg		       sizeof(XtCallbackRec) * count);
129444c061aSmrg    } else {
130444c061aSmrg	icl = (InternalCallbackList)
131444c061aSmrg	    XtRealloc((char *) icl, sizeof(InternalCallbackRec) +
132444c061aSmrg		      sizeof(XtCallbackRec) * (count + 1));
133444c061aSmrg    }
134444c061aSmrg    *callbacks = icl;
135444c061aSmrg    icl->count = 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    Widget hookobj;
167444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
168444c061aSmrg
169444c061aSmrg    LOCK_APP(app);
170444c061aSmrg    callbacks = FetchInternalList(widget, name);
171444c061aSmrg    if (!callbacks) {
172444c061aSmrg	XtAppWarningMsg(app,
173444c061aSmrg	       XtNinvalidCallbackList,XtNxtAddCallback,XtCXtToolkitError,
174444c061aSmrg              "Cannot find callback list in XtAddCallback",
175444c061aSmrg	      (String *)NULL, (Cardinal *)NULL);
176444c061aSmrg	UNLOCK_APP(app);
177444c061aSmrg	return;
178444c061aSmrg    }
179444c061aSmrg    _XtAddCallback(callbacks, callback, closure);
180444c061aSmrg    if (!_XtIsHookObject(widget)) {
181444c061aSmrg	hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
182444c061aSmrg	if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
183444c061aSmrg	    XtChangeHookDataRec call_data;
184444c061aSmrg
185444c061aSmrg	    call_data.type = XtHaddCallback;
186444c061aSmrg	    call_data.widget = widget;
187444c061aSmrg	    call_data.event_data = (XtPointer) name;
188444c061aSmrg	    XtCallCallbackList(hookobj,
189444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
190444c061aSmrg		(XtPointer)&call_data);
191444c061aSmrg	}
192444c061aSmrg    }
193444c061aSmrg    UNLOCK_APP(app);
194444c061aSmrg} /* XtAddCallback */
195444c061aSmrg
196444c061aSmrg/* ARGSUSED */
197444c061aSmrgstatic void AddCallbacks(
198444c061aSmrg    Widget		    widget,
199444c061aSmrg    InternalCallbackList   *callbacks,
200444c061aSmrg    XtCallbackList	    newcallbacks)
201444c061aSmrg{
202444c061aSmrg    register InternalCallbackList icl;
203444c061aSmrg    register int i, j;
204444c061aSmrg    register XtCallbackList cl;
205444c061aSmrg
206444c061aSmrg    icl = *callbacks;
207444c061aSmrg    i = icl ? icl->count : 0;
208444c061aSmrg    for (j=0, cl = newcallbacks; cl->callback; cl++, j++);
209444c061aSmrg    if (icl && icl->call_state) {
210444c061aSmrg	icl->call_state |= _XtCBFreeAfterCalling;
211444c061aSmrg	icl = (InternalCallbackList) __XtMalloc(sizeof(InternalCallbackRec) +
212444c061aSmrg					      sizeof(XtCallbackRec) * (i+j));
213444c061aSmrg	(void) memmove((char *)ToList(*callbacks), (char *)ToList(icl),
214444c061aSmrg		       sizeof(XtCallbackRec) * i);
215444c061aSmrg    } else {
216444c061aSmrg	icl = (InternalCallbackList) XtRealloc((char *) icl,
217444c061aSmrg					       sizeof(InternalCallbackRec) +
218444c061aSmrg					       sizeof(XtCallbackRec) * (i+j));
219444c061aSmrg    }
220444c061aSmrg    *callbacks = icl;
221444c061aSmrg    icl->count = i+j;
222444c061aSmrg    icl->is_padded = 0;
223444c061aSmrg    icl->call_state = 0;
224444c061aSmrg    for (cl = ToList(icl) + i; --j >= 0; )
225444c061aSmrg	*cl++ = *newcallbacks++;
226444c061aSmrg} /* AddCallbacks */
227444c061aSmrg
228444c061aSmrgvoid XtAddCallbacks(
229444c061aSmrg    Widget	    widget,
230444c061aSmrg    _Xconst char*   name,
231444c061aSmrg    XtCallbackList  xtcallbacks
232444c061aSmrg    )
233444c061aSmrg{
234444c061aSmrg    InternalCallbackList* callbacks;
235444c061aSmrg    Widget hookobj;
236444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
237444c061aSmrg
238444c061aSmrg    LOCK_APP(app);
239444c061aSmrg    callbacks = FetchInternalList(widget, name);
240444c061aSmrg    if (!callbacks) {
241444c061aSmrg	XtAppWarningMsg(app,
242444c061aSmrg	       XtNinvalidCallbackList,XtNxtAddCallback,XtCXtToolkitError,
243444c061aSmrg              "Cannot find callback list in XtAddCallbacks",
244444c061aSmrg	      (String *)NULL, (Cardinal *)NULL);
245444c061aSmrg	UNLOCK_APP(app);
246444c061aSmrg	return;
247444c061aSmrg    }
248444c061aSmrg    AddCallbacks(widget, callbacks, xtcallbacks);
249444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
250444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
251444c061aSmrg	XtChangeHookDataRec call_data;
252444c061aSmrg
253444c061aSmrg	call_data.type = XtHaddCallbacks;
254444c061aSmrg	call_data.widget = widget;
255444c061aSmrg	call_data.event_data = (XtPointer) name;
256444c061aSmrg	XtCallCallbackList(hookobj,
257444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
258444c061aSmrg		(XtPointer)&call_data);
259444c061aSmrg    }
260444c061aSmrg    UNLOCK_APP(app);
261444c061aSmrg} /* XtAddCallbacks */
262444c061aSmrg
263444c061aSmrgvoid _XtRemoveCallback (
264444c061aSmrg    InternalCallbackList   *callbacks,
265444c061aSmrg    XtCallbackProc	    callback,
266444c061aSmrg    XtPointer		    closure)
267444c061aSmrg{
268444c061aSmrg    register InternalCallbackList icl;
269444c061aSmrg    register int i, j;
270444c061aSmrg    register XtCallbackList cl, ncl, ocl;
271444c061aSmrg
272444c061aSmrg    icl = *callbacks;
273444c061aSmrg    if (!icl) return;
274444c061aSmrg
275444c061aSmrg    cl = ToList(icl);
276444c061aSmrg    for (i=icl->count; --i >= 0; cl++) {
277444c061aSmrg	if (cl->callback == callback && cl->closure == closure) {
278444c061aSmrg	    if (icl->call_state) {
279444c061aSmrg		icl->call_state |= _XtCBFreeAfterCalling;
280444c061aSmrg		if (icl->count == 1) {
281444c061aSmrg		    *callbacks = NULL;
282444c061aSmrg		} else {
283444c061aSmrg		    j = icl->count - i - 1;
284444c061aSmrg		    ocl = ToList(icl);
285444c061aSmrg		    icl = (InternalCallbackList)
286444c061aSmrg			__XtMalloc(sizeof(InternalCallbackRec) +
287444c061aSmrg				 sizeof(XtCallbackRec) * (i + j));
288444c061aSmrg		    icl->count = i + j;
289444c061aSmrg		    icl->is_padded = 0;
290444c061aSmrg		    icl->call_state = 0;
291444c061aSmrg		    ncl = ToList(icl);
292444c061aSmrg		    while (--j >= 0)
293444c061aSmrg			*ncl++ = *ocl++;
294444c061aSmrg		    while (--i >= 0)
295444c061aSmrg			*ncl++ = *++cl;
296444c061aSmrg		    *callbacks = icl;
297444c061aSmrg		}
298444c061aSmrg	    } else {
299444c061aSmrg		if (--icl->count) {
300444c061aSmrg		    ncl = cl + 1;
301444c061aSmrg		    while (--i >= 0)
302444c061aSmrg			*cl++ = *ncl++;
303444c061aSmrg		    icl = (InternalCallbackList)
304444c061aSmrg			XtRealloc((char *) icl, sizeof(InternalCallbackRec)
305444c061aSmrg				  + sizeof(XtCallbackRec) * icl->count);
306444c061aSmrg		    icl->is_padded = 0;
307444c061aSmrg		    *callbacks = icl;
308444c061aSmrg		} else {
309444c061aSmrg		    XtFree((char *) icl);
310444c061aSmrg		    *callbacks = NULL;
311444c061aSmrg		}
312444c061aSmrg	    }
313444c061aSmrg	    return;
314444c061aSmrg	}
315444c061aSmrg    }
316444c061aSmrg} /* _XtRemoveCallback */
317444c061aSmrg
318444c061aSmrgvoid XtRemoveCallback (
319444c061aSmrg    Widget	    widget,
320444c061aSmrg    _Xconst char*   name,
321444c061aSmrg    XtCallbackProc  callback,
322444c061aSmrg    XtPointer	    closure
323444c061aSmrg    )
324444c061aSmrg{
325444c061aSmrg    InternalCallbackList *callbacks;
326444c061aSmrg    Widget hookobj;
327444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
328444c061aSmrg
329444c061aSmrg    LOCK_APP(app);
330444c061aSmrg    callbacks = FetchInternalList(widget, name);
331444c061aSmrg    if (!callbacks) {
332444c061aSmrg	XtAppWarningMsg(app,
333444c061aSmrg	       XtNinvalidCallbackList,XtNxtRemoveCallback,XtCXtToolkitError,
334444c061aSmrg              "Cannot find callback list in XtRemoveCallback",
335444c061aSmrg	      (String *)NULL, (Cardinal *)NULL);
336444c061aSmrg	UNLOCK_APP(app);
337444c061aSmrg	return;
338444c061aSmrg    }
339444c061aSmrg    _XtRemoveCallback(callbacks, callback, closure);
340444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
341444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
342444c061aSmrg	XtChangeHookDataRec call_data;
343444c061aSmrg
344444c061aSmrg	call_data.type = XtHremoveCallback;
345444c061aSmrg	call_data.widget = widget;
346444c061aSmrg	call_data.event_data = (XtPointer) name;
347444c061aSmrg	XtCallCallbackList(hookobj,
348444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
349444c061aSmrg		(XtPointer)&call_data);
350444c061aSmrg    }
351444c061aSmrg    UNLOCK_APP(app);
352444c061aSmrg} /* XtRemoveCallback */
353444c061aSmrg
354444c061aSmrg
355444c061aSmrgvoid XtRemoveCallbacks (
356444c061aSmrg    Widget	    widget,
357444c061aSmrg    _Xconst char*   name,
358444c061aSmrg    XtCallbackList  xtcallbacks)
359444c061aSmrg{
360444c061aSmrg    InternalCallbackList *callbacks;
361444c061aSmrg    Widget hookobj;
362444c061aSmrg    int i;
363444c061aSmrg    InternalCallbackList icl;
364444c061aSmrg    XtCallbackList cl, ccl, rcl;
365444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
366444c061aSmrg
367444c061aSmrg    LOCK_APP(app);
368444c061aSmrg    callbacks = FetchInternalList(widget, name);
369444c061aSmrg    if (!callbacks) {
370444c061aSmrg	XtAppWarningMsg(app,
371444c061aSmrg	       XtNinvalidCallbackList,XtNxtRemoveCallback,XtCXtToolkitError,
372444c061aSmrg              "Cannot find callback list in XtRemoveCallbacks",
373444c061aSmrg	      (String *)NULL, (Cardinal *)NULL);
374444c061aSmrg	UNLOCK_APP(app);
375444c061aSmrg	return;
376444c061aSmrg    }
377444c061aSmrg
378444c061aSmrg    icl = *callbacks;
379444c061aSmrg    if (!icl) {
380444c061aSmrg	UNLOCK_APP(app);
381444c061aSmrg	return;
382444c061aSmrg    }
383444c061aSmrg
384444c061aSmrg    i = icl->count;
385444c061aSmrg    cl = ToList(icl);
386444c061aSmrg    if (icl->call_state) {
387444c061aSmrg	icl->call_state |= _XtCBFreeAfterCalling;
388444c061aSmrg	icl = (InternalCallbackList)__XtMalloc(sizeof(InternalCallbackRec) +
389444c061aSmrg					     sizeof(XtCallbackRec) * i);
390444c061aSmrg	icl->count = i;
391444c061aSmrg	icl->call_state = 0;
392444c061aSmrg    }
393444c061aSmrg    ccl = ToList(icl);
394444c061aSmrg    while (--i >= 0) {
395444c061aSmrg	*ccl++ = *cl;
396444c061aSmrg	for (rcl=xtcallbacks; rcl->callback; rcl++) {
397444c061aSmrg	    if (cl->callback == rcl->callback && cl->closure == rcl->closure) {
398444c061aSmrg		ccl--;
399444c061aSmrg		icl->count--;
400444c061aSmrg		break;
401444c061aSmrg	    }
402444c061aSmrg	}
403444c061aSmrg	cl++;
404444c061aSmrg    }
405444c061aSmrg    if (icl->count) {
406444c061aSmrg	icl = (InternalCallbackList)
407444c061aSmrg	    XtRealloc((char *)icl, (sizeof(InternalCallbackRec) +
408444c061aSmrg				    sizeof(XtCallbackRec) * icl->count));
409444c061aSmrg	icl->is_padded = 0;
410444c061aSmrg	*callbacks = icl;
411444c061aSmrg    } else {
412444c061aSmrg	XtFree((char *)icl);
413444c061aSmrg	*callbacks = NULL;
414444c061aSmrg    }
415444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
416444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
417444c061aSmrg	XtChangeHookDataRec call_data;
418444c061aSmrg
419444c061aSmrg	call_data.type = XtHremoveCallbacks;
420444c061aSmrg	call_data.widget = widget;
421444c061aSmrg	call_data.event_data = (XtPointer) name;
422444c061aSmrg	XtCallCallbackList(hookobj,
423444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
424444c061aSmrg		(XtPointer)&call_data);
425444c061aSmrg    }
426444c061aSmrg    UNLOCK_APP(app);
427444c061aSmrg} /* XtRemoveCallbacks */
428444c061aSmrg
429444c061aSmrg
430444c061aSmrgvoid _XtRemoveAllCallbacks (
431444c061aSmrg    InternalCallbackList *callbacks)
432444c061aSmrg{
433444c061aSmrg    register InternalCallbackList icl = *callbacks;
434444c061aSmrg
435444c061aSmrg    if (icl) {
436444c061aSmrg	if (icl->call_state)
437444c061aSmrg	    icl->call_state |= _XtCBFreeAfterCalling;
438444c061aSmrg	else
439444c061aSmrg	    XtFree((char *) icl);
440444c061aSmrg	*callbacks = NULL;
441444c061aSmrg    }
442444c061aSmrg} /* _XtRemoveAllCallbacks */
443444c061aSmrg
444444c061aSmrgvoid XtRemoveAllCallbacks(
445444c061aSmrg    Widget widget,
446444c061aSmrg    _Xconst char* name)
447444c061aSmrg{
448444c061aSmrg    InternalCallbackList *callbacks;
449444c061aSmrg    Widget hookobj;
450444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
451444c061aSmrg
452444c061aSmrg    LOCK_APP(app);
453444c061aSmrg    callbacks = FetchInternalList(widget, name);
454444c061aSmrg    if (!callbacks) {
455444c061aSmrg	XtAppWarningMsg(app,
456444c061aSmrg	       XtNinvalidCallbackList,XtNxtRemoveAllCallback,XtCXtToolkitError,
457444c061aSmrg              "Cannot find callback list in XtRemoveAllCallbacks",
458444c061aSmrg	      (String *)NULL, (Cardinal *)NULL);
459444c061aSmrg	UNLOCK_APP(app);
460444c061aSmrg	return;
461444c061aSmrg    }
462444c061aSmrg    _XtRemoveAllCallbacks(callbacks);
463444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
464444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
465444c061aSmrg	XtChangeHookDataRec call_data;
466444c061aSmrg
467444c061aSmrg	call_data.type = XtHremoveAllCallbacks;
468444c061aSmrg	call_data.widget = widget;
469444c061aSmrg	call_data.event_data = (XtPointer) name;
470444c061aSmrg	XtCallCallbackList(hookobj,
471444c061aSmrg		((HookObject)hookobj)->hooks.changehook_callbacks,
472444c061aSmrg		(XtPointer)&call_data);
473444c061aSmrg    }
474444c061aSmrg    UNLOCK_APP(app);
475444c061aSmrg} /* XtRemoveAllCallbacks */
476444c061aSmrg
477444c061aSmrgInternalCallbackList _XtCompileCallbackList(
478444c061aSmrg    XtCallbackList xtcallbacks)
479444c061aSmrg{
480444c061aSmrg    register int n;
481444c061aSmrg    register XtCallbackList xtcl, cl;
482444c061aSmrg    register InternalCallbackList callbacks;
483444c061aSmrg
484444c061aSmrg    for (n=0, xtcl=xtcallbacks; xtcl->callback; n++, xtcl++) {};
485444c061aSmrg    if (n == 0) return (InternalCallbackList) NULL;
486444c061aSmrg
487444c061aSmrg    callbacks = (InternalCallbackList) __XtMalloc(sizeof(InternalCallbackRec) +
488444c061aSmrg						sizeof(XtCallbackRec) * n);
489444c061aSmrg    callbacks->count = n;
490444c061aSmrg    callbacks->is_padded = 0;
491444c061aSmrg    callbacks->call_state = 0;
492444c061aSmrg    cl = ToList(callbacks);
493444c061aSmrg    while (--n >= 0)
494444c061aSmrg	*cl++ = *xtcallbacks++;
495444c061aSmrg    return(callbacks);
496444c061aSmrg} /* _XtCompileCallbackList */
497444c061aSmrg
498444c061aSmrg
499444c061aSmrgXtCallbackList _XtGetCallbackList(
500444c061aSmrg    InternalCallbackList *callbacks)
501444c061aSmrg{
502444c061aSmrg    register int i;
503444c061aSmrg    register InternalCallbackList icl;
504444c061aSmrg    register XtCallbackList cl, ocl;
505444c061aSmrg
506444c061aSmrg    icl = *callbacks;
507444c061aSmrg    if (!icl) {
508444c061aSmrg	static XtCallbackRec emptyList[1] = { {NULL, NULL} };
509444c061aSmrg	return (XtCallbackList)emptyList;
510444c061aSmrg    }
511444c061aSmrg    if (icl->is_padded)
512444c061aSmrg	return ToList(icl);
513444c061aSmrg    i = icl->count;
514444c061aSmrg    if (icl->call_state) {
515444c061aSmrg	icl->call_state |= _XtCBFreeAfterCalling;
516444c061aSmrg	ocl = ToList(icl);
517444c061aSmrg	icl = (InternalCallbackList) __XtMalloc(sizeof(InternalCallbackRec) +
518444c061aSmrg					      sizeof(XtCallbackRec) * (i+1));
519444c061aSmrg	icl->count = 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,
526444c061aSmrg					       sizeof(InternalCallbackRec) +
527444c061aSmrg					       sizeof(XtCallbackRec) * (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",
556444c061aSmrg	      (String *)NULL, (Cardinal *)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