FreeCalypso > hg > fc-tourmaline
view src/ui/mfw/mfw_kbd.c @ 292:0f688d07b068
block deep sleep on activity in new PWT and vibrator drivers
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 27 Mar 2022 00:29:19 +0000 |
parents | 7160f0d005d2 |
children |
line wrap: on
line source
/* +--------------------------------------------------------------------+ | PROJECT: MMI-Framework (8417) $Workfile:: mfw_kbd.c $| | $Author:: Es $ CONDAT GmbH $Revision:: 18 $| | CREATED: 21.09.98 $Modtime:: 23.03.00 8:24 $| | STATE : code | +--------------------------------------------------------------------+ MODULE : MFW_KBD PURPOSE : keyboard handling functions EXPORT : TO DO : adjust PEI/driver interface HISTORY : Sep 14, 2007 REF: OMAPS00145862 Adrian Salido Description: FT - MMI: Wrong trace class Solution: changed some event traces to function traces because the information content of this is low for non-MMI people and against TI coding convention. Oct 13, 2006 REF: OMAPS00097121 - x0039928 Description: Keyboard pressed in a loop. KBP_R after suspend-resume Solution : If the Auto press timer expires mmi checks the bsp kpd status and accordingly sets auto key in the key map. Sep 18, 2006 REF: OMAPS00094426 - x0039928 Description: Locosto - KPD Release event would NOT be generated if a key is pressed several times in a short period of time Solution : If the long press timer expires mmi checks the bsp kpd status and accordingly sets long press bit in the key map. xrashmic 22 Aug, 2004 MMI-SPR-32798 Adding the support for screen capture using a dynamically assigned key. Apr 03, 2005 REF: CRR 29988 - xpradipg Description: Optimisation 2: Reduce the keyboard buffer and the dtmf buffer size Solution : The keyboard buffer is reduced to 20 from 50 */ #define ENTITY_MFW #include "typedefs.h" #include "vsi.h" #include "pei.h" #include "custom.h" #include "gsm.h" #include <stdio.h> #include <string.h> #include "mfw_mfw.h" #include "mfw_sys.h" #include "mfw_tim.h" #include "drv_key.h" #include "mfw_win.h" #include "mfw_kbd.h" /* BEGIN ADD: Req ID: : Sumit : 14-Mar-05 */ #ifndef NEPTUNE_BOARD /* END ADD: Req ID: : Sumit : 14-Mar-05 */ #include "kpd/kpd_api.h" /* BEGIN ADD: Req ID: : Sumit : 14-Mar-05 */ #else #include "ti1_key.h" #endif /* NEPTUNE_BOARD*/ /* END ADD: Req ID: : Sumit : 14-Mar-05 */ #include "mfw_ffs.h" #include "mfw_utils.h" #include "mfw_mme.h" static int kbdCommand (U32 cmd, void *h); static int toLong (U32 t, void *h); static int toAuto (U32 t, void *h); static MfwCb doAlways; /* all cases handler */ static MfwHdr timLongH; /* the long press timer */ static MfwTim timLong; static MfwHdr timAutoH; /* the auto repeat timer */ static MfwTim timAuto; static U32 valAuto; /* auto start intervall */ static U32 valRepeat; /* auto repeat intervall */ static U32 curMap; /* current key map */ static U8 curKey; /* current key code */ static int still_processing_flag; // PATCH LE 06.06.00 // current MFW element needed for multiple instances EXTERN MfwHdr * current_mfw_elem; // END PATCH LE 06.06.00 /* ** KeyPress Buffer Macros and Limits */ // Apr 03, 2005 REF: CRR 29988 - xpradipg // Keyboard buffer reduced from 50 to 20 #ifdef FF_MMI_REDUCED_KBD_BUFFER #define MAX_KPRESS_BFR 20 #else #define MAX_KPRESS_BFR 50 #endif typedef struct keyPressDetailsTag { char make; char key; } keyPressDetails; // Sep 18, 2006 REF: OMAPS00094426 - x0039928 #if(BOARD == 71) UBYTE kpd_key; #endif static keyPressDetails keyPressBfr[MAX_KPRESS_BFR]; static SHORT mfw_kbd_kpress_buf_id; extern void sendKeyInd( T_KPD_VIRTUAL_KEY_ID virtual_key_id, T_KPD_KEY_STATE key_state, T_KPD_PRESS_STATE press_state); extern char drvGetKeyIndex( char key); /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbdInit | +--------------------------------------------------------------------+ PURPOSE : initialize keyboard handler */ MfwRes kbdInit (void) { timLong.time = 0; /* setup long press timer */ timLong.left = 0; timLong.handler = toLong; timLong.next = 0; timLongH.data = &timLong; timLongH.type = MfwTypTim; timAuto.time = 0; /* setup auto repeat timer */ timAuto.left = 0; timAuto.handler = toAuto; timAuto.next = 0; timAutoH.data = &timAuto; timAutoH.type = MfwTypTim; valAuto = valRepeat = 0; keyInit(kbdSignal); /* init keyboard driver */ mfwCommand[MfwTypKbd] = (MfwCb) kbdCommand; doAlways = 0; mfw_kbd_kpress_buf_id = mfw_cbuf_create(MAX_KPRESS_BFR, sizeof(keyPressDetails), FALSE, 0xFF, TRUE, keyPressBfr); if (mfw_kbd_kpress_buf_id < 0) TRACE_EVENT_P1("ERROR : mfw_cbuf_create failed with error value %d", mfw_kbd_kpress_buf_id); return MfwResOk; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbdExit | +--------------------------------------------------------------------+ PURPOSE : finalize keyboard handler */ MfwRes kbdExit (void) { mfwCommand[MfwTypKbd] = 0; keyExit(); return MfwResOk; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbdAlways | +--------------------------------------------------------------------+ PURPOSE : create keyboard control for all events */ MfwCb kbdAlways (MfwCb f) { MfwCb always = doAlways; doAlways = f; if (!f) { timStop(&timLongH); timStop(&timAutoH); } return always; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbdTime | +--------------------------------------------------------------------+ PURPOSE : define keyboard timeouts */ void kbdTime (long tLong, long tAuto, long tRepeat) { timLong.time = tLong; /* setup long press timer */ timAuto.time = tAuto; /* setup auto repeat timer */ valAuto = tAuto; /* save auto start timeout */ valRepeat = tRepeat; /* save repeat intervall */ } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbdCreate | +--------------------------------------------------------------------+ PURPOSE : create keyboard control */ MfwHnd kbdCreate (MfwHnd w, MfwEvt e, MfwCb f) { MfwHdr *hdr = (MfwHdr *) mfwAlloc(sizeof(MfwHdr)); MfwKbd *kbd = (MfwKbd *) mfwAlloc(sizeof(MfwKbd)); MfwHdr *insert_status =0; if (!hdr || !kbd) { TRACE_ERROR("ERROR: kbdCreate() Mem Alloc Failed."); if(hdr) mfwFree((U8*)hdr,sizeof(MfwHdr)); if(kbd) mfwFree((U8*)kbd,sizeof(MfwKbd)); return 0; } kbd->map = e; kbd->key = 0; kbd->handler = f; hdr->data = kbd; hdr->type = MfwTypKbd; insert_status = mfwInsert(w,hdr); if(!insert_status) { TRACE_ERROR("ERROR: kbdCreate() Failed to Install Handler. "); mfwFree((U8*)hdr,sizeof(MfwHdr)); mfwFree((U8*)kbd ,sizeof(MfwKbd)); return 0; } return insert_status; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbdDelete | +--------------------------------------------------------------------+ PURPOSE : delete keyboard control */ MfwRes kbdDelete (MfwHnd h) { MfwRes res; if (!h) return MfwResIllHnd; res = (mfwRemove(h)) ? MfwResOk : MfwResIllHnd; mfwFree(((MfwHdr *) h)->data,sizeof(MfwKbd)); mfwFree(h,sizeof(MfwHdr)); return res; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : sigExec | +--------------------------------------------------------------------+ PURPOSE : execute keyboard signal if the registered set of keys match the currently pressed key, the event handler is called, if the registered flags match the current flags according to the following table: M: Make/Break (key release events wanted) L: Long press event (timeout set via kbdTime()) A: Auto repeat event (timing defined via kbdTime()) M 0 0 0 0 1 1 1 1 current event flags --------- L 0 0 0 0 0 0 1 1 A 0 0 0 0 0 1 0 1 M L A ................. 0 0 0 . 0 0 0 0 1 0 0 0 0 0 1 . 0 0 0 0 1 1 0 1 registered 0 1 0 . 0 0 0 0 0 0 1 1 event ----------- 0 1 1 . 0 0 0 0 0 1 1 1 flags 1 0 0 . 1 1 1 1 1 0 0 0 1 0 1 . 1 1 1 1 1 1 0 1 1 1 0 . 1 1 1 1 0 0 1 1 1 1 1 . 1 1 1 1 0 1 1 1 */ static int sigExec (MfwHdr *curElem, U32 map, U8 key) { MfwKbd *kc; while (curElem) { if (curElem->type == MfwTypKbd) { kc = curElem->data; if (kc->map & map & ~KEY_FLAGS) { /* keys match */ kc->code = key; /* set current key code */ if (map & KEY_MAKE) { kc->key |= map; /* set key in control block */ } else { kc->key &= ~map; /* del key in control block */ kc->key &= ~KEY_MAKE; /* del make/break flag */ } if ((KEY_MAKE & ~map & kc->map) || (KEY_MAKE & map && ((KEY_LONG & map & kc->map) || (!(KEY_LONG & kc->map) && (KEY_AUTO & kc->map & map)) || (!(KEY_LONG & map) && !(KEY_AUTO & map) && !(KEY_LONG & kc->map)) || (!(KEY_LONG & map) && (KEY_AUTO & map) && (KEY_AUTO & kc->map))))) { if (kc->handler) /* handler valid */ { // PATCH LE 06.06.00 // store current mfw elem current_mfw_elem = curElem; // END PATCH LE 06.06.00 if ((*(kc->handler))(map,kc)) return 1; /* event consumed */ } } } } curElem = curElem->next; } return 0; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : sigDistribute | +--------------------------------------------------------------------+ PURPOSE : distribute keyboard event */ static void sigDistribute (U32 map, U8 key) { int res = 0; TRACE_EVENT("sigDistribute"); if (doAlways) if (doAlways(map,(void*) -1)) return; /* event consumed */ if (mfwSignallingMethod == 0) { if (mfwFocus) res = sigExec(mfwFocus,map,key); if (!res && mfwRoot) res = sigExec(mfwRoot,map,key); } else { MfwHdr *h = mfwFocus; if (!h) h = mfwRoot; while (h) { res = sigExec(h,map,key); /* Warning correction - x0020906 - 14-08-2006*/ if (res) break; if (h == mfwRoot) break; h = mfwParent(mfwParent(h)); if (h) h = ((MfwWin *)(h->data))->elems; } if (!res && mfwRoot && h != mfwRoot) res = sigExec(mfwRoot,map,key); } if (doAlways) (void)(doAlways(map,(void*) res));/*a0393213 lint warnings removal - void cast is done to avoid lint warning though the function returns int*/ return; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbdSignal | +--------------------------------------------------------------------+ PURPOSE : keyboard event (called by driver/PEI) */ #define MAX_CONSEC_KEYS 6 // Maximum number of keys which can be processed before // allowing the protocol stack processing time //xrashmic 22 Aug, 2004 MMI-SPR-32798 #ifdef MMI_EM_ENABLED #ifndef NEPTUNE_BOARD /* This is not valid for Neptune Engineering Mode, hence*/ extern U8 screenCaptureKey; void screen_capture(void); #endif /* ifndef NEPTUNE_BOARD */ #endif void kbdSignal (char make, char key) { U32 map; UBYTE temp=0 ; USHORT numElem; int loopNo; int keyNo; if ((kbd_processKeyInput()== QUEUE_EVERY_KEY) || (kbd_processKeyInput()== QUEUE_N_KEYS)) temp = dspl_Enable(0); /* removed in FreeCalypso */ /* mme_backlightEvent(BL_KEY_PRESS); */ loopNo = 0; keyNo = 0; while (kbd_getMakeAndKey(&make,&key) != -1) { #ifdef MMI_EM_ENABLED #ifndef NEPTUNE_BOARD /* This is not valid for Neptune Engineering Mode, hence*/ //xrashmic 22 Aug, 2004 MMI-SPR-32798 //If screen capture is enabled the key pressed is the screen capture key, //we write the LCD buffer into the FFS and and consume the key //event here itself without sending it to BMI // Also the screen capture key will be disabled here if(key== screenCaptureKey && make==1) { TRACE_EVENT("*****Capturing the screen"); screenCaptureKey=KCD_NONE; screen_capture(); dspl_Enable(temp); return; } #endif /* ifndef NEPTUNE_BOARD*/ #endif still_processing_flag = 1; TRACE_EVENT_P2("NDH : KbdSignal - key %d, state %02x", key, make); if (key <= KCD_MAX) /*a0393213 compiler warnings removal - comparison of key with 0 removed*/ { loopNo++; keyNo++; map = 1L << key; if (make) { map |= KEY_MAKE; curMap = map; curKey = key; timStart(&timLongH); timAuto.time = valAuto; /*NM, p007a*/ if (valAuto) timStart(&timAutoH); /*NM, p007a end*/ } else { map &= ~KEY_MAKE; curMap = map; //ES!! curKey = key; //ES!! timStop(&timLongH); if (valAuto) timStop(&timAutoH); } //Select when we update the display switch (kbd_processKeyInput()) { case QUEUE_EVERY_KEY: sigDistribute(map,key); break; case PROCESS_EVERY_KEY: temp = dspl_Enable(0); sigDistribute(map,key); dspl_Enable(temp); break; case QUEUE_N_KEYS: if ((loopNo %(NUM_QUEUE_KEYS*2))==0) { kbd_setDisplayUpdateNeeded(1); sigDistribute(map,key); dspl_Enable(temp); temp = dspl_Enable(0); kbd_setDisplayUpdateNeeded(0); } else sigDistribute(map,key); break; } } if (keyNo == MAX_CONSEC_KEYS) { still_processing_flag = FALSE; break; } still_processing_flag = FALSE; } numElem = mfw_cbuf_num_elements(mfw_kbd_kpress_buf_id); /* x0083025 on Sep 14, 2007 for OMAPS00145862 (adrian) */ MMI_TRACE_EVENT_P2("NDH >>> Kbd :- There are %d elements in the buffer (id : %d)" , numElem, mfw_kbd_kpress_buf_id); if ((keyNo == MAX_CONSEC_KEYS) && (numElem > 0)) { sendKeyInd(0, 0, 0); // dummy values to trigger another keypress_ind /* ** This delay is required to slow down the BMI when no trace is being output in order ** to permit the Protocol Stack & other tasks to function correctly */ vsi_t_sleep (VSI_CALLER 30); } if ((kbd_processKeyInput()== QUEUE_EVERY_KEY) || (kbd_processKeyInput()== QUEUE_N_KEYS)) dspl_Enable(temp); return; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : toLong | +--------------------------------------------------------------------+ PURPOSE : long press timeout handler */ static int toLong (U32 t, void *h) { // Sep 18, 2006 REF: OMAPS00094426 - x0039928 // Fix: On long key press timer expiry bsp kpd status is checked to see if the state is // in in Kpd pressed state and sets the long key bit. #if(BOARD == 71) UBYTE state; kpd_retrieve_key_status(kpd_key, KPD_DEFAULT_MODE, &state); if(!state) #endif curMap |= KEY_LONG; sigDistribute(curMap,curKey); return 0; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : toAuto | +--------------------------------------------------------------------+ PURPOSE : auto repeat timeout handler */ static int toAuto (U32 t, void *h) { #if(BOARD == 71) UBYTE state; kpd_retrieve_key_status(kpd_key, KPD_DEFAULT_MODE, &state); if(!state) { #endif curMap |= KEY_AUTO; sigDistribute(curMap,curKey); timAuto.time = valRepeat; /* NM p007c*/ if (valRepeat) timStart(&timAutoH); /* NM p007c end*/ #if(BOARD == 71) } #endif return 0; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbdCommand | +--------------------------------------------------------------------+ PURPOSE : handle mfw windows command */ static int kbdCommand (U32 cmd, void *h) { switch (cmd) { case MfwCmdDelete: /* delete me */ if (!h) return 0; kbdDelete(h); return 1; default: break; } return 0; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbd_putMakeAndKey | +--------------------------------------------------------------------+ PURPOSE : places 'make' (key up/down) and key index into a queue */ int kbd_putMakeAndKey( char make, char key) { keyPressDetails localKP; SHORT retVal; localKP.make = make; localKP.key = key; retVal = mfw_cbuf_put(mfw_kbd_kpress_buf_id, &localKP); if (retVal < 0) TRACE_EVENT_P1("ERROR : mfw_cbuf_put failed with error value %d", retVal); return (retVal); } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbd_getMakeAndKey | +--------------------------------------------------------------------+ PURPOSE : reads 'make' (key up/down) and key index into a queue Return +ve number - keys left in buffer 0 - no keys left - last key press returned -1 - no keys and none in buffer */ int kbd_getMakeAndKey( char* make, char* key) { keyPressDetails localKP; SHORT retVal; retVal = mfw_cbuf_get(mfw_kbd_kpress_buf_id, &localKP); if (retVal < 0) { *key = 0x7F; *make = 0; return (-1); } *make = !(localKP.make); *key = drvGetKeyIndex(localKP.key); return (mfw_cbuf_num_elements(mfw_kbd_kpress_buf_id)); } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbd_getNumElements | +--------------------------------------------------------------------+ PURPOSE : returns number of elements in queue */ int kbd_getNumElements(void) { return ((int)mfw_cbuf_num_elements(mfw_kbd_kpress_buf_id)); } int kbd_stillProcessingKeys(void) { return (still_processing_flag); } int mfwKey_skipDisplay( void ) { if ((mfw_cbuf_num_elements(mfw_kbd_kpress_buf_id) > 2) && (still_processing_flag == 1)) return (TRUE); else return (FALSE); } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbd_displayUpdateNeeded | +--------------------------------------------------------------------+ PURPOSE : returns TRUE if we need to update the display */ int displayUpdateNeeded; //used for output every 'n' key presses int kbd_displayUpdateNeeded(void) { if (kbd_processKeyInput()==PROCESS_EVERY_KEY) return (TRUE);//Processing each key press - always update screen else if (displayUpdateNeeded==0) return (TRUE);//need to update the display (1 in 6 output) else if (mfw_cbuf_num_elements(mfw_kbd_kpress_buf_id) > 1) return (FALSE);//keys in queue - do not update else return (TRUE);//only 1 key up/down in queue - update display } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbd_setDisplayUpdateNeeded | +--------------------------------------------------------------------+ PURPOSE : sets/clears the flag indicating we need to update the display */ void kbd_setDisplayUpdateNeeded(int set) { displayUpdateNeeded = set; } /* +--------------------------------------------------------------------+ | PROJECT : MMI-Framework (8417) MODULE : MFW_KBD | | STATE : code ROUTINE : kbd_processEveryKeyInput | +--------------------------------------------------------------------+ PURPOSE : indicates if the software should process each keypad input individually (TRUE) or if it should process keypad inputs one at a time (FALSE) */ int kbd_processKeyInput(void) { return (QUEUE_EVERY_KEY);//We buffer multiple key inputs }