|
|
1.1 ! root 1: #ifndef lint ! 2: static char rcsid[] = "$Header: TMparse.c,v 1.24 87/09/11 21:24:33 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: /* TMparse.c -- parse all X events into widget specific actions. */ ! 28: ! 29: #include <stdio.h> ! 30: #include "Xlib.h" ! 31: #include "Xutil.h" ! 32: #include "Intrinsic.h" ! 33: #include <strings.h> ! 34: #include "Atoms.h" ! 35: #include "TM.h" ! 36: #include "TMprivate.h" ! 37: ! 38: /* Private definitions. */ ! 39: #define LF 0x0a ! 40: #define BSLASH '\\' ! 41: ! 42: #define AtomToAction(atom) ((XtAction)StringToQuark(atom)) ! 43: ! 44: typedef int EventType; ! 45: typedef unsigned int XtEventType; ! 46: typedef unsigned int EventCode; ! 47: typedef unsigned int Value; ! 48: ! 49: typedef void (*ActionProc)(); ! 50: ! 51: typedef struct _EventKey { ! 52: char *event; ! 53: XrmQuark signature; ! 54: EventMask mask; ! 55: EventType eventType; ! 56: int detailType; ! 57: caddr_t detail; ! 58: }EventKey, *EventKeys; ! 59: ! 60: typedef struct { ! 61: char *name; ! 62: XrmQuark signature; ! 63: Value value; ! 64: } NameValueRec, *NameValueTable; ! 65: ! 66: typedef NameValueRec CompiledAction; ! 67: typedef NameValueTable CompiledActionTable; ! 68: ! 69: NameValueRec modifiers[] = { ! 70: {"Shift", 0, ShiftMask}, ! 71: {"Lock", 0, LockMask}, ! 72: {"Ctrl", 0, ControlMask}, ! 73: {"Mod1", 0, Mod1Mask}, ! 74: {"Mod2", 0, Mod2Mask}, ! 75: {"Mod3", 0, Mod3Mask}, ! 76: {"Mod4", 0, Mod4Mask}, ! 77: {"Mod5", 0, Mod5Mask}, ! 78: {"Meta", 0, Mod1Mask}, ! 79: ! 80: {"Button1", 0, Button1Mask}, ! 81: {"Button2", 0, Button2Mask}, ! 82: {"Button3", 0, Button3Mask}, ! 83: {"Button4", 0, Button4Mask}, ! 84: {"Button5", 0, Button5Mask}, ! 85: ! 86: {"Any", 0, AnyModifier}, ! 87: ! 88: {NULL, NULL, NULL}, ! 89: }; ! 90: ! 91: NameValueRec buttonNames[] = { ! 92: {"Button1", 0, Button1}, ! 93: {"Button2", 0, Button2}, ! 94: {"Button3", 0, Button3}, ! 95: {"Button4", 0, Button4}, ! 96: {"Button5", 0, Button5}, ! 97: {NULL, NULL, NULL}, ! 98: }; ! 99: ! 100: NameValueRec notifyModes[] = { ! 101: {"Normal", 0, NotifyNormal}, ! 102: {"Grab", 0, NotifyGrab}, ! 103: {"Ungrab", 0, NotifyUngrab}, ! 104: {"WhileGrabbed", 0, NotifyWhileGrabbed}, ! 105: {NULL, NULL, NULL}, ! 106: }; ! 107: ! 108: NameValueRec notifyDetail[] = { ! 109: {"Ancestor", 0, NotifyAncestor}, ! 110: {"Virtual", 0, NotifyVirtual}, ! 111: {"Inferior", 0, NotifyInferior}, ! 112: {"Nonlinear", 0, NotifyNonlinear}, ! 113: {"NonlinearVirtual", 0, NotifyNonlinearVirtual}, ! 114: {"Pointer", 0, NotifyPointer}, ! 115: {"PointerRoot", 0, NotifyPointerRoot}, ! 116: {"DetailNone", 0, NotifyDetailNone}, ! 117: {NULL, NULL, NULL}, ! 118: }; ! 119: ! 120: NameValueRec visibilityNotify[] = { ! 121: {"Unobscured", 0, VisibilityUnobscured}, ! 122: {"PartiallyObscured", 0, VisibilityPartiallyObscured}, ! 123: {"FullyObscured", 0, VisibilityFullyObscured}, ! 124: {NULL, NULL, NULL}, ! 125: }; ! 126: ! 127: NameValueRec circulation[] = { ! 128: {"OnTop", 0, PlaceOnTop}, ! 129: {"OnBottom", 0, PlaceOnBottom}, ! 130: {NULL, NULL, NULL}, ! 131: }; ! 132: ! 133: NameValueRec propertyChanged[] = { ! 134: {"NewValue", 0, PropertyNewValue}, ! 135: {"Delete", 0, PropertyDelete}, ! 136: {NULL, NULL, NULL}, ! 137: }; ! 138: ! 139: #define NEM NoEventMask ! 140: #define KPM KeyPressMask ! 141: #define KRM KeyReleaseMask ! 142: #define BPM ButtonPressMask ! 143: #define BRM ButtonReleaseMask ! 144: #define EWM EnterWindowMask ! 145: #define LWM LeaveWindowMask ! 146: #define PMM PointerMotionMask ! 147: #define PHM PointerMotionHintMask ! 148: #define B1M Button1MotionMask ! 149: #define B2M Button2MotionMask ! 150: #define B3M Button3MotionMask ! 151: #define B4M Button4MotionMask ! 152: #define B5M Button5MotionMask ! 153: #define BMM ButtonMotionMask ! 154: #define KSM KeymapStateMask ! 155: #define EXM ExposureMask ! 156: #define VCM VisibilityChangeMask ! 157: #define STM StructureNotifyMask ! 158: #define RRM ResizeRedirectMask ! 159: #define SSM SubstructureNotifyMask ! 160: #define SRM SubstructureRedirectMask ! 161: #define FCM FocusChangeMask ! 162: #define PCM PropertyChangeMask ! 163: #define CCM ColormapChangeMask ! 164: #define OGM OwnerGrabButtonMask ! 165: ! 166: #define DetailNone 0 ! 167: #define DetailTable 1 ! 168: #define DetailKeySym 2 ! 169: #define DetailImmed 3 ! 170: ! 171: EventKey events[] = { ! 172: {"KeyPress", NULL, KPM, KeyPress, DetailKeySym, NULL}, ! 173: {"KeyRelease", NULL, KRM, KeyRelease, DetailKeySym, NULL}, ! 174: {"ButtonPress", NULL, BPM, ButtonPress, DetailTable,(caddr_t)buttonNames}, ! 175: {"ButtonRelease", NULL, BRM, ButtonRelease,DetailTable,(caddr_t)buttonNames}, ! 176: {"MotionNotify", NULL, PMM, MotionNotify, DetailNone, NULL}, ! 177: {"EnterNotify", NULL, EWM, EnterNotify, DetailTable,(caddr_t)notifyModes}, ! 178: {"LeaveNotify", NULL, LWM, LeaveNotify, DetailTable,(caddr_t)notifyModes}, ! 179: {"FocusIn", NULL, FCM, FocusIn, DetailTable,(caddr_t)notifyModes}, ! 180: {"FocusOut", NULL, FCM, FocusOut, DetailTable,(caddr_t)notifyModes}, ! 181: {"KeymapNotify", NULL, KSM, KeymapNotify, DetailNone, NULL}, ! 182: {"Expose", NULL, EXM, Expose, DetailNone, NULL}, ! 183: {"GraphicsExpose", NULL, EXM, GraphicsExpose, DetailNone, NULL}, ! 184: {"NoExpose", NULL, EXM, NoExpose, DetailNone, NULL}, ! 185: {"VisibilityNotify",NULL, VCM, VisibilityNotify,DetailNone, NULL}, ! 186: {"CreateNotify", NULL, STM, CreateNotify, DetailNone, NULL}, ! 187: {"DestroyNotify", NULL, STM, DestroyNotify, DetailNone, NULL}, ! 188: {"UnmapNotify", NULL, STM, UnmapNotify, DetailNone, NULL}, ! 189: {"MapNotify", NULL, STM, MapNotify, DetailNone, NULL}, ! 190: {"MapRequest", NULL, SRM, MapRequest, DetailNone, NULL}, ! 191: {"ReparentNotify", NULL, STM, ReparentNotify, DetailNone, NULL}, ! 192: {"ConfigureNotify", NULL, STM, ConfigureNotify, DetailNone, NULL}, ! 193: {"ConfigureRequest",NULL, SRM, ConfigureRequest,DetailNone, NULL}, ! 194: {"GravityNotify", NULL, STM, GravityNotify, DetailNone, NULL}, ! 195: {"ResizeRequest", NULL, RRM, ResizeRequest, DetailNone, NULL}, ! 196: {"CirculateNotify", NULL, STM, CirculateNotify, DetailNone, NULL}, ! 197: {"CirculateRequest",NULL, SRM, CirculateRequest,DetailNone, NULL}, ! 198: {"PropertyNotify", NULL, PCM, PropertyNotify, DetailNone, NULL}, ! 199: {"SelectionClear", NULL, SRM, SelectionClear, DetailNone, NULL}, ! 200: {"SelectionRequest",NULL, SRM, SelectionRequest,DetailNone, NULL}, ! 201: {"SelectionNotify", NULL, SRM, SelectionNotify, DetailNone, NULL}, ! 202: {"ColormapNotify", NULL, CCM, ColormapNotify, DetailNone, NULL}, ! 203: {"ClientMessage", NULL, 0, ClientMessage, DetailNone, NULL}, ! 204: {"MappingNotify", NULL, 0, 0/*mapping*/, DetailNone, NULL}, ! 205: ! 206: {"Key", NULL, KPM, KeyPress, DetailKeySym, NULL}, ! 207: {"BtnDown", NULL, BPM, ButtonPress, DetailTable,(caddr_t)buttonNames}, ! 208: {"BtnUp", NULL, BRM, ButtonRelease,DetailTable,(caddr_t)buttonNames}, ! 209: {"Btn1Down", NULL, BPM, ButtonPress, DetailImmed,(caddr_t)Button1}, ! 210: {"Btn1Up", NULL, BRM, ButtonRelease, DetailImmed,(caddr_t)Button1}, ! 211: {"Btn2Down", NULL, BPM, ButtonPress, DetailImmed,(caddr_t)Button2}, ! 212: {"Btn2Up", NULL, BRM, ButtonRelease, DetailImmed,(caddr_t)Button2}, ! 213: {"Btn3Down", NULL, BPM, ButtonPress, DetailImmed,(caddr_t)Button3}, ! 214: {"Btn3Up", NULL, BRM, ButtonRelease, DetailImmed,(caddr_t)Button3}, ! 215: {"Btn4Down", NULL, BPM, ButtonPress, DetailImmed,(caddr_t)Button4}, ! 216: {"Btn4Up", NULL, BRM, ButtonRelease, DetailImmed,(caddr_t)Button4}, ! 217: {"Btn5Down", NULL, BPM, ButtonPress, DetailImmed,(caddr_t)Button5}, ! 218: {"Btn5Up", NULL, BRM, ButtonRelease, DetailImmed,(caddr_t)Button5}, ! 219: {"PtrMoved", NULL, PMM, MotionNotify, DetailNone, NULL}, ! 220: {"MouseMoved", NULL, PMM, MotionNotify, DetailNone, NULL}, ! 221: {"EnterWindow", NULL, EWM, EnterNotify, DetailTable,(caddr_t)notifyModes}, ! 222: {"LeaveWindow", NULL, LWM, LeaveNotify, DetailTable,(caddr_t)notifyModes}, ! 223: ! 224: { NULL, NULL, NULL, NULL, NULL, NULL}}; ! 225: ! 226: static Boolean initialized = FALSE; ! 227: ! 228: static void FreeEventSeq(event) ! 229: EventSeqPtr event; ! 230: { ! 231: if (event->next != NULL) ! 232: FreeEventSeq(event->next); ! 233: XtFree((char *)event->str); ! 234: XtFree((char *)event); ! 235: } ! 236: ! 237: static void CompileNameValueTable(table) ! 238: NameValueTable table; ! 239: { ! 240: int i; ! 241: ! 242: for (i=0; table[i].name; i++) ! 243: table[i].signature = StringToQuark(table[i].name); ! 244: } ! 245: ! 246: static void Compile_XtEventTable(table) ! 247: EventKeys table; ! 248: { ! 249: int i; ! 250: ! 251: for (i=0; table[i].event; i++) ! 252: table[i].signature = StringToQuark(table[i].event); ! 253: } ! 254: ! 255: static CompiledActionTable CompileActionTable(actions, count) ! 256: struct _XtActionsRec *actions; ! 257: Cardinal count; ! 258: { ! 259: int i; ! 260: CompiledActionTable compiledActionTable; ! 261: ! 262: compiledActionTable = (CompiledActionTable) XtCalloc( ! 263: count+1, (unsigned) sizeof(CompiledAction)); ! 264: ! 265: for (i=0; i<count; i++) { ! 266: compiledActionTable[i].name = actions[i].string; ! 267: compiledActionTable[i].signature = AtomToAction(actions[i].string); ! 268: compiledActionTable[i].value = (Value) actions[i].value; ! 269: } ! 270: ! 271: compiledActionTable[count].name = NULL; ! 272: compiledActionTable[count].signature = NULL; ! 273: compiledActionTable[count].value = NULL; ! 274: ! 275: return compiledActionTable; ! 276: } ! 277: ! 278: static void FreeCompiledActionTable(compiledActionTable) ! 279: CompiledActionTable compiledActionTable; ! 280: { ! 281: XtFree((char *)compiledActionTable); ! 282: } ! 283: ! 284: static Syntax(str) ! 285: char *str; ! 286: { ! 287: (void) fprintf(stderr, ! 288: "Translation table syntax error: %s\n", str); ! 289: } ! 290: ! 291: ! 292: ! 293: static XtEventType LookupXtEventType(eventStr) ! 294: char *eventStr; ! 295: ! 296: { ! 297: int i; ! 298: XrmQuark signature; ! 299: ! 300: signature = StringToQuark(eventStr); ! 301: for (i = 0; events[i].event != NULL; i++) ! 302: if (events[i].signature == signature) return i; ! 303: ! 304: Syntax("Unknown event type."); ! 305: return i; ! 306: } ! 307: ! 308: #ifdef notdef ! 309: /* ||| */ ! 310: { ! 311: /*** Parse the repetitions, for double click... ***/ ! 312: if (strcmp(repsStr, "") != NULL) { ! 313: EventSeqPtr tempEvent = curEvent; ! 314: int reps; ! 315: if (repsStr[0] >= '0' && repsStr[0] <= '9') ! 316: reps = StrToNum (repsStr); ! 317: else ! 318: reps = 1; ! 319: for (i=1; i<reps; i++) { ! 320: curEvent->next = (EventSeqPtr) XtMalloc((unsigned)sizeof(EventSeqRec)); ! 321: curEvent = curEvent->next; ! 322: curEvent->str = NULL; ! 323: curEvent->next = NULL; ! 324: curEvent->eventCode = tempEvent->eventCode; ! 325: curEvent->eventType = tempEvent->eventType; ! 326: curEvent->modifiersMask = tempEvent->modifiersMask; ! 327: } ! 328: } ! 329: } ! 330: #endif ! 331: ! 332: /*********************************************************************** ! 333: * LookupTableSym ! 334: * Given a table and string, it fills in the value if found and returns ! 335: * status ! 336: ***********************************************************************/ ! 337: ! 338: static Boolean LookupTableSym(table, name, valueP) ! 339: NameValueTable table; ! 340: char *name; ! 341: Value *valueP; ! 342: { ! 343: /* !!! should implement via hash or something else faster than linear search */ ! 344: ! 345: int i; ! 346: XrmQuark signature = StringToQuark(name); ! 347: ! 348: for (i=0;table[i].name != NULL;i++) ! 349: if (table[i].signature == signature) { ! 350: *valueP = table[i].value; ! 351: return TRUE; ! 352: } ! 353: ! 354: return FALSE; ! 355: } ! 356: ! 357: /*********************************************************************** ! 358: * InterpretAction ! 359: * Given an action, it returns a pointer to the appropriate procedure. ! 360: ***********************************************************************/ ! 361: ! 362: static ActionProc InterpretAction(compiledActionTable, action) ! 363: CompiledActionTable compiledActionTable; ! 364: String action; ! 365: { ! 366: Value actionProc; ! 367: ! 368: if (LookupTableSym(compiledActionTable, action, &actionProc)) ! 369: return (ActionProc) actionProc; ! 370: ! 371: return NULL; ! 372: } ! 373: ! 374: static char * ScanAlphanumeric(str) ! 375: char *str; ! 376: { ! 377: while ( ! 378: ('A' <= *str && *str <= 'Z') || ('a' <= *str && *str <= 'z') ! 379: || ('0' <= *str && *str <= '9')) str++; ! 380: return str; ! 381: } ! 382: ! 383: static char * ScanIdent(str) ! 384: char *str; ! 385: { ! 386: str = ScanAlphanumeric(str); ! 387: while ( ! 388: ('A' <= *str && *str <= 'Z') ! 389: || ('a' <= *str && *str <= 'z') ! 390: || ('0' <= *str && *str <= '9') ! 391: || (*str == '-') ! 392: || (*str == '_') ! 393: || (*str == '$') ! 394: ) str++; ! 395: return str; ! 396: } ! 397: ! 398: static char * ScanWhitespace(str) ! 399: char *str; ! 400: { ! 401: while (*str == ' ' || *str == '\t') str++; ! 402: return str; ! 403: } ! 404: ! 405: static char * ParseModifiers(str, modifierMaskP, modifierP) ! 406: char *str; ! 407: ModifierMask *modifierMaskP; ! 408: ModifierMask *modifierP; ! 409: { ! 410: char *start; ! 411: char modStr[100]; ! 412: Boolean notFlag; ! 413: Value maskBit; ! 414: ! 415: while (*str != '<') { ! 416: str = ScanWhitespace(str); ! 417: if (*str == '~') { notFlag = TRUE; str++; } else notFlag = FALSE; ! 418: start = str; ! 419: str = ScanAlphanumeric(str); ! 420: if (start == str) { ! 421: Syntax("Modifier or '<' expected."); ! 422: return str; ! 423: } ! 424: (void) strncpy(modStr, start, str-start); ! 425: modStr[str-start] = '\0'; ! 426: maskBit = 0; ! 427: if (!LookupTableSym(modifiers, modStr, &maskBit)) ! 428: Syntax("Unknown modifier name."); ! 429: *modifierMaskP |= maskBit; ! 430: if (notFlag) *modifierP &= ~maskBit; else *modifierP |= maskBit; ! 431: } ! 432: return str; ! 433: } ! 434: ! 435: static char * ParseXtEventType(str, eventTypeP) ! 436: char *str; ! 437: XtEventType *eventTypeP; ! 438: { ! 439: char *start = str; ! 440: char eventTypeStr[100]; ! 441: ! 442: str = ScanAlphanumeric(str); ! 443: (void) strncpy(eventTypeStr, start, str-start); ! 444: eventTypeStr[str-start] = '\0'; ! 445: *eventTypeP = LookupXtEventType(eventTypeStr); ! 446: ! 447: return str; ! 448: } ! 449: ! 450: static unsigned int StrToHex(str) ! 451: char *str; ! 452: { ! 453: char c; ! 454: int val = 0; ! 455: ! 456: while (c = *str) { ! 457: if ('0' <= c && c <= '9') val = val*16+c-'0'; ! 458: else if ('a' <= c && c <= 'z') val = val*16+c-'a'+10; ! 459: else if ('A' <= c && c <= 'Z') val = val*16+c-'A'+10; ! 460: else return -1; ! 461: str++; ! 462: } ! 463: ! 464: return val; ! 465: } ! 466: ! 467: static unsigned int StrToOct(str) ! 468: char *str; ! 469: { ! 470: char c; ! 471: int val = 0; ! 472: ! 473: while (c = *str) { ! 474: if ('0' <= c && c <= '7') val = val*8+c-'0'; else return -1; ! 475: str++; ! 476: } ! 477: ! 478: return val; ! 479: } ! 480: ! 481: static unsigned int StrToNum(str) ! 482: char *str; ! 483: { ! 484: char c; ! 485: int val = 0; ! 486: ! 487: if (*str == '0') { ! 488: str++; ! 489: if (*str == 'x' || *str == 'X') return StrToHex(++str); ! 490: else return StrToOct(str); ! 491: } ! 492: ! 493: while (c = *str) { ! 494: if ('0' <= c && c <= '9') val = val*10+c-'0'; ! 495: else return -1; ! 496: str++; ! 497: } ! 498: ! 499: return val; ! 500: } ! 501: ! 502: static KeySym XStringToKeySym(str) ! 503: char *str; ! 504: { ! 505: ! 506: /* ||| replace this with real one when xlib has it... */ ! 507: ! 508: if (str == NULL) return (KeySym) 0; ! 509: if ('0' <= *str && *str <= '9') return (KeySym) StrToNum(str); ! 510: if ('A' <= *str && *str <= 'Z') return (KeySym) *str+'a'-'A'; ! 511: return (KeySym) *str; ! 512: } ! 513: ! 514: static char * ParseKeySym(str, eventCodeMaskP, eventCodeP) ! 515: char *str; ! 516: EventCode *eventCodeMaskP; ! 517: EventCode *eventCodeP; ! 518: { ! 519: char keySymName[100], *start; ! 520: ! 521: str = ScanWhitespace(str); ! 522: ! 523: if (*str == '\\') { ! 524: str++; ! 525: keySymName[0] = *str; ! 526: str++; ! 527: keySymName[1] = '\0'; ! 528: *eventCodeP = XStringToKeySym(keySymName); ! 529: *eventCodeMaskP = ~0L; ! 530: } else if (*str == ',' || *str == ':') { ! 531: /* no detail */ ! 532: *eventCodeP = 0L; ! 533: *eventCodeMaskP = 0L; ! 534: } else { ! 535: start = str; ! 536: while (*str != ',' && *str != ':') str++; ! 537: (void) strncpy(keySymName, start, str-start); ! 538: keySymName[str-start] = '\0'; ! 539: *eventCodeP = XStringToKeySym(keySymName); ! 540: *eventCodeMaskP = ~0L; ! 541: } ! 542: ! 543: return str; ! 544: } ! 545: ! 546: ! 547: static char * ParseTableSym(str, table, eventCodeMaskP, eventCodeP) ! 548: char *str; ! 549: NameValueTable table; ! 550: EventCode *eventCodeMaskP; ! 551: EventCode *eventCodeP; ! 552: { ! 553: char *start = str; ! 554: char tableSymName[100]; ! 555: ! 556: *eventCodeP = 0L; ! 557: str = ScanAlphanumeric(str); ! 558: if (str == start) {*eventCodeMaskP = 0L; return str; } ! 559: (void) strncpy(tableSymName, start, str-start); ! 560: tableSymName[str-start] = '\0'; ! 561: if (! LookupTableSym(table, tableSymName, eventCodeP)) ! 562: Syntax("Unknown Detail Type."); ! 563: *eventCodeMaskP = ~0L; ! 564: ! 565: return str; ! 566: } ! 567: ! 568: ! 569: static char * ParseDetail(str, eventType, eventCodeMaskP, eventCodeP) ! 570: char *str; ! 571: XtEventType eventType; ! 572: EventCode *eventCodeMaskP; ! 573: EventCode *eventCodeP; ! 574: { ! 575: switch (events[eventType].detailType) { ! 576: ! 577: case DetailImmed: ! 578: *eventCodeMaskP = ~0L; ! 579: *eventCodeP = (EventCode) events[eventType].detail; ! 580: return str; ! 581: ! 582: case DetailKeySym: ! 583: str = ParseKeySym(str, eventCodeMaskP, eventCodeP); ! 584: return str; ! 585: ! 586: case DetailTable: ! 587: str = ParseTableSym( ! 588: str, (NameValueTable)events[eventType].detail, ! 589: eventCodeMaskP, eventCodeP); ! 590: return str; ! 591: ! 592: default: ! 593: *eventCodeMaskP = 0L; ! 594: *eventCodeP = 0L; ! 595: return str; ! 596: } ! 597: } ! 598: ! 599: ! 600: static char * ParseEvent(str, eventP) ! 601: char *str; ! 602: EventSeqPtr eventP; ! 603: { ! 604: ModifierMask modifierMask = 0; ! 605: ModifierMask modifiers = 0; ! 606: XtEventType eventType = 0; ! 607: EventCode eventCodeMask = 0L; ! 608: EventCode eventCode = 0L; ! 609: ! 610: str = ParseModifiers(str, &modifierMask, &modifiers); ! 611: if (*str != '<') Syntax("Missing '<'"); else str++; ! 612: str = ParseXtEventType(str, &eventType); ! 613: if (*str != '>') Syntax("Missing '>'"); else str++; ! 614: str = ParseDetail(str, eventType, &eventCodeMask, &eventCode); ! 615: ! 616: eventP->modifierMask = modifierMask; ! 617: eventP->modifiers = modifiers; ! 618: eventP->eventType = (EventType)eventType; ! 619: eventP->eventCodeMask = eventCodeMask; ! 620: eventP->eventCode = eventCode; ! 621: ! 622: return str; ! 623: } ! 624: ! 625: static char * ParseQuotedStringEvent(str, eventP) ! 626: char *str; ! 627: EventSeqPtr eventP; ! 628: { ! 629: int j; ! 630: ! 631: ModifierMask ctrlMask; ! 632: ModifierMask metaMask; ! 633: ModifierMask shiftMask; ! 634: char c; ! 635: char s[2]; ! 636: ! 637: (void) LookupTableSym(modifiers, "Ctrl", (Value *) &ctrlMask); ! 638: (void) LookupTableSym(modifiers, "Meta", (Value *) &metaMask); ! 639: (void) LookupTableSym(modifiers, "Shift", (Value *) &shiftMask); ! 640: ! 641: eventP->modifierMask = ctrlMask | metaMask | shiftMask; ! 642: ! 643: for (j=0; j < 2; j++) ! 644: if (*str=='^' && !(eventP->modifiers | ctrlMask)) { ! 645: str++; ! 646: eventP->modifiers |= ctrlMask; ! 647: } else if (*str == '$' && !(eventP->modifiers | metaMask)) { ! 648: str++; ! 649: eventP->modifiers |= metaMask; ! 650: } else if (*str == '\\') { ! 651: str++; ! 652: c = *str; ! 653: str++; ! 654: break; ! 655: } else { ! 656: c = *str; ! 657: str++; ! 658: break; ! 659: } ! 660: eventP->eventType = (EventType) LookupXtEventType("Key"); ! 661: if ('A' <= c && c <= 'Z') { ! 662: eventP->modifiers |= shiftMask; ! 663: c += 'a' - 'A'; ! 664: } ! 665: s[0] = c; ! 666: s[1] = '\0'; ! 667: eventP->eventCode = XStringToKeySym(s); ! 668: ! 669: return str; ! 670: } ! 671: ! 672: ! 673: /*********************************************************************** ! 674: * ParseEventSeq ! 675: * Parses the left hand side of a translation table production ! 676: * up to, and consuming the ":". ! 677: * Takes a pointer to a char* (where to start parsing) and returns an ! 678: * event seq (in a passed in variable), having updated the char * ! 679: **********************************************************************/ ! 680: ! 681: static char *ParseEventSeq(str, eventSeqP) ! 682: char *str; ! 683: EventSeqPtr *eventSeqP; ! 684: { ! 685: EventSeqPtr *nextEventP = eventSeqP; ! 686: ! 687: *eventSeqP = NULL; ! 688: ! 689: while (*str != ':') { ! 690: EventSeqPtr event; ! 691: ! 692: event = (EventSeqPtr) XtMalloc((unsigned)sizeof(EventSeqRec)); ! 693: event->str = NULL; ! 694: event->modifierMask = 0; ! 695: event->modifiers = 0; ! 696: event->eventType = 0; ! 697: event->eventCodeMask = 0L; ! 698: event->eventCode = 0L; ! 699: event->next = NULL; ! 700: event->actions = NULL; ! 701: ! 702: if (*str == '"') { ! 703: str++; ! 704: while (*str != '"') { ! 705: str = ParseQuotedStringEvent(str, event); ! 706: *nextEventP = event; ! 707: nextEventP = &event->next; ! 708: } ! 709: str++; ! 710: } else { ! 711: str = ParseEvent(str, event); ! 712: *nextEventP = event; ! 713: nextEventP = &event->next; ! 714: } ! 715: str = ScanWhitespace(str); ! 716: if (*str != ':') ! 717: if (*str != ',') { ! 718: Syntax("',' expected."); ! 719: } else str++; ! 720: } ! 721: str++; ! 722: ! 723: return str; ! 724: } ! 725: ! 726: ! 727: static char * ParseActionProc(str, actionProcP, actionProcNameP) ! 728: char *str; ! 729: ActionProc *actionProcP; ! 730: char **actionProcNameP; ! 731: { ! 732: char *start = str; ! 733: char procName[100]; ! 734: ! 735: str = ScanIdent(str); ! 736: (void) strncpy(procName, start, str-start); ! 737: procName[str-start] = '\0'; ! 738: ! 739: /* ||| */ ! 740: /* ! 741: if (! LookupTableSym(procName, actions, actionProcP)) ! 742: Syntax("Unkown action proc."); ! 743: */ ! 744: *actionProcP = NULL; ! 745: *actionProcNameP = strncpy( ! 746: XtMalloc((unsigned)(str-start+1)), procName, str-start+1); ! 747: return str; ! 748: } ! 749: ! 750: ! 751: static char * ParseParamSeq(str, paramSeqP, paramNumP) ! 752: char *str; ! 753: char ***paramSeqP; ! 754: unsigned long *paramNumP; ! 755: { ! 756: /* ||| */ ! 757: *paramSeqP = NULL; ! 758: *paramNumP = 0; ! 759: ! 760: return str; ! 761: } ! 762: ! 763: static char * ParseAction(str, actionP) ! 764: char *str; ! 765: ActionPtr actionP; ! 766: { ! 767: str = ParseActionProc(str, &actionP->proc, &actionP->token); ! 768: if (*str == '(') { ! 769: str++; ! 770: str = ParseParamSeq(str, &actionP->param, &actionP->paramNum); ! 771: } else { Syntax("Missing '('"); } ! 772: if (*str == ')') str++; else Syntax("Missing ')'"); ! 773: ! 774: return str; ! 775: } ! 776: ! 777: ! 778: static char *ParseActionSeq(str, actionsP) ! 779: char *str; ! 780: ActionPtr *actionsP; ! 781: { ! 782: ActionPtr *nextActionP = actionsP; ! 783: ! 784: *actionsP = NULL; ! 785: ! 786: while (*str != '\0') { ! 787: ActionPtr action; ! 788: ! 789: action = (ActionPtr) XtMalloc((unsigned)sizeof(ActionRec)); ! 790: action->token = NULL; ! 791: action->proc = NULL; ! 792: action->param = NULL; ! 793: action->paramNum = 0; ! 794: action->next = NULL; ! 795: ! 796: str = ParseAction(str, action); ! 797: str = ScanWhitespace(str); ! 798: *nextActionP = action; ! 799: nextActionP = &action->next; ! 800: } ! 801: ! 802: return str; ! 803: } ! 804: ! 805: ! 806: /*********************************************************************** ! 807: * ParseTranslationTableProduction ! 808: * Parses one line of event bindings. ! 809: ***********************************************************************/ ! 810: ! 811: static void ParseTranslationTableProduction(w, compiledActionTable, str) ! 812: Widget w; ! 813: CompiledActionTable compiledActionTable; ! 814: char *str; ! 815: { ! 816: EventSeqPtr eventSeq = NULL; ! 817: ActionPtr actions = NULL; ! 818: ! 819: EventSeqPtr esp; ! 820: ActionPtr ap; ! 821: ! 822: str = ParseEventSeq(str, &eventSeq); ! 823: str = ScanWhitespace(str); ! 824: str = ParseActionSeq(str, &actions); ! 825: ! 826: for (esp=eventSeq; esp!=NULL; esp=esp->next) { ! 827: XtAddEventHandler( ! 828: w, ! 829: events[esp->eventType].mask, ! 830: (Boolean) (events[esp->eventType].mask == 0), ! 831: TranslateEvent, (Opaque) NULL); ! 832: #ifdef ndef ! 833: /* double click needs to make sure that you have selected on both ! 834: button down and up. */ ! 835: if (events[esp->eventType].mask & ButtonPressMask) ! 836: XtAddEventHandler( ! 837: w, ButtonReleaseMask, FALSE, TranslateEvent, NULL); ! 838: if (events[esp->eventType].mask & ButtonReleaseMask) ! 839: XtAddEventHandler( ! 840: w, ButtonPressMask, FALSE, TranslateEvent, NULL); ! 841: #endif ! 842: if (esp->next == NULL) { ! 843: /* put the action procs in at the end */ ! 844: esp->actions = actions; ! 845: } ! 846: /* change translation manager events into real x events */ ! 847: esp->eventType = events[esp->eventType].eventType; ! 848: /* don't use esp->eventType as an index into event from here on... */ ! 849: w->core.translations->eventObjTbl = EventMapObjectCreate( ! 850: w->core.translations, esp); ! 851: } ! 852: ! 853: /* run down the action list, binding action names to procs */ ! 854: for (ap=actions; ap!=NULL; ap=ap->next) { ! 855: ap->proc = InterpretAction(compiledActionTable, ap->token); ! 856: } ! 857: ! 858: /* add the events and actions to the state table */ ! 859: w->core.translations->eventObjTbl = EventMapObjectSet( ! 860: w->core.translations, eventSeq); ! 861: ! 862: FreeEventSeq(eventSeq); ! 863: ! 864: } ! 865: ! 866: /* ! 867: * Parses a user's or applications translation table ! 868: */ ! 869: ! 870: static void ParseTranslationTable(w, compiledActionTable) ! 871: Widget w; ! 872: CompiledActionTable compiledActionTable; ! 873: { ! 874: char **translationTableSource = (char **)w->core.translations; ! 875: int i; ! 876: ! 877: w->core.translations = ! 878: (_XtTranslations) XtMalloc((unsigned) sizeof(TranslationData)); ! 879: w->core.translations->numEvents = 0; ! 880: w->core.translations->eventTblSize = 0; ! 881: w->core.translations->eventObjTbl = NULL; ! 882: ! 883: /* !!! need some way of setting this !!! */ ! 884: w->core.translations->clickTime = 50; ! 885: ! 886: i = 0; ! 887: while (translationTableSource[i]) { ! 888: ParseTranslationTableProduction( ! 889: w, compiledActionTable, translationTableSource[i]); ! 890: i++; ! 891: } ! 892: ! 893: } ! 894: ! 895: /*** public procedures ***/ ! 896: ! 897: void DefineTranslation(w) ! 898: Widget w; ! 899: { ! 900: /* this procedure assumes that there is a string table in the */ ! 901: /* core.translations field. It compiles it, combines it with */ ! 902: /* the action bindings and puts the resulting internal data */ ! 903: /* structure into the core.translations field. Note that this means */ ! 904: /* that if you call DefineTranslation twice, bad things will happen */ ! 905: ! 906: CompiledActionTable compiledActionTable; ! 907: ! 908: if (w->core.widget_class->core_class.actions == NULL) return; ! 909: ! 910: compiledActionTable = ! 911: CompileActionTable( ! 912: w->core.widget_class->core_class.actions, ! 913: w->core.widget_class->core_class.num_actions); ! 914: ParseTranslationTable(w, compiledActionTable); ! 915: FreeCompiledActionTable(compiledActionTable); ! 916: ! 917: ! 918: /* double click needs to make sure that you have selected on both ! 919: button down and up. */ ! 920: #ifdef ndef ! 921: if (w->core.event_mask & ButtonPressMask || ! 922: w->core.event_mask & ButtonReleaseMask) ! 923: w->core.event_mask |= ButtonPressMask | ButtonReleaseMask; ! 924: #endif ! 925: } ! 926: ! 927: void TranslateInitialize() ! 928: { ! 929: if (initialized) return; ! 930: ! 931: initialized = TRUE; ! 932: ! 933: Compile_XtEventTable( events ); ! 934: CompileNameValueTable( modifiers ); ! 935: CompileNameValueTable( buttonNames ); ! 936: CompileNameValueTable( notifyModes ); ! 937: CompileNameValueTable( notifyDetail ); ! 938: CompileNameValueTable( visibilityNotify ); ! 939: CompileNameValueTable( circulation ); ! 940: CompileNameValueTable( propertyChanged ); ! 941: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.