Removed REE_PATH option, as it's no longer needed.
Fixed presumed cut/paste error in copyright message.
// 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 <k32keys.h>
#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;
}