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