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

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

unix.superglobalmegacorp.com

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