TMprint.c revision 2265a131
1444c061aSmrg/* $Xorg: TMprint.c,v 1.4 2001/02/09 02:03:58 xorgcvs Exp $ */ 2444c061aSmrg 3444c061aSmrg/*********************************************************** 4444c061aSmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts 5444c061aSmrgCopyright 1993 by Sun Microsystems, Inc. Mountain View, CA. 6444c061aSmrg 7444c061aSmrg All Rights Reserved 8444c061aSmrg 9444c061aSmrgPermission to use, copy, modify, and distribute this software and its 10444c061aSmrgdocumentation for any purpose and without fee is hereby granted, 11444c061aSmrgprovided that the above copyright notice appear in all copies and that 12444c061aSmrgboth that copyright notice and this permission notice appear in 13444c061aSmrgsupporting documentation, and that the names of Digital or Sun not be 14444c061aSmrgused in advertising or publicity pertaining to distribution of the 15444c061aSmrgsoftware without specific, written prior permission. 16444c061aSmrg 17444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 18444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 19444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 20444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 21444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 22444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 23444c061aSmrgSOFTWARE. 24444c061aSmrg 25444c061aSmrgSUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 26444c061aSmrgINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- 27444c061aSmrgNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- 28444c061aSmrgABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 29444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 30444c061aSmrgPROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 31444c061aSmrgOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 32444c061aSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 33444c061aSmrg 34444c061aSmrg******************************************************************/ 35444c061aSmrg 36444c061aSmrg/* 37444c061aSmrg 38444c061aSmrgCopyright 1987, 1988, 1998 The Open Group 39444c061aSmrg 40444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its 41444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that 42444c061aSmrgthe above copyright notice appear in all copies and that both that 43444c061aSmrgcopyright notice and this permission notice appear in supporting 44444c061aSmrgdocumentation. 45444c061aSmrg 46444c061aSmrgThe above copyright notice and this permission notice shall be included in 47444c061aSmrgall copies or substantial portions of the Software. 48444c061aSmrg 49444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 50444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 51444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 52444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 53444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 54444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 55444c061aSmrg 56444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be 57444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings 58444c061aSmrgin this Software without prior written authorization from The Open Group. 59444c061aSmrg 60444c061aSmrg*/ 61444c061aSmrg/* $XFree86: xc/lib/Xt/TMprint.c,v 1.6 2001/12/14 19:56:31 dawes Exp $ */ 62444c061aSmrg 63444c061aSmrg/*LINTLIBRARY*/ 64444c061aSmrg#ifdef HAVE_CONFIG_H 65444c061aSmrg#include <config.h> 66444c061aSmrg#endif 67444c061aSmrg#include "IntrinsicI.h" 68444c061aSmrg#include <stdio.h> 69444c061aSmrg 70444c061aSmrgtypedef struct _TMStringBufRec{ 71444c061aSmrg String start; 72444c061aSmrg String current; 73444c061aSmrg Cardinal max; 74444c061aSmrg}TMStringBufRec, *TMStringBuf; 75444c061aSmrg 76444c061aSmrg 77444c061aSmrg#define STR_THRESHOLD 25 78444c061aSmrg#define STR_INCAMOUNT 100 79444c061aSmrg#define CHECK_STR_OVERFLOW(sb) \ 80444c061aSmrgif (sb->current - sb->start > (int)sb->max - STR_THRESHOLD) \ 81444c061aSmrg{ String old = sb->start; \ 82444c061aSmrg sb->start = XtRealloc(old, (Cardinal)(sb->max += STR_INCAMOUNT)); \ 83444c061aSmrg sb->current = sb->current - old + sb->start; \ 84444c061aSmrg} 85444c061aSmrg 86444c061aSmrg#define ExpandForChars(sb, nchars ) \ 87444c061aSmrg if ((unsigned)(sb->current - sb->start) > sb->max - STR_THRESHOLD - nchars) { \ 88444c061aSmrg String old = sb->start; \ 89444c061aSmrg sb->start = XtRealloc(old, \ 90444c061aSmrg (Cardinal)(sb->max += STR_INCAMOUNT + nchars)); \ 91444c061aSmrg sb->current = sb->current - old + sb->start; \ 92444c061aSmrg } 93444c061aSmrg 94444c061aSmrg#define ExpandToFit(sb, more) \ 95444c061aSmrg{ \ 96444c061aSmrg size_t l = strlen(more); \ 97444c061aSmrg ExpandForChars(sb, l); \ 98444c061aSmrg } 99444c061aSmrg 100444c061aSmrgstatic void PrintModifiers( 101444c061aSmrg TMStringBuf sb, 102444c061aSmrg unsigned long mask, unsigned long mod) 103444c061aSmrg{ 104444c061aSmrg Boolean notfirst = False; 105444c061aSmrg CHECK_STR_OVERFLOW(sb); 106444c061aSmrg 107444c061aSmrg if (mask == ~0UL && mod == 0) { 108444c061aSmrg *sb->current++ = '!'; 109444c061aSmrg *sb->current = '\0'; 110444c061aSmrg return; 111444c061aSmrg } 112444c061aSmrg 113444c061aSmrg#define PRINTMOD(modmask,modstring) \ 114444c061aSmrg if (mask & modmask) { \ 115444c061aSmrg if (! (mod & modmask)) { \ 116444c061aSmrg *sb->current++ = '~'; \ 117444c061aSmrg notfirst = True; \ 118444c061aSmrg } \ 119444c061aSmrg else if (notfirst) \ 120444c061aSmrg *sb->current++ = ' '; \ 121444c061aSmrg else notfirst = True; \ 122444c061aSmrg strcpy(sb->current, modstring); \ 123444c061aSmrg sb->current += strlen(sb->current); \ 124444c061aSmrg } 125444c061aSmrg 126444c061aSmrg PRINTMOD(ShiftMask, "Shift"); 127444c061aSmrg PRINTMOD(ControlMask, "Ctrl"); /* name is not CtrlMask... */ 128444c061aSmrg PRINTMOD(LockMask, "Lock"); 129444c061aSmrg PRINTMOD(Mod1Mask, "Mod1"); 130444c061aSmrg CHECK_STR_OVERFLOW(sb); 131444c061aSmrg PRINTMOD(Mod2Mask, "Mod2"); 132444c061aSmrg PRINTMOD(Mod3Mask, "Mod3"); 133444c061aSmrg PRINTMOD(Mod4Mask, "Mod4"); 134444c061aSmrg PRINTMOD(Mod5Mask, "Mod5"); 135444c061aSmrg CHECK_STR_OVERFLOW(sb); 136444c061aSmrg PRINTMOD(Button1Mask, "Button1"); 137444c061aSmrg PRINTMOD(Button2Mask, "Button2"); 138444c061aSmrg PRINTMOD(Button3Mask, "Button3"); 139444c061aSmrg CHECK_STR_OVERFLOW(sb); 140444c061aSmrg PRINTMOD(Button4Mask, "Button4"); 141444c061aSmrg PRINTMOD(Button5Mask, "Button5"); 142444c061aSmrg 143444c061aSmrg#undef PRINTMOD 144444c061aSmrg} 145444c061aSmrg 146444c061aSmrgstatic void PrintEventType( 147444c061aSmrg TMStringBuf sb, 148444c061aSmrg unsigned long event) 149444c061aSmrg{ 150444c061aSmrg CHECK_STR_OVERFLOW(sb); 151444c061aSmrg switch (event) { 152444c061aSmrg#define PRINTEVENT(event, name) case event: (void) strcpy(sb->current, name); break; 153444c061aSmrg PRINTEVENT(KeyPress, "<KeyPress>") 154444c061aSmrg PRINTEVENT(KeyRelease, "<KeyRelease>") 155444c061aSmrg PRINTEVENT(ButtonPress, "<ButtonPress>") 156444c061aSmrg PRINTEVENT(ButtonRelease, "<ButtonRelease>") 157444c061aSmrg PRINTEVENT(MotionNotify, "<MotionNotify>") 158444c061aSmrg PRINTEVENT(EnterNotify, "<EnterNotify>") 159444c061aSmrg PRINTEVENT(LeaveNotify, "<LeaveNotify>") 160444c061aSmrg PRINTEVENT(FocusIn, "<FocusIn>") 161444c061aSmrg PRINTEVENT(FocusOut, "<FocusOut>") 162444c061aSmrg PRINTEVENT(KeymapNotify, "<KeymapNotify>") 163444c061aSmrg PRINTEVENT(Expose, "<Expose>") 164444c061aSmrg PRINTEVENT(GraphicsExpose, "<GraphicsExpose>") 165444c061aSmrg PRINTEVENT(NoExpose, "<NoExpose>") 166444c061aSmrg PRINTEVENT(VisibilityNotify, "<VisibilityNotify>") 167444c061aSmrg PRINTEVENT(CreateNotify, "<CreateNotify>") 168444c061aSmrg PRINTEVENT(DestroyNotify, "<DestroyNotify>") 169444c061aSmrg PRINTEVENT(UnmapNotify, "<UnmapNotify>") 170444c061aSmrg PRINTEVENT(MapNotify, "<MapNotify>") 171444c061aSmrg PRINTEVENT(MapRequest, "<MapRequest>") 172444c061aSmrg PRINTEVENT(ReparentNotify, "<ReparentNotify>") 173444c061aSmrg PRINTEVENT(ConfigureNotify, "<ConfigureNotify>") 174444c061aSmrg PRINTEVENT(ConfigureRequest, "<ConfigureRequest>") 175444c061aSmrg PRINTEVENT(GravityNotify, "<GravityNotify>") 176444c061aSmrg PRINTEVENT(ResizeRequest, "<ResizeRequest>") 177444c061aSmrg PRINTEVENT(CirculateNotify, "<CirculateNotify>") 178444c061aSmrg PRINTEVENT(CirculateRequest, "<CirculateRequest>") 179444c061aSmrg PRINTEVENT(PropertyNotify, "<PropertyNotify>") 180444c061aSmrg PRINTEVENT(SelectionClear, "<SelectionClear>") 181444c061aSmrg PRINTEVENT(SelectionRequest, "<SelectionRequest>") 182444c061aSmrg PRINTEVENT(SelectionNotify, "<SelectionNotify>") 183444c061aSmrg PRINTEVENT(ColormapNotify, "<ColormapNotify>") 184444c061aSmrg PRINTEVENT(ClientMessage, "<ClientMessage>") 185444c061aSmrg case _XtEventTimerEventType: 186444c061aSmrg (void) strcpy(sb->current,"<EventTimer>"); 187444c061aSmrg break; 188444c061aSmrg default: 189444c061aSmrg (void) sprintf(sb->current, "<0x%x>", (int) event); 190444c061aSmrg#undef PRINTEVENT 191444c061aSmrg } 192444c061aSmrg sb->current += strlen(sb->current); 193444c061aSmrg} 194444c061aSmrg 195444c061aSmrgstatic void PrintCode( 196444c061aSmrg TMStringBuf sb, 197444c061aSmrg unsigned long mask, unsigned long code) 198444c061aSmrg{ 199444c061aSmrg CHECK_STR_OVERFLOW(sb); 200444c061aSmrg if (mask != 0) { 201444c061aSmrg if (mask != ~0UL) 202444c061aSmrg (void) sprintf(sb->current, "0x%lx:0x%lx", mask, code); 203444c061aSmrg else (void) sprintf(sb->current, /*"0x%lx"*/ "%d", (unsigned)code); 204444c061aSmrg sb->current += strlen(sb->current); 205444c061aSmrg } 206444c061aSmrg} 207444c061aSmrg 208444c061aSmrgstatic void PrintKeysym( 209444c061aSmrg TMStringBuf sb, 210444c061aSmrg KeySym keysym) 211444c061aSmrg{ 212444c061aSmrg String keysymName; 213444c061aSmrg 214444c061aSmrg if (keysym == 0) return; 215444c061aSmrg 216444c061aSmrg CHECK_STR_OVERFLOW(sb); 217444c061aSmrg keysymName = XKeysymToString(keysym); 218444c061aSmrg if (keysymName == NULL) 219444c061aSmrg PrintCode(sb,~0UL,(unsigned long)keysym); 220444c061aSmrg else { 221444c061aSmrg ExpandToFit(sb, keysymName); 222444c061aSmrg strcpy(sb->current, keysymName); 223444c061aSmrg sb->current += strlen(sb->current); 224444c061aSmrg } 225444c061aSmrg} 226444c061aSmrg 227444c061aSmrgstatic void PrintAtom( 228444c061aSmrg TMStringBuf sb, 229444c061aSmrg Display *dpy, 230444c061aSmrg Atom atom) 231444c061aSmrg{ 232444c061aSmrg String atomName; 233444c061aSmrg 234444c061aSmrg if (atom == 0) return; 235444c061aSmrg 236444c061aSmrg atomName = (dpy ? XGetAtomName(dpy, atom) : NULL); 237444c061aSmrg 238444c061aSmrg if (! atomName) 239444c061aSmrg PrintCode(sb,~0UL,(unsigned long)atom); 240444c061aSmrg else { 241444c061aSmrg ExpandToFit( sb, atomName ); 242444c061aSmrg strcpy(sb->current, atomName); 243444c061aSmrg sb->current += strlen(sb->current); 244444c061aSmrg XFree(atomName); 245444c061aSmrg } 246444c061aSmrg} 247444c061aSmrg 248444c061aSmrgstatic void PrintLateModifiers( 249444c061aSmrg TMStringBuf sb, 250444c061aSmrg LateBindingsPtr lateModifiers) 251444c061aSmrg{ 252444c061aSmrg for (; lateModifiers->keysym; lateModifiers++) { 253444c061aSmrg CHECK_STR_OVERFLOW(sb); 254444c061aSmrg if (lateModifiers->knot) { 255444c061aSmrg *sb->current++ = '~'; 256444c061aSmrg } else { 257444c061aSmrg *sb->current++ = ' '; 258444c061aSmrg } 259444c061aSmrg strcpy(sb->current, XKeysymToString(lateModifiers->keysym)); 260444c061aSmrg sb->current += strlen(sb->current); 261444c061aSmrg if (lateModifiers->pair) { 262444c061aSmrg *(sb->current -= 2) = '\0'; /* strip "_L" */ 263444c061aSmrg lateModifiers++; /* skip _R keysym */ 264444c061aSmrg } 265444c061aSmrg } 266444c061aSmrg} 267444c061aSmrg 268444c061aSmrgstatic void PrintEvent( 269444c061aSmrg TMStringBuf sb, 270444c061aSmrg register TMTypeMatch typeMatch, 271444c061aSmrg register TMModifierMatch modMatch, 272444c061aSmrg Display *dpy) 273444c061aSmrg{ 274444c061aSmrg if (modMatch->standard) *sb->current++ = ':'; 275444c061aSmrg 276444c061aSmrg PrintModifiers(sb, modMatch->modifierMask, modMatch->modifiers); 277444c061aSmrg if (modMatch->lateModifiers != NULL) 278444c061aSmrg PrintLateModifiers(sb, modMatch->lateModifiers); 279444c061aSmrg PrintEventType(sb, typeMatch->eventType); 280444c061aSmrg switch (typeMatch->eventType) { 281444c061aSmrg case KeyPress: 282444c061aSmrg case KeyRelease: 283444c061aSmrg PrintKeysym(sb, (KeySym)typeMatch->eventCode); 284444c061aSmrg break; 285444c061aSmrg 286444c061aSmrg case PropertyNotify: 287444c061aSmrg case SelectionClear: 288444c061aSmrg case SelectionRequest: 289444c061aSmrg case SelectionNotify: 290444c061aSmrg case ClientMessage: 291444c061aSmrg PrintAtom(sb, dpy, (Atom)typeMatch->eventCode); 292444c061aSmrg break; 293444c061aSmrg 294444c061aSmrg default: 295444c061aSmrg PrintCode(sb, typeMatch->eventCodeMask, typeMatch->eventCode); 296444c061aSmrg } 297444c061aSmrg} 298444c061aSmrg 299444c061aSmrgstatic void PrintParams( 300444c061aSmrg TMStringBuf sb, 301444c061aSmrg String *params, 302444c061aSmrg Cardinal num_params) 303444c061aSmrg{ 304444c061aSmrg register Cardinal i; 305444c061aSmrg for (i = 0; i<num_params; i++) { 306444c061aSmrg ExpandToFit( sb, params[i] ); 307444c061aSmrg if (i != 0) { 308444c061aSmrg *sb->current++ = ','; 309444c061aSmrg *sb->current++ = ' '; 310444c061aSmrg } 311444c061aSmrg *sb->current++ = '"'; 312444c061aSmrg strcpy(sb->current, params[i]); 313444c061aSmrg sb->current += strlen(sb->current); 314444c061aSmrg *sb->current++ = '"'; 315444c061aSmrg } 316444c061aSmrg *sb->current = '\0'; 317444c061aSmrg} 318444c061aSmrg 319444c061aSmrgstatic void PrintActions( 320444c061aSmrg TMStringBuf sb, 321444c061aSmrg register ActionPtr actions, 322444c061aSmrg XrmQuark *quarkTbl, 323444c061aSmrg Widget accelWidget) 324444c061aSmrg{ 325444c061aSmrg while (actions != NULL) { 326444c061aSmrg String proc; 327444c061aSmrg 328444c061aSmrg *sb->current++ = ' '; 329444c061aSmrg 330444c061aSmrg if (accelWidget) { 331444c061aSmrg /* accelerator */ 332444c061aSmrg String name = XtName(accelWidget); 333444c061aSmrg int nameLen = strlen(name); 334444c061aSmrg ExpandForChars(sb, nameLen ); 335444c061aSmrg XtMemmove(sb->current, name, nameLen ); 336444c061aSmrg sb->current += nameLen; 337444c061aSmrg *sb->current++ = '`'; 338444c061aSmrg } 339444c061aSmrg proc = XrmQuarkToString(quarkTbl[actions->idx]); 340444c061aSmrg ExpandToFit( sb, proc ); 341444c061aSmrg strcpy(sb->current, proc); 342444c061aSmrg sb->current += strlen(proc); 343444c061aSmrg *sb->current++ = '('; 344444c061aSmrg PrintParams(sb, actions->params, actions->num_params); 345444c061aSmrg *sb->current++ = ')'; 346444c061aSmrg actions = actions->next; 347444c061aSmrg } 348444c061aSmrg *sb->current = '\0'; 349444c061aSmrg} 350444c061aSmrg 351444c061aSmrgstatic Boolean LookAheadForCycleOrMulticlick( 352444c061aSmrg register StatePtr state, 353444c061aSmrg StatePtr *state_return, /* state to print, usually startState */ 354444c061aSmrg int *countP, 355444c061aSmrg StatePtr *nextLevelP) 356444c061aSmrg{ 357444c061aSmrg int repeatCount = 0; 358444c061aSmrg StatePtr startState = state; 359444c061aSmrg Boolean isCycle = startState->isCycleEnd; 360444c061aSmrg TMTypeMatch sTypeMatch; 361444c061aSmrg TMModifierMatch sModMatch; 362444c061aSmrg 363444c061aSmrg LOCK_PROCESS; 364444c061aSmrg sTypeMatch = TMGetTypeMatch(startState->typeIndex); 365444c061aSmrg sModMatch = TMGetModifierMatch(startState->modIndex); 366444c061aSmrg 367444c061aSmrg *state_return = startState; 368444c061aSmrg 369444c061aSmrg for (state = state->nextLevel; state != NULL; state = state->nextLevel) { 370444c061aSmrg TMTypeMatch typeMatch = TMGetTypeMatch(state->typeIndex); 371444c061aSmrg TMModifierMatch modMatch = TMGetModifierMatch(state->modIndex); 372444c061aSmrg 373444c061aSmrg /* try to pick up the correct state with actions, to be printed */ 374444c061aSmrg /* This is to accommodate <ButtonUp>(2+), for example */ 375444c061aSmrg if (state->isCycleStart) 376444c061aSmrg *state_return = state; 377444c061aSmrg 378444c061aSmrg if (state->isCycleEnd) { 379444c061aSmrg *countP = repeatCount; 380444c061aSmrg UNLOCK_PROCESS; 381444c061aSmrg return True; 382444c061aSmrg } 383444c061aSmrg if ((startState->typeIndex == state->typeIndex) && 384444c061aSmrg (startState->modIndex == state->modIndex)) { 385444c061aSmrg repeatCount++; 386444c061aSmrg *nextLevelP = state; 387444c061aSmrg } 388444c061aSmrg else if (typeMatch->eventType == _XtEventTimerEventType) 389444c061aSmrg continue; 390444c061aSmrg else /* not same event as starting event and not timer */ { 391444c061aSmrg unsigned int type = sTypeMatch->eventType; 392444c061aSmrg unsigned int t = typeMatch->eventType; 393444c061aSmrg if ( (type == ButtonPress && t != ButtonRelease) 394444c061aSmrg || (type == ButtonRelease && t != ButtonPress) 395444c061aSmrg || (type == KeyPress && t != KeyRelease) 396444c061aSmrg || (type == KeyRelease && t != KeyPress) 397444c061aSmrg || typeMatch->eventCode != sTypeMatch->eventCode 398444c061aSmrg || modMatch->modifiers != sModMatch->modifiers 399444c061aSmrg || modMatch->modifierMask != sModMatch->modifierMask 400444c061aSmrg || modMatch->lateModifiers != sModMatch->lateModifiers 401444c061aSmrg || typeMatch->eventCodeMask != sTypeMatch->eventCodeMask 402444c061aSmrg || typeMatch->matchEvent != sTypeMatch->matchEvent 403444c061aSmrg || modMatch->standard != sModMatch->standard) 404444c061aSmrg /* not inverse of starting event, either */ 405444c061aSmrg break; 406444c061aSmrg } 407444c061aSmrg } 408444c061aSmrg *countP = repeatCount; 409444c061aSmrg UNLOCK_PROCESS; 410444c061aSmrg return isCycle; 411444c061aSmrg} 412444c061aSmrg 413444c061aSmrgstatic void PrintComplexState( 414444c061aSmrg TMStringBuf sb, 415444c061aSmrg Boolean includeRHS, 416444c061aSmrg StatePtr state, 417444c061aSmrg TMStateTree stateTree, 418444c061aSmrg Widget accelWidget, 419444c061aSmrg Display *dpy) 420444c061aSmrg{ 421444c061aSmrg int clickCount = 0; 422444c061aSmrg Boolean cycle; 423444c061aSmrg StatePtr nextLevel = NULL; 424444c061aSmrg StatePtr triggerState = NULL; 425444c061aSmrg 426444c061aSmrg /* print the current state */ 427444c061aSmrg if (! state) return; 428444c061aSmrg LOCK_PROCESS; 429444c061aSmrg cycle = LookAheadForCycleOrMulticlick(state, &triggerState, &clickCount, 430444c061aSmrg &nextLevel); 431444c061aSmrg 432444c061aSmrg PrintEvent(sb, TMGetTypeMatch(triggerState->typeIndex), 433444c061aSmrg TMGetModifierMatch(triggerState->modIndex), dpy); 434444c061aSmrg 435444c061aSmrg if (cycle || clickCount) { 436444c061aSmrg if (clickCount) 437444c061aSmrg sprintf(sb->current, "(%d%s)", clickCount+1, cycle ? "+" : ""); 438444c061aSmrg else 439444c061aSmrg (void) strncpy(sb->current, "(+)", 4); 440444c061aSmrg sb->current += strlen(sb->current); 441444c061aSmrg if (! state->actions && nextLevel) 442444c061aSmrg state = nextLevel; 443444c061aSmrg while (! state->actions && ! state->isCycleEnd) 444444c061aSmrg state = state->nextLevel; /* should be trigger state */ 445444c061aSmrg } 446444c061aSmrg 447444c061aSmrg if (state->actions) { 448444c061aSmrg if (includeRHS) { 449444c061aSmrg CHECK_STR_OVERFLOW(sb); 450444c061aSmrg *sb->current++ = ':'; 451444c061aSmrg PrintActions(sb, 452444c061aSmrg state->actions, 453444c061aSmrg ((TMSimpleStateTree)stateTree)->quarkTbl, 454444c061aSmrg accelWidget); 455444c061aSmrg *sb->current++ = '\n'; 456444c061aSmrg } 457444c061aSmrg } 458444c061aSmrg else { 459444c061aSmrg if (state->nextLevel && !cycle && !clickCount) 460444c061aSmrg *sb->current++ = ','; 461444c061aSmrg else { 462444c061aSmrg /* no actions are attached to this production */ 463444c061aSmrg *sb->current++ = ':'; 464444c061aSmrg *sb->current++ = '\n'; 465444c061aSmrg } 466444c061aSmrg } 467444c061aSmrg *sb->current = '\0'; 468444c061aSmrg 469444c061aSmrg /* print succeeding states */ 470444c061aSmrg if (state->nextLevel && !cycle && !clickCount) 471444c061aSmrg PrintComplexState(sb, includeRHS, state->nextLevel, 472444c061aSmrg stateTree, accelWidget, dpy); 473444c061aSmrg UNLOCK_PROCESS; 474444c061aSmrg} 475444c061aSmrg 476444c061aSmrgtypedef struct{ 477444c061aSmrg TMShortCard tIndex; 478444c061aSmrg TMShortCard bIndex; 479444c061aSmrg}PrintRec, *Print; 480444c061aSmrg 481444c061aSmrgstatic int FindNextMatch( 482444c061aSmrg PrintRec *printData, 483444c061aSmrg TMShortCard numPrints, 484444c061aSmrg XtTranslations xlations, 485444c061aSmrg TMBranchHead branchHead, 486444c061aSmrg StatePtr nextLevel, 487444c061aSmrg TMShortCard startIndex) 488444c061aSmrg{ 489444c061aSmrg TMShortCard i; 490444c061aSmrg TMComplexStateTree stateTree; 491444c061aSmrg StatePtr currState, candState; 492444c061aSmrg Boolean noMatch = True; 493444c061aSmrg TMBranchHead prBranchHead; 494444c061aSmrg 495444c061aSmrg for (i = startIndex; noMatch && i < numPrints; i++) { 496444c061aSmrg stateTree = (TMComplexStateTree) 497444c061aSmrg xlations->stateTreeTbl[printData[i].tIndex]; 498444c061aSmrg prBranchHead = 499444c061aSmrg &(stateTree->branchHeadTbl[printData[i].bIndex]); 500444c061aSmrg 501444c061aSmrg if ((prBranchHead->typeIndex == branchHead->typeIndex) && 502444c061aSmrg (prBranchHead->modIndex == branchHead->modIndex)) { 503444c061aSmrg if (prBranchHead->isSimple) { 504444c061aSmrg if (!nextLevel) 505444c061aSmrg return i; 506444c061aSmrg } 507444c061aSmrg else { 508444c061aSmrg currState = TMComplexBranchHead(stateTree, prBranchHead); 509444c061aSmrg currState = currState->nextLevel; 510444c061aSmrg candState = nextLevel; 511444c061aSmrg for (; 512444c061aSmrg ((currState && !currState->isCycleEnd) && 513444c061aSmrg (candState && !candState->isCycleEnd)); 514444c061aSmrg currState = currState->nextLevel, 515444c061aSmrg candState = candState->nextLevel) { 516444c061aSmrg if ((currState->typeIndex != candState->typeIndex) || 517444c061aSmrg (currState->modIndex != candState->modIndex)) 518444c061aSmrg break; 519444c061aSmrg } 520444c061aSmrg if (candState == currState) { 521444c061aSmrg return i; 522444c061aSmrg } 523444c061aSmrg } 524444c061aSmrg } 525444c061aSmrg } 526444c061aSmrg return TM_NO_MATCH; 527444c061aSmrg} 528444c061aSmrg 529444c061aSmrgstatic void ProcessLaterMatches( 530444c061aSmrg PrintRec *printData, 531444c061aSmrg XtTranslations xlations, 532444c061aSmrg TMShortCard tIndex, 533444c061aSmrg int bIndex, 534444c061aSmrg TMShortCard *numPrintsRtn) 535444c061aSmrg{ 536444c061aSmrg TMComplexStateTree stateTree; 537444c061aSmrg int i, j; 538444c061aSmrg TMBranchHead branchHead, matchBranch = NULL; 539444c061aSmrg 540444c061aSmrg for (i = tIndex; i < (int)xlations->numStateTrees; i++) { 541444c061aSmrg stateTree = (TMComplexStateTree)xlations->stateTreeTbl[i]; 542444c061aSmrg if (i == tIndex) { 543444c061aSmrg matchBranch = &stateTree->branchHeadTbl[bIndex]; 544444c061aSmrg j = bIndex+1; 545444c061aSmrg } 546444c061aSmrg else j = 0; 547444c061aSmrg for (branchHead = &stateTree->branchHeadTbl[j]; 548444c061aSmrg j < (int)stateTree->numBranchHeads; 549444c061aSmrg j++, branchHead++) { 550444c061aSmrg if ((branchHead->typeIndex == matchBranch->typeIndex) && 551444c061aSmrg (branchHead->modIndex == matchBranch->modIndex)) { 552444c061aSmrg StatePtr state; 553444c061aSmrg if (!branchHead->isSimple) 554444c061aSmrg state = TMComplexBranchHead(stateTree, branchHead); 555444c061aSmrg else 556444c061aSmrg state = NULL; 557444c061aSmrg if ((!branchHead->isSimple || branchHead->hasActions) && 558444c061aSmrg (FindNextMatch(printData, 559444c061aSmrg *numPrintsRtn, 560444c061aSmrg xlations, 561444c061aSmrg branchHead, 562444c061aSmrg (state ? state->nextLevel : NULL), 563444c061aSmrg 0) == TM_NO_MATCH)) { 564444c061aSmrg printData[*numPrintsRtn].tIndex = i; 565444c061aSmrg printData[*numPrintsRtn].bIndex = j; 566444c061aSmrg (*numPrintsRtn)++; 567444c061aSmrg } 568444c061aSmrg } 569444c061aSmrg } 570444c061aSmrg } 571444c061aSmrg} 572444c061aSmrg 573444c061aSmrgstatic void ProcessStateTree( 574444c061aSmrg PrintRec *printData, 575444c061aSmrg XtTranslations xlations, 576444c061aSmrg TMShortCard tIndex, 577444c061aSmrg TMShortCard *numPrintsRtn) 578444c061aSmrg{ 579444c061aSmrg TMComplexStateTree stateTree; 580444c061aSmrg int i; 581444c061aSmrg TMBranchHead branchHead; 582444c061aSmrg 583444c061aSmrg stateTree = (TMComplexStateTree)xlations->stateTreeTbl[tIndex]; 584444c061aSmrg 585444c061aSmrg for (i = 0, branchHead = stateTree->branchHeadTbl; 586444c061aSmrg i < (int)stateTree->numBranchHeads; 587444c061aSmrg i++, branchHead++) { 588444c061aSmrg StatePtr state; 589444c061aSmrg if (!branchHead->isSimple) 590444c061aSmrg state = TMComplexBranchHead(stateTree, branchHead); 591444c061aSmrg else 592444c061aSmrg state = NULL; 593444c061aSmrg if (FindNextMatch(printData, *numPrintsRtn, xlations, branchHead, 594444c061aSmrg (state ? state->nextLevel : NULL), 0) 595444c061aSmrg == TM_NO_MATCH) { 596444c061aSmrg if (!branchHead->isSimple || branchHead->hasActions) { 597444c061aSmrg printData[*numPrintsRtn].tIndex = tIndex; 598444c061aSmrg printData[*numPrintsRtn].bIndex = i; 599444c061aSmrg (*numPrintsRtn)++; 600444c061aSmrg } 601444c061aSmrg LOCK_PROCESS; 602444c061aSmrg if (_XtGlobalTM.newMatchSemantics == False) 603444c061aSmrg ProcessLaterMatches(printData, 604444c061aSmrg xlations, 605444c061aSmrg tIndex, 606444c061aSmrg i, 607444c061aSmrg numPrintsRtn); 608444c061aSmrg UNLOCK_PROCESS; 609444c061aSmrg } 610444c061aSmrg } 611444c061aSmrg} 612444c061aSmrg 613444c061aSmrgstatic void PrintState( 614444c061aSmrg TMStringBuf sb, 615444c061aSmrg TMStateTree tree, 616444c061aSmrg TMBranchHead branchHead, 617444c061aSmrg Boolean includeRHS, 618444c061aSmrg Widget accelWidget, 619444c061aSmrg Display *dpy) 620444c061aSmrg{ 621444c061aSmrg TMComplexStateTree stateTree = (TMComplexStateTree)tree; 622444c061aSmrg LOCK_PROCESS; 623444c061aSmrg if (branchHead->isSimple) { 624444c061aSmrg PrintEvent(sb, 625444c061aSmrg TMGetTypeMatch(branchHead->typeIndex), 626444c061aSmrg TMGetModifierMatch(branchHead->modIndex), 627444c061aSmrg dpy); 628444c061aSmrg if (includeRHS) { 629444c061aSmrg ActionRec actRec; 630444c061aSmrg 631444c061aSmrg CHECK_STR_OVERFLOW(sb); 632444c061aSmrg *sb->current++ = ':'; 633444c061aSmrg actRec.idx = TMBranchMore(branchHead); 634444c061aSmrg actRec.num_params = 0; 635444c061aSmrg actRec.params = NULL; 636444c061aSmrg actRec.next = NULL; 637444c061aSmrg PrintActions(sb, 638444c061aSmrg &actRec, 639444c061aSmrg stateTree->quarkTbl, 640444c061aSmrg accelWidget); 641444c061aSmrg *sb->current++ = '\n'; 642444c061aSmrg } 643444c061aSmrg else 644444c061aSmrg *sb->current++ = ','; 645444c061aSmrg#ifdef TRACE_TM 646444c061aSmrg if (!branchHead->hasActions) 647444c061aSmrg printf(" !! no actions !! "); 648444c061aSmrg#endif 649444c061aSmrg } 650444c061aSmrg else { /* it's a complex branchHead */ 651444c061aSmrg StatePtr state = TMComplexBranchHead(stateTree, branchHead); 652444c061aSmrg PrintComplexState(sb, 653444c061aSmrg includeRHS, 654444c061aSmrg state, 655444c061aSmrg tree, 656444c061aSmrg accelWidget, 657444c061aSmrg (Display *)NULL); 658444c061aSmrg } 659444c061aSmrg *sb->current = '\0'; 660444c061aSmrg UNLOCK_PROCESS; 661444c061aSmrg} 662444c061aSmrg 663444c061aSmrgString _XtPrintXlations( 664444c061aSmrg Widget w, 665444c061aSmrg XtTranslations xlations, 666444c061aSmrg Widget accelWidget, 667444c061aSmrg _XtBoolean includeRHS) 668444c061aSmrg{ 669444c061aSmrg register Cardinal i; 670444c061aSmrg#define STACKPRINTSIZE 250 671444c061aSmrg PrintRec stackPrints[STACKPRINTSIZE]; 672444c061aSmrg PrintRec *prints; 673444c061aSmrg TMStringBufRec sbRec, *sb = &sbRec; 674444c061aSmrg TMShortCard numPrints, maxPrints; 675444c061aSmrg#ifdef TRACE_TM 676444c061aSmrg TMBindData bindData = (TMBindData)w->core.tm.proc_table; 677444c061aSmrg Boolean hasAccel = (accelWidget ? True : False); 678444c061aSmrg#endif /* TRACE_TM */ 679444c061aSmrg if (xlations == NULL) return NULL; 680444c061aSmrg 681444c061aSmrg sb->current = sb->start = __XtMalloc((Cardinal)1000); 682444c061aSmrg sb->max = 1000; 683444c061aSmrg maxPrints = 0; 684444c061aSmrg for (i = 0; i < xlations->numStateTrees; i++) 685444c061aSmrg maxPrints += 686444c061aSmrg ((TMSimpleStateTree)(xlations->stateTreeTbl[i]))->numBranchHeads; 687444c061aSmrg prints = (PrintRec *) 688444c061aSmrg XtStackAlloc(maxPrints * sizeof(PrintRec), stackPrints); 689444c061aSmrg 690444c061aSmrg numPrints = 0; 691444c061aSmrg for (i = 0; i < xlations->numStateTrees; i++) 692444c061aSmrg ProcessStateTree(prints, xlations, i, &numPrints); 693444c061aSmrg 694444c061aSmrg for (i = 0; i < numPrints; i++) { 695444c061aSmrg TMSimpleStateTree stateTree = (TMSimpleStateTree) 696444c061aSmrg xlations->stateTreeTbl[prints[i].tIndex]; 697444c061aSmrg TMBranchHead branchHead = 698444c061aSmrg &stateTree->branchHeadTbl[prints[i].bIndex]; 699444c061aSmrg#ifdef TRACE_TM 700444c061aSmrg TMComplexBindProcs complexBindProcs; 701444c061aSmrg 702444c061aSmrg if (hasAccel == False) { 703444c061aSmrg accelWidget = NULL; 704444c061aSmrg if (bindData->simple.isComplex) { 705444c061aSmrg complexBindProcs = TMGetComplexBindEntry(bindData, 0); 706444c061aSmrg accelWidget = complexBindProcs[prints[i].tIndex].widget; 707444c061aSmrg } 708444c061aSmrg } 709444c061aSmrg#endif /* TRACE_TM */ 710444c061aSmrg PrintState(sb, (TMStateTree)stateTree, branchHead, 711444c061aSmrg includeRHS, accelWidget, XtDisplay(w)); 712444c061aSmrg } 713444c061aSmrg XtStackFree((XtPointer)prints, (XtPointer)stackPrints); 714444c061aSmrg return (sb->start); 715444c061aSmrg} 716444c061aSmrg 717444c061aSmrg 718444c061aSmrg#ifndef NO_MIT_HACKS 719444c061aSmrg/*ARGSUSED*/ 720444c061aSmrgvoid _XtDisplayTranslations( 721444c061aSmrg Widget widget, 722444c061aSmrg XEvent *event, 723444c061aSmrg String *params, 724444c061aSmrg Cardinal *num_params) 725444c061aSmrg{ 726444c061aSmrg String xString; 727444c061aSmrg 728444c061aSmrg xString = _XtPrintXlations(widget, 729444c061aSmrg widget->core.tm.translations, 730444c061aSmrg NULL, 731444c061aSmrg True); 7322265a131Smrg if (xString) { 7332265a131Smrg printf("%s\n",xString); 7342265a131Smrg XtFree(xString); 7352265a131Smrg } 736444c061aSmrg} 737444c061aSmrg 738444c061aSmrg/*ARGSUSED*/ 739444c061aSmrgvoid _XtDisplayAccelerators( 740444c061aSmrg Widget widget, 741444c061aSmrg XEvent *event, 742444c061aSmrg String *params, 743444c061aSmrg Cardinal *num_params) 744444c061aSmrg{ 745444c061aSmrg String xString; 746444c061aSmrg 747444c061aSmrg 748444c061aSmrg xString = _XtPrintXlations(widget, 749444c061aSmrg widget->core.accelerators, 750444c061aSmrg NULL, 751444c061aSmrg True); 7522265a131Smrg if (xString) { 7532265a131Smrg printf("%s\n",xString); 7542265a131Smrg XtFree(xString); 7552265a131Smrg } 756444c061aSmrg} 757444c061aSmrg 758444c061aSmrg/*ARGSUSED*/ 759444c061aSmrgvoid _XtDisplayInstalledAccelerators( 760444c061aSmrg Widget widget, 761444c061aSmrg XEvent *event, 762444c061aSmrg String *params, 763444c061aSmrg Cardinal *num_params) 764444c061aSmrg{ 765444c061aSmrg Widget eventWidget 766444c061aSmrg = XtWindowToWidget(event->xany.display, event->xany.window); 767444c061aSmrg register Cardinal i; 768444c061aSmrg TMStringBufRec sbRec, *sb = &sbRec; 769444c061aSmrg XtTranslations xlations; 770444c061aSmrg#define STACKPRINTSIZE 250 771444c061aSmrg PrintRec stackPrints[STACKPRINTSIZE]; 772444c061aSmrg PrintRec *prints; 773444c061aSmrg TMShortCard numPrints, maxPrints; 774444c061aSmrg TMBindData bindData = (TMBindData) eventWidget->core.tm.proc_table; 775444c061aSmrg TMComplexBindProcs complexBindProcs; 776444c061aSmrg 777444c061aSmrg if ((eventWidget == NULL) || 778444c061aSmrg ((xlations = eventWidget->core.tm.translations) == NULL) || 779444c061aSmrg (bindData->simple.isComplex == False)) 780444c061aSmrg return; 781444c061aSmrg 782444c061aSmrg sb->current = sb->start = __XtMalloc((Cardinal)1000); 783444c061aSmrg sb->start[0] = '\0'; 784444c061aSmrg sb->max = 1000; 785444c061aSmrg maxPrints = 0; 786444c061aSmrg for (i = 0; i < xlations->numStateTrees; i++) 787444c061aSmrg maxPrints += 788444c061aSmrg ((TMSimpleStateTree)xlations->stateTreeTbl[i])->numBranchHeads; 789444c061aSmrg prints = (PrintRec *) 790444c061aSmrg XtStackAlloc(maxPrints * sizeof(PrintRec), stackPrints); 791444c061aSmrg 792444c061aSmrg numPrints = 0; 793444c061aSmrg 794444c061aSmrg complexBindProcs = TMGetComplexBindEntry(bindData, 0); 795444c061aSmrg for (i = 0; 796444c061aSmrg i < xlations->numStateTrees; 797444c061aSmrg i++, complexBindProcs++) { 798444c061aSmrg if (complexBindProcs->widget) 799444c061aSmrg { 800444c061aSmrg ProcessStateTree(prints, xlations, i, &numPrints); 801444c061aSmrg } 802444c061aSmrg } 803444c061aSmrg for (i = 0; i < numPrints; i++) { 804444c061aSmrg TMSimpleStateTree stateTree = (TMSimpleStateTree) 805444c061aSmrg xlations->stateTreeTbl[prints[i].tIndex]; 806444c061aSmrg TMBranchHead branchHead = 807444c061aSmrg &stateTree->branchHeadTbl[prints[i].bIndex]; 808444c061aSmrg 809444c061aSmrg complexBindProcs = TMGetComplexBindEntry(bindData, 0); 810444c061aSmrg 811444c061aSmrg PrintState(sb, (TMStateTree)stateTree, branchHead, True, 812444c061aSmrg complexBindProcs[prints[i].tIndex].widget, 813444c061aSmrg XtDisplay(widget)); 814444c061aSmrg } 815444c061aSmrg XtStackFree((XtPointer)prints, (XtPointer)stackPrints); 816444c061aSmrg printf("%s\n", sb->start); 817444c061aSmrg XtFree(sb->start); 818444c061aSmrg} 819444c061aSmrg#endif /*NO_MIT_HACKS*/ 820444c061aSmrg 821444c061aSmrgString _XtPrintActions( 822444c061aSmrg register ActionRec *actions, 823444c061aSmrg XrmQuark *quarkTbl) 824444c061aSmrg{ 825444c061aSmrg TMStringBufRec sbRec, *sb = &sbRec; 826444c061aSmrg 827444c061aSmrg sb->max = 1000; 828444c061aSmrg sb->current = sb->start = __XtMalloc((Cardinal)1000); 829444c061aSmrg PrintActions(sb, 830444c061aSmrg actions, 831444c061aSmrg quarkTbl, 832444c061aSmrg (Widget)NULL); 833444c061aSmrg return sb->start; 834444c061aSmrg} 835444c061aSmrg 836444c061aSmrgString _XtPrintState( 837444c061aSmrg TMStateTree stateTree, 838444c061aSmrg TMBranchHead branchHead) 839444c061aSmrg{ 840444c061aSmrg TMStringBufRec sbRec, *sb = &sbRec; 841444c061aSmrg 842444c061aSmrg sb->current = sb->start = __XtMalloc((Cardinal)1000); 843444c061aSmrg sb->max = 1000; 844444c061aSmrg PrintState(sb, stateTree, branchHead, 845444c061aSmrg True, (Widget)NULL, (Display *)NULL); 846444c061aSmrg return sb->start; 847444c061aSmrg} 848444c061aSmrg 849444c061aSmrg 850444c061aSmrgString _XtPrintEventSeq( 851444c061aSmrg register EventSeqPtr eventSeq, 852444c061aSmrg Display *dpy) 853444c061aSmrg{ 854444c061aSmrg TMStringBufRec sbRec, *sb = &sbRec; 855444c061aSmrg TMTypeMatch typeMatch; 856444c061aSmrg TMModifierMatch modMatch; 857444c061aSmrg#define MAXSEQS 100 858444c061aSmrg EventSeqPtr eventSeqs[MAXSEQS]; 859444c061aSmrg TMShortCard i, j; 860444c061aSmrg Boolean cycle = False; 861444c061aSmrg 862444c061aSmrg sb->current = sb->start = __XtMalloc((Cardinal)1000); 863444c061aSmrg sb->max = 1000; 864444c061aSmrg for (i = 0; 865444c061aSmrg i < MAXSEQS && eventSeq != NULL && !cycle; 866444c061aSmrg eventSeq = eventSeq->next, i++) 867444c061aSmrg { 868444c061aSmrg eventSeqs[i] = eventSeq; 869444c061aSmrg for (j = 0; j < i && !cycle; j++) 870444c061aSmrg if (eventSeqs[j] == eventSeq) 871444c061aSmrg cycle = True; 872444c061aSmrg } 873444c061aSmrg LOCK_PROCESS; 874444c061aSmrg for (j = 0; j < i; j++) { 875444c061aSmrg typeMatch = 876444c061aSmrg TMGetTypeMatch(_XtGetTypeIndex(&eventSeqs[j]->event)); 877444c061aSmrg modMatch = 878444c061aSmrg TMGetModifierMatch(_XtGetModifierIndex(&eventSeqs[j]->event)); 879444c061aSmrg PrintEvent(sb, typeMatch, modMatch, dpy); 880444c061aSmrg if (j < i) 881444c061aSmrg *sb->current++ = ','; 882444c061aSmrg } 883444c061aSmrg UNLOCK_PROCESS; 884444c061aSmrg return sb->start; 885444c061aSmrg} 886