Callback.c revision fdf6a26f
1/*********************************************************** 2Copyright (c) 1993, Oracle and/or its affiliates. 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#if __STDC_VERSION__ >= 199901L 84#define ToList(p) ((p)->callbacks) 85#else 86#define ToList(p) ((XtCallbackList) ((p)+1)) 87#endif 88 89static InternalCallbackList * 90FetchInternalList(Widget widget, 91 _Xconst char *name) 92{ 93 XrmQuark quark; 94 int n; 95 CallbackTable offsets; 96 InternalCallbackList *retval = NULL; 97 98 quark = StringToQuark(name); 99 LOCK_PROCESS; 100 offsets = (CallbackTable) 101 widget->core.widget_class->core_class.callback_private; 102 103 for (n = (int) (long) *(offsets++); --n >= 0; offsets++) 104 if (quark == (*offsets)->xrm_name) { 105 retval = (InternalCallbackList *) 106 ((char *) widget - (*offsets)->xrm_offset - 1); 107 break; 108 } 109 UNLOCK_PROCESS; 110 return retval; 111} 112 113void 114_XtAddCallback(InternalCallbackList *callbacks, 115 XtCallbackProc callback, 116 XtPointer closure) 117{ 118 register InternalCallbackList icl; 119 register XtCallbackList cl; 120 register int count; 121 122 icl = *callbacks; 123 count = icl ? icl->count : 0; 124 125 if (icl && icl->call_state) { 126 icl->call_state |= _XtCBFreeAfterCalling; 127 icl = (InternalCallbackList) 128 __XtMalloc((Cardinal) (sizeof(InternalCallbackRec) + 129 sizeof(XtCallbackRec) * (size_t) (count + 130 1))); 131 (void) memmove((char *) ToList(icl), (char *) ToList(*callbacks), 132 sizeof(XtCallbackRec) * (size_t) count); 133 } 134 else { 135 icl = (InternalCallbackList) 136 XtRealloc((char *) icl, (Cardinal) (sizeof(InternalCallbackRec) + 137 sizeof(XtCallbackRec) * 138 (size_t) (count + 1))); 139 } 140 *callbacks = icl; 141 icl->count = (unsigned short) (count + 1); 142 icl->is_padded = 0; 143 icl->call_state = 0; 144 cl = ToList(icl) + count; 145 cl->callback = callback; 146 cl->closure = closure; 147} /* _XtAddCallback */ 148 149void 150_XtAddCallbackOnce(register InternalCallbackList *callbacks, 151 XtCallbackProc callback, 152 XtPointer closure) 153{ 154 register XtCallbackList cl = ToList(*callbacks); 155 register int i; 156 157 for (i = (*callbacks)->count; --i >= 0; cl++) 158 if (cl->callback == callback && cl->closure == closure) 159 return; 160 161 _XtAddCallback(callbacks, callback, closure); 162} /* _XtAddCallbackOnce */ 163 164void 165XtAddCallback(Widget widget, 166 _Xconst char *name, 167 XtCallbackProc callback, 168 XtPointer closure) 169{ 170 InternalCallbackList *callbacks; 171 XtAppContext app = XtWidgetToApplicationContext(widget); 172 173 LOCK_APP(app); 174 callbacks = FetchInternalList(widget, name); 175 if (!callbacks) { 176 XtAppWarningMsg(app, 177 XtNinvalidCallbackList, XtNxtAddCallback, 178 XtCXtToolkitError, 179 "Cannot find callback list in XtAddCallback", NULL, 180 NULL); 181 UNLOCK_APP(app); 182 return; 183 } 184 _XtAddCallback(callbacks, callback, closure); 185 if (!_XtIsHookObject(widget)) { 186 Widget hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); 187 188 if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) { 189 XtChangeHookDataRec call_data; 190 191 call_data.type = XtHaddCallback; 192 call_data.widget = widget; 193 call_data.event_data = (XtPointer) name; 194 XtCallCallbackList(hookobj, 195 ((HookObject) hookobj)->hooks. 196 changehook_callbacks, (XtPointer) &call_data); 197 } 198 } 199 UNLOCK_APP(app); 200} /* XtAddCallback */ 201 202static void 203AddCallbacks(Widget widget _X_UNUSED, 204 InternalCallbackList *callbacks, 205 XtCallbackList newcallbacks) 206{ 207 register InternalCallbackList icl; 208 register int i, j; 209 register XtCallbackList cl; 210 211 icl = *callbacks; 212 i = icl ? icl->count : 0; 213 for (j = 0, cl = newcallbacks; cl->callback; cl++, j++); 214 if (icl && icl->call_state) { 215 icl->call_state |= _XtCBFreeAfterCalling; 216 icl = (InternalCallbackList) 217 __XtMalloc((Cardinal) 218 (sizeof(InternalCallbackRec) + 219 sizeof(XtCallbackRec) * (size_t) (i + j))); 220 (void) memmove((char *) ToList(*callbacks), (char *) ToList(icl), 221 sizeof(XtCallbackRec) * (size_t) i); 222 } 223 else { 224 icl = (InternalCallbackList) XtRealloc((char *) icl, 225 (Cardinal) (sizeof 226 (InternalCallbackRec) 227 + 228 sizeof(XtCallbackRec) 229 * (size_t) (i + j))); 230 } 231 *callbacks = icl; 232 icl->count = (unsigned short) (i + j); 233 icl->is_padded = 0; 234 icl->call_state = 0; 235 for (cl = ToList(icl) + i; --j >= 0;) 236 *cl++ = *newcallbacks++; 237} /* AddCallbacks */ 238 239void 240XtAddCallbacks(Widget widget, 241 _Xconst char *name, 242 XtCallbackList xtcallbacks) 243{ 244 InternalCallbackList *callbacks; 245 Widget hookobj; 246 XtAppContext app = XtWidgetToApplicationContext(widget); 247 248 LOCK_APP(app); 249 callbacks = FetchInternalList(widget, name); 250 if (!callbacks) { 251 XtAppWarningMsg(app, 252 XtNinvalidCallbackList, XtNxtAddCallback, 253 XtCXtToolkitError, 254 "Cannot find callback list in XtAddCallbacks", NULL, 255 NULL); 256 UNLOCK_APP(app); 257 return; 258 } 259 AddCallbacks(widget, callbacks, xtcallbacks); 260 hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); 261 if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) { 262 XtChangeHookDataRec call_data; 263 264 call_data.type = XtHaddCallbacks; 265 call_data.widget = widget; 266 call_data.event_data = (XtPointer) name; 267 XtCallCallbackList(hookobj, 268 ((HookObject) hookobj)->hooks.changehook_callbacks, 269 (XtPointer) &call_data); 270 } 271 UNLOCK_APP(app); 272} /* XtAddCallbacks */ 273 274void 275_XtRemoveCallback(InternalCallbackList *callbacks, 276 XtCallbackProc callback, 277 XtPointer closure) 278{ 279 register InternalCallbackList icl; 280 register int i, j; 281 register XtCallbackList cl, ncl, ocl; 282 283 icl = *callbacks; 284 if (!icl) 285 return; 286 287 cl = ToList(icl); 288 for (i = icl->count; --i >= 0; cl++) { 289 if (cl->callback == callback && cl->closure == closure) { 290 if (icl->call_state) { 291 icl->call_state |= _XtCBFreeAfterCalling; 292 if (icl->count == 1) { 293 *callbacks = NULL; 294 } 295 else { 296 j = icl->count - i - 1; 297 ocl = ToList(icl); 298 icl = (InternalCallbackList) 299 __XtMalloc((Cardinal) (sizeof(InternalCallbackRec) + 300 sizeof(XtCallbackRec) * 301 (size_t) (i + j))); 302 icl->count = (unsigned short) (i + j); 303 icl->is_padded = 0; 304 icl->call_state = 0; 305 ncl = ToList(icl); 306 while (--j >= 0) 307 *ncl++ = *ocl++; 308 while (--i >= 0) 309 *ncl++ = *++cl; 310 *callbacks = icl; 311 } 312 } 313 else { 314 if (--icl->count) { 315 ncl = cl + 1; 316 while (--i >= 0) 317 *cl++ = *ncl++; 318 icl = (InternalCallbackList) 319 XtRealloc((char *) icl, 320 (Cardinal) (sizeof(InternalCallbackRec) 321 + 322 sizeof(XtCallbackRec) * 323 icl->count)); 324 icl->is_padded = 0; 325 *callbacks = icl; 326 } 327 else { 328 XtFree((char *) icl); 329 *callbacks = NULL; 330 } 331 } 332 return; 333 } 334 } 335} /* _XtRemoveCallback */ 336 337void 338XtRemoveCallback(Widget widget, 339 _Xconst char *name, 340 XtCallbackProc callback, 341 XtPointer closure) 342{ 343 InternalCallbackList *callbacks; 344 Widget hookobj; 345 XtAppContext app = XtWidgetToApplicationContext(widget); 346 347 LOCK_APP(app); 348 callbacks = FetchInternalList(widget, name); 349 if (!callbacks) { 350 XtAppWarningMsg(app, 351 XtNinvalidCallbackList, XtNxtRemoveCallback, 352 XtCXtToolkitError, 353 "Cannot find callback list in XtRemoveCallback", NULL, 354 NULL); 355 UNLOCK_APP(app); 356 return; 357 } 358 _XtRemoveCallback(callbacks, callback, closure); 359 hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); 360 if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) { 361 XtChangeHookDataRec call_data; 362 363 call_data.type = XtHremoveCallback; 364 call_data.widget = widget; 365 call_data.event_data = (XtPointer) name; 366 XtCallCallbackList(hookobj, 367 ((HookObject) hookobj)->hooks.changehook_callbacks, 368 (XtPointer) &call_data); 369 } 370 UNLOCK_APP(app); 371} /* XtRemoveCallback */ 372 373void 374XtRemoveCallbacks(Widget widget, 375 _Xconst char *name, 376 XtCallbackList xtcallbacks) 377{ 378 InternalCallbackList *callbacks; 379 Widget hookobj; 380 int i; 381 InternalCallbackList icl; 382 XtCallbackList cl, ccl, rcl; 383 XtAppContext app = XtWidgetToApplicationContext(widget); 384 385 LOCK_APP(app); 386 callbacks = FetchInternalList(widget, name); 387 if (!callbacks) { 388 XtAppWarningMsg(app, 389 XtNinvalidCallbackList, XtNxtRemoveCallback, 390 XtCXtToolkitError, 391 "Cannot find callback list in XtRemoveCallbacks", NULL, 392 NULL); 393 UNLOCK_APP(app); 394 return; 395 } 396 397 icl = *callbacks; 398 if (!icl) { 399 UNLOCK_APP(app); 400 return; 401 } 402 403 i = icl->count; 404 cl = ToList(icl); 405 if (icl->call_state) { 406 icl->call_state |= _XtCBFreeAfterCalling; 407 icl = 408 (InternalCallbackList) 409 __XtMalloc((Cardinal) 410 (sizeof(InternalCallbackRec) + 411 sizeof(XtCallbackRec) * (size_t) i)); 412 icl->count = (unsigned short) i; 413 icl->call_state = 0; 414 } 415 ccl = ToList(icl); 416 while (--i >= 0) { 417 *ccl++ = *cl; 418 for (rcl = xtcallbacks; rcl->callback; rcl++) { 419 if (cl->callback == rcl->callback && cl->closure == rcl->closure) { 420 ccl--; 421 icl->count--; 422 break; 423 } 424 } 425 cl++; 426 } 427 if (icl->count) { 428 icl = (InternalCallbackList) 429 XtRealloc((char *) icl, (Cardinal) (sizeof(InternalCallbackRec) + 430 sizeof(XtCallbackRec) * 431 icl->count)); 432 icl->is_padded = 0; 433 *callbacks = icl; 434 } 435 else { 436 XtFree((char *) icl); 437 *callbacks = NULL; 438 } 439 hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); 440 if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) { 441 XtChangeHookDataRec call_data; 442 443 call_data.type = XtHremoveCallbacks; 444 call_data.widget = widget; 445 call_data.event_data = (XtPointer) name; 446 XtCallCallbackList(hookobj, 447 ((HookObject) hookobj)->hooks.changehook_callbacks, 448 (XtPointer) &call_data); 449 } 450 UNLOCK_APP(app); 451} /* XtRemoveCallbacks */ 452 453void 454_XtRemoveAllCallbacks(InternalCallbackList *callbacks) 455{ 456 register InternalCallbackList icl = *callbacks; 457 458 if (icl) { 459 if (icl->call_state) 460 icl->call_state |= _XtCBFreeAfterCalling; 461 else 462 XtFree((char *) icl); 463 *callbacks = NULL; 464 } 465} /* _XtRemoveAllCallbacks */ 466 467void 468XtRemoveAllCallbacks(Widget widget, _Xconst char *name) 469{ 470 InternalCallbackList *callbacks; 471 Widget hookobj; 472 XtAppContext app = XtWidgetToApplicationContext(widget); 473 474 LOCK_APP(app); 475 callbacks = FetchInternalList(widget, name); 476 if (!callbacks) { 477 XtAppWarningMsg(app, 478 XtNinvalidCallbackList, XtNxtRemoveAllCallback, 479 XtCXtToolkitError, 480 "Cannot find callback list in XtRemoveAllCallbacks", 481 NULL, NULL); 482 UNLOCK_APP(app); 483 return; 484 } 485 _XtRemoveAllCallbacks(callbacks); 486 hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); 487 if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) { 488 XtChangeHookDataRec call_data; 489 490 call_data.type = XtHremoveAllCallbacks; 491 call_data.widget = widget; 492 call_data.event_data = (XtPointer) name; 493 XtCallCallbackList(hookobj, 494 ((HookObject) hookobj)->hooks.changehook_callbacks, 495 (XtPointer) &call_data); 496 } 497 UNLOCK_APP(app); 498} /* XtRemoveAllCallbacks */ 499 500InternalCallbackList 501_XtCompileCallbackList(XtCallbackList xtcallbacks) 502{ 503 register int n; 504 register XtCallbackList xtcl, cl; 505 register InternalCallbackList callbacks; 506 507 for (n = 0, xtcl = xtcallbacks; xtcl->callback; n++, xtcl++) { 508 }; 509 if (n == 0) 510 return (InternalCallbackList) NULL; 511 512 callbacks = 513 (InternalCallbackList) 514 __XtMalloc((Cardinal) 515 (sizeof(InternalCallbackRec) + 516 sizeof(XtCallbackRec) * (size_t) n)); 517 callbacks->count = (unsigned short) n; 518 callbacks->is_padded = 0; 519 callbacks->call_state = 0; 520 cl = ToList(callbacks); 521 while (--n >= 0) 522 *cl++ = *xtcallbacks++; 523 return (callbacks); 524} /* _XtCompileCallbackList */ 525 526XtCallbackList 527_XtGetCallbackList(InternalCallbackList *callbacks) 528{ 529 int i; 530 InternalCallbackList icl; 531 XtCallbackList cl; 532 533 icl = *callbacks; 534 if (!icl) { 535 static XtCallbackRec emptyList[1] = { {NULL, NULL} }; 536 return (XtCallbackList) emptyList; 537 } 538 if (icl->is_padded) 539 return ToList(icl); 540 i = icl->count; 541 if (icl->call_state) { 542 XtCallbackList ocl; 543 544 icl->call_state |= _XtCBFreeAfterCalling; 545 ocl = ToList(icl); 546 icl = (InternalCallbackList) 547 __XtMalloc((Cardinal) 548 (sizeof(InternalCallbackRec) + 549 sizeof(XtCallbackRec) * (size_t) (i + 1))); 550 icl->count = (unsigned short) i; 551 icl->call_state = 0; 552 cl = ToList(icl); 553 while (--i >= 0) 554 *cl++ = *ocl++; 555 } 556 else { 557 icl = (InternalCallbackList) 558 XtRealloc((char *) icl, (Cardinal) (sizeof(InternalCallbackRec) 559 + sizeof(XtCallbackRec) 560 * (size_t) (i + 1))); 561 cl = ToList(icl) + i; 562 } 563 icl->is_padded = 1; 564 cl->callback = (XtCallbackProc) NULL; 565 cl->closure = NULL; 566 *callbacks = icl; 567 return ToList(icl); 568} 569 570void 571XtCallCallbacks(Widget widget, 572 _Xconst char *name, 573 XtPointer call_data) 574{ 575 InternalCallbackList *callbacks; 576 InternalCallbackList icl; 577 XtCallbackList cl; 578 int i; 579 char ostate; 580 XtAppContext app = XtWidgetToApplicationContext(widget); 581 582 LOCK_APP(app); 583 callbacks = FetchInternalList(widget, name); 584 if (!callbacks) { 585 XtAppWarningMsg(app, 586 XtNinvalidCallbackList, XtNxtCallCallback, 587 XtCXtToolkitError, 588 "Cannot find callback list in XtCallCallbacks", NULL, 589 NULL); 590 UNLOCK_APP(app); 591 return; 592 } 593 594 icl = *callbacks; 595 if (!icl) { 596 UNLOCK_APP(app); 597 return; 598 } 599 cl = ToList(icl); 600 if (icl->count == 1) { 601 (*cl->callback) (widget, cl->closure, call_data); 602 UNLOCK_APP(app); 603 return; 604 } 605 ostate = icl->call_state; 606 icl->call_state = _XtCBCalling; 607 for (i = icl->count; --i >= 0; cl++) 608 (*cl->callback) (widget, cl->closure, call_data); 609 if (ostate) 610 icl->call_state |= ostate; 611 else if (icl->call_state & _XtCBFreeAfterCalling) 612 XtFree((char *) icl); 613 else 614 icl->call_state = ostate; 615 UNLOCK_APP(app); 616} /* XtCallCallbacks */ 617 618XtCallbackStatus 619XtHasCallbacks(Widget widget, 620 _Xconst char *callback_name) 621{ 622 InternalCallbackList *callbacks; 623 XtCallbackStatus retval = XtCallbackHasSome; 624 625 WIDGET_TO_APPCON(widget); 626 627 LOCK_APP(app); 628 callbacks = FetchInternalList(widget, callback_name); 629 if (!callbacks) 630 retval = XtCallbackNoList; 631 else if (!*callbacks) 632 retval = XtCallbackHasNone; 633 UNLOCK_APP(app); 634 return retval; 635} /* XtHasCallbacks */ 636 637void 638XtCallCallbackList(Widget widget, 639 XtCallbackList callbacks, 640 XtPointer call_data) 641{ 642 register InternalCallbackList icl; 643 register XtCallbackList cl; 644 register int i; 645 char ostate; 646 647 WIDGET_TO_APPCON(widget); 648 649 LOCK_APP(app); 650 if (!callbacks) { 651 UNLOCK_APP(app); 652 return; 653 } 654 icl = (InternalCallbackList) callbacks; 655 cl = ToList(icl); 656 if (icl->count == 1) { 657 (*cl->callback) (widget, cl->closure, call_data); 658 UNLOCK_APP(app); 659 return; 660 } 661 ostate = icl->call_state; 662 icl->call_state = _XtCBCalling; 663 for (i = icl->count; --i >= 0; cl++) 664 (*cl->callback) (widget, cl->closure, call_data); 665 if (ostate) 666 icl->call_state |= ostate; 667 else if (icl->call_state & _XtCBFreeAfterCalling) 668 XtFree((char *) icl); 669 else 670 icl->call_state = 0; 671 UNLOCK_APP(app); 672} /* XtCallCallbackList */ 673 674void 675_XtPeekCallback(Widget widget _X_UNUSED, 676 XtCallbackList callbacks, 677 XtCallbackProc *callback, 678 XtPointer *closure) 679{ 680 register InternalCallbackList icl = (InternalCallbackList) callbacks; 681 register XtCallbackList cl; 682 683 if (!callbacks) { 684 *callback = (XtCallbackProc) NULL; 685 return; 686 } 687 cl = ToList(icl); 688 *callback = cl->callback; 689 *closure = cl->closure; 690 return; 691} 692 693void 694_XtCallConditionalCallbackList(Widget widget, 695 XtCallbackList callbacks, 696 XtPointer call_data, 697 _XtConditionProc cond_proc) 698{ 699 register InternalCallbackList icl; 700 register XtCallbackList cl; 701 register int i; 702 char ostate; 703 704 WIDGET_TO_APPCON(widget); 705 706 LOCK_APP(app); 707 if (!callbacks) { 708 UNLOCK_APP(app); 709 return; 710 } 711 icl = (InternalCallbackList) callbacks; 712 cl = ToList(icl); 713 if (icl->count == 1) { 714 (*cl->callback) (widget, cl->closure, call_data); 715 (void) (*cond_proc) (call_data); 716 UNLOCK_APP(app); 717 return; 718 } 719 ostate = icl->call_state; 720 icl->call_state = _XtCBCalling; 721 for (i = icl->count; --i >= 0; cl++) { 722 (*cl->callback) (widget, cl->closure, call_data); 723 if (!(*cond_proc) (call_data)) 724 break; 725 } 726 if (ostate) 727 icl->call_state |= ostate; 728 else if (icl->call_state & _XtCBFreeAfterCalling) 729 XtFree((char *) icl); 730 else 731 icl->call_state = 0; 732 UNLOCK_APP(app); 733} 734