1444c061aSmrg/***********************************************************
2fdf6a26fSmrgCopyright (c) 1993, Oracle and/or its affiliates.
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 */
83fdf6a26fSmrg#if __STDC_VERSION__ >= 199901L
84fdf6a26fSmrg#define ToList(p) ((p)->callbacks)
85fdf6a26fSmrg#else
86444c061aSmrg#define ToList(p) ((XtCallbackList) ((p)+1))
87fdf6a26fSmrg#endif
88444c061aSmrg
89a3bd7f05Smrgstatic InternalCallbackList *
90a3bd7f05SmrgFetchInternalList(Widget widget,
91a3bd7f05Smrg                  _Xconst char *name)
92444c061aSmrg{
93444c061aSmrg    XrmQuark quark;
94444c061aSmrg    int n;
95444c061aSmrg    CallbackTable offsets;
96a3bd7f05Smrg    InternalCallbackList *retval = NULL;
97444c061aSmrg
98444c061aSmrg    quark = StringToQuark(name);
99444c061aSmrg    LOCK_PROCESS;
100444c061aSmrg    offsets = (CallbackTable)
101a3bd7f05Smrg        widget->core.widget_class->core_class.callback_private;
102a3bd7f05Smrg
103a3bd7f05Smrg    for (n = (int) (long) *(offsets++); --n >= 0; offsets++)
104a3bd7f05Smrg        if (quark == (*offsets)->xrm_name) {
105a3bd7f05Smrg            retval = (InternalCallbackList *)
106a3bd7f05Smrg                ((char *) widget - (*offsets)->xrm_offset - 1);
107a3bd7f05Smrg            break;
108a3bd7f05Smrg        }
109444c061aSmrg    UNLOCK_PROCESS;
110444c061aSmrg    return retval;
111444c061aSmrg}
112444c061aSmrg
113a3bd7f05Smrgvoid
114a3bd7f05Smrg_XtAddCallback(InternalCallbackList *callbacks,
115a3bd7f05Smrg               XtCallbackProc callback,
116a3bd7f05Smrg               XtPointer closure)
117444c061aSmrg{
118444c061aSmrg    register InternalCallbackList icl;
119444c061aSmrg    register XtCallbackList cl;
120444c061aSmrg    register int count;
121444c061aSmrg
122444c061aSmrg    icl = *callbacks;
123444c061aSmrg    count = icl ? icl->count : 0;
124444c061aSmrg
125444c061aSmrg    if (icl && icl->call_state) {
126a3bd7f05Smrg        icl->call_state |= _XtCBFreeAfterCalling;
127a3bd7f05Smrg        icl = (InternalCallbackList)
128a3bd7f05Smrg            __XtMalloc((Cardinal) (sizeof(InternalCallbackRec) +
129a3bd7f05Smrg                                   sizeof(XtCallbackRec) * (size_t) (count +
130a3bd7f05Smrg                                                                     1)));
131a3bd7f05Smrg        (void) memmove((char *) ToList(icl), (char *) ToList(*callbacks),
132a3bd7f05Smrg                       sizeof(XtCallbackRec) * (size_t) count);
133a3bd7f05Smrg    }
134a3bd7f05Smrg    else {
135a3bd7f05Smrg        icl = (InternalCallbackList)
136a3bd7f05Smrg            XtRealloc((char *) icl, (Cardinal) (sizeof(InternalCallbackRec) +
137a3bd7f05Smrg                                                sizeof(XtCallbackRec) *
138a3bd7f05Smrg                                                (size_t) (count + 1)));
139444c061aSmrg    }
140444c061aSmrg    *callbacks = icl;
1410568f49bSmrg    icl->count = (unsigned short) (count + 1);
142444c061aSmrg    icl->is_padded = 0;
143444c061aSmrg    icl->call_state = 0;
144444c061aSmrg    cl = ToList(icl) + count;
145444c061aSmrg    cl->callback = callback;
146444c061aSmrg    cl->closure = closure;
147a3bd7f05Smrg}                               /* _XtAddCallback */
148444c061aSmrg
149a3bd7f05Smrgvoid
150a3bd7f05Smrg_XtAddCallbackOnce(register InternalCallbackList *callbacks,
151a3bd7f05Smrg                   XtCallbackProc callback,
152a3bd7f05Smrg                   XtPointer closure)
153444c061aSmrg{
154444c061aSmrg    register XtCallbackList cl = ToList(*callbacks);
155444c061aSmrg    register int i;
156444c061aSmrg
157a3bd7f05Smrg    for (i = (*callbacks)->count; --i >= 0; cl++)
158a3bd7f05Smrg        if (cl->callback == callback && cl->closure == closure)
159a3bd7f05Smrg            return;
160444c061aSmrg
161444c061aSmrg    _XtAddCallback(callbacks, callback, closure);
162a3bd7f05Smrg}                               /* _XtAddCallbackOnce */
163a3bd7f05Smrg
164a3bd7f05Smrgvoid
165a3bd7f05SmrgXtAddCallback(Widget widget,
166a3bd7f05Smrg              _Xconst char *name,
167a3bd7f05Smrg              XtCallbackProc callback,
168a3bd7f05Smrg              XtPointer closure)
169444c061aSmrg{
170444c061aSmrg    InternalCallbackList *callbacks;
171444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
172444c061aSmrg
173444c061aSmrg    LOCK_APP(app);
174444c061aSmrg    callbacks = FetchInternalList(widget, name);
175444c061aSmrg    if (!callbacks) {
176a3bd7f05Smrg        XtAppWarningMsg(app,
177a3bd7f05Smrg                        XtNinvalidCallbackList, XtNxtAddCallback,
178a3bd7f05Smrg                        XtCXtToolkitError,
179a3bd7f05Smrg                        "Cannot find callback list in XtAddCallback", NULL,
180a3bd7f05Smrg                        NULL);
181a3bd7f05Smrg        UNLOCK_APP(app);
182a3bd7f05Smrg        return;
183444c061aSmrg    }
184444c061aSmrg    _XtAddCallback(callbacks, callback, closure);
185444c061aSmrg    if (!_XtIsHookObject(widget)) {
1860568f49bSmrg        Widget hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
187444c061aSmrg
188a3bd7f05Smrg        if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
189a3bd7f05Smrg            XtChangeHookDataRec call_data;
190a3bd7f05Smrg
191a3bd7f05Smrg            call_data.type = XtHaddCallback;
192a3bd7f05Smrg            call_data.widget = widget;
193a3bd7f05Smrg            call_data.event_data = (XtPointer) name;
194a3bd7f05Smrg            XtCallCallbackList(hookobj,
195a3bd7f05Smrg                               ((HookObject) hookobj)->hooks.
196a3bd7f05Smrg                               changehook_callbacks, (XtPointer) &call_data);
197a3bd7f05Smrg        }
198444c061aSmrg    }
199444c061aSmrg    UNLOCK_APP(app);
200a3bd7f05Smrg}                               /* XtAddCallback */
201444c061aSmrg
202a3bd7f05Smrgstatic void
203a3bd7f05SmrgAddCallbacks(Widget widget _X_UNUSED,
204a3bd7f05Smrg             InternalCallbackList *callbacks,
205a3bd7f05Smrg             XtCallbackList newcallbacks)
206444c061aSmrg{
207444c061aSmrg    register InternalCallbackList icl;
208444c061aSmrg    register int i, j;
209444c061aSmrg    register XtCallbackList cl;
210444c061aSmrg
211444c061aSmrg    icl = *callbacks;
212444c061aSmrg    i = icl ? icl->count : 0;
213a3bd7f05Smrg    for (j = 0, cl = newcallbacks; cl->callback; cl++, j++);
214444c061aSmrg    if (icl && icl->call_state) {
215a3bd7f05Smrg        icl->call_state |= _XtCBFreeAfterCalling;
216a3bd7f05Smrg        icl = (InternalCallbackList)
217a3bd7f05Smrg            __XtMalloc((Cardinal)
218a3bd7f05Smrg                       (sizeof(InternalCallbackRec) +
219a3bd7f05Smrg                        sizeof(XtCallbackRec) * (size_t) (i + j)));
220a3bd7f05Smrg        (void) memmove((char *) ToList(*callbacks), (char *) ToList(icl),
221a3bd7f05Smrg                       sizeof(XtCallbackRec) * (size_t) i);
222a3bd7f05Smrg    }
223a3bd7f05Smrg    else {
224a3bd7f05Smrg        icl = (InternalCallbackList) XtRealloc((char *) icl,
225a3bd7f05Smrg                                               (Cardinal) (sizeof
226a3bd7f05Smrg                                                           (InternalCallbackRec)
227a3bd7f05Smrg                                                           +
228a3bd7f05Smrg                                                           sizeof(XtCallbackRec)
229a3bd7f05Smrg                                                           * (size_t) (i + j)));
230444c061aSmrg    }
231444c061aSmrg    *callbacks = icl;
232a3bd7f05Smrg    icl->count = (unsigned short) (i + j);
233444c061aSmrg    icl->is_padded = 0;
234444c061aSmrg    icl->call_state = 0;
235a3bd7f05Smrg    for (cl = ToList(icl) + i; --j >= 0;)
236a3bd7f05Smrg        *cl++ = *newcallbacks++;
237a3bd7f05Smrg}                               /* AddCallbacks */
238a3bd7f05Smrg
239a3bd7f05Smrgvoid
240a3bd7f05SmrgXtAddCallbacks(Widget widget,
241a3bd7f05Smrg               _Xconst char *name,
242a3bd7f05Smrg               XtCallbackList xtcallbacks)
243444c061aSmrg{
244a3bd7f05Smrg    InternalCallbackList *callbacks;
245444c061aSmrg    Widget hookobj;
246444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
247444c061aSmrg
248444c061aSmrg    LOCK_APP(app);
249444c061aSmrg    callbacks = FetchInternalList(widget, name);
250444c061aSmrg    if (!callbacks) {
251a3bd7f05Smrg        XtAppWarningMsg(app,
252a3bd7f05Smrg                        XtNinvalidCallbackList, XtNxtAddCallback,
253a3bd7f05Smrg                        XtCXtToolkitError,
254a3bd7f05Smrg                        "Cannot find callback list in XtAddCallbacks", NULL,
255a3bd7f05Smrg                        NULL);
256a3bd7f05Smrg        UNLOCK_APP(app);
257a3bd7f05Smrg        return;
258444c061aSmrg    }
259444c061aSmrg    AddCallbacks(widget, callbacks, xtcallbacks);
260444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
261444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
262a3bd7f05Smrg        XtChangeHookDataRec call_data;
263a3bd7f05Smrg
264a3bd7f05Smrg        call_data.type = XtHaddCallbacks;
265a3bd7f05Smrg        call_data.widget = widget;
266a3bd7f05Smrg        call_data.event_data = (XtPointer) name;
267a3bd7f05Smrg        XtCallCallbackList(hookobj,
268a3bd7f05Smrg                           ((HookObject) hookobj)->hooks.changehook_callbacks,
269a3bd7f05Smrg                           (XtPointer) &call_data);
270444c061aSmrg    }
271444c061aSmrg    UNLOCK_APP(app);
272a3bd7f05Smrg}                               /* XtAddCallbacks */
273444c061aSmrg
274a3bd7f05Smrgvoid
275a3bd7f05Smrg_XtRemoveCallback(InternalCallbackList *callbacks,
276a3bd7f05Smrg                  XtCallbackProc callback,
277a3bd7f05Smrg                  XtPointer closure)
278444c061aSmrg{
279444c061aSmrg    register InternalCallbackList icl;
280444c061aSmrg    register int i, j;
281444c061aSmrg    register XtCallbackList cl, ncl, ocl;
282444c061aSmrg
283444c061aSmrg    icl = *callbacks;
284a3bd7f05Smrg    if (!icl)
285a3bd7f05Smrg        return;
286444c061aSmrg
287444c061aSmrg    cl = ToList(icl);
288a3bd7f05Smrg    for (i = icl->count; --i >= 0; cl++) {
289a3bd7f05Smrg        if (cl->callback == callback && cl->closure == closure) {
290a3bd7f05Smrg            if (icl->call_state) {
291a3bd7f05Smrg                icl->call_state |= _XtCBFreeAfterCalling;
292a3bd7f05Smrg                if (icl->count == 1) {
293a3bd7f05Smrg                    *callbacks = NULL;
294a3bd7f05Smrg                }
295a3bd7f05Smrg                else {
296a3bd7f05Smrg                    j = icl->count - i - 1;
297a3bd7f05Smrg                    ocl = ToList(icl);
298a3bd7f05Smrg                    icl = (InternalCallbackList)
299a3bd7f05Smrg                        __XtMalloc((Cardinal) (sizeof(InternalCallbackRec) +
300a3bd7f05Smrg                                               sizeof(XtCallbackRec) *
301a3bd7f05Smrg                                               (size_t) (i + j)));
302a3bd7f05Smrg                    icl->count = (unsigned short) (i + j);
303a3bd7f05Smrg                    icl->is_padded = 0;
304a3bd7f05Smrg                    icl->call_state = 0;
305a3bd7f05Smrg                    ncl = ToList(icl);
306a3bd7f05Smrg                    while (--j >= 0)
307a3bd7f05Smrg                        *ncl++ = *ocl++;
308a3bd7f05Smrg                    while (--i >= 0)
309a3bd7f05Smrg                        *ncl++ = *++cl;
310a3bd7f05Smrg                    *callbacks = icl;
311a3bd7f05Smrg                }
312a3bd7f05Smrg            }
313a3bd7f05Smrg            else {
314a3bd7f05Smrg                if (--icl->count) {
315a3bd7f05Smrg                    ncl = cl + 1;
316a3bd7f05Smrg                    while (--i >= 0)
317a3bd7f05Smrg                        *cl++ = *ncl++;
318a3bd7f05Smrg                    icl = (InternalCallbackList)
319a3bd7f05Smrg                        XtRealloc((char *) icl,
320a3bd7f05Smrg                                  (Cardinal) (sizeof(InternalCallbackRec)
321a3bd7f05Smrg                                              +
322a3bd7f05Smrg                                              sizeof(XtCallbackRec) *
323a3bd7f05Smrg                                              icl->count));
324a3bd7f05Smrg                    icl->is_padded = 0;
325a3bd7f05Smrg                    *callbacks = icl;
326a3bd7f05Smrg                }
327a3bd7f05Smrg                else {
328a3bd7f05Smrg                    XtFree((char *) icl);
329a3bd7f05Smrg                    *callbacks = NULL;
330a3bd7f05Smrg                }
331a3bd7f05Smrg            }
332a3bd7f05Smrg            return;
333a3bd7f05Smrg        }
334a3bd7f05Smrg    }
335a3bd7f05Smrg}                               /* _XtRemoveCallback */
336a3bd7f05Smrg
337a3bd7f05Smrgvoid
338a3bd7f05SmrgXtRemoveCallback(Widget widget,
339a3bd7f05Smrg                 _Xconst char *name,
340a3bd7f05Smrg                 XtCallbackProc callback,
341a3bd7f05Smrg                 XtPointer closure)
342444c061aSmrg{
343444c061aSmrg    InternalCallbackList *callbacks;
344444c061aSmrg    Widget hookobj;
345444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
346444c061aSmrg
347444c061aSmrg    LOCK_APP(app);
348444c061aSmrg    callbacks = FetchInternalList(widget, name);
349444c061aSmrg    if (!callbacks) {
350a3bd7f05Smrg        XtAppWarningMsg(app,
351a3bd7f05Smrg                        XtNinvalidCallbackList, XtNxtRemoveCallback,
352a3bd7f05Smrg                        XtCXtToolkitError,
353a3bd7f05Smrg                        "Cannot find callback list in XtRemoveCallback", NULL,
354a3bd7f05Smrg                        NULL);
355a3bd7f05Smrg        UNLOCK_APP(app);
356a3bd7f05Smrg        return;
357444c061aSmrg    }
358444c061aSmrg    _XtRemoveCallback(callbacks, callback, closure);
359444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
360444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
361a3bd7f05Smrg        XtChangeHookDataRec call_data;
362a3bd7f05Smrg
363a3bd7f05Smrg        call_data.type = XtHremoveCallback;
364a3bd7f05Smrg        call_data.widget = widget;
365a3bd7f05Smrg        call_data.event_data = (XtPointer) name;
366a3bd7f05Smrg        XtCallCallbackList(hookobj,
367a3bd7f05Smrg                           ((HookObject) hookobj)->hooks.changehook_callbacks,
368a3bd7f05Smrg                           (XtPointer) &call_data);
369444c061aSmrg    }
370444c061aSmrg    UNLOCK_APP(app);
371a3bd7f05Smrg}                               /* XtRemoveCallback */
372444c061aSmrg
373a3bd7f05Smrgvoid
374a3bd7f05SmrgXtRemoveCallbacks(Widget widget,
375a3bd7f05Smrg                  _Xconst char *name,
376a3bd7f05Smrg                  XtCallbackList xtcallbacks)
377444c061aSmrg{
378444c061aSmrg    InternalCallbackList *callbacks;
379444c061aSmrg    Widget hookobj;
380444c061aSmrg    int i;
381444c061aSmrg    InternalCallbackList icl;
382444c061aSmrg    XtCallbackList cl, ccl, rcl;
383444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
384444c061aSmrg
385444c061aSmrg    LOCK_APP(app);
386444c061aSmrg    callbacks = FetchInternalList(widget, name);
387444c061aSmrg    if (!callbacks) {
388a3bd7f05Smrg        XtAppWarningMsg(app,
389a3bd7f05Smrg                        XtNinvalidCallbackList, XtNxtRemoveCallback,
390a3bd7f05Smrg                        XtCXtToolkitError,
391a3bd7f05Smrg                        "Cannot find callback list in XtRemoveCallbacks", NULL,
392a3bd7f05Smrg                        NULL);
393a3bd7f05Smrg        UNLOCK_APP(app);
394a3bd7f05Smrg        return;
395444c061aSmrg    }
396444c061aSmrg
397444c061aSmrg    icl = *callbacks;
398444c061aSmrg    if (!icl) {
399a3bd7f05Smrg        UNLOCK_APP(app);
400a3bd7f05Smrg        return;
401444c061aSmrg    }
402444c061aSmrg
403444c061aSmrg    i = icl->count;
404444c061aSmrg    cl = ToList(icl);
405444c061aSmrg    if (icl->call_state) {
406a3bd7f05Smrg        icl->call_state |= _XtCBFreeAfterCalling;
407a3bd7f05Smrg        icl =
408a3bd7f05Smrg            (InternalCallbackList)
409a3bd7f05Smrg            __XtMalloc((Cardinal)
410a3bd7f05Smrg                       (sizeof(InternalCallbackRec) +
411a3bd7f05Smrg                        sizeof(XtCallbackRec) * (size_t) i));
412a3bd7f05Smrg        icl->count = (unsigned short) i;
413a3bd7f05Smrg        icl->call_state = 0;
414444c061aSmrg    }
415444c061aSmrg    ccl = ToList(icl);
416444c061aSmrg    while (--i >= 0) {
417a3bd7f05Smrg        *ccl++ = *cl;
418a3bd7f05Smrg        for (rcl = xtcallbacks; rcl->callback; rcl++) {
419a3bd7f05Smrg            if (cl->callback == rcl->callback && cl->closure == rcl->closure) {
420a3bd7f05Smrg                ccl--;
421a3bd7f05Smrg                icl->count--;
422a3bd7f05Smrg                break;
423a3bd7f05Smrg            }
424a3bd7f05Smrg        }
425a3bd7f05Smrg        cl++;
426444c061aSmrg    }
427444c061aSmrg    if (icl->count) {
428a3bd7f05Smrg        icl = (InternalCallbackList)
429a3bd7f05Smrg            XtRealloc((char *) icl, (Cardinal) (sizeof(InternalCallbackRec) +
430a3bd7f05Smrg                                                sizeof(XtCallbackRec) *
431a3bd7f05Smrg                                                icl->count));
432a3bd7f05Smrg        icl->is_padded = 0;
433a3bd7f05Smrg        *callbacks = icl;
434a3bd7f05Smrg    }
435a3bd7f05Smrg    else {
436a3bd7f05Smrg        XtFree((char *) icl);
437a3bd7f05Smrg        *callbacks = NULL;
438444c061aSmrg    }
439444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
440444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
441a3bd7f05Smrg        XtChangeHookDataRec call_data;
442a3bd7f05Smrg
443a3bd7f05Smrg        call_data.type = XtHremoveCallbacks;
444a3bd7f05Smrg        call_data.widget = widget;
445a3bd7f05Smrg        call_data.event_data = (XtPointer) name;
446a3bd7f05Smrg        XtCallCallbackList(hookobj,
447a3bd7f05Smrg                           ((HookObject) hookobj)->hooks.changehook_callbacks,
448a3bd7f05Smrg                           (XtPointer) &call_data);
449444c061aSmrg    }
450444c061aSmrg    UNLOCK_APP(app);
451a3bd7f05Smrg}                               /* XtRemoveCallbacks */
452444c061aSmrg
453a3bd7f05Smrgvoid
454a3bd7f05Smrg_XtRemoveAllCallbacks(InternalCallbackList *callbacks)
455444c061aSmrg{
456444c061aSmrg    register InternalCallbackList icl = *callbacks;
457444c061aSmrg
458444c061aSmrg    if (icl) {
459a3bd7f05Smrg        if (icl->call_state)
460a3bd7f05Smrg            icl->call_state |= _XtCBFreeAfterCalling;
461a3bd7f05Smrg        else
462a3bd7f05Smrg            XtFree((char *) icl);
463a3bd7f05Smrg        *callbacks = NULL;
464444c061aSmrg    }
465a3bd7f05Smrg}                               /* _XtRemoveAllCallbacks */
466444c061aSmrg
467a3bd7f05Smrgvoid
468a3bd7f05SmrgXtRemoveAllCallbacks(Widget widget, _Xconst char *name)
469444c061aSmrg{
470444c061aSmrg    InternalCallbackList *callbacks;
471444c061aSmrg    Widget hookobj;
472444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
473444c061aSmrg
474444c061aSmrg    LOCK_APP(app);
475444c061aSmrg    callbacks = FetchInternalList(widget, name);
476444c061aSmrg    if (!callbacks) {
477a3bd7f05Smrg        XtAppWarningMsg(app,
478a3bd7f05Smrg                        XtNinvalidCallbackList, XtNxtRemoveAllCallback,
479a3bd7f05Smrg                        XtCXtToolkitError,
480a3bd7f05Smrg                        "Cannot find callback list in XtRemoveAllCallbacks",
481a3bd7f05Smrg                        NULL, NULL);
482a3bd7f05Smrg        UNLOCK_APP(app);
483a3bd7f05Smrg        return;
484444c061aSmrg    }
485444c061aSmrg    _XtRemoveAllCallbacks(callbacks);
486444c061aSmrg    hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget));
487444c061aSmrg    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
488a3bd7f05Smrg        XtChangeHookDataRec call_data;
489a3bd7f05Smrg
490a3bd7f05Smrg        call_data.type = XtHremoveAllCallbacks;
491a3bd7f05Smrg        call_data.widget = widget;
492a3bd7f05Smrg        call_data.event_data = (XtPointer) name;
493a3bd7f05Smrg        XtCallCallbackList(hookobj,
494a3bd7f05Smrg                           ((HookObject) hookobj)->hooks.changehook_callbacks,
495a3bd7f05Smrg                           (XtPointer) &call_data);
496444c061aSmrg    }
497444c061aSmrg    UNLOCK_APP(app);
498a3bd7f05Smrg}                               /* XtRemoveAllCallbacks */
499444c061aSmrg
500a3bd7f05SmrgInternalCallbackList
501a3bd7f05Smrg_XtCompileCallbackList(XtCallbackList xtcallbacks)
502444c061aSmrg{
503444c061aSmrg    register int n;
504444c061aSmrg    register XtCallbackList xtcl, cl;
505444c061aSmrg    register InternalCallbackList callbacks;
506444c061aSmrg
507a3bd7f05Smrg    for (n = 0, xtcl = xtcallbacks; xtcl->callback; n++, xtcl++) {
508a3bd7f05Smrg    };
509a3bd7f05Smrg    if (n == 0)
510a3bd7f05Smrg        return (InternalCallbackList) NULL;
511444c061aSmrg
512a3bd7f05Smrg    callbacks =
513a3bd7f05Smrg        (InternalCallbackList)
514a3bd7f05Smrg        __XtMalloc((Cardinal)
515a3bd7f05Smrg                   (sizeof(InternalCallbackRec) +
516a3bd7f05Smrg                    sizeof(XtCallbackRec) * (size_t) n));
5170568f49bSmrg    callbacks->count = (unsigned short) n;
518444c061aSmrg    callbacks->is_padded = 0;
519444c061aSmrg    callbacks->call_state = 0;
520444c061aSmrg    cl = ToList(callbacks);
521444c061aSmrg    while (--n >= 0)
522a3bd7f05Smrg        *cl++ = *xtcallbacks++;
523a3bd7f05Smrg    return (callbacks);
524a3bd7f05Smrg}                               /* _XtCompileCallbackList */
525444c061aSmrg
526a3bd7f05SmrgXtCallbackList
527a3bd7f05Smrg_XtGetCallbackList(InternalCallbackList *callbacks)
528444c061aSmrg{
5290568f49bSmrg    int i;
5300568f49bSmrg    InternalCallbackList icl;
5310568f49bSmrg    XtCallbackList cl;
532444c061aSmrg
533444c061aSmrg    icl = *callbacks;
534444c061aSmrg    if (!icl) {
535a3bd7f05Smrg        static XtCallbackRec emptyList[1] = { {NULL, NULL} };
536a3bd7f05Smrg        return (XtCallbackList) emptyList;
537444c061aSmrg    }
538444c061aSmrg    if (icl->is_padded)
539a3bd7f05Smrg        return ToList(icl);
540444c061aSmrg    i = icl->count;
541444c061aSmrg    if (icl->call_state) {
5420568f49bSmrg        XtCallbackList ocl;
543a3bd7f05Smrg
544a3bd7f05Smrg        icl->call_state |= _XtCBFreeAfterCalling;
545a3bd7f05Smrg        ocl = ToList(icl);
546a3bd7f05Smrg        icl = (InternalCallbackList)
547a3bd7f05Smrg            __XtMalloc((Cardinal)
548a3bd7f05Smrg                       (sizeof(InternalCallbackRec) +
549a3bd7f05Smrg                        sizeof(XtCallbackRec) * (size_t) (i + 1)));
550a3bd7f05Smrg        icl->count = (unsigned short) i;
551a3bd7f05Smrg        icl->call_state = 0;
552a3bd7f05Smrg        cl = ToList(icl);
553a3bd7f05Smrg        while (--i >= 0)
554a3bd7f05Smrg            *cl++ = *ocl++;
555a3bd7f05Smrg    }
556a3bd7f05Smrg    else {
557a3bd7f05Smrg        icl = (InternalCallbackList)
558a3bd7f05Smrg            XtRealloc((char *) icl, (Cardinal) (sizeof(InternalCallbackRec)
559a3bd7f05Smrg                                                + sizeof(XtCallbackRec)
560a3bd7f05Smrg                                                * (size_t) (i + 1)));
561a3bd7f05Smrg        cl = ToList(icl) + i;
562444c061aSmrg    }
563444c061aSmrg    icl->is_padded = 1;
564444c061aSmrg    cl->callback = (XtCallbackProc) NULL;
565444c061aSmrg    cl->closure = NULL;
566444c061aSmrg    *callbacks = icl;
567444c061aSmrg    return ToList(icl);
568444c061aSmrg}
569444c061aSmrg
570a3bd7f05Smrgvoid
571a3bd7f05SmrgXtCallCallbacks(Widget widget,
572a3bd7f05Smrg                _Xconst char *name,
573a3bd7f05Smrg                XtPointer call_data)
574444c061aSmrg{
575444c061aSmrg    InternalCallbackList *callbacks;
576444c061aSmrg    InternalCallbackList icl;
577444c061aSmrg    XtCallbackList cl;
578444c061aSmrg    int i;
579444c061aSmrg    char ostate;
580444c061aSmrg    XtAppContext app = XtWidgetToApplicationContext(widget);
581444c061aSmrg
582444c061aSmrg    LOCK_APP(app);
583444c061aSmrg    callbacks = FetchInternalList(widget, name);
584444c061aSmrg    if (!callbacks) {
585a3bd7f05Smrg        XtAppWarningMsg(app,
586a3bd7f05Smrg                        XtNinvalidCallbackList, XtNxtCallCallback,
587a3bd7f05Smrg                        XtCXtToolkitError,
588a3bd7f05Smrg                        "Cannot find callback list in XtCallCallbacks", NULL,
589a3bd7f05Smrg                        NULL);
590a3bd7f05Smrg        UNLOCK_APP(app);
591a3bd7f05Smrg        return;
592444c061aSmrg    }
593444c061aSmrg
594444c061aSmrg    icl = *callbacks;
595444c061aSmrg    if (!icl) {
596a3bd7f05Smrg        UNLOCK_APP(app);
597a3bd7f05Smrg        return;
598444c061aSmrg    }
599444c061aSmrg    cl = ToList(icl);
600444c061aSmrg    if (icl->count == 1) {
601a3bd7f05Smrg        (*cl->callback) (widget, cl->closure, call_data);
602a3bd7f05Smrg        UNLOCK_APP(app);
603a3bd7f05Smrg        return;
604444c061aSmrg    }
605444c061aSmrg    ostate = icl->call_state;
606444c061aSmrg    icl->call_state = _XtCBCalling;
607444c061aSmrg    for (i = icl->count; --i >= 0; cl++)
608a3bd7f05Smrg        (*cl->callback) (widget, cl->closure, call_data);
609444c061aSmrg    if (ostate)
610a3bd7f05Smrg        icl->call_state |= ostate;
611444c061aSmrg    else if (icl->call_state & _XtCBFreeAfterCalling)
612a3bd7f05Smrg        XtFree((char *) icl);
613444c061aSmrg    else
614a3bd7f05Smrg        icl->call_state = ostate;
615444c061aSmrg    UNLOCK_APP(app);
616a3bd7f05Smrg}                               /* XtCallCallbacks */
617444c061aSmrg
618a3bd7f05SmrgXtCallbackStatus
619a3bd7f05SmrgXtHasCallbacks(Widget widget,
620a3bd7f05Smrg               _Xconst char *callback_name)
621444c061aSmrg{
622444c061aSmrg    InternalCallbackList *callbacks;
623444c061aSmrg    XtCallbackStatus retval = XtCallbackHasSome;
624a3bd7f05Smrg
625444c061aSmrg    WIDGET_TO_APPCON(widget);
626444c061aSmrg
627444c061aSmrg    LOCK_APP(app);
628444c061aSmrg    callbacks = FetchInternalList(widget, callback_name);
629444c061aSmrg    if (!callbacks)
630a3bd7f05Smrg        retval = XtCallbackNoList;
631444c061aSmrg    else if (!*callbacks)
632a3bd7f05Smrg        retval = XtCallbackHasNone;
633444c061aSmrg    UNLOCK_APP(app);
634444c061aSmrg    return retval;
635a3bd7f05Smrg}                               /* XtHasCallbacks */
636444c061aSmrg
637a3bd7f05Smrgvoid
638a3bd7f05SmrgXtCallCallbackList(Widget widget,
639a3bd7f05Smrg                   XtCallbackList callbacks,
640a3bd7f05Smrg                   XtPointer call_data)
641444c061aSmrg{
642444c061aSmrg    register InternalCallbackList icl;
643444c061aSmrg    register XtCallbackList cl;
644444c061aSmrg    register int i;
645444c061aSmrg    char ostate;
646a3bd7f05Smrg
647444c061aSmrg    WIDGET_TO_APPCON(widget);
648444c061aSmrg
649444c061aSmrg    LOCK_APP(app);
650444c061aSmrg    if (!callbacks) {
651a3bd7f05Smrg        UNLOCK_APP(app);
652a3bd7f05Smrg        return;
653444c061aSmrg    }
654a3bd7f05Smrg    icl = (InternalCallbackList) callbacks;
655444c061aSmrg    cl = ToList(icl);
656444c061aSmrg    if (icl->count == 1) {
657a3bd7f05Smrg        (*cl->callback) (widget, cl->closure, call_data);
658a3bd7f05Smrg        UNLOCK_APP(app);
659a3bd7f05Smrg        return;
660444c061aSmrg    }
661444c061aSmrg    ostate = icl->call_state;
662444c061aSmrg    icl->call_state = _XtCBCalling;
663444c061aSmrg    for (i = icl->count; --i >= 0; cl++)
664a3bd7f05Smrg        (*cl->callback) (widget, cl->closure, call_data);
665444c061aSmrg    if (ostate)
666a3bd7f05Smrg        icl->call_state |= ostate;
667444c061aSmrg    else if (icl->call_state & _XtCBFreeAfterCalling)
668a3bd7f05Smrg        XtFree((char *) icl);
669444c061aSmrg    else
670a3bd7f05Smrg        icl->call_state = 0;
671444c061aSmrg    UNLOCK_APP(app);
672a3bd7f05Smrg}                               /* XtCallCallbackList */
673444c061aSmrg
674a3bd7f05Smrgvoid
675a3bd7f05Smrg_XtPeekCallback(Widget widget _X_UNUSED,
676a3bd7f05Smrg                XtCallbackList callbacks,
677a3bd7f05Smrg                XtCallbackProc *callback,
678a3bd7f05Smrg                XtPointer *closure)
679444c061aSmrg{
680444c061aSmrg    register InternalCallbackList icl = (InternalCallbackList) callbacks;
681444c061aSmrg    register XtCallbackList cl;
682444c061aSmrg
683444c061aSmrg    if (!callbacks) {
684a3bd7f05Smrg        *callback = (XtCallbackProc) NULL;
685a3bd7f05Smrg        return;
686444c061aSmrg    }
687444c061aSmrg    cl = ToList(icl);
688444c061aSmrg    *callback = cl->callback;
689444c061aSmrg    *closure = cl->closure;
690444c061aSmrg    return;
691444c061aSmrg}
692444c061aSmrg
693a3bd7f05Smrgvoid
694a3bd7f05Smrg_XtCallConditionalCallbackList(Widget widget,
695a3bd7f05Smrg                               XtCallbackList callbacks,
696a3bd7f05Smrg                               XtPointer call_data,
697a3bd7f05Smrg                               _XtConditionProc cond_proc)
698444c061aSmrg{
699444c061aSmrg    register InternalCallbackList icl;
700444c061aSmrg    register XtCallbackList cl;
701444c061aSmrg    register int i;
702444c061aSmrg    char ostate;
703a3bd7f05Smrg
704444c061aSmrg    WIDGET_TO_APPCON(widget);
705444c061aSmrg
706444c061aSmrg    LOCK_APP(app);
707444c061aSmrg    if (!callbacks) {
708a3bd7f05Smrg        UNLOCK_APP(app);
709a3bd7f05Smrg        return;
710444c061aSmrg    }
711a3bd7f05Smrg    icl = (InternalCallbackList) callbacks;
712444c061aSmrg    cl = ToList(icl);
713444c061aSmrg    if (icl->count == 1) {
714a3bd7f05Smrg        (*cl->callback) (widget, cl->closure, call_data);
715a3bd7f05Smrg        (void) (*cond_proc) (call_data);
716a3bd7f05Smrg        UNLOCK_APP(app);
717a3bd7f05Smrg        return;
718444c061aSmrg    }
719444c061aSmrg    ostate = icl->call_state;
720444c061aSmrg    icl->call_state = _XtCBCalling;
721444c061aSmrg    for (i = icl->count; --i >= 0; cl++) {
722a3bd7f05Smrg        (*cl->callback) (widget, cl->closure, call_data);
723a3bd7f05Smrg        if (!(*cond_proc) (call_data))
724a3bd7f05Smrg            break;
725444c061aSmrg    }
726444c061aSmrg    if (ostate)
727a3bd7f05Smrg        icl->call_state |= ostate;
728444c061aSmrg    else if (icl->call_state & _XtCBFreeAfterCalling)
729a3bd7f05Smrg        XtFree((char *) icl);
730444c061aSmrg    else
731a3bd7f05Smrg        icl->call_state = 0;
732444c061aSmrg    UNLOCK_APP(app);
733444c061aSmrg}
734