📄 evtque.c
字号:
/* *---------------------------------------------------------------------- * T-Kernel / Standard Extension * * Copyright (C) 2006 by Ken Sakamura. All rights reserved. * T-Kernel / Standard Extension is distributed * under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* * evtque.c (event) * * Event management * Event queue and its related processing */#include "evtmgr.h"#include <extension/message.h>LOCAL void keyRptCycHdr( void );LOCAL W getFirstEvtMask( W t_mask, SYSTIME now );LOCAL WER getFirstEvtType( void );LOCAL ER emGetEvtQue( W t_mask, EVENT *evt, W opt );LOCAL ER emPutEvtQue( EVENT *evt, W opt );LOCAL void emRmvEvtQue( W t_mask, W last_mask );#define TSD_TLE_VAL_15 15#define TSD_GEM_POS_0 0#define TSD_GEM_POS_1 1#define TSD_GEM_POS_2 2#define TSD_GEM_POS_3 3#define TSD_GEM_POS_5 5#define TSD_GEM_POS_6 6#define TSD_GEM_POS_7 7#define TSD_GEM_POS_8 8#define TSD_GEM_POS_9 9#define TSD_GEM_POS_10 10#define TSD_GEM_POS_11 11#define TSD_GEM_POS_12 12#define TSD_GEM_POS_13 13#define TSD_GEM_POS_14 14#define TSD_GEQ_VAL_0X8000 0x8000U#define TSD_TLE_VAL_0X7FFFFFFF (long)0x7fffffff/* * Cyclic start handler for key repeat */LOCAL void keyRptCycHdr( void ){ evtque.keyRpt.timing = TRUE; tkse_brk_msg();}/* * Start/Stop the key repeat * Stop when interval = 0. */EXPORT ER emSetKeyRepeat( W offset, W interval, BOOL force ){ T_CCYC ccyc; ER err; evtque.keyRpt.timing = FALSE; if ( !force && (interval == evtque.keyRpt.interval) ) { return E_OK; /* Continue */ } if ( evtque.keyRpt.cycid > 0 ) { /* Stop */ tk_del_cyc(evtque.keyRpt.cycid); evtque.keyRpt.cycid = 0; } if ( interval > 0 ) { /* Start */ SetOBJNAME(ccyc.exinf, "Evt"); ccyc.cycatr = TA_HLNG | TA_STA; ccyc.cychdr = keyRptCycHdr; ccyc.cyctim = (UW)interval; ccyc.cycphs = (UW)offset; err = tk_cre_cyc(&ccyc); if ( err < E_OK ) { err = ERtoERR(err); goto err_ret; } evtque.keyRpt.cycid = (ID)err; } evtque.keyRpt.interval = interval; return E_OK;err_ret: evtque.keyRpt.interval = 0; DEBUG_PRINT(("emSetKeyRepeat err = %d\n", err)); return err;}/* ------------------------------------------------------------------------ */#define XEM_WHEEL 0x00010000 /* Wheel event pseudo mask *//* * Event priority mask */#define EPM_1 (EM_APPL1|EM_APPL2|EM_APPL3|EM_APPL4)#define EPM_2 (EM_BUTDWN|EM_BUTUP|EM_KEYDWN|EM_KEYUP)#define EPM_3 (EM_AUTKEY)#define EPM_4 (EM_DEVICE|EM_EXDEV)#define EPM_5 (EM_APPL5|EM_APPL6|EM_APPL7|EM_APPL8)#define EPM_6 (XEM_WHEEL)#define EPM_7 (0)/* * Obtain the event priority mask of the highest priority in the event queue in t_mask. */LOCAL W getFirstEvtMask( W t_mask, SYSTIME now ){ SYSTIME life; if ( ((t_mask & EM_APPL1) != 0) && (evtque.cnt[TSD_GEM_POS_7] > 0) ) { return EPM_1; } if ( ((t_mask & EM_APPL2) != 0) && (evtque.cnt[TSD_GEM_POS_8] > 0) ) { return EPM_1; } if ( ((t_mask & EM_APPL3) != 0) && (evtque.cnt[TSD_GEM_POS_9] > 0) ) { return EPM_1; } if ( ((t_mask & EM_APPL4) != 0) && (evtque.cnt[TSD_GEM_POS_10] > 0) ) { return EPM_1; } if ( ((t_mask & EM_BUTDWN) != 0) && (evtque.cnt[TSD_GEM_POS_0] > 0) ) { return EPM_2; } if ( ((t_mask & EM_BUTUP) != 0) && (evtque.cnt[TSD_GEM_POS_1] > 0) ) { return EPM_2; } if ( ((t_mask & EM_KEYDWN) != 0) && (evtque.cnt[TSD_GEM_POS_2] > 0) ) { return EPM_2; } if ( ((t_mask & EM_KEYUP) != 0) && (evtque.cnt[TSD_GEM_POS_3] > 0) ) { return EPM_2; } if ( ((UW)t_mask & evtque.sysEvtMsk & EM_AUTKEY) != 0U ) { if ( (evtque.keyRpt.interval > 0) && evtque.keyRpt.timing ) { return EPM_3; } } if ( ((t_mask & EM_DEVICE) != 0 )&&( evtque.cnt[TSD_GEM_POS_5] > 0 )) { return EPM_4; } if ( ((t_mask & EM_EXDEV) != 0 )&&( evtque.cnt[TSD_GEM_POS_6] > 0 )) { return EPM_4; } if ( ((t_mask & EM_APPL5) != 0 )&&( evtque.cnt[TSD_GEM_POS_11] > 0 )) { return EPM_5; } if ( ((t_mask & EM_APPL6) != 0 )&&( evtque.cnt[TSD_GEM_POS_12] > 0 )) { return EPM_5; } if ( ((t_mask & EM_APPL7) != 0 )&&( evtque.cnt[TSD_GEM_POS_13] > 0 )) { return EPM_5; } if ( ((t_mask & EM_APPL8) != 0 )&&( evtque.cnt[TSD_GEM_POS_14] > 0 )) { return EPM_5; } if ( ((t_mask & EM_AUTKEY) != 0 )&&( evtque.wheel != 0 )) { life = ll_add(evtque.lastWheel, ltoll(emInfo.evtLifeTime)); if ( ll_cmp(life, now) >= (SYSTIME)0 ) { return EPM_6; } } return EPM_7;}/* * Obtain the event type of the highest priority in the event queue. */LOCAL WER getFirstEvtType( void ){ W msk; EmEvt *ep; SYSTIME now; getEvtTime(&now); msk = getFirstEvtMask(EM_ALL, now); switch ( msk ) { case EM_NULL: return EV_NULL; case XEM_WHEEL: case EM_AUTKEY: return EV_AUTKEY; default: /* nothing to do */ break; } ep = (EmEvt*)evtque.que.next; if ( ep == (EmEvt*)&evtque.que ) { return E_SYS; } return ep->evt.type;}/* * Fetch from the event queue. */LOCAL ER emGetEvtQue( W t_mask, EVENT *evt, W opt ){ W mask; SYSTIME now; EmEvt *ep; Enter; getEvtTime(&now); /* Obtain the event priority mask of the highest priority in the queue in t_mask. */ mask = getFirstEvtMask(t_mask, now); switch ( mask ) { case EM_NULL: /* Set the null event. */ evt->type = EV_NULL; evt->time = (UW)lltol(now); evt->pos = evtque.pos; evt->stat = evtque.stat; evt->data.info = 0; break; case EM_AUTKEY: /* Set the key repeat event. */ evt->type = EV_AUTKEY; evt->time = (UW)lltol(now); evt->pos = evtque.pos; evt->stat = evtque.stat; evt->data.key.keytop = evtque.keytop; evt->data.key.code = evtque.code; setLastEvt(EV_AUTKEY, now); break; case XEM_WHEEL: /* Set the wheel event. */ evt->type = EV_AUTKEY; evt->time = (UW)lltol(evtque.lastWheel); evt->pos = evtque.pos; evt->stat = evtque.stat; evt->data.key.keytop = (UH)(TSD_GEQ_VAL_0X8000 + evtque.wheel); evt->data.key.code = ( evtque.wheel > 0 )? KC_SS_D: KC_SS_U; break; default: /* Retrieve a target event from the event queue. */ mask &= t_mask; for ( ep = (EmEvt*)evtque.que.next; ep != (EmEvt*)&evtque.que; ep = (EmEvt*)ep->q.next ) { if ( (toEvtMsk(ep->evt.type) & (UW)mask) != 0 ) { break; } } if ( ep == (EmEvt*)&evtque.que) { Return (E_SYS); } /* Fetch the event. */ *evt = ep->evt; if ( opt == CLR ) { /* Delete from the event queue. */ rmvEmEvt(ep); freeEmEvt(ep); } break; } if ( evt->type != EV_NULL ) { /* Delete the wheel event. */ evtque.wheel = 0; } if ( mask == XEM_WHEEL ) { Return (E_OK); } /* Set the timing of the key repeat. */ switch ( evt->type ) { case EV_KEYDWN: if ( evtque.pressKey && ((evt->data.key.keytop >= KEYMAX) || (BTST(emInfo.repeatKeymap, (W)evt->data.key.keytop) != 0)) ) { /* When a key is being pressed currently * and it is a repeat key, start the repeat. * (When key top code is beyond the repeat key map, * it is handled as a repeat key.) */ (void)emSetKeyRepeat(emInfo.repeatOffset, emInfo.repeatInterval, TRUE); } else { (void)emSetKeyRepeat(0, 0, FALSE); } break; case EV_AUTKEY: (void)emSetKeyRepeat(emInfo.repeatOffset, emInfo.repeatInterval, FALSE); break; case EV_KEYUP: /* Normally, the repeat is stopped in the device event receiving task side. Stop the repeat here just to be on the safe side. */ (void)emSetKeyRepeat(0, 0, FALSE); break; default: /* nothing to do */ break; } Return (E_OK);}/* * Register in the event queue. */LOCAL ER emPutEvtQue( EVENT *evt, W opt ){ EmEvt *ep; SYSTIME now; Enter; /* Ignore if the system event mask is 0. */ if ( !isMatchEvtMsk(evt->type) ) { Return (E_OK); } /* Reserve free entry for the queue. */ ep = newEmEvt(); if ( ep == NULL ) { Return (E_SYSMEM); } ep->evt = *evt; /* Current time */ getEvtTime(&now); if ( (opt & EP_TIME) != 0 ) { /* Set the current time to the event. */ ep->evt.time = (UW)lltol(now); } if ( (opt & EP_POS) != 0 ) { /* Set the current PD position to the event. */ ep->evt.pos = evtque.pos; } if ( (opt & EP_STAT) != 0 ) { /* Set the current metakey and PD button state to the event. */ ep->evt.stat = evtque.stat; } /* Add to the event queue. */ putEmEvt(ep); setLastEvt(ep->evt.type, now); /* Send the event message. */ (void)emSendEvtMsg(&ep->evt, NULL, 0); Return (E_OK);}/* * Delete the event from the event queue. */LOCAL void emRmvEvtQue( W t_mask, W last_mask ){ EmEvt *ep, *next; W msk; Enter; for ( ep = (EmEvt*)evtque.que.next; ep != (EmEvt*)&evtque.que; ep = next ) { next = (EmEvt*)ep->q.next; msk = (W)toEvtMsk(ep->evt.type); if ( ((msk & last_mask) != 0) && (last_mask != EM_ALL) ) { break; } if ( (msk & t_mask) != 0 ) { /* Delete the event. */ rmvEmEvt(ep); freeEmEvt(ep); if ( last_mask == EM_ALL ) { break; } } } Exit;}/* ------------------------------------------------------------------------ *//* * Obtain the event. */EXPORT WER _tkse_get_evt( W t_mask, EVENT *evt, W opt ){ ER err; err = CheckSpaceRW(evt, sizeof(EVENT)); if ( err < E_OK ) { goto err_ret; } /* Parameter check */ if ( ((opt != CLR) && (opt != NOCLR)) || (((UW)t_mask & ~(UW)EM_ALL) != 0) || (t_mask == 0) ) { err = E_PAR; goto err_ret; } /* Fetch from the event queue. */ err = emGetEvtQue(t_mask, evt, opt); if ( err < E_OK ) { goto err_ret; } return evt->type;err_ret: DEBUG_PRINT(("_tkse_get_evt err = %d\n", err)); return err;}/* * Event occurrence */EXPORT ER _tkse_put_evt( EVENT *evt, W opt ){ ER err; err = CheckSpaceR(evt, sizeof(EVENT)); if ( err < E_OK ) { goto err_ret; } /* Parameter check */ if ( (((UW)opt & ~(UW)EP_ALL) != 0) || (evt->type > EV_APPL8) || (evt->type <= EV_NULL) || (evt->type == EV_AUTKEY) ) { err = E_PAR; goto err_ret; } /* Add to the event queue. */ err = emPutEvtQue(evt, opt); if ( err < E_OK ) { goto err_ret; } /* Notify the message management of the event occurrence. */ tkse_brk_msg(); return E_OK;err_ret: DEBUG_PRINT(("_tkse_put_evt err = %d\n", err)); return err;}/* * Delete the event. */EXPORT ER _tkse_clr_evt( W t_mask, W last_mask ){ ER err; /* Parameter check */ if ( (((UW)t_mask & ~(UW)EM_ALL) != 0) || (t_mask == 0) || (((UW)last_mask & ~(UW)EM_ALL) != 0) ) { err = E_PAR; goto err_ret; } /* Delete the event from the event queue. */ emRmvEvtQue(t_mask, last_mask); return E_OK;err_ret: DEBUG_PRINT(("_tkse_clr_evt err = %d\n", err)); return err;}/* * Change the system event mask. */EXPORT WER _tkse_chg_emk( W mask ){ UW curmsk; Enter; curmsk = evtque.sysEvtMsk; if ( mask >= 0 ) { evtque.sysEvtMsk = (UW)mask & (UW)EM_ALL; } Return ((WER)curmsk);}/* * Obtain the PD position. */EXPORT WER _tkse_get_pdp( PNT *pos ){ WER err; err = CheckSpaceRW(pos, sizeof(PNT)); if ( err < E_OK ) { goto err_ret; } LOCK_EM( *pos = evtque.pos; err = getFirstEvtType(); ); return err;err_ret: DEBUG_PRINT(("_tkse_get_pdp err = %d\n", err)); return err;}/* * Obtain the elapsed time from the last event occurrence. */EXPORT WER _tkse_las_evt( W t_mask ){ SYSTIME now; W i; ER err; /* Parameter check */ if ( ((UW)t_mask & ~(UW)EM_ALL) != 0 ) { err = E_PAR; goto err_ret; } Enter; /* Current time */ getEvtTime(&now); if ( t_mask == EM_NULL ) { /* Reset the time of the last event occurrence. */ for ( i = 0; i < TSD_TLE_VAL_15; ++i ) { evtque.last[i] = now; } err = E_OK; } else { SYSTIME last = ltoll(0); /* Obtain the time of the last event occurrence. */ for ( i = 0; i < TSD_TLE_VAL_15; ++i, t_mask >>= 1 ) { if ( (t_mask & 1) == 0 ) { continue; } if ( ll_cmp(evtque.last[i], last) > (longlong)0 ) { last = evtque.last[i]; } } /* Obtain the elapsed time. */ last = ll_sub(now, last); err = ( ll_cmp(last, ltoll(TSD_TLE_VAL_0X7FFFFFFF)) > (longlong)0 )? TSD_TLE_VAL_0X7FFFFFFF: lltol(last); } Return (err);err_ret: DEBUG_PRINT(("_tkse_las_evt err = %d\n", err)); return err;}/* ------------------------------------------------------------------------ *//* * Generate/Initialize an event queue. */EXPORT ER emInitEvtQue( void ){ EmEvt *bp; ER err; W i; QueInit(&evtque.que); QueInit(&evtque.free); evtque.sysEvtMsk = EM_NULL; /* Reserve the memory to store an event. */ bp = (EmEvt*)Kmalloc(sizeof(EmEvt) * (UW)emInfo.maxEvtQue); if ( bp == NULL ) { err = E_SYSMEM; goto err_ret; } evtque.buf = bp; /* Register the event storing area in free list. */ for ( i = 0; i < emInfo.maxEvtQue; ++i ) { QueInsert(&bp->q, &evtque.free); bp++; } return E_OK;err_ret: DEBUG_PRINT(("emInitEvtQue err = %d\n", err)); return err;}/* * Delete the event queue. */EXPORT ER emDeleteEvtQue( void ){ /* Release the cyclic start handler for key repeat. */ if ( evtque.keyRpt.cycid > 0 ) { tk_del_cyc(evtque.keyRpt.cycid); } /* Release the event storing area. */ if ( evtque.buf != NULL ) { Kfree((VB*)evtque.buf); } return E_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -