home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / Xt / TMprint.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  23.0 KB  |  842 lines

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