Callback.c revision 0568f49b
1/*********************************************************** 2Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved. 3 4Permission is hereby granted, free of charge, to any person obtaining a 5copy of this software and associated documentation files (the "Software"), 6to deal in the Software without restriction, including without limitation 7the rights to use, copy, modify, merge, publish, distribute, sublicense, 8and/or sell copies of the Software, and to permit persons to whom the 9Software is furnished to do so, subject to the following conditions: 10 11The above copyright notice and this permission notice (including the next 12paragraph) shall be included in all copies or substantial portions of the 13Software. 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21DEALINGS IN THE SOFTWARE. 22 23Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 24 25 All Rights Reserved 26 27Permission to use, copy, modify, and distribute this software and its 28documentation for any purpose and without fee is hereby granted, 29provided that the above copyright notice appear in all copies and that 30both that copyright notice and this permission notice appear in 31supporting documentation, and that the name of Digital not be 32used in advertising or publicity pertaining to distribution of the 33software without specific, written prior permission. 34 35DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 36ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 37DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 38ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 39WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 40ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 41SOFTWARE. 42 43******************************************************************/ 44 45/* 46 47Copyright 1987, 1988, 1998 The Open Group 48 49Permission to use, copy, modify, distribute, and sell this software and its 50documentation for any purpose is hereby granted without fee, provided that 51the above copyright notice appear in all copies and that both that 52copyright notice and this permission notice appear in supporting 53documentation. 54 55The above copyright notice and this permission notice shall be included in 56all copies or substantial portions of the Software. 57 58THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 59IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 60FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 61OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 62AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 63CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 64 65Except as contained in this notice, the name of The Open Group shall not be 66used in advertising or otherwise to promote the sale, use or other dealings 67in this Software without prior written authorization from The Open Group. 68 69*/ 70 71#ifdef HAVE_CONFIG_H 72#include <config.h> 73#endif 74#include "IntrinsicI.h" 75 76static _Xconst _XtString XtNinvalidCallbackList = "invalidCallbackList"; 77static _Xconst _XtString XtNxtAddCallback = "xtAddCallback"; 78static _Xconst _XtString XtNxtRemoveCallback = "xtRemoveCallback"; 79static _Xconst _XtString XtNxtRemoveAllCallback = "xtRemoveAllCallback"; 80static _Xconst _XtString XtNxtCallCallback = "xtCallCallback"; 81 82/* However it doesn't contain a final NULL record */ 83#define ToList(p) ((XtCallbackList) ((p)+1)) 84 85static InternalCallbackList* FetchInternalList( 86 Widget widget, 87 _Xconst char *name) 88{ 89 XrmQuark quark; 90 int n; 91 CallbackTable offsets; 92 InternalCallbackList* retval = NULL; 93 94 quark = StringToQuark(name); 95 LOCK_PROCESS; 96 offsets = (CallbackTable) 97 widget->core.widget_class->core_class.callback_private; 98 99 for (n = (int)(long) *(offsets++); --n >= 0; offsets++) 100 if (quark == (*offsets)->xrm_name) { 101 retval = (InternalCallbackList *) 102 ((char *) widget - (*offsets)->xrm_offset - 1); 103 break; 104 } 105 UNLOCK_PROCESS; 106 return retval; 107} 108 109 110void _XtAddCallback( 111 InternalCallbackList* callbacks, 112 XtCallbackProc callback, 113 XtPointer closure) 114{ 115 register InternalCallbackList icl; 116 register XtCallbackList cl; 117 register int count; 118 119 icl = *callbacks; 120 count = icl ? icl->count : 0; 121 122 if (icl && icl->call_state) { 123 icl->call_state |= _XtCBFreeAfterCalling; 124 icl = (InternalCallbackList) 125 __XtMalloc((Cardinal) (sizeof(InternalCallbackRec) + 126 sizeof(XtCallbackRec) * (size_t) (count + 1))); 127 (void) memmove((char *)ToList(icl), (char *)ToList(*callbacks), 128 sizeof(XtCallbackRec) * (size_t) count); 129 } else { 130 icl = (InternalCallbackList) 131 XtRealloc((char *) icl, (Cardinal)(sizeof(InternalCallbackRec) + 132 sizeof(XtCallbackRec) * (size_t) (count + 1))); 133 } 134 *callbacks = icl; 135 icl->count = (unsigned short) (count + 1); 136 icl->is_padded = 0; 137 icl->call_state = 0; 138 cl = ToList(icl) + count; 139 cl->callback = callback; 140 cl->closure = closure; 141} /* _XtAddCallback */ 142 143void _XtAddCallbackOnce( 144 register InternalCallbackList*callbacks, 145 XtCallbackProc callback, 146 XtPointer closure) 147{ 148 register XtCallbackList cl = ToList(*callbacks); 149 register int i; 150 151 for (i=(*callbacks)->count; --i >= 0; cl++) 152 if (cl->callback == callback && cl->closure == closure) 153 return; 154 155 _XtAddCallback(callbacks, callback, closure); 156} /* _XtAddCallbackOnce */ 157 158void XtAddCallback( 159 Widget widget, 160 _Xconst char* name, 161 XtCallbackProc callback, 162 XtPointer closure 163 ) 164{ 165 InternalCallbackList *callbacks; 166 XtAppContext app = XtWidgetToApplicationContext(widget); 167 168 LOCK_APP(app); 169 callbacks = FetchInternalList(widget, name); 170 if (!callbacks) { 171 XtAppWarningMsg(app, 172 XtNinvalidCallbackList,XtNxtAddCallback,XtCXtToolkitError, 173 "Cannot find callback list in XtAddCallback", 174 NULL, NULL); 175 UNLOCK_APP(app); 176 return; 177 } 178 _XtAddCallback(callbacks, callback, closure); 179 if (!_XtIsHookObject(widget)) { 180 Widget hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); 181 if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) { 182 XtChangeHookDataRec call_data; 183 184 call_data.type = XtHaddCallback; 185 call_data.widget = widget; 186 call_data.event_data = (XtPointer) name; 187 XtCallCallbackList(hookobj, 188 ((HookObject)hookobj)->hooks.changehook_callbacks, 189 (XtPointer)&call_data); 190 } 191 } 192 UNLOCK_APP(app); 193} /* XtAddCallback */ 194 195/* ARGSUSED */ 196static void AddCallbacks( 197 Widget widget, 198 InternalCallbackList *callbacks, 199 XtCallbackList newcallbacks) 200{ 201 register InternalCallbackList icl; 202 register int i, j; 203 register XtCallbackList cl; 204 205 icl = *callbacks; 206 i = icl ? icl->count : 0; 207 for (j=0, cl = newcallbacks; cl->callback; cl++, j++); 208 if (icl && icl->call_state) { 209 icl->call_state |= _XtCBFreeAfterCalling; 210 icl = (InternalCallbackList) __XtMalloc((Cardinal)(sizeof(InternalCallbackRec) + 211 sizeof(XtCallbackRec) * (size_t) (i+j))); 212 (void) memmove((char *)ToList(*callbacks), (char *)ToList(icl), 213 sizeof(XtCallbackRec) * (size_t) i); 214 } else { 215 icl = (InternalCallbackList) XtRealloc((char *) icl, 216 (Cardinal)(sizeof(InternalCallbackRec) + 217 sizeof(XtCallbackRec) * (size_t) (i+j))); 218 } 219 *callbacks = icl; 220 icl->count = (unsigned short) (i+j); 221 icl->is_padded = 0; 222 icl->call_state = 0; 223 for (cl = ToList(icl) + i; --j >= 0; ) 224 *cl++ = *newcallbacks++; 225} /* AddCallbacks */ 226 227void XtAddCallbacks( 228 Widget widget, 229 _Xconst char* name, 230 XtCallbackList xtcallbacks 231 ) 232{ 233 InternalCallbackList* callbacks; 234 Widget hookobj; 235 XtAppContext app = XtWidgetToApplicationContext(widget); 236 237 LOCK_APP(app); 238 callbacks = FetchInternalList(widget, name); 239 if (!callbacks) { 240 XtAppWarningMsg(app, 241 XtNinvalidCallbackList,XtNxtAddCallback,XtCXtToolkitError, 242 "Cannot find callback list in XtAddCallbacks", 243 NULL, NULL); 244 UNLOCK_APP(app); 245 return; 246 } 247 AddCallbacks(widget, callbacks, xtcallbacks); 248 hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); 249 if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) { 250 XtChangeHookDataRec call_data; 251 252 call_data.type = XtHaddCallbacks; 253 call_data.widget = widget; 254 call_data.event_data = (XtPointer) name; 255 XtCallCallbackList(hookobj, 256 ((HookObject)hookobj)->hooks.changehook_callbacks, 257 (XtPointer)&call_data); 258 } 259 UNLOCK_APP(app); 260} /* XtAddCallbacks */ 261 262void _XtRemoveCallback ( 263 InternalCallbackList *callbacks, 264 XtCallbackProc callback, 265 XtPointer closure) 266{ 267 register InternalCallbackList icl; 268 register int i, j; 269 register XtCallbackList cl, ncl, ocl; 270 271 icl = *callbacks; 272 if (!icl) return; 273 274 cl = ToList(icl); 275 for (i=icl->count; --i >= 0; cl++) { 276 if (cl->callback == callback && cl->closure == closure) { 277 if (icl->call_state) { 278 icl->call_state |= _XtCBFreeAfterCalling; 279 if (icl->count == 1) { 280 *callbacks = NULL; 281 } else { 282 j = icl->count - i - 1; 283 ocl = ToList(icl); 284 icl = (InternalCallbackList) 285 __XtMalloc((Cardinal) (sizeof(InternalCallbackRec) + 286 sizeof(XtCallbackRec) * (size_t) (i + j))); 287 icl->count = (unsigned short) (i + j); 288 icl->is_padded = 0; 289 icl->call_state = 0; 290 ncl = ToList(icl); 291 while (--j >= 0) 292 *ncl++ = *ocl++; 293 while (--i >= 0) 294 *ncl++ = *++cl; 295 *callbacks = icl; 296 } 297 } else { 298 if (--icl->count) { 299 ncl = cl + 1; 300 while (--i >= 0) 301 *cl++ = *ncl++; 302 icl = (InternalCallbackList) 303 XtRealloc((char *) icl, (Cardinal) (sizeof(InternalCallbackRec) 304 + sizeof(XtCallbackRec) * icl->count)); 305 icl->is_padded = 0; 306 *callbacks = icl; 307 } else { 308 XtFree((char *) icl); 309 *callbacks = NULL; 310 } 311 } 312 return; 313 } 314 } 315} /* _XtRemoveCallback */ 316 317void XtRemoveCallback ( 318 Widget widget, 319 _Xconst char* name, 320 XtCallbackProc callback, 321 XtPointer closure 322 ) 323{ 324 InternalCallbackList *callbacks; 325 Widget hookobj; 326 XtAppContext app = XtWidgetToApplicationContext(widget); 327 328 LOCK_APP(app); 329 callbacks = FetchInternalList(widget, name); 330 if (!callbacks) { 331 XtAppWarningMsg(app, 332 XtNinvalidCallbackList,XtNxtRemoveCallback,XtCXtToolkitError, 333 "Cannot find callback list in XtRemoveCallback", 334 NULL, NULL); 335 UNLOCK_APP(app); 336 return; 337 } 338 _XtRemoveCallback(callbacks, callback, closure); 339 hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); 340 if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) { 341 XtChangeHookDataRec call_data; 342 343 call_data.type = XtHremoveCallback; 344 call_data.widget = widget; 345 call_data.event_data = (XtPointer) name; 346 XtCallCallbackList(hookobj, 347 ((HookObject)hookobj)->hooks.changehook_callbacks, 348 (XtPointer)&call_data); 349 } 350 UNLOCK_APP(app); 351} /* XtRemoveCallback */ 352 353 354void XtRemoveCallbacks ( 355 Widget widget, 356 _Xconst char* name, 357 XtCallbackList xtcallbacks) 358{ 359 InternalCallbackList *callbacks; 360 Widget hookobj; 361 int i; 362 InternalCallbackList icl; 363 XtCallbackList cl, ccl, rcl; 364 XtAppContext app = XtWidgetToApplicationContext(widget); 365 366 LOCK_APP(app); 367 callbacks = FetchInternalList(widget, name); 368 if (!callbacks) { 369 XtAppWarningMsg(app, 370 XtNinvalidCallbackList,XtNxtRemoveCallback,XtCXtToolkitError, 371 "Cannot find callback list in XtRemoveCallbacks", 372 NULL, NULL); 373 UNLOCK_APP(app); 374 return; 375 } 376 377 icl = *callbacks; 378 if (!icl) { 379 UNLOCK_APP(app); 380 return; 381 } 382 383 i = icl->count; 384 cl = ToList(icl); 385 if (icl->call_state) { 386 icl->call_state |= _XtCBFreeAfterCalling; 387 icl = (InternalCallbackList)__XtMalloc((Cardinal)(sizeof(InternalCallbackRec) + 388 sizeof(XtCallbackRec) * (size_t) i)); 389 icl->count = (unsigned short) i; 390 icl->call_state = 0; 391 } 392 ccl = ToList(icl); 393 while (--i >= 0) { 394 *ccl++ = *cl; 395 for (rcl=xtcallbacks; rcl->callback; rcl++) { 396 if (cl->callback == rcl->callback && cl->closure == rcl->closure) { 397 ccl--; 398 icl->count--; 399 break; 400 } 401 } 402 cl++; 403 } 404 if (icl->count) { 405 icl = (InternalCallbackList) 406 XtRealloc((char *)icl, (Cardinal) (sizeof(InternalCallbackRec) + 407 sizeof(XtCallbackRec) * icl->count)); 408 icl->is_padded = 0; 409 *callbacks = icl; 410 } else { 411 XtFree((char *)icl); 412 *callbacks = NULL; 413 } 414 hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); 415 if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) { 416 XtChangeHookDataRec call_data; 417 418 call_data.type = XtHremoveCallbacks; 419 call_data.widget = widget; 420 call_data.event_data = (XtPointer) name; 421 XtCallCallbackList(hookobj, 422 ((HookObject)hookobj)->hooks.changehook_callbacks, 423 (XtPointer)&call_data); 424 } 425 UNLOCK_APP(app); 426} /* XtRemoveCallbacks */ 427 428 429void _XtRemoveAllCallbacks ( 430 InternalCallbackList *callbacks) 431{ 432 register InternalCallbackList icl = *callbacks; 433 434 if (icl) { 435 if (icl->call_state) 436 icl->call_state |= _XtCBFreeAfterCalling; 437 else 438 XtFree((char *) icl); 439 *callbacks = NULL; 440 } 441} /* _XtRemoveAllCallbacks */ 442 443void XtRemoveAllCallbacks( 444 Widget widget, 445 _Xconst char* name) 446{ 447 InternalCallbackList *callbacks; 448 Widget hookobj; 449 XtAppContext app = XtWidgetToApplicationContext(widget); 450 451 LOCK_APP(app); 452 callbacks = FetchInternalList(widget, name); 453 if (!callbacks) { 454 XtAppWarningMsg(app, 455 XtNinvalidCallbackList,XtNxtRemoveAllCallback,XtCXtToolkitError, 456 "Cannot find callback list in XtRemoveAllCallbacks", 457 NULL, NULL); 458 UNLOCK_APP(app); 459 return; 460 } 461 _XtRemoveAllCallbacks(callbacks); 462 hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); 463 if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) { 464 XtChangeHookDataRec call_data; 465 466 call_data.type = XtHremoveAllCallbacks; 467 call_data.widget = widget; 468 call_data.event_data = (XtPointer) name; 469 XtCallCallbackList(hookobj, 470 ((HookObject)hookobj)->hooks.changehook_callbacks, 471 (XtPointer)&call_data); 472 } 473 UNLOCK_APP(app); 474} /* XtRemoveAllCallbacks */ 475 476InternalCallbackList _XtCompileCallbackList( 477 XtCallbackList xtcallbacks) 478{ 479 register int n; 480 register XtCallbackList xtcl, cl; 481 register InternalCallbackList callbacks; 482 483 for (n=0, xtcl=xtcallbacks; xtcl->callback; n++, xtcl++) {}; 484 if (n == 0) return (InternalCallbackList) NULL; 485 486 callbacks = (InternalCallbackList) __XtMalloc((Cardinal) (sizeof(InternalCallbackRec) + 487 sizeof(XtCallbackRec) * (size_t) n)); 488 callbacks->count = (unsigned short) n; 489 callbacks->is_padded = 0; 490 callbacks->call_state = 0; 491 cl = ToList(callbacks); 492 while (--n >= 0) 493 *cl++ = *xtcallbacks++; 494 return(callbacks); 495} /* _XtCompileCallbackList */ 496 497 498XtCallbackList _XtGetCallbackList( 499 InternalCallbackList *callbacks) 500{ 501 int i; 502 InternalCallbackList icl; 503 XtCallbackList cl; 504 505 icl = *callbacks; 506 if (!icl) { 507 static XtCallbackRec emptyList[1] = { {NULL, NULL} }; 508 return (XtCallbackList)emptyList; 509 } 510 if (icl->is_padded) 511 return ToList(icl); 512 i = icl->count; 513 if (icl->call_state) { 514 XtCallbackList ocl; 515 icl->call_state |= _XtCBFreeAfterCalling; 516 ocl = ToList(icl); 517 icl = (InternalCallbackList) __XtMalloc((Cardinal)(sizeof(InternalCallbackRec) + 518 sizeof(XtCallbackRec) * (size_t) (i+1))); 519 icl->count = (unsigned short) i; 520 icl->call_state = 0; 521 cl = ToList(icl); 522 while (--i >= 0) 523 *cl++ = *ocl++; 524 } else { 525 icl = (InternalCallbackList) XtRealloc((char *)icl, 526 (Cardinal)(sizeof(InternalCallbackRec) + 527 sizeof(XtCallbackRec) * (size_t)(i+1))); 528 cl = ToList(icl) + i; 529 } 530 icl->is_padded = 1; 531 cl->callback = (XtCallbackProc) NULL; 532 cl->closure = NULL; 533 *callbacks = icl; 534 return ToList(icl); 535} 536 537void XtCallCallbacks( 538 Widget widget, 539 _Xconst char* name, 540 XtPointer call_data 541 ) 542{ 543 InternalCallbackList *callbacks; 544 InternalCallbackList icl; 545 XtCallbackList cl; 546 int i; 547 char ostate; 548 XtAppContext app = XtWidgetToApplicationContext(widget); 549 550 LOCK_APP(app); 551 callbacks = FetchInternalList(widget, name); 552 if (!callbacks) { 553 XtAppWarningMsg(app, 554 XtNinvalidCallbackList,XtNxtCallCallback,XtCXtToolkitError, 555 "Cannot find callback list in XtCallCallbacks", 556 NULL, NULL); 557 UNLOCK_APP(app); 558 return; 559 } 560 561 icl = *callbacks; 562 if (!icl) { 563 UNLOCK_APP(app); 564 return; 565 } 566 cl = ToList(icl); 567 if (icl->count == 1) { 568 (*cl->callback) (widget, cl->closure, call_data); 569 UNLOCK_APP(app); 570 return; 571 } 572 ostate = icl->call_state; 573 icl->call_state = _XtCBCalling; 574 for (i = icl->count; --i >= 0; cl++) 575 (*cl->callback) (widget, cl->closure, call_data); 576 if (ostate) 577 icl->call_state |= ostate; 578 else if (icl->call_state & _XtCBFreeAfterCalling) 579 XtFree((char *)icl); 580 else 581 icl->call_state = ostate; 582 UNLOCK_APP(app); 583} /* XtCallCallbacks */ 584 585 586XtCallbackStatus XtHasCallbacks( 587 Widget widget, 588 _Xconst char* callback_name 589 ) 590{ 591 InternalCallbackList *callbacks; 592 XtCallbackStatus retval = XtCallbackHasSome; 593 WIDGET_TO_APPCON(widget); 594 595 LOCK_APP(app); 596 callbacks = FetchInternalList(widget, callback_name); 597 if (!callbacks) 598 retval = XtCallbackNoList; 599 else if (!*callbacks) 600 retval = XtCallbackHasNone; 601 UNLOCK_APP(app); 602 return retval; 603} /* XtHasCallbacks */ 604 605 606void XtCallCallbackList( 607 Widget widget, 608 XtCallbackList callbacks, 609 XtPointer call_data) 610{ 611 register InternalCallbackList icl; 612 register XtCallbackList cl; 613 register int i; 614 char ostate; 615 WIDGET_TO_APPCON(widget); 616 617 LOCK_APP(app); 618 if (!callbacks) { 619 UNLOCK_APP(app); 620 return; 621 } 622 icl = (InternalCallbackList)callbacks; 623 cl = ToList(icl); 624 if (icl->count == 1) { 625 (*cl->callback) (widget, cl->closure, call_data); 626 UNLOCK_APP(app); 627 return; 628 } 629 ostate = icl->call_state; 630 icl->call_state = _XtCBCalling; 631 for (i = icl->count; --i >= 0; cl++) 632 (*cl->callback) (widget, cl->closure, call_data); 633 if (ostate) 634 icl->call_state |= ostate; 635 else if (icl->call_state & _XtCBFreeAfterCalling) 636 XtFree((char *)icl); 637 else 638 icl->call_state = 0; 639 UNLOCK_APP(app); 640} /* XtCallCallbackList */ 641 642void _XtPeekCallback( 643 Widget widget, 644 XtCallbackList callbacks, 645 XtCallbackProc *callback, 646 XtPointer *closure) 647{ 648 register InternalCallbackList icl = (InternalCallbackList) callbacks; 649 register XtCallbackList cl; 650 651 if (!callbacks) { 652 *callback = (XtCallbackProc) NULL; 653 return; 654 } 655 cl = ToList(icl); 656 *callback = cl->callback; 657 *closure = cl->closure; 658 return; 659} 660 661void _XtCallConditionalCallbackList( 662 Widget widget, 663 XtCallbackList callbacks, 664 XtPointer call_data, 665 _XtConditionProc cond_proc) 666{ 667 register InternalCallbackList icl; 668 register XtCallbackList cl; 669 register int i; 670 char ostate; 671 WIDGET_TO_APPCON(widget); 672 673 LOCK_APP(app); 674 if (!callbacks) { 675 UNLOCK_APP(app); 676 return; 677 } 678 icl = (InternalCallbackList)callbacks; 679 cl = ToList(icl); 680 if (icl->count == 1) { 681 (*cl->callback) (widget, cl->closure, call_data); 682 (void) (*cond_proc)(call_data); 683 UNLOCK_APP(app); 684 return; 685 } 686 ostate = icl->call_state; 687 icl->call_state = _XtCBCalling; 688 for (i = icl->count; --i >= 0; cl++) { 689 (*cl->callback) (widget, cl->closure, call_data); 690 if (! (*cond_proc)(call_data)) 691 break; 692 } 693 if (ostate) 694 icl->call_state |= ostate; 695 else if (icl->call_state & _XtCBFreeAfterCalling) 696 XtFree((char *)icl); 697 else 698 icl->call_state = 0; 699 UNLOCK_APP(app); 700} 701