|
|
1.1 ! root 1: #ifndef lint ! 2: static char rcsid[] = "$Header: TMstate.c,v 1.9 87/09/11 21:24:37 haynes Rel $"; ! 3: #endif lint ! 4: ! 5: /* ! 6: * Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital Equipment ! 15: * Corporation not be used in advertising or publicity pertaining to ! 16: * distribution of the software without specific, written prior permission. ! 17: * ! 18: * ! 19: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 20: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 21: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 22: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 23: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 24: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 25: * SOFTWARE. ! 26: */ ! 27: /* TMstate.c -- maintains the state table of actions for the translation ! 28: * manager. ! 29: */ ! 30: ! 31: #include "Xlib.h" ! 32: #include "Intrinsic.h" ! 33: #include "Atoms.h" ! 34: #include "TM.h" ! 35: #include "TMprivate.h" ! 36: ! 37: extern char *strcpy(); ! 38: ! 39: static void FreeActionRecs(action) ! 40: ActionPtr action; ! 41: { ! 42: int i; ! 43: if (action->next != NULL) ! 44: FreeActionRecs(action->next); ! 45: if (action->param != NULL) ! 46: for (i=0; i<action->paramNum; i++) ! 47: XtFree(action->param[i]); ! 48: XtFree(action->token); ! 49: XtFree((char *)action->param); ! 50: XtFree((char *)action); ! 51: } ! 52: ! 53: ! 54: static void FreeStateRecs(state) ! 55: StatePtr state; ! 56: { ! 57: if (state->next != NULL) ! 58: FreeStateRecs(state->next); ! 59: if (state->nextLevel != NULL) ! 60: FreeStateRecs(state->nextLevel); ! 61: if (state->actions != NULL) ! 62: FreeActionRecs(state->actions); ! 63: XtFree((char *)state->actions); ! 64: XtFree((char *)state->next); ! 65: XtFree((char *)state->nextLevel); ! 66: } ! 67: ! 68: static void PrintModifiers(mask, mod) ! 69: unsigned long mask, mod; ! 70: { ! 71: if (mask & ShiftMask) ! 72: (void) printf("<%sShift>", ((mod & ShiftMask) ? "" : "~")); ! 73: if (mask & ControlMask) ! 74: (void) printf("<%sCtrl>", ((mod & ControlMask) ? "" : "~")); ! 75: if (mask & LockMask) ! 76: (void) printf("<%sLock>", ((mod & LockMask) ? "" : "~")); ! 77: if (mask & Mod1Mask) ! 78: (void) printf("<%sMeta>", ((mod & Mod1Mask) ? "" : "~")); ! 79: if (mask & Mod2Mask) ! 80: (void) printf("<%sMod2>", ((mod & Mod2Mask) ? "" : "~")); ! 81: if (mask & Mod3Mask) ! 82: (void) printf("<%sMod3>", ((mod & Mod3Mask) ? "" : "~")); ! 83: if (mask & Mod4Mask) ! 84: (void) printf("<%sMod4>", ((mod & Mod4Mask) ? "" : "~")); ! 85: if (mask & Mod5Mask) ! 86: (void) printf("<%sMod5>", ((mod & Mod5Mask) ? "" : "~")); ! 87: } ! 88: ! 89: static void PrintEvent(event, endStr) ! 90: unsigned long event; ! 91: char * endStr; ! 92: { ! 93: (void) strcpy(endStr, ""); ! 94: switch (event) { ! 95: case KeyPressMask: ! 96: (void) printf("<Key>"); ! 97: break; ! 98: case KeyReleaseMask: ! 99: (void) printf("<Key>"); ! 100: break; ! 101: case ButtonPressMask: ! 102: (void) printf("<Btn"); ! 103: (void) strcpy(endStr, "Down>"); ! 104: break; ! 105: case ButtonReleaseMask: ! 106: (void) printf("<Btn"); ! 107: (void) strcpy(endStr, "Up>"); ! 108: break; ! 109: } ! 110: } ! 111: ! 112: static void PrintCode(code) ! 113: unsigned long code; ! 114: { ! 115: char ch; ! 116: ch = code - 'a' + 'A'; ! 117: if (ch >= 'A' && ch <= 'Z') ! 118: (void) printf("%c",ch); ! 119: else ! 120: (void) printf("%d", code); ! 121: } ! 122: ! 123: static void PrintActions(ev, code, mask, modif, actions, j) ! 124: unsigned long ev[], mask[], modif[], code[]; ! 125: ActionPtr actions; ! 126: int j; ! 127: { ! 128: char endStr[20]; ! 129: int i; ! 130: for (i=0; i<j; i++) { ! 131: PrintModifiers(mask[i], modif[i]); ! 132: PrintEvent(ev[i], endStr); ! 133: PrintCode(code[i]); ! 134: (void) printf("%s ",endStr); ! 135: } ! 136: while (actions != NULL && actions->token != NULL) { ! 137: (void) printf("---------> action = %s\n", actions->token); ! 138: actions = actions->next; ! 139: } ! 140: (void) printf("\n"); ! 141: } ! 142: ! 143: /* ! 144: * there are certain cases where you want to ignore the event and stay ! 145: * in the same state. ! 146: */ ! 147: static Boolean SpecialCase(event) ! 148: EventSeqPtr event; ! 149: { ! 150: if (event->eventType == MotionNotify || event->eventType == ButtonPress || ! 151: event->eventType == ButtonRelease) ! 152: return TRUE; ! 153: else ! 154: return FALSE; ! 155: } ! 156: ! 157: ! 158: static int FindEvent(translations, eventSeq) ! 159: _XtTranslations translations; ! 160: EventSeqPtr eventSeq; ! 161: { ! 162: EventObjPtr eventTbl = translations->eventObjTbl; ! 163: int i; ! 164: ! 165: for (i=0; i < translations->numEvents; i++) { ! 166: if ( ! 167: (eventTbl[i].eventType == eventSeq->eventType) && ! 168: (eventTbl[i].eventCode == eventSeq->eventCode) && ! 169: (eventTbl[i].eventCodeMask == eventSeq->eventCodeMask) && ! 170: (eventTbl[i].modifiers == eventSeq->modifiers) && ! 171: (eventTbl[i].modifierMask == eventSeq->modifierMask) ! 172: ) ! 173: return(i); ! 174: } ! 175: return(-1); ! 176: } ! 177: ! 178: ! 179: static int MatchEvent(translations, eventSeq) ! 180: _XtTranslations translations; ! 181: EventSeqPtr eventSeq; ! 182: { ! 183: EventObjPtr eventTbl = translations->eventObjTbl; ! 184: int i; ! 185: ! 186: for (i=0; i < translations->numEvents; i++) { ! 187: if ((eventTbl[i].eventType == eventSeq->eventType) && ! 188: (eventTbl[i].eventCode == ! 189: (eventTbl[i].eventCodeMask & eventSeq->eventCode)) && ! 190: (eventTbl[i].modifiers == ! 191: (eventTbl[i].modifierMask & eventSeq->modifiers)) ! 192: ) ! 193: return(i); ! 194: } ! 195: return(-1); ! 196: } ! 197: ! 198: ! 199: static EventObjPtr CreateStates(translations, index, eventSeq) ! 200: _XtTranslations translations; ! 201: int index; ! 202: EventSeqPtr eventSeq; ! 203: { ! 204: EventObjPtr eventObjTbl = translations->eventObjTbl; ! 205: StatePtr state; ! 206: Boolean found = FALSE; ! 207: ActionPtr actions = eventSeq->actions; ! 208: ! 209: if (eventObjTbl[index].state == NULL) { ! 210: eventObjTbl[index].state = (StatePtr) XtMalloc((unsigned)sizeof(StateRec)); ! 211: state = eventObjTbl[index].state; ! 212: state->index = index; ! 213: state->nextLevel = NULL; ! 214: state->next = NULL; ! 215: state->actions = NULL; ; ! 216: } else { ! 217: state = eventObjTbl[index].state; ! 218: do { ! 219: found = FALSE; ! 220: if (eventSeq->next != NULL && state->nextLevel != NULL) { ! 221: eventSeq = eventSeq->next; ! 222: index = FindEvent(translations, eventSeq); ! 223: state = state->nextLevel; ! 224: if (state->index == index) ! 225: found = TRUE; ! 226: while (state->next != NULL && !found) { ! 227: state = state->next; ! 228: if (state->index == index) ! 229: found = TRUE; ! 230: } ! 231: if (!found) { ! 232: state->next = (StatePtr) XtMalloc((unsigned)sizeof(StateRec)); ! 233: state = state->next; ! 234: state->index = index; ! 235: state->nextLevel = NULL; ! 236: state->next = NULL; ! 237: state->actions = NULL; ! 238: } ! 239: } ! 240: } while (found); ! 241: } ! 242: while (eventSeq->next != NULL) { ! 243: eventSeq = eventSeq->next; ! 244: index = FindEvent(translations, eventSeq); ! 245: state->nextLevel = (StatePtr) XtMalloc((unsigned)sizeof(StateRec)); ! 246: state = state->nextLevel; ! 247: state->index = index; ! 248: state->nextLevel = NULL; ! 249: state->next = NULL; ! 250: state->actions = NULL; ! 251: } ! 252: if (state->actions != NULL) ! 253: FreeActionRecs(state->actions); ! 254: state->actions = actions; ! 255: ! 256: return eventObjTbl; ! 257: } ! 258: ! 259: ! 260: /*** Public procedures ***/ ! 261: EventObjPtr EventMapObjectCreate(translations, eventSeq) ! 262: _XtTranslations translations; ! 263: EventSeqPtr eventSeq; ! 264: { ! 265: EventObjPtr new; ! 266: ! 267: if (FindEvent(translations, eventSeq) >= 0) ! 268: return translations->eventObjTbl; ! 269: ! 270: if (translations->numEvents == translations->eventTblSize) { ! 271: translations->eventTblSize += 100; ! 272: translations->eventObjTbl = (EventObjPtr) XtRealloc( ! 273: (char *)translations->eventObjTbl, ! 274: translations->eventTblSize*sizeof(EventObjRec)); ! 275: } ! 276: ! 277: new = &translations->eventObjTbl[translations->numEvents]; ! 278: ! 279: new->eventType = eventSeq->eventType; ! 280: new->eventCodeMask = eventSeq->eventCodeMask; ! 281: new->eventCode = eventSeq->eventCode; ! 282: new->modifierMask = eventSeq->modifierMask; ! 283: new->modifiers = eventSeq->modifiers; ! 284: new->state = NULL; ! 285: ! 286: translations->numEvents++; ! 287: return translations->eventObjTbl; ! 288: } ! 289: ! 290: ! 291: EventObjPtr EventMapObjectGet(translations, eventSeq) ! 292: _XtTranslations translations; ! 293: EventSeqPtr eventSeq; ! 294: { ! 295: EventObjPtr eventTbl = translations->eventObjTbl; ! 296: int index; ! 297: if ((index = FindEvent(translations, eventSeq)) < 0) ! 298: return NULL; ! 299: else ! 300: return &eventTbl[index]; ! 301: } ! 302: ! 303: ! 304: EventObjPtr EventMapObjectSet(translations, eventSeq) ! 305: _XtTranslations translations; ! 306: EventSeqPtr eventSeq; ! 307: { ! 308: EventObjPtr eventTbl = translations->eventObjTbl; ! 309: int index; ! 310: if ((index = FindEvent(translations, eventSeq)) >= 0) ! 311: eventTbl = CreateStates(translations, index, eventSeq); ! 312: return eventTbl; ! 313: } ! 314: ! 315: ! 316: /* ARGSUSED */ ! 317: void TranslateEvent(w, closure, event) ! 318: Widget w; ! 319: Opaque closure; ! 320: register XEvent *event; ! 321: { ! 322: static unsigned long upTime=0; ! 323: static Boolean buttonUp = FALSE; ! 324: static StatePtr curState = NULL; ! 325: StatePtr oldState; ! 326: EventSeqRec curEvent; ! 327: int index; ! 328: ActionPtr actions; ! 329: Boolean specialCase; ! 330: ! 331: oldState = 0; ! 332: specialCase = FALSE; ! 333: curEvent.eventCodeMask = 0; ! 334: curEvent.eventCode = 0; ! 335: curEvent.modifierMask = 0; ! 336: curEvent.modifiers = 0; ! 337: curEvent.eventType = event->type; ! 338: switch (event->type) { ! 339: case KeyPress: ! 340: case KeyRelease: ! 341: buttonUp = FALSE; ! 342: curEvent.modifiers = event->xkey.state; ! 343: event->xkey.state = 0; ! 344: curEvent.eventCode = XLookupKeysym(&event->xkey, 0); ! 345: event->xkey.state = curEvent.modifiers; ! 346: break; ! 347: case ButtonPress: ! 348: if (buttonUp && curState != NULL) ! 349: if ((unsigned long) ! 350: (upTime - event->xbutton.time) > ! 351: w->core.translations->clickTime) ! 352: curState = NULL; ! 353: buttonUp = FALSE; ! 354: curEvent.eventCode = event->xbutton.button; ! 355: curEvent.modifiers = event->xbutton.state; ! 356: break; ! 357: case ButtonRelease: ! 358: buttonUp = TRUE; ! 359: upTime = event->xbutton.time; ! 360: curEvent.eventCode = event->xbutton.button; ! 361: curEvent.modifiers = event->xbutton.state; ! 362: break; ! 363: case MotionNotify: ! 364: buttonUp = FALSE; ! 365: curEvent.modifiers = event->xmotion.state; ! 366: break; ! 367: case EnterNotify: ! 368: case LeaveNotify: ! 369: buttonUp = FALSE; ! 370: curEvent.modifiers = event->xcrossing.state; ! 371: break; ! 372: default: ! 373: buttonUp = FALSE; ! 374: break; ! 375: } ! 376: if (curState != NULL) { /* check the current level */ ! 377: index = MatchEvent(w->core.translations, &curEvent); ! 378: oldState = curState; ! 379: while (curState != NULL && curState->index != index) ! 380: curState = curState->next; ! 381: if (curState == NULL) ! 382: if (SpecialCase(&curEvent)) { ! 383: curState = oldState; ! 384: specialCase = TRUE; ! 385: } else { /* nothing at level but you performed an action on the ! 386: last event---> start over with this new event. */ ! 387: if (oldState->actions != NULL) { ! 388: curState = oldState; ! 389: index = MatchEvent(w->core.translations, &curEvent); ! 390: curState = w->core.translations->eventObjTbl[index].state; ! 391: } ! 392: } ! 393: } else { ! 394: index = MatchEvent(w->core.translations, &curEvent); ! 395: if (index == -1) return; ! 396: curState = w->core.translations->eventObjTbl[index].state; ! 397: } ! 398: if (curState != NULL && !specialCase) { ! 399: actions = curState->actions; ! 400: while (actions != NULL) { /* perform any actions */ ! 401: if (actions->proc != NULL) ! 402: /*!!!!! should have params here */ ! 403: (*(actions->proc))(w, event); ! 404: actions = actions->next; ! 405: } ! 406: curState = curState->nextLevel; ! 407: } ! 408: } ! 409: ! 410: void TranslateTableFree(translations) ! 411: _XtTranslations translations; ! 412: { ! 413: EventObjPtr tbl = translations->eventObjTbl; ! 414: int i; ! 415: ! 416: /* !!! ref count this, it may be shared */ ! 417: ! 418: for (i=0; i<translations->numEvents; i++) { ! 419: if (tbl[i].state != NULL) FreeStateRecs(tbl[i].state); ! 420: } ! 421: XtFree((char *)tbl); ! 422: XtFree((char *)translations); ! 423: } ! 424: ! 425: ! 426: void TranslateTablePrint(translations) ! 427: _XtTranslations translations; ! 428: { ! 429: EventObjPtr tbl = translations->eventObjTbl; ! 430: int i, j; ! 431: unsigned long ev[100], code[100], mask[100], modif[100]; ! 432: StatePtr stack[100], state; ! 433: ! 434: for (i=0; i<translations->numEvents; i++) { ! 435: j=0; ! 436: if (tbl[i].state != NULL) { ! 437: state = tbl[i].state; ! 438: stack[j] = tbl[i].state; ! 439: ev[j] = tbl[i].eventType; ! 440: code[j] = tbl[i].eventCode; ! 441: mask[j] = tbl[i].modifierMask; ! 442: modif[j++] = tbl[i].modifiers; ! 443: if (state->actions != NULL) ! 444: PrintActions(ev, code, mask, modif, state->actions, j); ! 445: do { ! 446: do { ! 447: while (state->nextLevel != NULL) { ! 448: state = state->nextLevel; ! 449: stack[j] = state; ! 450: ev[j] = tbl[state->index].eventType; ! 451: code[j] = tbl[state->index].eventCode; ! 452: mask[j] = tbl[state->index].modifierMask; ! 453: modif[j++] = tbl[state->index].modifiers; ! 454: if (state->actions != NULL) ! 455: PrintActions( ! 456: ev, code, mask, modif, state->actions, j); ! 457: } ! 458: j--; ! 459: if (state->next != NULL) { ! 460: state = state->next; ! 461: stack[j] = state; ! 462: ev[j] = tbl[state->index].eventType; ! 463: code[j] = tbl[state->index].eventCode; ! 464: mask[j] = tbl[state->index].modifierMask; ! 465: modif[j++] = tbl[state->index].modifiers; ! 466: if (state->actions != NULL) ! 467: PrintActions( ! 468: ev, code, mask, modif, state->actions, j); ! 469: } ! 470: } while (state->next != NULL && state->nextLevel != NULL); ! 471: j--; ! 472: state = stack[j]; ! 473: if (state->next != NULL) { ! 474: state = state->next; ! 475: stack[j] = state; ! 476: ev[j] = tbl[state->index].eventType; ! 477: code[j] = tbl[state->index].eventCode; ! 478: mask[j] = tbl[state->index].modifierMask; ! 479: modif[j++] = tbl[state->index].modifiers; ! 480: if (state->actions != NULL) ! 481: PrintActions(ev, code, mask, modif, state->actions, j); ! 482: } else ! 483: j--; ! 484: } while (j-1>0); ! 485: } ! 486: } ! 487: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.