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