home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / Xt / TMprint.c.orig < prev    next >
Encoding:
Text File  |  1991-06-26  |  22.4 KB  |  822 lines

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