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