diff -r 000000000000 -r 6663340f3fc9 omap3530/beagle_drivers/keytran/keymap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omap3530/beagle_drivers/keytran/keymap.cpp Thu Oct 15 12:59:54 2009 +0100 @@ -0,0 +1,2227 @@ +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// omap3530/beagle_drivers/keytran/keymap.cpp +// This file is part of the Beagle Base port +// The keyboard lookup tables giving the function to be carried out +// and the new state of the keyboard +// + + +#include + +#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0])) + + +// +// Scancode conversion tables +// -------------------------- +// The scancode conversion is arranged as a tree of tables which are used to +// convert a scancode to a keycode, taking into account the modifier state +// (shift, control, fn) +// +// How the tables work: +// -------------------- +// Firstly, there is a distinction between the "scancodes" used in scanning +// the keyboard, and the "scancodes" used in this files. +// +// Typically the keyboard driver already contains a table to convert hardware +// key location codes produced during keyboard scanning into EPOC "scancodes". +// EPOC scancodes are defined for "standard" keys like shift, backspace, +// escape, in the TStdScanCode enum (see E32KEYS.H), and should be ASCII codes +// for normal characters. The keyboard driver should add these EPOC scancodes +// to the event queue, not hardware-dependant key locations. +// +// For now on "scancode" refers to EPOC scancodes: +// +// The keyboard is divided into a number of "blocks" of contiguous scancodes +// +// Blocks map to keycodes in a keycode table, and several blocks can be +// grouped and map to a single keycode table. Blocks map into the keycode +// table in the order they are declared. For example, if two scancode blocks +// with a range of 5 scancodes map to a single 10-entry keycode table, scancodes +// which fall in the first block will map to the first 5 entries in the keycode +// table, scancodes falling in the second block map the the next 5 entries in +// the keycode table. +// +// In theory it is possible to have multiple [keycode,scancode blocks] groups +// but there is little point doing this - grouping all the scancode blocks +// with a single keycode table holding all possible keycode values is usually +// sufficient (and simpler). However, there are some special cases where this +// is useful - the most obvious example is handling of shift and caps lock. +// The shift key implies everything that the caps-lock key does (upper case +// letters) plus some shifted characters for other keys. This is done by +// defining two tables - the first handles only caps-lock (upper case), the +// second handles all other keys that are affected only by shift. If caps- +// lock is active, only the caps-lock table is used. If shift is pressed both +// the caps-lock and shift tables are scanned for the conversion. This allows +// a base table to be extended with "extras", much like deriving a class from +// base class and extending it. +// +// +// There is one or more [keycode table, scancode blocks] group for each +// modifier state - e.g. a lower-case table, upper-case, ctrl, ctrl-shift. +// This is the root of the table. +// +// When converting a scancode the key translator first obtains the correct +// conversion tables for the modifier state. It then traverses all the scancode +// blocks looking for one which contains the scancode being converted. Once +// a matching scancode range is located, the key translator maps this into +// its position in the associated keycode table to obtain the converted keycode. +// +// The key tables below appear more complicated than they really are because of +// the intermediate structures that hold pointers to other structures. The +// important structures are: +// SScanCodeBlock - contains a "start" and "end" for a scancode range +// SConvSubTable - groups a number of scanode blocks with a keycode table +// SConvTableNode - points to SConvSubTables for each modifier state +// SConvTable - the root of the translation table - points to 1..n SConvTableNode +// +// The keycode tables are just an array of TUint16. +// + + +// +// TO DO: (optional) +// +// Keys which are not affected by modifier state +// + +// +// This is a simple example of scancode to keycode mapping. The first block +// in scanCodeBlock_unmodifiable is a range of several scancodes, so maps to +// several entries in the keycode table convKeyCodes_unmodifiable. +// EStdKeyLeftShift -> maps to -> EKeyLeftShift +// EStdKeyRightShift -> maps to -> EKeyRightShift +// ... +// EStdKeyScrollLock -> maps to -> EKeyScrollLock +// +LOCAL_D const SScanCodeBlock scanCodeBlock_unmodifiable[]= + { + {EStdKeyLeftShift, EStdKeyScrollLock}, // range 1: left shift to scroll lock + }; + +LOCAL_D const TUint16 convKeyCodes_unmodifiable[]= + { + EKeyLeftShift, + EKeyRightShift, + EKeyLeftAlt, + EKeyRightAlt, + EKeyLeftCtrl, + EKeyRightCtrl, + EKeyLeftFunc, + EKeyRightFunc, + EKeyCapsLock, + EKeyNumLock, + EKeyScrollLock + }; + + + +// +// TO DO: (optional) +// +// Base conversion table +// this table traps all of the keyboard's scanCodes except those in +// convKeyCodes_unmodifiable. It appears last in the top-level table and +// is used to convert any scancode that is not converted by any of the +// other tables +// +LOCAL_D const SScanCodeBlock scanCodeBlock_base[]= + { + {EStdKeyNull, EStdKeyDownArrow}, // scancode range 1 + {'0', '9'}, // scancode range 2 + {'A', 'Z'}, // scancode range 3 + {EStdKeyF1, EStdKeyDictaphoneRecord}, // scancode range 4 + }; + +LOCAL_D const TUint16 convKeyCodes_base[]= + { + EKeyNull, // scancode range 1 mapping starts here + EKeyBackspace, + EKeyTab, + EKeyEnter, + EKeyEscape, + ' ', + EKeyPrintScreen, + EKeyPause, + EKeyHome, + EKeyEnd, + EKeyPageUp, + EKeyPageDown, + EKeyInsert, + EKeyDelete, + EKeyLeftArrow, + EKeyRightArrow, + EKeyUpArrow, + EKeyDownArrow, + '0', // scancode range 2 mapping starts here + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + 'a', // scancode range 3 mapping starts here + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + EKeyF1, // scancode range 4 mapping starts here + EKeyF2, + EKeyF3, + EKeyF4, + EKeyF5, + EKeyF6, + EKeyF7, + EKeyF8, + EKeyF9, + EKeyF10, + EKeyF11, + EKeyF12, + EKeyF13, + EKeyF14, + EKeyF15, + EKeyF16, + EKeyF17, + EKeyF18, + EKeyF19, + EKeyF20, + EKeyF21, + EKeyF22, + EKeyF23, + EKeyF24, + '`', + ',', + '.', + '/', + '\\', + ';', + '\'', + '#', + '[', + ']', + '-', + '=', + '/', + '*', + '-', + '+', + EKeyEnter, + EKeyEnd, + EKeyDownArrow, + EKeyPageDown, + EKeyLeftArrow, + EKeyNull, // numeric keypad '5' + EKeyRightArrow, + EKeyHome, + EKeyUpArrow, + EKeyPageUp, + EKeyInsert, + EKeyDelete, + EKeyMenu, + EKeyBacklightOn, + EKeyBacklightOff, + EKeyBacklightToggle, + EKeyIncContrast, + EKeyDecContrast, + EKeySliderDown, + EKeySliderUp, + EKeyDictaphonePlay, + EKeyDictaphoneStop, + EKeyDictaphoneRecord + }; + + +// +// TO DO: (optional) +// +// caps-lock: this table traps those scanCodes which are affected by caps-lock +// +LOCAL_D const SScanCodeBlock scanCodeBlock_capsLock[]= + { + {'A', 'Z'} // only alpha keys are affected by caps-lock + }; + +LOCAL_D const TUint16 convKeyCodes_capsLock[]= + { + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z' + }; + +// +// TO DO: (optional) +// +// shift: this table traps those scanCodes which are affected +// by normal shift key EXCEPT for those scanCodes affected by caps-lock +// + +LOCAL_D const SScanCodeBlock scanCodeBlock_shift[]= + { + {'0', '9'}, + {EStdKeyXXX, EStdKeyEquals}, + }; + +LOCAL_D const TUint16 convKeyCodes_shift[]= + { + ')', + '!', + '@',/*'"',*/ + '#', /*ELatin1Pound,*/ + '$', + '%', + '^', + '&', + '*', + '(', + '~', /*ELatin1LogicNot,*/ + '<', + '>', + '?', + '|', + ':', + '"', + '|', /*'~',*/ + '{', + '}', + '_', + '+' + }; + +// +// TO DO: (optional) +// +// func: this table traps those scanCodes which are affected +// by the func key but not shift +// +LOCAL_D const SScanCodeBlock scanCodeBlock_func[]= + { + {EStdKeyEscape, EStdKeyEscape}, + {'M', 'M'}, + {EStdKeyComma, EStdKeyComma}, + {EStdKeyLeftArrow, EStdKeyDownArrow}, + }; + +LOCAL_D const TUint16 convKeyCodes_func[]= + { + EKeyOff, + EKeyDecContrast, + EKeyIncContrast, + EKeyHome, + EKeyEnd, + EKeyPageUp, + EKeyPageDown, + }; + +// +// TO DO: (optional) +// +// func: this table traps those scanCodes which are affected +// by func and shift - this is for func pressed, shift not pressed +// +//LOCAL_D const SScanCodeBlock scanCodeBlock_funcUnshifted[]= +// { +// {'E', 'E'}, +// }; + +//LOCAL_D const TUint16 convKeyCodes_funcUnshifted[]= +// { +// ELatin1LcEacute, +// }; + +// +// TO DO: (optional) +// +// func: this table traps those scanCodes which are affected +// by func and shift - this is for func and shift both pressed +// +//LOCAL_D const SScanCodeBlock scanCodeBlock_funcShifted[]= +// { +// {'E', 'E'}, +// }; + +//LOCAL_D const TUint16 convKeyCodes_funcShifted[]= +// { +// ELatin1UcEacute, +// }; + +// +// TO DO: (optional) +// +// ctrl: this table traps those scanCodes which are affected by ctrl +// +LOCAL_D const SScanCodeBlock scanCodeBlock_ctrl[]= + { + // + // NOTE: The space key gets handled elsewhere, otherwise it gets + // thrown away as a NULL key + // {EStdKeySpace, EStdKeySpace}, + + {'A', 'Z'}, + {EStdKeyComma, EStdKeyComma}, + }; + +LOCAL_D const TUint16 convKeyCodes_ctrl[]= + { +// 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + ',', + }; + + + +// +// TO DO: (optional) +// +// Each set of scancode+keycode tables must be grouped into a SConvSubTable. +// The lines below define a number of SConvSubTables for each of the groups +// above. +// +LOCAL_D const SConvSubTable + convSubTable_unmodifiable= // table for unmodifiable keys + { + &convKeyCodes_unmodifiable[0], // the keycode table + { + ARRAY_LENGTH(scanCodeBlock_unmodifiable), // number of scancode blocks + &scanCodeBlock_unmodifiable[0] // pointer to scancode blocks + } + }, + convSubTable_base= // table for base keys + { + &convKeyCodes_base[0], // keycode table + { + ARRAY_LENGTH(scanCodeBlock_base), // number of scancode blocks + &scanCodeBlock_base[0] // pointer to scancode blocks + } + }, + convSubTable_capsLock= + { + &convKeyCodes_capsLock[0], + { + ARRAY_LENGTH(scanCodeBlock_capsLock), + &scanCodeBlock_capsLock[0] + } + }, + convSubTable_shift= + { + &convKeyCodes_shift[0], + { + ARRAY_LENGTH(scanCodeBlock_shift), + &scanCodeBlock_shift[0] + } + }, + convSubTable_func= + { + &convKeyCodes_func[0], + { + ARRAY_LENGTH(scanCodeBlock_func), + &scanCodeBlock_func[0] + } + }, +// convSubTable_funcUnshifted= +// { +// &convKeyCodes_funcUnshifted[0], +// { +// ARRAY_LENGTH(scanCodeBlock_funcUnshifted), +// &scanCodeBlock_funcUnshifted[0] +// } +// }, +// convSubTable_funcShifted= +// { +// &convKeyCodes_funcShifted[0], +// { +// ARRAY_LENGTH(scanCodeBlock_funcShifted), +// &scanCodeBlock_funcShifted[0] +// } +// }, + convSubTable_ctrl= + { + &convKeyCodes_ctrl[0], + { + ARRAY_LENGTH(scanCodeBlock_ctrl), + &scanCodeBlock_ctrl[0] + } + }; + +// +// TO DO: (optional) +// +// We need to declare arrays of SConvSubTable for each modifier state we +// are going to handle. As mentioned above, it is possible to have several +// [keycode table, scancode blocks] groups scanned for each keyboard state. +// +// Some modifier states use more than one conversion group. The simple example +// is handling of caps-lock and shift. +// +// Caps-lock means all letters are upper-case +// shift means all letters are upper case AND some other keys return control characters +// +// Obviously the shift key means everything cpas-lock means PLUS a bit more. So +// we define two tables, the caps-lock table defines only the uppercase conversion, +// and the shift table defines all OTHER shifted keys not already handled by +// caps-lock. The caps-lock modifier state then only scans the caps-lock table, and +// the shift state scans both tables. +// +LOCAL_D const SConvSubTable + * const convSubTableArray_unmodifiable[]={&convSubTable_unmodifiable}, + * const convSubTableArray_base[]={&convSubTable_base}, + + // + // The caps-lock state scans only the caps-lock table, to handle + // conversion to upper case + // + * const convSubTableArray_capsLock[]={&convSubTable_capsLock}, + // + // The shift table scans the caps-lock table to handle upper case, + // and also the shift table which handles some keys that are not affected + // by caps lock (such as 0-9). + // + * const convSubTableArray_shift[]={&convSubTable_capsLock, &convSubTable_shift}, + // + // Pressing shift with caps-lock active reverts to lower-case letters, + // but other keys remain shifted. This time we only scan the shift table + // so only the non-alpha keys will be shifted + // + * const convSubTableArray_capsLockShift[]={&convSubTable_shift}, + + // + // Like the shift/caps-lock situation, the function key has two states, + // shifted and unshifted. Also, some keys may be independant of whether + // the shift key is pressed. So there are three tables defined. One declares + // all keys that are independant of shift state, the other two tables handle + // shifted and unshifted func. + // + // Unshifted func uses the independant set + funcUnshifted + // + // * const convSubTableArray_func[]={&convSubTable_func, &convSubTable_funcUnshifted}, + * const convSubTableArray_func[]={&convSubTable_func}, + // + // Shifted func uses the independant set + funcShifted + // + // * const convSubTableArray_funcShift[]={&convSubTable_func,&convSubTable_funcShifted}, + // + // This keyboard table makes control independant of func and shift + // + * const convSubTableArray_ctrl[]={&convSubTable_ctrl}; + +// +// TO DO: (optional) +// +// This is the top of the scancode conversion tree. It is a set of pointers +// to the SConvSubTable arrays declared above. +// +// The order of these nodes is VITAL, as the scanCode/modifiers are +// searched for a match in this order +// +// The modifier state is matched by using a mask and a compare value. This is +// used as follows: +// +// match is true if ( (modifierState & mask) == compareValue +// +// For example, if the mask is (EModifierFunc|EModifierShift) and the +// compare value is EModifierFunc, this will match ANY combination of +// modifiers that has func pressed and shift not pressed +// +LOCAL_D const SConvTableNode convTableNodes[]= + { + { + { + 0, // modifier mask = no modifiers + 0 // modifier compare = no modifiers + }, + ARRAY_LENGTH(convSubTableArray_unmodifiable), // number of SConvSubTables + &convSubTableArray_unmodifiable[0] // pointer to SConvSubTable array + }, + { + { + EModifierCtrl, // modifier mask = check for ctrl + EModifierCtrl // modifier compare = anything with ctrl pressed + }, + ARRAY_LENGTH(convSubTableArray_ctrl), + &convSubTableArray_ctrl[0] + }, + { + { + // + // Check for Func pressed + // + EModifierFunc, + EModifierFunc + }, + ARRAY_LENGTH(convSubTableArray_func), + &convSubTableArray_func[0] + }, + { + { + // + // Check for caps-lock pressed, shift not pressed + // + EModifierCapsLock|EModifierShift, + EModifierCapsLock + }, + ARRAY_LENGTH(convSubTableArray_capsLock), + &convSubTableArray_capsLock[0] + }, + { + { + // + // Check for caps-lock not pressed, shift pressed + // + EModifierShift|EModifierCapsLock, + EModifierShift + }, + ARRAY_LENGTH(convSubTableArray_shift), + &convSubTableArray_shift[0] + }, + { + { + // + // Check for caps-lock pressed, shift pressed + // + EModifierCapsLock|EModifierShift, + EModifierCapsLock|EModifierShift + }, + ARRAY_LENGTH(convSubTableArray_capsLockShift), + &convSubTableArray_capsLockShift[0] + }, + { + // + // This is the base table. It must appear last so that it can + // provide a default conversion for any scancodes that are not + // handled by any of the tables above + // + { + 0, + 0 + }, + ARRAY_LENGTH(convSubTableArray_base), + &convSubTableArray_base[0] + } + }; + +// +// The top-level exported data structure of all the conversion tables +// This just points to the SConvTableNodes above +// +LOCAL_D const SConvTable ConvTable= + { + ARRAY_LENGTH(convTableNodes), + &convTableNodes[0] + }; + +// The list of scan-codes on the numeric keypad +LOCAL_D const SScanCodeBlock keypadScanCodeBlockArray[]= + { + {EStdKeyNumLock, EStdKeyNumLock}, + {EStdKeyNkpForwardSlash, EStdKeyNkpFullStop} + }; + +LOCAL_D const SScanCodeBlockList ConvTableKeypadScanCodes= + { + ARRAY_LENGTH(keypadScanCodeBlockArray), + &keypadScanCodeBlockArray[0] + }; + +// +// TO DO: (optional) +// +// List of keycodes that do not autorepeat +// +// These are usually control keys like shift, ctrl, escape +// +LOCAL_D const TUint16 nonAutorepKeyCodeArray[]= + { + EKeyEscape, + EKeyPrintScreen, + EKeyPause, + EKeyInsert, + EKeyLeftShift, + EKeyRightShift, + EKeyLeftAlt, + EKeyRightAlt, + EKeyLeftCtrl, + EKeyRightCtrl, + EKeyLeftFunc, + EKeyRightFunc, + EKeyCapsLock, + EKeyNumLock, + EKeyScrollLock, + EKeyMenu, + EKeyDictaphonePlay, + EKeyDictaphoneStop, + EKeyDictaphoneRecord + }; + +// +// TO DO: (optional) +// +// Declare blocks of non-autorepeating keycodes +// +LOCAL_D const SKeyCodeList ConvTableNonAutorepKeyCodes= + { + ARRAY_LENGTH(nonAutorepKeyCodeArray), // number of keycode arrays + &nonAutorepKeyCodeArray[0] // pointer to arrays + }; + + + + + + +///////////////////////////////////////////////////////////////////// +// Keyboard state tables +// + +// What these tables do +// -------------------- +// +// These tables control the way "special" keystrokes modify the behaviour +// of the keyboard. There are two major uses for this: +// +// - handling modifier keys e.g. caps-lock, shift, alt, fn and defining +// what modifier flags are affected by these keypresses +// +// - switching the keyboard into special states (see below) +// +// Keyboard states +// --------------- +// +// Keyboard states are used to switch the keyboard into a special mode where it +// can be used to enter unusual characters. There are two uses for this: +// +// - entering numeric codes, by pressing ctrl and typing the decimal code +// - entering accented characters by pressing a key combination which +// enters "accented mode" then pressing a key. There can be multiple +// accented modes. +// +// You can see an example of accented modes on a Psion Series 5 by +// pressing Fn+Z, followed by A - this will produce an a with an umlaut (ä) +// +// These tables are also used to select simpler states such as caps-lock +// and num-lock. +// +// +// The main data structure is a SFuncTableEntry. Each of these contains +// three fields: +// +// 1. modifier match - this works the same way as the scancode conversion +// tables above, there is a mask and a compare value +// +// 2. a keycode patters - this is used to match with the keycode or keycodes +// that the state should respond to. This is a TKeyCodePattern structure +// which defines what sort of match should be performed. +// +// 3. a function and state change structure, SFuncAndState. This defines the +// state to change to, the function to perform, and a parameter for the +// function if required. +// +// TKeyCodePattern structures have two fields. The first is a keycode value +// and is only used for some match types. The second field select the type +// of match to perform: +// +// EAnyKey - match any key +// EAnyAlphaNumeric - match any alpha or numeric key +// EAnyAlpha - match any alpha key +// EAnyAlphaLowerCase - match any lower-case key +// EAnyAlphaUpperCase - match any upper-case key +// EAnyDecimalDigit - match any decimal digit +// EAnyModifierKey - match any modifier key (e.g. alt, fn, ctrl) +// EMatchKey - match if equal to keycode value in first field +// EMatchLeftOrRight - match if equal to keycode value or (keycode value + 1) +// EMatchKeyCaseInsens - like EMatchKey but perform case-insensitive comparison +// +// + +// the "array" parameter must be a true array and not a pointer +#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0])) + +#define TABLE_ENTRY_ANOTHER_CTRL_DIGIT \ + { \ + { \ + EModifierKeyUp|EModifierFunc, \ + 0 \ + }, \ + { \ + EKeyNull, \ + EAnyDigitGivenRadix \ + }, \ + { \ + EStateCtrlDigits, \ + EAddOnCtrlDigit, \ + 0 \ + } \ + } + +// +// TO DO: (optional) +// +// This table is searched for a match if a match has not been +// found in the current state's table +// + +LOCAL_D const SFuncTableEntry defaultTable[]= + { + { + // + // prevent key up events generating keycodes + // + { + EModifierKeyUp, // mask = key up + EModifierKeyUp // match = key up - i.e. accept any key up event + }, + { + EKeyNull, // dummy value, not used + EAnyKey // accept any key + }, + { + EStateUnchanged, // state will not change + EDoNothing, // no action to perform + 0 + } + }, + { + // + // prevent any modifier key (e.g. shift, ctrl) from changing state + // + { + 0, // match any modifier state + 0 + }, + { + EKeyNull, // dummy value + EAnyModifierKey // match any modifier key + }, + { + EStateUnchanged, // don't change state + EDoNothing, // nothing to do + 0 + } + }, + { + // + // filter out any unprocessed codes + // + { + 0, // match any modifier state + 0 + }, + { + EKeyNull, // dummy value + EAnyKey // match any key + }, + { + EStateNormal, // switch back to normal keyboard state + EDoNothing, // nothing to do + 0 + } + } + }; + +// +// TO DO: (optional) +// +// This table controls which keys change which modifiers; +// NOTE: the state field in this table is ignored +// + +LOCAL_D const SFuncTableEntry modifierTable[]= + { + { + { + EModifierKeyUp, // check key-up modifier flag + 0 // make sure it's zero (i.e. ignore key-up events) + }, + { + // + // Here we want to match only the caps-lock key. We specify the + // keycode we are looking for in the first field, and EMatchKey + // in the second field + // + EKeyCapsLock, // we want to respond to caps-lock key + EMatchKey // match caps-lock only + }, + { + EStateUnchanged, // ignored + EToggleModifier, // function = toggle modifier state + EModifierCapsLock // this is the modifier to toggle + } + }, + { + { + EModifierKeyUp, + 0 + }, + { + EKeyNumLock, // this one matched num-lock + EMatchKey // match only num-lock + }, + { + EStateUnchanged, // ignored + EToggleModifier, // function = toggle modifier state + EModifierNumLock // this is the modifier to toggle + } + }, + { + { + EModifierKeyUp, + 0 + }, + { + EKeyScrollLock, // match scroll-lock key + EMatchKey + }, + { + EStateUnchanged, + EToggleModifier, // function = toggle modifier + EModifierScrollLock // modifier to toggle + } + }, + { + { + EModifierKeyUp, + 0 + }, + { + EKeyLeftAlt, // match left alt key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on a modifier + EModifierAlt|EModifierLeftAlt // alt turns on this modifier combination + } + }, + { + { + EModifierKeyUp, // goes with previous table, this handles the alt + EModifierKeyUp // key being released + }, + { + EKeyLeftAlt, // match left alt key again + EMatchKey + }, + { + EStateUnchanged, + ETurnOffModifier, // function = turn off the modifier + EModifierLeftAlt // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyLeftFunc, // match left fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierFunc|EModifierLeftFunc // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, this matched the + EModifierKeyUp // left-fn key up event + }, + { + EKeyLeftFunc, // match left fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierLeftFunc // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyLeftShift, // match left shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierShift|EModifierLeftShift // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches left shift + EModifierKeyUp // key up event + }, + { + EKeyLeftShift, // match left shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // turn off modifier + EModifierLeftShift // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyLeftCtrl, // match left ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierCtrl|EModifierLeftCtrl // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches left ctrl + EModifierKeyUp // key up event + }, + { + EKeyLeftCtrl, // match left ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierLeftCtrl // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightAlt, // match right alt key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierAlt|EModifierRightAlt // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches right alt + EModifierKeyUp // key up event + }, + { + EKeyRightAlt, // match right alt key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightAlt // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightFunc, // match right fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierFunc|EModifierRightFunc // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches right fn + EModifierKeyUp // key up event + }, + { + EKeyRightFunc, // match right fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightFunc // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightShift, // match right shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierShift|EModifierRightShift // modifier combinatoin to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, handles right shift + EModifierKeyUp // key up event + }, + { + EKeyRightShift, // match right shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightShift // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightCtrl, // match right ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierCtrl|EModifierRightCtrl // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matched right ctrl + EModifierKeyUp // key up event + }, + { + EKeyRightCtrl, // match right ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightCtrl // modifier to turn off + } + } + }; + + +// +// TO DO: (optional) +// +// Tables corresponding to keyboard states. +// +// There are 13 keyboard states. States 0 to 9 can be used to create alternative +// keyboard layouts for entering accented or unusual characters. Switching into +// these states is done by a keypress. Implementation of the states is optional +// depending on how many special state you want - you may implement 10 states, +// you might decide not to implement any. +// +// State 10 is the normal state. The table for state 10 defines which keypresses +// change to other states. +// +// States 11 and 12 are used when entering the numeric code of a character. State +// 11 is for entering a specific number of digits. State 12 is for accepting +// digits until Ctrl is released. +// +// +// As before, each SFuncTableEntry entry defines: +// - modifier conditions that must be matched +// - a keycode match pattern (typically an exact key match) +// - the function to perform and new state +// +// Switching into states 0..9,11,12 is done by entries in table10 +// + +//LOCAL_D const SFuncTableEntry table0[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +LOCAL_D const SFuncTableEntry table1[]= + { + // + // Table for special keyboard state 1 + // This state is entered by pressing Fn+q (see table10) + // + // The table makes certain keys return accented characters + // + { + { + // + // Function must be release, and this must be a key down event + // + EModifierFunc|EModifierKeyUp, + 0 + }, + { + // + // match an 'e' keypress, convert to an ae ligature (æ) + // + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, // switch back to state normal (table10) + EPassSpecialKeyThru, // turn keypress into a special character + ELatin1LcAe // this is the character to pass on + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'c', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcCcedilla + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 's', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1EsTset + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOslash + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'd', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcThorn + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 't', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSoftTh + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'l', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LeftChevron + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'r', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1RightChevron + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'x', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1InvExclam + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'q', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1InvQuest + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAo + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'p', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1Pound + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table2[]= + { + // + // Table for special keyboard state 2 + // This state is entered by pressing Fn+z (see table10) + // + // The table makes certain keys return accented characters + // See table1 for an explanation of the contents + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'y', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcYumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1SpaceUmlaut + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table3[]= + { + // + // Table for special keyboard state 3 + // This state is entered by pressing Fn+x (see table10) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1SpaceGrave + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table4[]= + { + // + // Table for special keyboard state 4 + // This state is entered by pressing Fn+c (see table10) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'y', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcYacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSpaceAcute + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table5[]= + { + // + // Table for special keyboard state 5 + // This state is entered by pressing Fn+v (see table10) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAtilde + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'n', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcNtilde + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOtilde + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSpaceTilde + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table6[]= + { + // + // Table for special keyboard state 6 + // This state is entered by pressing Fn+b (see table6) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSpaceCirc + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +// +// TO DO: (optional) +// +// State 7,8,9 aren't used in this example. +// You can implement them if you want more special states +// + +//LOCAL_D const SFuncTableEntry table7[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +//LOCAL_D const SFuncTableEntry table8[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +//LOCAL_D const SFuncTableEntry table9[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + + +LOCAL_D const SFuncTableEntry table10[]= + { + // + // TO DO: (optional) + // + // Table keyboard state 10 - the normal state + // + // This table controls which keys switch into the special states + // 0-9, 11 and 12. + // + + { + // + // Make sure key-up events are ignored by handling them first and + // doing nothing + // + { + EModifierKeyUp, + EModifierKeyUp + }, + { + EKeyNull, + EAnyKey + }, + { + EStateUnchanged, + EDoNothing, + 0 + } + }, + { + // + // Check for ctrl-number presses + // This will enter state EStateCtrlDigits (state 12) which allows + // entry of a numeric keycode + // + { + EModifierCtrl|EModifierFunc|EModifierKeyUp, + EModifierCtrl + }, + { + EKeyNull, + EAnyDecimalDigit + }, + { + EStateDerivedFromDigitEntered, + EAddOnCtrlDigit, + 0 + } + }, + { + // + // Any other key events that have not been trapped are just + // passed through unchanged + // + { + 0, + 0 + }, + { + EKeyNull, + EAnyKey + }, + { + EStateUnchanged, + EPassKeyThru, + 0 + } + } + }; + +//LOCAL_D const SFuncTableEntry table11[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +LOCAL_D const SFuncTableEntry table12[]= + { + // + // Table 12 handles entring digit codes. The keyboard will remain in this + // state until the Ctrl key is released + // + { + { + // + // Look for a key up event + // + EModifierKeyUp, + EModifierKeyUp + }, + { + // + // Match either left or right Ctrl key (i.e. this matches a Ctrl key release) + // + EKeyLeftCtrl, + EMatchLeftOrRight + }, + { + EStateNormal, // return to normal state (table10) + EPassCtrlDigitsThru, // and pass through the numeric code we have accumulated + 0 + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + + +// +// TO DO: (optional) +// +// Array of state control tables above. If a state is not used set the array +// size to zero and the pointer to NULL +// +// The tables must be declared here in order from table 0 to table 12 +// +LOCAL_D const SFuncTable genFuncTables[]= + { + { + // + // state 0 + // + 0, // state 0 not used, size = 0 + NULL // state 0 not used, pointer = NULL + }, + { + // + // state 1 + // + ARRAY_LENGTH(table1), // size of table 1 + &table1[0] // pointer to table 1 + }, + { + // + // state 2 + // + ARRAY_LENGTH(table2), + &table2[0] + }, + { + // + // state 3 + // + ARRAY_LENGTH(table3), + &table3[0] + }, + { + // + // state 4 + // + ARRAY_LENGTH(table4), + &table4[0] + }, + { + // + // state 5 + // + ARRAY_LENGTH(table5), + &table5[0] + }, + { + // + // state 6 + // + ARRAY_LENGTH(table6), + &table6[0] + }, + { + // + // state 7 + // + 0, + NULL + }, + { + // + // state 8 + // + 0, + NULL + }, + { + // + // state 9 + // + 0, + NULL + }, + { + // + // state 10 + // + ARRAY_LENGTH(table10), + &table10[0] + }, + { + // + // state 11 + // + 0, + NULL + }, + { + // + // state 12 + // + ARRAY_LENGTH(table12), + &table12[0] + } + }; + + +// +// Root of the state modifier tables +// +LOCAL_D const SFuncTables FuncTables= + { + { + // + // The default processing table + // + ARRAY_LENGTH(defaultTable), + &defaultTable[0] + }, + { + // + // The modifier control table + // + ARRAY_LENGTH(modifierTable), + &modifierTable[0] + }, + // + // The state control tables + // + ARRAY_LENGTH(genFuncTables), + &genFuncTables[0] + }; + + +// +// The following exported functions give the key translator access to +// the control tables above +// +EXPORT_C void KeyDataSettings(TRadix &aRadix,TCtrlDigitsTermination &aCtrlDigitsTermination,TInt &aDefaultCtrlDigitsMaxCount, + TInt &aMaximumCtrlDigitsMaxCount) + { + aRadix=EDecimal; + aCtrlDigitsTermination=ETerminationByCtrlUp; + aDefaultCtrlDigitsMaxCount=3; + aMaximumCtrlDigitsMaxCount=10; + } + +EXPORT_C void KeyDataFuncTable(SFuncTables &aFuncTables) + { + aFuncTables=FuncTables; + } + +EXPORT_C void KeyDataConvTable(SConvTable &aConvTable, TUint &aConvTableFirstScanCode,TUint &aConvTableLastScanCode, + SScanCodeBlockList &aKeypadScanCode,SKeyCodeList &aNonAutorepKeyCodes) + { + aConvTable=ConvTable; + aConvTableFirstScanCode=scanCodeBlock_base[0].firstScanCode; + aConvTableLastScanCode=scanCodeBlock_base[ARRAY_LENGTH(scanCodeBlock_base)-1].lastScanCode; + aKeypadScanCode=ConvTableKeypadScanCodes; + aNonAutorepKeyCodes=ConvTableNonAutorepKeyCodes; + }