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