/* * processing of INP_KEY */ LOCAL BOOL execINP_KEY( InnerEvent *evt, ReceiveData *msg ) { KeyTop keytop; UW kbsel; KeyState *ks; if ( msg->head.cmd.err != DEV_OK ) { /* resetting key state due to error */ kpAllResetKeyMap(); if ( isQueEmpty(&StatMach.useq) ) return FALSE; kpExecKeyStateMachine((KeyState*)StatMach.useq.next, evt, msg); return !isQueEmpty(&StatMach.useq); } keytop = toKeyTop(&msg->kb); /* look for KeyState that matches keytop */ ks = (KeyState*)QueSearch(&StatMach.useq, &StatMach.useq, keytop.w, offsetof(KeyState, keytop.w)); kbsel = ( ks == (KeyState*)&StatMach.useq )? kpMgrInfo.kpState.stat.kbsel: ks->kbsel; /* change keymap */ kpSetOrResetKeyMap(keytop, kbsel, msg->kb.stat.press); if ( ks == (KeyState*)&StatMach.useq ) { /* search empty KeyState */ ks = (KeyState*)QueRemoveNext(&StatMach.freq); if ( ks == NULL ) return FALSE; /* initialize KeyState */ ks->keytop = keytop; ks->kbsel = kbsel; ks->state = ( kpGetKeyKind(keytop) <= NormalKey )? KS_RELEASE: SS_RELEASE; memset(&ks->u, 0, sizeof(ks->u)); QueInsert((QUEUE*)ks, &StatMach.useq); } /* execute the state machine */ kpExecKeyStateMachine(ks, evt, msg); return FALSE; }
/* * shift key : release status */ LOCAL KState ssRelease( KeyState *skey, InnerEvent *evt, ReceiveData *msg ) { W keykind; SYSTIM lnow; UW now; ER err; if ( msg == NULL ) return SS_RELEASE; switch ( msg->head.cmd.cmd ) { case INP_KEY: if ( msg->kb.stat.press != 0 ) break; /* no break */ default: return SS_RELEASE; } /* current time */ err = tk_get_tim(&lnow); if ( err != E_OK ) { DEBUG_PRINT(("ssRelease, tk_get_tim err = %d\n", err)); return SS_ERROR; } now = lnow.lo; /* repeated press during the time interval for double click, key type is not changed. */ if ( !(skey->u.s.pressCount == 1 && (now - skey->u.s.pressTime) <= keyMode.dclktime) ) { /* key type */ keykind = kpGetKeyKind(skey->keytop); if ( keykind <= NormalKey ) { /* enter the ordinary state machine for normal keys */ memset(&skey->u.i, 0, sizeof(skey->u.i)); return KS_RELEASE; } skey->u.s.skind = keykind; } return SS_ONTIME; }
/* * direct input key: release status */ LOCAL KState ksRelease( KeyState *inkey, InnerEvent *evt, ReceiveData *msg ) { W keykind = kpGetKeyKind(inkey->keytop); if ( msg == NULL ) { if ( keykind == NormalKey ) { StatMach.keyPress--; /* quasi-event for key up notification */ sendPseudoKeyUpMsg(); } kpReleaseKey(inkey); return KS_RELEASE; } switch ( msg->head.cmd.cmd ) { case INP_KEY: if ( msg->kb.stat.press == 0 ) { kpReleaseKey(inkey); return KS_RELEASE; } break; case PIC_KEYUP: /* previous key was released */ break; default: return KS_RELEASE; } /* If ON effective or ineffective period is not zero, simultaneous pressing of multiple keys is * not allowed. However, main CC keys are exceptions. */ if ( StatMach.keyPress > 0 && keykind == NormalKey && (keyMode.ontime > 0 || keyMode.invtime > 0) ) return KS_RELEASE; if ( keykind == NormalKey ) StatMach.keyPress++; return KS_ONTIME; }