Annotation of researchv9/X11/src/X.V11R1/lib/Xtk/TMparse.c, revision 1.1.1.1

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: } 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.