TMprint.c revision 1477040f
1/* $Xorg: TMprint.c,v 1.4 2001/02/09 02:03:58 xorgcvs Exp $ */ 2 3/*********************************************************** 4Copyright 1993 Sun Microsystems, Inc. All rights reserved. 5 6Permission is hereby granted, free of charge, to any person obtaining a 7copy of this software and associated documentation files (the "Software"), 8to deal in the Software without restriction, including without limitation 9the rights to use, copy, modify, merge, publish, distribute, sublicense, 10and/or sell copies of the Software, and to permit persons to whom the 11Software is furnished to do so, subject to the following conditions: 12 13The above copyright notice and this permission notice (including the next 14paragraph) shall be included in all copies or substantial portions of the 15Software. 16 17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23DEALINGS IN THE SOFTWARE. 24 25Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 26 27 All Rights Reserved 28 29Permission to use, copy, modify, and distribute this software and its 30documentation for any purpose and without fee is hereby granted, 31provided that the above copyright notice appear in all copies and that 32both that copyright notice and this permission notice appear in 33supporting documentation, and that the name of Digital not be 34used in advertising or publicity pertaining to distribution of the 35software without specific, written prior permission. 36 37DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 39DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 43SOFTWARE. 44 45******************************************************************/ 46 47/* 48 49Copyright 1987, 1988, 1998 The Open Group 50 51Permission to use, copy, modify, distribute, and sell this software and its 52documentation for any purpose is hereby granted without fee, provided that 53the above copyright notice appear in all copies and that both that 54copyright notice and this permission notice appear in supporting 55documentation. 56 57The above copyright notice and this permission notice shall be included in 58all copies or substantial portions of the Software. 59 60THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 61IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 62FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 63OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 64AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 65CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 66 67Except as contained in this notice, the name of The Open Group shall not be 68used in advertising or otherwise to promote the sale, use or other dealings 69in this Software without prior written authorization from The Open Group. 70 71*/ 72/* $XFree86: xc/lib/Xt/TMprint.c,v 1.6 2001/12/14 19:56:31 dawes Exp $ */ 73 74/*LINTLIBRARY*/ 75#ifdef HAVE_CONFIG_H 76#include <config.h> 77#endif 78#include "IntrinsicI.h" 79#include <stdio.h> 80 81typedef struct _TMStringBufRec{ 82 String start; 83 String current; 84 Cardinal max; 85}TMStringBufRec, *TMStringBuf; 86 87 88#define STR_THRESHOLD 25 89#define STR_INCAMOUNT 100 90#define CHECK_STR_OVERFLOW(sb) \ 91if (sb->current - sb->start > (int)sb->max - STR_THRESHOLD) \ 92{ String old = sb->start; \ 93 sb->start = XtRealloc(old, (Cardinal)(sb->max += STR_INCAMOUNT)); \ 94 sb->current = sb->current - old + sb->start; \ 95} 96 97#define ExpandForChars(sb, nchars ) \ 98 if ((unsigned)(sb->current - sb->start) > sb->max - STR_THRESHOLD - nchars) { \ 99 String old = sb->start; \ 100 sb->start = XtRealloc(old, \ 101 (Cardinal)(sb->max += STR_INCAMOUNT + nchars)); \ 102 sb->current = sb->current - old + sb->start; \ 103 } 104 105#define ExpandToFit(sb, more) \ 106{ \ 107 size_t l = strlen(more); \ 108 ExpandForChars(sb, l); \ 109 } 110 111static void PrintModifiers( 112 TMStringBuf sb, 113 unsigned long mask, unsigned long mod) 114{ 115 Boolean notfirst = False; 116 CHECK_STR_OVERFLOW(sb); 117 118 if (mask == ~0UL && mod == 0) { 119 *sb->current++ = '!'; 120 *sb->current = '\0'; 121 return; 122 } 123 124#define PRINTMOD(modmask,modstring) \ 125 if (mask & modmask) { \ 126 if (! (mod & modmask)) { \ 127 *sb->current++ = '~'; \ 128 notfirst = True; \ 129 } \ 130 else if (notfirst) \ 131 *sb->current++ = ' '; \ 132 else notfirst = True; \ 133 strcpy(sb->current, modstring); \ 134 sb->current += strlen(sb->current); \ 135 } 136 137 PRINTMOD(ShiftMask, "Shift"); 138 PRINTMOD(ControlMask, "Ctrl"); /* name is not CtrlMask... */ 139 PRINTMOD(LockMask, "Lock"); 140 PRINTMOD(Mod1Mask, "Mod1"); 141 CHECK_STR_OVERFLOW(sb); 142 PRINTMOD(Mod2Mask, "Mod2"); 143 PRINTMOD(Mod3Mask, "Mod3"); 144 PRINTMOD(Mod4Mask, "Mod4"); 145 PRINTMOD(Mod5Mask, "Mod5"); 146 CHECK_STR_OVERFLOW(sb); 147 PRINTMOD(Button1Mask, "Button1"); 148 PRINTMOD(Button2Mask, "Button2"); 149 PRINTMOD(Button3Mask, "Button3"); 150 CHECK_STR_OVERFLOW(sb); 151 PRINTMOD(Button4Mask, "Button4"); 152 PRINTMOD(Button5Mask, "Button5"); 153 154#undef PRINTMOD 155} 156 157static void PrintEventType( 158 TMStringBuf sb, 159 unsigned long event) 160{ 161 CHECK_STR_OVERFLOW(sb); 162 switch (event) { 163#define PRINTEVENT(event, name) case event: (void) strcpy(sb->current, name); break; 164 PRINTEVENT(KeyPress, "<KeyPress>") 165 PRINTEVENT(KeyRelease, "<KeyRelease>") 166 PRINTEVENT(ButtonPress, "<ButtonPress>") 167 PRINTEVENT(ButtonRelease, "<ButtonRelease>") 168 PRINTEVENT(MotionNotify, "<MotionNotify>") 169 PRINTEVENT(EnterNotify, "<EnterNotify>") 170 PRINTEVENT(LeaveNotify, "<LeaveNotify>") 171 PRINTEVENT(FocusIn, "<FocusIn>") 172 PRINTEVENT(FocusOut, "<FocusOut>") 173 PRINTEVENT(KeymapNotify, "<KeymapNotify>") 174 PRINTEVENT(Expose, "<Expose>") 175 PRINTEVENT(GraphicsExpose, "<GraphicsExpose>") 176 PRINTEVENT(NoExpose, "<NoExpose>") 177 PRINTEVENT(VisibilityNotify, "<VisibilityNotify>") 178 PRINTEVENT(CreateNotify, "<CreateNotify>") 179 PRINTEVENT(DestroyNotify, "<DestroyNotify>") 180 PRINTEVENT(UnmapNotify, "<UnmapNotify>") 181 PRINTEVENT(MapNotify, "<MapNotify>") 182 PRINTEVENT(MapRequest, "<MapRequest>") 183 PRINTEVENT(ReparentNotify, "<ReparentNotify>") 184 PRINTEVENT(ConfigureNotify, "<ConfigureNotify>") 185 PRINTEVENT(ConfigureRequest, "<ConfigureRequest>") 186 PRINTEVENT(GravityNotify, "<GravityNotify>") 187 PRINTEVENT(ResizeRequest, "<ResizeRequest>") 188 PRINTEVENT(CirculateNotify, "<CirculateNotify>") 189 PRINTEVENT(CirculateRequest, "<CirculateRequest>") 190 PRINTEVENT(PropertyNotify, "<PropertyNotify>") 191 PRINTEVENT(SelectionClear, "<SelectionClear>") 192 PRINTEVENT(SelectionRequest, "<SelectionRequest>") 193 PRINTEVENT(SelectionNotify, "<SelectionNotify>") 194 PRINTEVENT(ColormapNotify, "<ColormapNotify>") 195 PRINTEVENT(ClientMessage, "<ClientMessage>") 196 case _XtEventTimerEventType: 197 (void) strcpy(sb->current,"<EventTimer>"); 198 break; 199 default: 200 (void) sprintf(sb->current, "<0x%x>", (int) event); 201#undef PRINTEVENT 202 } 203 sb->current += strlen(sb->current); 204} 205 206static void PrintCode( 207 TMStringBuf sb, 208 unsigned long mask, unsigned long code) 209{ 210 CHECK_STR_OVERFLOW(sb); 211 if (mask != 0) { 212 if (mask != ~0UL) 213 (void) sprintf(sb->current, "0x%lx:0x%lx", mask, code); 214 else (void) sprintf(sb->current, /*"0x%lx"*/ "%d", (unsigned)code); 215 sb->current += strlen(sb->current); 216 } 217} 218 219static void PrintKeysym( 220 TMStringBuf sb, 221 KeySym keysym) 222{ 223 String keysymName; 224 225 if (keysym == 0) return; 226 227 CHECK_STR_OVERFLOW(sb); 228 keysymName = XKeysymToString(keysym); 229 if (keysymName == NULL) 230 PrintCode(sb,~0UL,(unsigned long)keysym); 231 else { 232 ExpandToFit(sb, keysymName); 233 strcpy(sb->current, keysymName); 234 sb->current += strlen(sb->current); 235 } 236} 237 238static void PrintAtom( 239 TMStringBuf sb, 240 Display *dpy, 241 Atom atom) 242{ 243 String atomName; 244 245 if (atom == 0) return; 246 247 atomName = (dpy ? XGetAtomName(dpy, atom) : NULL); 248 249 if (! atomName) 250 PrintCode(sb,~0UL,(unsigned long)atom); 251 else { 252 ExpandToFit( sb, atomName ); 253 strcpy(sb->current, atomName); 254 sb->current += strlen(sb->current); 255 XFree(atomName); 256 } 257} 258 259static void PrintLateModifiers( 260 TMStringBuf sb, 261 LateBindingsPtr lateModifiers) 262{ 263 for (; lateModifiers->keysym; lateModifiers++) { 264 CHECK_STR_OVERFLOW(sb); 265 if (lateModifiers->knot) { 266 *sb->current++ = '~'; 267 } else { 268 *sb->current++ = ' '; 269 } 270 strcpy(sb->current, XKeysymToString(lateModifiers->keysym)); 271 sb->current += strlen(sb->current); 272 if (lateModifiers->pair) { 273 *(sb->current -= 2) = '\0'; /* strip "_L" */ 274 lateModifiers++; /* skip _R keysym */ 275 } 276 } 277} 278 279static void PrintEvent( 280 TMStringBuf sb, 281 register TMTypeMatch typeMatch, 282 register TMModifierMatch modMatch, 283 Display *dpy) 284{ 285 if (modMatch->standard) *sb->current++ = ':'; 286 287 PrintModifiers(sb, modMatch->modifierMask, modMatch->modifiers); 288 if (modMatch->lateModifiers != NULL) 289 PrintLateModifiers(sb, modMatch->lateModifiers); 290 PrintEventType(sb, typeMatch->eventType); 291 switch (typeMatch->eventType) { 292 case KeyPress: 293 case KeyRelease: 294 PrintKeysym(sb, (KeySym)typeMatch->eventCode); 295 break; 296 297 case PropertyNotify: 298 case SelectionClear: 299 case SelectionRequest: 300 case SelectionNotify: 301 case ClientMessage: 302 PrintAtom(sb, dpy, (Atom)typeMatch->eventCode); 303 break; 304 305 default: 306 PrintCode(sb, typeMatch->eventCodeMask, typeMatch->eventCode); 307 } 308} 309 310static void PrintParams( 311 TMStringBuf sb, 312 String *params, 313 Cardinal num_params) 314{ 315 register Cardinal i; 316 for (i = 0; i<num_params; i++) { 317 ExpandToFit( sb, params[i] ); 318 if (i != 0) { 319 *sb->current++ = ','; 320 *sb->current++ = ' '; 321 } 322 *sb->current++ = '"'; 323 strcpy(sb->current, params[i]); 324 sb->current += strlen(sb->current); 325 *sb->current++ = '"'; 326 } 327 *sb->current = '\0'; 328} 329 330static void PrintActions( 331 TMStringBuf sb, 332 register ActionPtr actions, 333 XrmQuark *quarkTbl, 334 Widget accelWidget) 335{ 336 while (actions != NULL) { 337 String proc; 338 339 *sb->current++ = ' '; 340 341 if (accelWidget) { 342 /* accelerator */ 343 String name = XtName(accelWidget); 344 int nameLen = strlen(name); 345 ExpandForChars(sb, nameLen ); 346 XtMemmove(sb->current, name, nameLen ); 347 sb->current += nameLen; 348 *sb->current++ = '`'; 349 } 350 proc = XrmQuarkToString(quarkTbl[actions->idx]); 351 ExpandToFit( sb, proc ); 352 strcpy(sb->current, proc); 353 sb->current += strlen(proc); 354 *sb->current++ = '('; 355 PrintParams(sb, actions->params, actions->num_params); 356 *sb->current++ = ')'; 357 actions = actions->next; 358 } 359 *sb->current = '\0'; 360} 361 362static Boolean LookAheadForCycleOrMulticlick( 363 register StatePtr state, 364 StatePtr *state_return, /* state to print, usually startState */ 365 int *countP, 366 StatePtr *nextLevelP) 367{ 368 int repeatCount = 0; 369 StatePtr startState = state; 370 Boolean isCycle = startState->isCycleEnd; 371 TMTypeMatch sTypeMatch; 372 TMModifierMatch sModMatch; 373 374 LOCK_PROCESS; 375 sTypeMatch = TMGetTypeMatch(startState->typeIndex); 376 sModMatch = TMGetModifierMatch(startState->modIndex); 377 378 *state_return = startState; 379 380 for (state = state->nextLevel; state != NULL; state = state->nextLevel) { 381 TMTypeMatch typeMatch = TMGetTypeMatch(state->typeIndex); 382 TMModifierMatch modMatch = TMGetModifierMatch(state->modIndex); 383 384 /* try to pick up the correct state with actions, to be printed */ 385 /* This is to accommodate <ButtonUp>(2+), for example */ 386 if (state->isCycleStart) 387 *state_return = state; 388 389 if (state->isCycleEnd) { 390 *countP = repeatCount; 391 UNLOCK_PROCESS; 392 return True; 393 } 394 if ((startState->typeIndex == state->typeIndex) && 395 (startState->modIndex == state->modIndex)) { 396 repeatCount++; 397 *nextLevelP = state; 398 } 399 else if (typeMatch->eventType == _XtEventTimerEventType) 400 continue; 401 else /* not same event as starting event and not timer */ { 402 unsigned int type = sTypeMatch->eventType; 403 unsigned int t = typeMatch->eventType; 404 if ( (type == ButtonPress && t != ButtonRelease) 405 || (type == ButtonRelease && t != ButtonPress) 406 || (type == KeyPress && t != KeyRelease) 407 || (type == KeyRelease && t != KeyPress) 408 || typeMatch->eventCode != sTypeMatch->eventCode 409 || modMatch->modifiers != sModMatch->modifiers 410 || modMatch->modifierMask != sModMatch->modifierMask 411 || modMatch->lateModifiers != sModMatch->lateModifiers 412 || typeMatch->eventCodeMask != sTypeMatch->eventCodeMask 413 || typeMatch->matchEvent != sTypeMatch->matchEvent 414 || modMatch->standard != sModMatch->standard) 415 /* not inverse of starting event, either */ 416 break; 417 } 418 } 419 *countP = repeatCount; 420 UNLOCK_PROCESS; 421 return isCycle; 422} 423 424static void PrintComplexState( 425 TMStringBuf sb, 426 Boolean includeRHS, 427 StatePtr state, 428 TMStateTree stateTree, 429 Widget accelWidget, 430 Display *dpy) 431{ 432 int clickCount = 0; 433 Boolean cycle; 434 StatePtr nextLevel = NULL; 435 StatePtr triggerState = NULL; 436 437 /* print the current state */ 438 if (! state) return; 439 LOCK_PROCESS; 440 cycle = LookAheadForCycleOrMulticlick(state, &triggerState, &clickCount, 441 &nextLevel); 442 443 PrintEvent(sb, TMGetTypeMatch(triggerState->typeIndex), 444 TMGetModifierMatch(triggerState->modIndex), dpy); 445 446 if (cycle || clickCount) { 447 if (clickCount) 448 sprintf(sb->current, "(%d%s)", clickCount+1, cycle ? "+" : ""); 449 else 450 (void) strncpy(sb->current, "(+)", 4); 451 sb->current += strlen(sb->current); 452 if (! state->actions && nextLevel) 453 state = nextLevel; 454 while (! state->actions && ! state->isCycleEnd) 455 state = state->nextLevel; /* should be trigger state */ 456 } 457 458 if (state->actions) { 459 if (includeRHS) { 460 CHECK_STR_OVERFLOW(sb); 461 *sb->current++ = ':'; 462 PrintActions(sb, 463 state->actions, 464 ((TMSimpleStateTree)stateTree)->quarkTbl, 465 accelWidget); 466 *sb->current++ = '\n'; 467 } 468 } 469 else { 470 if (state->nextLevel && !cycle && !clickCount) 471 *sb->current++ = ','; 472 else { 473 /* no actions are attached to this production */ 474 *sb->current++ = ':'; 475 *sb->current++ = '\n'; 476 } 477 } 478 *sb->current = '\0'; 479 480 /* print succeeding states */ 481 if (state->nextLevel && !cycle && !clickCount) 482 PrintComplexState(sb, includeRHS, state->nextLevel, 483 stateTree, accelWidget, dpy); 484 UNLOCK_PROCESS; 485} 486 487typedef struct{ 488 TMShortCard tIndex; 489 TMShortCard bIndex; 490}PrintRec, *Print; 491 492static int FindNextMatch( 493 PrintRec *printData, 494 TMShortCard numPrints, 495 XtTranslations xlations, 496 TMBranchHead branchHead, 497 StatePtr nextLevel, 498 TMShortCard startIndex) 499{ 500 TMShortCard i; 501 TMComplexStateTree stateTree; 502 StatePtr currState, candState; 503 Boolean noMatch = True; 504 TMBranchHead prBranchHead; 505 506 for (i = startIndex; noMatch && i < numPrints; i++) { 507 stateTree = (TMComplexStateTree) 508 xlations->stateTreeTbl[printData[i].tIndex]; 509 prBranchHead = 510 &(stateTree->branchHeadTbl[printData[i].bIndex]); 511 512 if ((prBranchHead->typeIndex == branchHead->typeIndex) && 513 (prBranchHead->modIndex == branchHead->modIndex)) { 514 if (prBranchHead->isSimple) { 515 if (!nextLevel) 516 return i; 517 } 518 else { 519 currState = TMComplexBranchHead(stateTree, prBranchHead); 520 currState = currState->nextLevel; 521 candState = nextLevel; 522 for (; 523 ((currState && !currState->isCycleEnd) && 524 (candState && !candState->isCycleEnd)); 525 currState = currState->nextLevel, 526 candState = candState->nextLevel) { 527 if ((currState->typeIndex != candState->typeIndex) || 528 (currState->modIndex != candState->modIndex)) 529 break; 530 } 531 if (candState == currState) { 532 return i; 533 } 534 } 535 } 536 } 537 return TM_NO_MATCH; 538} 539 540static void ProcessLaterMatches( 541 PrintRec *printData, 542 XtTranslations xlations, 543 TMShortCard tIndex, 544 int bIndex, 545 TMShortCard *numPrintsRtn) 546{ 547 TMComplexStateTree stateTree; 548 int i, j; 549 TMBranchHead branchHead, matchBranch = NULL; 550 551 for (i = tIndex; i < (int)xlations->numStateTrees; i++) { 552 stateTree = (TMComplexStateTree)xlations->stateTreeTbl[i]; 553 if (i == tIndex) { 554 matchBranch = &stateTree->branchHeadTbl[bIndex]; 555 j = bIndex+1; 556 } 557 else j = 0; 558 for (branchHead = &stateTree->branchHeadTbl[j]; 559 j < (int)stateTree->numBranchHeads; 560 j++, branchHead++) { 561 if ((branchHead->typeIndex == matchBranch->typeIndex) && 562 (branchHead->modIndex == matchBranch->modIndex)) { 563 StatePtr state; 564 if (!branchHead->isSimple) 565 state = TMComplexBranchHead(stateTree, branchHead); 566 else 567 state = NULL; 568 if ((!branchHead->isSimple || branchHead->hasActions) && 569 (FindNextMatch(printData, 570 *numPrintsRtn, 571 xlations, 572 branchHead, 573 (state ? state->nextLevel : NULL), 574 0) == TM_NO_MATCH)) { 575 printData[*numPrintsRtn].tIndex = i; 576 printData[*numPrintsRtn].bIndex = j; 577 (*numPrintsRtn)++; 578 } 579 } 580 } 581 } 582} 583 584static void ProcessStateTree( 585 PrintRec *printData, 586 XtTranslations xlations, 587 TMShortCard tIndex, 588 TMShortCard *numPrintsRtn) 589{ 590 TMComplexStateTree stateTree; 591 int i; 592 TMBranchHead branchHead; 593 594 stateTree = (TMComplexStateTree)xlations->stateTreeTbl[tIndex]; 595 596 for (i = 0, branchHead = stateTree->branchHeadTbl; 597 i < (int)stateTree->numBranchHeads; 598 i++, branchHead++) { 599 StatePtr state; 600 if (!branchHead->isSimple) 601 state = TMComplexBranchHead(stateTree, branchHead); 602 else 603 state = NULL; 604 if (FindNextMatch(printData, *numPrintsRtn, xlations, branchHead, 605 (state ? state->nextLevel : NULL), 0) 606 == TM_NO_MATCH) { 607 if (!branchHead->isSimple || branchHead->hasActions) { 608 printData[*numPrintsRtn].tIndex = tIndex; 609 printData[*numPrintsRtn].bIndex = i; 610 (*numPrintsRtn)++; 611 } 612 LOCK_PROCESS; 613 if (_XtGlobalTM.newMatchSemantics == False) 614 ProcessLaterMatches(printData, 615 xlations, 616 tIndex, 617 i, 618 numPrintsRtn); 619 UNLOCK_PROCESS; 620 } 621 } 622} 623 624static void PrintState( 625 TMStringBuf sb, 626 TMStateTree tree, 627 TMBranchHead branchHead, 628 Boolean includeRHS, 629 Widget accelWidget, 630 Display *dpy) 631{ 632 TMComplexStateTree stateTree = (TMComplexStateTree)tree; 633 LOCK_PROCESS; 634 if (branchHead->isSimple) { 635 PrintEvent(sb, 636 TMGetTypeMatch(branchHead->typeIndex), 637 TMGetModifierMatch(branchHead->modIndex), 638 dpy); 639 if (includeRHS) { 640 ActionRec actRec; 641 642 CHECK_STR_OVERFLOW(sb); 643 *sb->current++ = ':'; 644 actRec.idx = TMBranchMore(branchHead); 645 actRec.num_params = 0; 646 actRec.params = NULL; 647 actRec.next = NULL; 648 PrintActions(sb, 649 &actRec, 650 stateTree->quarkTbl, 651 accelWidget); 652 *sb->current++ = '\n'; 653 } 654 else 655 *sb->current++ = ','; 656#ifdef TRACE_TM 657 if (!branchHead->hasActions) 658 printf(" !! no actions !! "); 659#endif 660 } 661 else { /* it's a complex branchHead */ 662 StatePtr state = TMComplexBranchHead(stateTree, branchHead); 663 PrintComplexState(sb, 664 includeRHS, 665 state, 666 tree, 667 accelWidget, 668 (Display *)NULL); 669 } 670 *sb->current = '\0'; 671 UNLOCK_PROCESS; 672} 673 674String _XtPrintXlations( 675 Widget w, 676 XtTranslations xlations, 677 Widget accelWidget, 678 _XtBoolean includeRHS) 679{ 680 register Cardinal i; 681#define STACKPRINTSIZE 250 682 PrintRec stackPrints[STACKPRINTSIZE]; 683 PrintRec *prints; 684 TMStringBufRec sbRec, *sb = &sbRec; 685 TMShortCard numPrints, maxPrints; 686#ifdef TRACE_TM 687 TMBindData bindData = (TMBindData)w->core.tm.proc_table; 688 Boolean hasAccel = (accelWidget ? True : False); 689#endif /* TRACE_TM */ 690 if (xlations == NULL) return NULL; 691 692 sb->current = sb->start = __XtMalloc((Cardinal)1000); 693 sb->max = 1000; 694 maxPrints = 0; 695 for (i = 0; i < xlations->numStateTrees; i++) 696 maxPrints += 697 ((TMSimpleStateTree)(xlations->stateTreeTbl[i]))->numBranchHeads; 698 prints = (PrintRec *) 699 XtStackAlloc(maxPrints * sizeof(PrintRec), stackPrints); 700 701 numPrints = 0; 702 for (i = 0; i < xlations->numStateTrees; i++) 703 ProcessStateTree(prints, xlations, i, &numPrints); 704 705 for (i = 0; i < numPrints; i++) { 706 TMSimpleStateTree stateTree = (TMSimpleStateTree) 707 xlations->stateTreeTbl[prints[i].tIndex]; 708 TMBranchHead branchHead = 709 &stateTree->branchHeadTbl[prints[i].bIndex]; 710#ifdef TRACE_TM 711 TMComplexBindProcs complexBindProcs; 712 713 if (hasAccel == False) { 714 accelWidget = NULL; 715 if (bindData->simple.isComplex) { 716 complexBindProcs = TMGetComplexBindEntry(bindData, 0); 717 accelWidget = complexBindProcs[prints[i].tIndex].widget; 718 } 719 } 720#endif /* TRACE_TM */ 721 PrintState(sb, (TMStateTree)stateTree, branchHead, 722 includeRHS, accelWidget, XtDisplay(w)); 723 } 724 XtStackFree((XtPointer)prints, (XtPointer)stackPrints); 725 return (sb->start); 726} 727 728 729#ifndef NO_MIT_HACKS 730/*ARGSUSED*/ 731void _XtDisplayTranslations( 732 Widget widget, 733 XEvent *event, 734 String *params, 735 Cardinal *num_params) 736{ 737 String xString; 738 739 xString = _XtPrintXlations(widget, 740 widget->core.tm.translations, 741 NULL, 742 True); 743 if (xString) { 744 printf("%s\n",xString); 745 XtFree(xString); 746 } 747} 748 749/*ARGSUSED*/ 750void _XtDisplayAccelerators( 751 Widget widget, 752 XEvent *event, 753 String *params, 754 Cardinal *num_params) 755{ 756 String xString; 757 758 759 xString = _XtPrintXlations(widget, 760 widget->core.accelerators, 761 NULL, 762 True); 763 if (xString) { 764 printf("%s\n",xString); 765 XtFree(xString); 766 } 767} 768 769/*ARGSUSED*/ 770void _XtDisplayInstalledAccelerators( 771 Widget widget, 772 XEvent *event, 773 String *params, 774 Cardinal *num_params) 775{ 776 Widget eventWidget 777 = XtWindowToWidget(event->xany.display, event->xany.window); 778 register Cardinal i; 779 TMStringBufRec sbRec, *sb = &sbRec; 780 XtTranslations xlations; 781#define STACKPRINTSIZE 250 782 PrintRec stackPrints[STACKPRINTSIZE]; 783 PrintRec *prints; 784 TMShortCard numPrints, maxPrints; 785 TMBindData bindData = (TMBindData) eventWidget->core.tm.proc_table; 786 TMComplexBindProcs complexBindProcs; 787 788 if ((eventWidget == NULL) || 789 ((xlations = eventWidget->core.tm.translations) == NULL) || 790 (bindData->simple.isComplex == False)) 791 return; 792 793 sb->current = sb->start = __XtMalloc((Cardinal)1000); 794 sb->start[0] = '\0'; 795 sb->max = 1000; 796 maxPrints = 0; 797 for (i = 0; i < xlations->numStateTrees; i++) 798 maxPrints += 799 ((TMSimpleStateTree)xlations->stateTreeTbl[i])->numBranchHeads; 800 prints = (PrintRec *) 801 XtStackAlloc(maxPrints * sizeof(PrintRec), stackPrints); 802 803 numPrints = 0; 804 805 complexBindProcs = TMGetComplexBindEntry(bindData, 0); 806 for (i = 0; 807 i < xlations->numStateTrees; 808 i++, complexBindProcs++) { 809 if (complexBindProcs->widget) 810 { 811 ProcessStateTree(prints, xlations, i, &numPrints); 812 } 813 } 814 for (i = 0; i < numPrints; i++) { 815 TMSimpleStateTree stateTree = (TMSimpleStateTree) 816 xlations->stateTreeTbl[prints[i].tIndex]; 817 TMBranchHead branchHead = 818 &stateTree->branchHeadTbl[prints[i].bIndex]; 819 820 complexBindProcs = TMGetComplexBindEntry(bindData, 0); 821 822 PrintState(sb, (TMStateTree)stateTree, branchHead, True, 823 complexBindProcs[prints[i].tIndex].widget, 824 XtDisplay(widget)); 825 } 826 XtStackFree((XtPointer)prints, (XtPointer)stackPrints); 827 printf("%s\n", sb->start); 828 XtFree(sb->start); 829} 830#endif /*NO_MIT_HACKS*/ 831 832String _XtPrintActions( 833 register ActionRec *actions, 834 XrmQuark *quarkTbl) 835{ 836 TMStringBufRec sbRec, *sb = &sbRec; 837 838 sb->max = 1000; 839 sb->current = sb->start = __XtMalloc((Cardinal)1000); 840 PrintActions(sb, 841 actions, 842 quarkTbl, 843 (Widget)NULL); 844 return sb->start; 845} 846 847String _XtPrintState( 848 TMStateTree stateTree, 849 TMBranchHead branchHead) 850{ 851 TMStringBufRec sbRec, *sb = &sbRec; 852 853 sb->current = sb->start = __XtMalloc((Cardinal)1000); 854 sb->max = 1000; 855 PrintState(sb, stateTree, branchHead, 856 True, (Widget)NULL, (Display *)NULL); 857 return sb->start; 858} 859 860 861String _XtPrintEventSeq( 862 register EventSeqPtr eventSeq, 863 Display *dpy) 864{ 865 TMStringBufRec sbRec, *sb = &sbRec; 866 TMTypeMatch typeMatch; 867 TMModifierMatch modMatch; 868#define MAXSEQS 100 869 EventSeqPtr eventSeqs[MAXSEQS]; 870 TMShortCard i, j; 871 Boolean cycle = False; 872 873 sb->current = sb->start = __XtMalloc((Cardinal)1000); 874 sb->max = 1000; 875 for (i = 0; 876 i < MAXSEQS && eventSeq != NULL && !cycle; 877 eventSeq = eventSeq->next, i++) 878 { 879 eventSeqs[i] = eventSeq; 880 for (j = 0; j < i && !cycle; j++) 881 if (eventSeqs[j] == eventSeq) 882 cycle = True; 883 } 884 LOCK_PROCESS; 885 for (j = 0; j < i; j++) { 886 typeMatch = 887 TMGetTypeMatch(_XtGetTypeIndex(&eventSeqs[j]->event)); 888 modMatch = 889 TMGetModifierMatch(_XtGetModifierIndex(&eventSeqs[j]->event)); 890 PrintEvent(sb, typeMatch, modMatch, dpy); 891 if (j < i) 892 *sb->current++ = ','; 893 } 894 UNLOCK_PROCESS; 895 return sb->start; 896} 897