os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/keymap.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // template\template_variant\specific\keymap.cpp
    15 // This file is part of the Template Base port
    16 // The keyboard lookup tables giving the function to be carried out
    17 // and the new state of the keyboard
    18 // 
    19 //
    20 
    21 
    22 #include <k32keys.h>
    23 
    24 #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
    25 
    26 
    27 //
    28 // Scancode conversion tables
    29 // --------------------------
    30 // The scancode conversion is arranged as a tree of tables which are used to
    31 // convert a scancode to a keycode, taking into account the modifier state
    32 // (shift, control, fn)
    33 //
    34 // How the tables work:
    35 // --------------------
    36 // Firstly, there is a distinction between the "scancodes" used in scanning
    37 // the keyboard, and the "scancodes" used in this files.
    38 //
    39 // Typically the keyboard driver already contains a table to convert hardware
    40 // key location codes produced during keyboard scanning into EPOC "scancodes".
    41 // EPOC scancodes are defined for "standard" keys like shift, backspace,
    42 // escape, in the TStdScanCode enum (see E32KEYS.H), and should be ASCII codes
    43 // for normal characters. The keyboard driver should add these EPOC scancodes
    44 // to the event queue, not hardware-dependant key locations.
    45 //
    46 // For now on "scancode" refers to EPOC scancodes:
    47 //
    48 // The keyboard is divided into a number of "blocks" of contiguous scancodes
    49 //
    50 // Blocks map to keycodes in a keycode table, and several blocks can be
    51 // grouped and map to a single keycode table. Blocks map into the keycode
    52 // table in the order they are declared. For example, if two scancode blocks
    53 // with a range of 5 scancodes map to a single 10-entry keycode table, scancodes
    54 // which fall in the first block will map to the first 5 entries in the keycode
    55 // table, scancodes falling in the second block map the the next 5 entries in
    56 // the keycode table.
    57 //
    58 // In theory it is possible to have multiple [keycode,scancode blocks] groups
    59 // but there is little point doing this - grouping all the scancode blocks
    60 // with a single keycode table holding all possible keycode values is usually
    61 // sufficient (and simpler). However, there are some special cases where this
    62 // is useful - the most obvious example is handling of shift and caps lock.
    63 // The shift key implies everything that the caps-lock key does (upper case
    64 // letters) plus some shifted characters for other keys. This is done by 
    65 // defining two tables - the first handles only caps-lock (upper case), the 
    66 // second handles all other keys that are affected only by shift. If caps-
    67 // lock is active, only the caps-lock table is used. If shift is pressed both
    68 // the caps-lock and shift tables are scanned for the conversion. This allows
    69 // a base table to be extended with "extras", much like deriving a class from
    70 // base class and extending it.
    71 //
    72 //
    73 // There is one or more [keycode table, scancode blocks] group for each
    74 // modifier state - e.g. a lower-case table, upper-case, ctrl, ctrl-shift.
    75 // This is the root of the table.
    76 //
    77 // When converting a scancode the key translator first obtains the correct
    78 // conversion tables for the modifier state. It then traverses all the scancode
    79 // blocks looking for one which contains the scancode being converted. Once
    80 // a matching scancode range is located, the key translator maps this into
    81 // its position in the associated keycode table to obtain the converted keycode.
    82 //
    83 // The key tables below appear more complicated than they really are because of
    84 // the intermediate structures that hold pointers to other structures. The
    85 // important structures are:
    86 //		SScanCodeBlock - contains a "start" and "end" for a scancode range
    87 //		SConvSubTable - groups a number of scanode blocks with a keycode table
    88 //		SConvTableNode - points to SConvSubTables for each modifier state
    89 //		SConvTable - the root of the translation table - points to 1..n SConvTableNode
    90 //
    91 // The keycode tables are just an array of TUint16.
    92 //
    93 
    94 
    95 //
    96 // TO DO: (optional)
    97 //
    98 // Keys which are not affected by modifier state
    99 //
   100 
   101 //
   102 // This is a simple example of scancode to keycode mapping. The first block
   103 // in scanCodeBlock_unmodifiable is a range of several scancodes, so maps to
   104 // several entries in the keycode table convKeyCodes_unmodifiable.
   105 //		EStdKeyLeftShift -> maps to -> EKeyLeftShift
   106 //		EStdKeyRightShift -> maps to -> EKeyRightShift
   107 //		...
   108 //		EStdKeyScrollLock -> maps to -> EKeyScrollLock
   109 //
   110 LOCAL_D const SScanCodeBlock scanCodeBlock_unmodifiable[]=
   111 	{
   112 	{EStdKeyLeftShift, EStdKeyScrollLock},	// range 1: left shift to scroll lock
   113 	};
   114 
   115 LOCAL_D const TUint16 convKeyCodes_unmodifiable[]=
   116 	{
   117 	EKeyLeftShift,
   118 	EKeyRightShift,
   119 	EKeyLeftAlt,
   120 	EKeyRightAlt,
   121 	EKeyLeftCtrl,
   122 	EKeyRightCtrl,
   123 	EKeyLeftFunc,
   124 	EKeyRightFunc,
   125 	EKeyCapsLock,
   126 	EKeyNumLock,
   127 	EKeyScrollLock
   128 	};
   129 
   130 
   131 
   132 //
   133 // TO DO: (optional)
   134 //
   135 // Base conversion table
   136 // this table traps all of the keyboard's scanCodes except those in
   137 // convKeyCodes_unmodifiable. It appears last in the top-level table and
   138 // is used to convert any scancode that is not converted by any of the
   139 // other tables
   140 //
   141 LOCAL_D const SScanCodeBlock scanCodeBlock_base[]=
   142 	{
   143 	{EStdKeyNull, EStdKeyDownArrow},		// scancode range 1
   144 	{'0', '9'},								// scancode range 2
   145 	{'A', 'Z'},								// scancode range 3
   146 	{EStdKeyF1, EStdKeyDictaphoneRecord},	// scancode range 4
   147 	};
   148 
   149 LOCAL_D const TUint16 convKeyCodes_base[]=
   150 	{
   151 	EKeyNull,				// scancode range 1 mapping starts here
   152 	EKeyBackspace,
   153 	EKeyTab,
   154 	EKeyEnter,
   155 	EKeyEscape,
   156 	' ',
   157 	EKeyPrintScreen,
   158 	EKeyPause,
   159 	EKeyHome,
   160 	EKeyEnd,
   161 	EKeyPageUp,
   162 	EKeyPageDown,
   163 	EKeyInsert,
   164 	EKeyDelete,
   165 	EKeyLeftArrow,
   166 	EKeyRightArrow,
   167 	EKeyUpArrow,
   168 	EKeyDownArrow,
   169 	'0',					// scancode range 2 mapping starts here
   170 	'1',
   171 	'2',
   172 	'3',
   173 	'4',
   174 	'5',
   175 	'6',
   176 	'7',
   177 	'8',
   178 	'9',
   179 	'a',					// scancode range 3 mapping starts here
   180 	'b',
   181 	'c',
   182 	'd',
   183 	'e',
   184 	'f',
   185 	'g',
   186 	'h',
   187 	'i',
   188 	'j',
   189 	'k',
   190 	'l',
   191 	'm',
   192 	'n',
   193 	'o',
   194 	'p',
   195 	'q',
   196 	'r',
   197 	's',
   198 	't',
   199 	'u',
   200 	'v',
   201 	'w',
   202 	'x',
   203 	'y',
   204 	'z',
   205 	EKeyF1,						// scancode range 4 mapping starts here
   206 	EKeyF2,
   207 	EKeyF3,
   208 	EKeyF4,
   209 	EKeyF5,
   210 	EKeyF6,
   211 	EKeyF7,
   212 	EKeyF8,
   213 	EKeyF9,
   214 	EKeyF10,
   215 	EKeyF11,
   216 	EKeyF12,
   217 	EKeyF13,
   218 	EKeyF14,
   219 	EKeyF15,
   220 	EKeyF16,
   221 	EKeyF17,
   222 	EKeyF18,
   223 	EKeyF19,
   224 	EKeyF20,
   225 	EKeyF21,
   226 	EKeyF22,
   227 	EKeyF23,
   228 	EKeyF24,
   229 	'`',
   230 	',',
   231 	'.',
   232 	'/',
   233 	'\\',
   234 	';',
   235 	'\'',
   236 	'#',
   237 	'[',
   238 	']',
   239 	'-',
   240 	'=',
   241 	'/',
   242 	'*',
   243 	'-',
   244 	'+',
   245 	EKeyEnter,
   246 	EKeyEnd,
   247 	EKeyDownArrow,
   248 	EKeyPageDown,
   249 	EKeyLeftArrow,
   250 	EKeyNull, // numeric keypad '5'
   251 	EKeyRightArrow,
   252 	EKeyHome,
   253 	EKeyUpArrow,
   254 	EKeyPageUp,
   255 	EKeyInsert,
   256 	EKeyDelete,
   257 	EKeyMenu,
   258 	EKeyBacklightOn,
   259 	EKeyBacklightOff,
   260 	EKeyBacklightToggle,
   261 	EKeyIncContrast,
   262 	EKeyDecContrast,
   263 	EKeySliderDown,
   264 	EKeySliderUp,
   265 	EKeyDictaphonePlay,
   266 	EKeyDictaphoneStop,
   267 	EKeyDictaphoneRecord
   268 	};
   269 
   270 
   271 //
   272 // TO DO: (optional)
   273 //	
   274 // caps-lock: this table traps those scanCodes which are affected by caps-lock
   275 //
   276 LOCAL_D const SScanCodeBlock scanCodeBlock_capsLock[]=
   277 	{
   278 	{'A', 'Z'}			// only alpha keys are affected by caps-lock
   279 	};
   280 
   281 LOCAL_D const TUint16 convKeyCodes_capsLock[]=
   282 	{
   283 	'A',
   284 	'B',
   285 	'C',
   286 	'D',
   287 	'E',
   288 	'F',
   289 	'G',
   290 	'H',
   291 	'I',
   292 	'J',
   293 	'K',
   294 	'L',
   295 	'M',
   296 	'N',
   297 	'O',
   298 	'P',
   299 	'Q',
   300 	'R',
   301 	'S',
   302 	'T',
   303 	'U',
   304 	'V',
   305 	'W',
   306 	'X',
   307 	'Y',
   308 	'Z'
   309 	};
   310 
   311 //
   312 // TO DO: (optional)
   313 //
   314 // shift: this table traps those scanCodes which are affected
   315 // by normal shift key EXCEPT for those scanCodes affected by caps-lock
   316 //
   317 
   318 LOCAL_D const SScanCodeBlock scanCodeBlock_shift[]=
   319 	{
   320 	{'0', '9'},
   321 	{EStdKeyXXX, EStdKeyEquals},
   322 	};
   323 
   324 LOCAL_D const TUint16 convKeyCodes_shift[]=
   325 	{
   326 	')',
   327 	'!',
   328 	'@',/*'"',*/
   329 	'#',			/*ELatin1Pound,*/
   330 	'$',
   331 	'%',
   332 	'^',
   333 	'&',
   334 	'*',
   335 	'(',
   336 	'~',   /*ELatin1LogicNot,*/
   337 	'<',
   338 	'>',
   339 	'?',
   340 	'|',
   341 	':',
   342 	'"',
   343 	'|', /*'~',*/
   344 	'{',
   345 	'}',
   346 	'_',
   347 	'+'
   348 	};
   349 
   350 //
   351 // TO DO: (optional)
   352 //
   353 // func: this table traps those scanCodes which are affected
   354 // by the func key but not shift
   355 //
   356 LOCAL_D const SScanCodeBlock scanCodeBlock_func[]=
   357 	{
   358     {EStdKeyEscape, EStdKeyEscape},
   359     {'M', 'M'},
   360     {EStdKeyComma, EStdKeyComma},
   361     {EStdKeyLeftArrow, EStdKeyDownArrow},
   362 	};
   363 
   364 LOCAL_D const TUint16 convKeyCodes_func[]=
   365 	{
   366     EKeyOff,
   367     EKeyDecContrast,
   368     EKeyIncContrast,
   369     EKeyHome,
   370     EKeyEnd,
   371     EKeyPageUp,
   372     EKeyPageDown,
   373 	};
   374 
   375 //
   376 // TO DO: (optional)
   377 //
   378 // func: this table traps those scanCodes which are affected
   379 // by func and shift - this is for func pressed, shift not pressed
   380 //
   381 //LOCAL_D const SScanCodeBlock scanCodeBlock_funcUnshifted[]=
   382 //	{
   383 //	{'E', 'E'},
   384 //	};
   385 
   386 //LOCAL_D const TUint16 convKeyCodes_funcUnshifted[]=
   387 //	{
   388 //	ELatin1LcEacute,
   389 //	};
   390 
   391 //
   392 // TO DO: (optional)
   393 //
   394 // func: this table traps those scanCodes which are affected
   395 // by func and shift - this is for func and shift both pressed
   396 //
   397 //LOCAL_D const SScanCodeBlock scanCodeBlock_funcShifted[]=
   398 //	{
   399 //	{'E', 'E'},
   400 //	};
   401 
   402 //LOCAL_D const TUint16 convKeyCodes_funcShifted[]=
   403 //	{
   404 //	ELatin1UcEacute,
   405 //	};
   406 
   407 //
   408 // TO DO: (optional)
   409 //
   410 // ctrl: this table traps those scanCodes which are affected by ctrl
   411 //
   412 LOCAL_D const SScanCodeBlock scanCodeBlock_ctrl[]=
   413 	{
   414 	//
   415 	// NOTE: The space key gets handled elsewhere, otherwise it gets
   416 	// thrown away as a NULL key
   417 	//	{EStdKeySpace, EStdKeySpace},
   418 
   419 	{'A', 'Z'},
   420     {EStdKeyComma, EStdKeyComma},
   421 	};
   422 
   423 LOCAL_D const TUint16 convKeyCodes_ctrl[]=
   424 	{
   425 //	0,
   426 	1,
   427 	2,
   428 	3,
   429 	4,
   430 	5,
   431 	6,
   432 	7,
   433 	8,
   434 	9,
   435 	10,
   436 	11,
   437 	12,
   438 	13,
   439 	14,
   440 	15,
   441 	16,
   442 	17,
   443 	18,
   444 	19,
   445 	20,
   446 	21,
   447 	22,
   448 	23,
   449 	24,
   450 	25,
   451 	26,
   452 	',',
   453 	};
   454 
   455 
   456 
   457 //
   458 // TO DO: (optional)
   459 //
   460 // Each set of scancode+keycode tables must be grouped into a SConvSubTable.
   461 // The lines below define a number of SConvSubTables for each of the groups
   462 // above.
   463 //
   464 LOCAL_D const SConvSubTable
   465 	convSubTable_unmodifiable=							// table for unmodifiable keys
   466 		{
   467 		&convKeyCodes_unmodifiable[0],					// the keycode table
   468 			{
   469 			ARRAY_LENGTH(scanCodeBlock_unmodifiable),	// number of scancode blocks
   470 			&scanCodeBlock_unmodifiable[0]				// pointer to scancode blocks
   471 			}
   472 		},
   473 	convSubTable_base=									// table for base keys
   474 		{
   475 		&convKeyCodes_base[0],							// keycode table
   476 			{
   477 			ARRAY_LENGTH(scanCodeBlock_base),			// number of scancode blocks
   478 			&scanCodeBlock_base[0]						// pointer to scancode blocks
   479 			}
   480 		},
   481 	convSubTable_capsLock=
   482 		{
   483 		&convKeyCodes_capsLock[0],
   484 			{
   485 			ARRAY_LENGTH(scanCodeBlock_capsLock),
   486 			&scanCodeBlock_capsLock[0]
   487 			}
   488 		},
   489 	convSubTable_shift=
   490 		{
   491 		&convKeyCodes_shift[0],
   492 			{
   493 			ARRAY_LENGTH(scanCodeBlock_shift),
   494 			&scanCodeBlock_shift[0]
   495 			}
   496 		},
   497 	convSubTable_func=
   498 		{
   499 		&convKeyCodes_func[0],
   500 			{
   501 			ARRAY_LENGTH(scanCodeBlock_func),
   502 			&scanCodeBlock_func[0]
   503 			}
   504 		},
   505 //	convSubTable_funcUnshifted=
   506 //		{
   507 //		&convKeyCodes_funcUnshifted[0],
   508 //			{
   509 //			ARRAY_LENGTH(scanCodeBlock_funcUnshifted),
   510 //			&scanCodeBlock_funcUnshifted[0]
   511 //			}
   512 //		},
   513 //	convSubTable_funcShifted=
   514 //		{
   515 //		&convKeyCodes_funcShifted[0],
   516 //			{
   517 //			ARRAY_LENGTH(scanCodeBlock_funcShifted),
   518 //			&scanCodeBlock_funcShifted[0]
   519 //			}
   520 //		},
   521 	convSubTable_ctrl=
   522 		{
   523 		&convKeyCodes_ctrl[0],
   524 			{
   525 			ARRAY_LENGTH(scanCodeBlock_ctrl),
   526 			&scanCodeBlock_ctrl[0]
   527 			}
   528 		};
   529 
   530 //
   531 // TO DO: (optional)
   532 //
   533 // We need to declare arrays of SConvSubTable for each modifier state we
   534 // are going to handle. As mentioned above, it is possible to have several
   535 // [keycode table, scancode blocks] groups scanned for each keyboard state.
   536 //
   537 // Some modifier states use more than one conversion group. The simple example
   538 // is handling of caps-lock and shift. 
   539 //
   540 // Caps-lock means all letters are upper-case
   541 // shift means all letters are upper case AND some other keys return control characters
   542 //
   543 // Obviously the shift key means everything cpas-lock means PLUS a bit more. So
   544 // we define two tables, the caps-lock table defines only the uppercase conversion,
   545 // and the shift table defines all OTHER shifted keys not already handled by
   546 // caps-lock. The caps-lock modifier state then only scans the caps-lock table, and
   547 // the shift state scans both tables.
   548 //
   549 LOCAL_D const SConvSubTable
   550 	* const convSubTableArray_unmodifiable[]={&convSubTable_unmodifiable},
   551 	* const convSubTableArray_base[]={&convSubTable_base},
   552 
   553 	//
   554 	// The caps-lock state scans only the caps-lock table, to handle
   555 	// conversion to upper case
   556 	//
   557 	* const convSubTableArray_capsLock[]={&convSubTable_capsLock},
   558 	//
   559 	// The shift table scans the caps-lock table to handle upper case, 
   560 	// and also the shift table which handles some keys that are not affected
   561 	// by caps lock (such as 0-9).
   562 	//
   563 	* const convSubTableArray_shift[]={&convSubTable_capsLock, &convSubTable_shift},
   564 	//
   565 	// Pressing shift with caps-lock active reverts to lower-case letters,
   566 	// but other keys remain shifted. This time we only scan the shift table
   567 	// so only the non-alpha keys will be shifted
   568 	//
   569 	* const convSubTableArray_capsLockShift[]={&convSubTable_shift},
   570 
   571 	//
   572 	// Like the shift/caps-lock situation, the function key has two states,
   573 	// shifted and unshifted. Also, some keys may be independant of whether
   574 	// the shift key is pressed. So there are three tables defined. One declares
   575 	// all keys that are independant of shift state, the other two tables handle
   576 	// shifted and unshifted func.
   577 	//
   578 	// Unshifted func uses the independant set + funcUnshifted
   579 	//
   580 	//	* const convSubTableArray_func[]={&convSubTable_func, &convSubTable_funcUnshifted},
   581 	* const convSubTableArray_func[]={&convSubTable_func},
   582 	//
   583 	// Shifted func uses the independant set + funcShifted
   584 	//
   585 	//	* const convSubTableArray_funcShift[]={&convSubTable_func,&convSubTable_funcShifted},
   586 	//
   587 	// This keyboard table makes control independant of func and shift
   588 	//
   589 	* const convSubTableArray_ctrl[]={&convSubTable_ctrl};
   590 
   591 //
   592 // TO DO: (optional)
   593 //
   594 // This is the top of the scancode conversion tree. It is a set of pointers
   595 // to the SConvSubTable arrays declared above.
   596 //
   597 // The order of these nodes is VITAL, as the scanCode/modifiers are
   598 // searched for a match in this order
   599 //
   600 // The modifier state is matched by using a mask and a compare value. This is
   601 // used as follows:
   602 //
   603 //	match is true if ( (modifierState & mask) == compareValue
   604 //
   605 // For example, if the mask is (EModifierFunc|EModifierShift) and the
   606 // compare value is EModifierFunc, this will match ANY combination of
   607 // modifiers that has func pressed and shift not pressed
   608 //
   609 LOCAL_D const SConvTableNode convTableNodes[]=
   610 	{
   611 		{
   612 			{
   613 			0,		// modifier mask = no modifiers
   614 			0		// modifier compare = no modifiers
   615 			},
   616 		ARRAY_LENGTH(convSubTableArray_unmodifiable),	// number of SConvSubTables
   617 		&convSubTableArray_unmodifiable[0]				// pointer to SConvSubTable array
   618 		},
   619 		{
   620 			{
   621 			EModifierCtrl,	// modifier mask = check for ctrl
   622 			EModifierCtrl	// modifier compare = anything with ctrl pressed
   623 			},
   624 		ARRAY_LENGTH(convSubTableArray_ctrl),
   625 		&convSubTableArray_ctrl[0]
   626 		},
   627 		{
   628 			{
   629 			//
   630 			// Check for Func pressed
   631 			//
   632 			EModifierFunc,
   633 			EModifierFunc
   634 			},
   635 		ARRAY_LENGTH(convSubTableArray_func),
   636 		&convSubTableArray_func[0]
   637 		},
   638 		{
   639 			{
   640 			//
   641 			// Check for caps-lock pressed, shift not pressed
   642 			//
   643 			EModifierCapsLock|EModifierShift,
   644 			EModifierCapsLock
   645 			},
   646 		ARRAY_LENGTH(convSubTableArray_capsLock),
   647 		&convSubTableArray_capsLock[0]
   648 		},
   649 		{
   650 			{
   651 			//
   652 			// Check for caps-lock not pressed, shift pressed
   653 			//
   654 			EModifierShift|EModifierCapsLock,
   655 			EModifierShift
   656 			},
   657 		ARRAY_LENGTH(convSubTableArray_shift),
   658 		&convSubTableArray_shift[0]
   659 		},
   660 		{
   661 			{
   662 			//
   663 			// Check for caps-lock pressed, shift pressed
   664 			//
   665 			EModifierCapsLock|EModifierShift,
   666 			EModifierCapsLock|EModifierShift
   667 			},
   668 		ARRAY_LENGTH(convSubTableArray_capsLockShift),
   669 		&convSubTableArray_capsLockShift[0]
   670 		},
   671 		{
   672 		//
   673 		// This is the base table. It must appear last so that it can
   674 		// provide a default conversion for any scancodes that are not
   675 		// handled by any of the tables above
   676 		//
   677 			{
   678 			0,
   679 			0
   680 			},
   681 		ARRAY_LENGTH(convSubTableArray_base),
   682 		&convSubTableArray_base[0]
   683 		}
   684 	};
   685 
   686 //
   687 // The top-level exported data structure of all the conversion tables
   688 // This just points to the SConvTableNodes above
   689 //
   690 LOCAL_D const SConvTable ConvTable=
   691 	{
   692 	ARRAY_LENGTH(convTableNodes),
   693 	&convTableNodes[0]
   694 	};
   695 
   696 // The list of scan-codes on the numeric keypad
   697 LOCAL_D const SScanCodeBlock keypadScanCodeBlockArray[]=
   698 	{
   699 	{EStdKeyNumLock, EStdKeyNumLock},
   700 	{EStdKeyNkpForwardSlash, EStdKeyNkpFullStop}
   701 	};
   702 
   703 LOCAL_D const SScanCodeBlockList ConvTableKeypadScanCodes=
   704 	{
   705 	ARRAY_LENGTH(keypadScanCodeBlockArray),
   706 	&keypadScanCodeBlockArray[0]
   707 	};
   708 
   709 //
   710 // TO DO: (optional)
   711 //
   712 // List of keycodes that do not autorepeat
   713 //
   714 // These are usually control keys like shift, ctrl, escape
   715 //
   716 LOCAL_D const TUint16 nonAutorepKeyCodeArray[]=
   717 	{
   718 	EKeyEscape,
   719 	EKeyPrintScreen,
   720 	EKeyPause,
   721 	EKeyInsert,
   722 	EKeyLeftShift,
   723 	EKeyRightShift,
   724 	EKeyLeftAlt,
   725 	EKeyRightAlt,
   726 	EKeyLeftCtrl,
   727 	EKeyRightCtrl,
   728 	EKeyLeftFunc,
   729 	EKeyRightFunc,
   730 	EKeyCapsLock,
   731 	EKeyNumLock,
   732 	EKeyScrollLock,
   733 	EKeyMenu,
   734 	EKeyDictaphonePlay,
   735 	EKeyDictaphoneStop,
   736 	EKeyDictaphoneRecord
   737 	};
   738 
   739 //
   740 // TO DO: (optional)
   741 //
   742 // Declare blocks of non-autorepeating keycodes
   743 //
   744 LOCAL_D const SKeyCodeList ConvTableNonAutorepKeyCodes=
   745 	{
   746 	ARRAY_LENGTH(nonAutorepKeyCodeArray),	// number of keycode arrays
   747 	&nonAutorepKeyCodeArray[0]				// pointer to arrays
   748 	};
   749 
   750 
   751 
   752 
   753 
   754 
   755 /////////////////////////////////////////////////////////////////////
   756 // Keyboard state tables
   757 //
   758 
   759 // What these tables do
   760 // --------------------
   761 //
   762 // These tables control the way "special" keystrokes modify the behaviour
   763 // of the keyboard. There are two major uses for this:
   764 //
   765 //	- handling modifier keys e.g. caps-lock, shift, alt, fn and defining
   766 //		what modifier flags are affected by these keypresses
   767 //
   768 //	- switching the keyboard into special states (see below)
   769 //
   770 // Keyboard states
   771 // ---------------
   772 // 
   773 // Keyboard states are used to switch the keyboard into a special mode where it
   774 // can be used to enter unusual characters. There are two uses for this:
   775 //
   776 // - entering numeric codes, by pressing ctrl and typing the decimal code
   777 // - entering accented characters by pressing a key combination which
   778 //		enters "accented mode" then pressing a key. There can be multiple
   779 //		accented modes.
   780 //
   781 // You can see an example of accented modes on a Psion Series 5 by
   782 // pressing Fn+Z, followed by A - this will produce an a with an umlaut (ä)
   783 //
   784 // These tables are also used to select simpler states such as caps-lock
   785 // and num-lock.
   786 //
   787 //
   788 // The main data structure is a SFuncTableEntry. Each of these contains
   789 // three fields:
   790 //
   791 // 1. modifier match - this works the same way as the scancode conversion
   792 //     tables above, there is a mask and a compare value
   793 //
   794 // 2. a keycode patters - this is used to match with the keycode or keycodes
   795 //     that the state should respond to. This is a TKeyCodePattern structure
   796 //     which defines what sort of match should be performed.
   797 //
   798 // 3. a function and state change structure, SFuncAndState. This defines the
   799 //     state to change to, the function to perform, and a parameter for the
   800 //     function if required.
   801 //
   802 // TKeyCodePattern structures have two fields. The first is a keycode value
   803 // and is only used for some match types. The second field select the type
   804 // of match to perform:
   805 //
   806 //	EAnyKey - match any key
   807 //	EAnyAlphaNumeric - match any alpha or numeric key
   808 //	EAnyAlpha - match any alpha key
   809 //	EAnyAlphaLowerCase - match any lower-case key
   810 //	EAnyAlphaUpperCase - match any upper-case key
   811 //	EAnyDecimalDigit - match any decimal digit
   812 //	EAnyModifierKey - match any modifier key (e.g. alt, fn, ctrl)
   813 //	EMatchKey - match if equal to keycode value in first field
   814 //	EMatchLeftOrRight - match if equal to keycode value or (keycode value + 1)
   815 //	EMatchKeyCaseInsens - like EMatchKey but perform case-insensitive comparison
   816 //
   817 //
   818 
   819 // the "array" parameter must be a true array and not a pointer
   820 #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
   821 
   822 #define TABLE_ENTRY_ANOTHER_CTRL_DIGIT					\
   823 	{  													\
   824 		{												\
   825 		EModifierKeyUp|EModifierFunc,					\
   826 		0												\
   827 		},												\
   828 		{												\
   829 		EKeyNull,										\
   830 		EAnyDigitGivenRadix								\
   831 		},												\
   832 		{												\
   833 		EStateCtrlDigits,								\
   834 		EAddOnCtrlDigit,								\
   835 		0												\
   836 		}												\
   837 	}
   838 
   839 //
   840 // TO DO: (optional)
   841 //
   842 // This table is searched for a match if a match has not been
   843 // found in the current state's table
   844 //
   845 
   846 LOCAL_D const SFuncTableEntry defaultTable[]=
   847 	{
   848 		{ 
   849 		//
   850 		// prevent key up events generating keycodes
   851 		//
   852 			{
   853 			EModifierKeyUp,		// mask = key up
   854 			EModifierKeyUp		// match = key up - i.e. accept any key up event
   855 			},
   856 			{
   857 			EKeyNull,			// dummy value, not used
   858 			EAnyKey				// accept any key
   859 			},
   860 			{
   861 			EStateUnchanged,	// state will not change
   862 			EDoNothing,			// no action to perform
   863 			0
   864 			}
   865 		},
   866 		{ 
   867 		//
   868 		// prevent any modifier key (e.g. shift, ctrl) from changing state
   869 		//
   870 			{
   871 			0,					// match any modifier state
   872 			0
   873 			},
   874 			{
   875 			EKeyNull,			// dummy value
   876 			EAnyModifierKey		// match any modifier key
   877 			},
   878 			{
   879 			EStateUnchanged,	// don't change state
   880 			EDoNothing,			// nothing to do
   881 			0
   882 			}
   883 		},
   884 		{ 
   885 		//
   886 		// filter out any unprocessed codes
   887 		//
   888 			{
   889 			0,					// match any modifier state
   890 			0
   891 			},
   892 			{
   893 			EKeyNull,			// dummy value
   894 			EAnyKey				// match any key
   895 			},
   896 			{
   897 			EStateNormal,		// switch back to normal keyboard state
   898 			EDoNothing,			// nothing to do
   899 			0
   900 			}
   901 		}
   902 	};
   903 
   904 //
   905 // TO DO: (optional)
   906 //
   907 // This table controls which keys change which modifiers;
   908 // NOTE: the state field in this table is ignored
   909 //
   910 
   911 LOCAL_D const SFuncTableEntry modifierTable[]=
   912 	{
   913 		{
   914 			{
   915 			EModifierKeyUp,		// check key-up modifier flag
   916 			0					// make sure it's zero (i.e. ignore key-up events)
   917 			},
   918 			{
   919 			//
   920 			// Here we want to match only the caps-lock key. We specify the
   921 			// keycode we are looking for in the first field, and EMatchKey
   922 			// in the second field
   923 			//
   924 			EKeyCapsLock,		// we want to respond to caps-lock key
   925 			EMatchKey			// match caps-lock only
   926 			},
   927 			{
   928 			EStateUnchanged,	// ignored
   929 			EToggleModifier,	// function = toggle modifier state
   930 			EModifierCapsLock	// this is the modifier to toggle
   931 			}
   932 		},
   933 		{
   934 			{
   935 			EModifierKeyUp,
   936 			0
   937 			},
   938 			{
   939 			EKeyNumLock,		// this one matched num-lock
   940 			EMatchKey			// match only num-lock
   941 			},
   942 			{
   943 			EStateUnchanged,	// ignored
   944 			EToggleModifier,	// function = toggle modifier state
   945 			EModifierNumLock	// this is the modifier to toggle
   946 			}
   947 		},
   948 		{
   949 			{
   950 			EModifierKeyUp,
   951 			0
   952 			},
   953 			{
   954 			EKeyScrollLock,		// match scroll-lock key
   955 			EMatchKey
   956 			},
   957 			{
   958 			EStateUnchanged,
   959 			EToggleModifier,	// function = toggle modifier
   960 			EModifierScrollLock	// modifier to toggle
   961 			}
   962 		},
   963 		{
   964 			{
   965 			EModifierKeyUp,
   966 			0
   967 			},
   968 			{
   969 			EKeyLeftAlt,		// match left alt key
   970 			EMatchKey
   971 			},
   972 			{
   973 			EStateUnchanged,	// ignored
   974 			ETurnOnModifier,	// function = turn on a modifier
   975 			EModifierAlt|EModifierLeftAlt	// alt turns on this modifier combination
   976 			}
   977 		},
   978 		{
   979 			{
   980 			EModifierKeyUp,		// goes with previous table, this handles the alt
   981 			EModifierKeyUp		// key being released
   982 			},
   983 			{
   984 			EKeyLeftAlt,		// match left alt key again
   985 			EMatchKey
   986 			},
   987 			{
   988 			EStateUnchanged,
   989 			ETurnOffModifier,	// function = turn off the modifier
   990 			EModifierLeftAlt	// modifier to turn off
   991 			}
   992 		},
   993 		{
   994 			{
   995 			EModifierKeyUp,		// key down event (key-up flag == 0)
   996 			0
   997 			},
   998 			{
   999 			EKeyLeftFunc,		// match left fn key
  1000 			EMatchKey
  1001 			},
  1002 			{
  1003 			EStateUnchanged,	// ignored
  1004 			ETurnOnModifier,	// function = turn on modifier
  1005 			EModifierFunc|EModifierLeftFunc	// modifier combination to turn on
  1006 			}
  1007 		},
  1008 		{
  1009 			{
  1010 			EModifierKeyUp,		// goes with above table, this matched the
  1011 			EModifierKeyUp		// left-fn key up event
  1012 			},
  1013 			{
  1014 			EKeyLeftFunc,		// match left fn key
  1015 			EMatchKey
  1016 			},
  1017 			{
  1018 			EStateUnchanged,	// ignored
  1019 			ETurnOffModifier,	// function = turn off modifier
  1020 			EModifierLeftFunc	// modifier to turn off
  1021 			}
  1022 		},
  1023 		{
  1024 			{
  1025 			EModifierKeyUp,		// key down event (key-up flag == 0)
  1026 			0
  1027 			},
  1028 			{
  1029 			EKeyLeftShift,		// match left shift key
  1030 			EMatchKey
  1031 			},
  1032 			{
  1033 			EStateUnchanged,	// ignored
  1034 			ETurnOnModifier,	// function = turn on modifier
  1035 			EModifierShift|EModifierLeftShift	// modifier combination to turn on
  1036 			}
  1037 		},
  1038 		{
  1039 			{
  1040 			EModifierKeyUp,		// goes with above table, matches left shift
  1041 			EModifierKeyUp		// key up event
  1042 			},
  1043 			{
  1044 			EKeyLeftShift,		// match left shift key
  1045 			EMatchKey
  1046 			},
  1047 			{
  1048 			EStateUnchanged,	// ignored
  1049 			ETurnOffModifier,	// turn off modifier
  1050 			EModifierLeftShift	// modifier to turn off
  1051 			}
  1052 		},
  1053 		{
  1054 			{
  1055 			EModifierKeyUp,		// key down event (key-up flag == 0)
  1056 			0
  1057 			},
  1058 			{
  1059 			EKeyLeftCtrl,		// match left ctrl key
  1060 			EMatchKey
  1061 			},
  1062 			{
  1063 			EStateUnchanged,	// ignored
  1064 			ETurnOnModifier,	// function = turn on modifier
  1065 			EModifierCtrl|EModifierLeftCtrl	// modifier combination to turn on
  1066 			}
  1067 		},
  1068 		{
  1069 			{
  1070 			EModifierKeyUp,		// goes with above table, matches left ctrl
  1071 			EModifierKeyUp		// key up event
  1072 			},
  1073 			{
  1074 			EKeyLeftCtrl,		// match left ctrl key
  1075 			EMatchKey
  1076 			},
  1077 			{
  1078 			EStateUnchanged,	// ignored
  1079 			ETurnOffModifier,	// function = turn off modifier
  1080 			EModifierLeftCtrl	// modifier to turn off
  1081 			}
  1082 		},
  1083 		{
  1084 			{
  1085 			EModifierKeyUp,		// key down event (key-up flag == 0)
  1086 			0
  1087 			},
  1088 			{
  1089 			EKeyRightAlt,		// match right alt key
  1090 			EMatchKey
  1091 			},
  1092 			{
  1093 			EStateUnchanged,	// ignored
  1094 			ETurnOnModifier,	// function = turn on modifier
  1095 			EModifierAlt|EModifierRightAlt	// modifier combination to turn on
  1096 			}
  1097 		},
  1098 		{
  1099 			{
  1100 			EModifierKeyUp,		// goes with above table, matches right alt
  1101 			EModifierKeyUp		// key up event
  1102 			},
  1103 			{
  1104 			EKeyRightAlt,		// match right alt key
  1105 			EMatchKey
  1106 			},
  1107 			{
  1108 			EStateUnchanged,	// ignored
  1109 			ETurnOffModifier,	// function = turn off modifier
  1110 			EModifierRightAlt	// modifier to turn off
  1111 			}
  1112 		},
  1113 		{
  1114 			{
  1115 			EModifierKeyUp,		// key down event (key-up flag == 0)
  1116 			0
  1117 			},
  1118 			{
  1119 			EKeyRightFunc,		// match right fn key
  1120 			EMatchKey
  1121 			},
  1122 			{
  1123 			EStateUnchanged,	// ignored
  1124 			ETurnOnModifier,	// function = turn on modifier
  1125 			EModifierFunc|EModifierRightFunc	// modifier combination to turn on
  1126 			}
  1127 		},
  1128 		{
  1129 			{
  1130 			EModifierKeyUp,		// goes with above table, matches right fn
  1131 			EModifierKeyUp		// key up event
  1132 			},
  1133 			{
  1134 			EKeyRightFunc,		// match right fn key
  1135 			EMatchKey
  1136 			},
  1137 			{
  1138 			EStateUnchanged,	// ignored
  1139 			ETurnOffModifier,	// function = turn off modifier
  1140 			EModifierRightFunc	// modifier to turn off
  1141 			}
  1142 		},
  1143 		{
  1144 			{
  1145 			EModifierKeyUp,		// key down event (key-up flag == 0)
  1146 			0
  1147 			},
  1148 			{
  1149 			EKeyRightShift,		// match right shift key
  1150 			EMatchKey
  1151 			},
  1152 			{
  1153 			EStateUnchanged,	// ignored
  1154 			ETurnOnModifier,	// function = turn on modifier
  1155 			EModifierShift|EModifierRightShift	// modifier combinatoin to turn on
  1156 			}
  1157 		},
  1158 		{
  1159 			{
  1160 			EModifierKeyUp,		// goes with above table, handles right shift
  1161 			EModifierKeyUp		// key up event
  1162 			},
  1163 			{
  1164 			EKeyRightShift,		// match right shift key
  1165 			EMatchKey
  1166 			},
  1167 			{
  1168 			EStateUnchanged,	// ignored
  1169 			ETurnOffModifier,	// function = turn off modifier
  1170 			EModifierRightShift	// modifier to turn off
  1171 			}
  1172 		},
  1173 		{
  1174 			{
  1175 			EModifierKeyUp,		// key down event (key-up flag == 0)
  1176 			0
  1177 			},
  1178 			{
  1179 			EKeyRightCtrl,		// match right ctrl key
  1180 			EMatchKey
  1181 			},
  1182 			{
  1183 			EStateUnchanged,	// ignored
  1184 			ETurnOnModifier,	// function = turn on modifier
  1185 			EModifierCtrl|EModifierRightCtrl	// modifier combination to turn on
  1186 			}
  1187 		},
  1188 		{
  1189 			{
  1190 			EModifierKeyUp,		// goes with above table, matched right ctrl
  1191 			EModifierKeyUp		// key up event
  1192 			},
  1193 			{
  1194 			EKeyRightCtrl,		// match right ctrl key
  1195 			EMatchKey
  1196 			},
  1197 			{
  1198 			EStateUnchanged,	// ignored
  1199 			ETurnOffModifier,	// function = turn off modifier
  1200 			EModifierRightCtrl	// modifier to turn off
  1201 			}
  1202 		}
  1203 	};
  1204 
  1205 
  1206 //
  1207 // TO DO: (optional)
  1208 //
  1209 // Tables corresponding to keyboard states.
  1210 //
  1211 // There are 13 keyboard states. States 0 to 9 can be used to create alternative
  1212 // keyboard layouts for entering accented or unusual characters. Switching into
  1213 // these states is done by a keypress. Implementation of the states is optional
  1214 // depending on how many special state you want - you may implement 10 states,
  1215 // you might decide not to implement any.
  1216 //
  1217 // State 10 is the normal state. The table for state 10 defines which keypresses
  1218 // change to other states.
  1219 //
  1220 // States 11 and 12 are used when entering the numeric code of a character. State
  1221 // 11 is for entering a specific number of digits. State 12 is for accepting
  1222 // digits until Ctrl is released.
  1223 //	
  1224 //
  1225 // As before, each SFuncTableEntry entry defines:
  1226 //	- modifier conditions that must be matched
  1227 //	- a keycode match pattern (typically an exact key match)
  1228 //	- the function to perform and new state
  1229 //
  1230 // Switching into states 0..9,11,12 is done by entries in table10
  1231 //
  1232 
  1233 //LOCAL_D const SFuncTableEntry table0[]=
  1234 //	{
  1235 //	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  1236 //	};
  1237 
  1238 LOCAL_D const SFuncTableEntry table1[]=
  1239 	{
  1240 	//
  1241 	// Table for special keyboard state 1
  1242 	// This state is entered by pressing Fn+q (see table10)
  1243 	//
  1244 	// The table makes certain keys return accented characters
  1245 	//
  1246 		{
  1247 			{
  1248 			//
  1249 			// Function must be release, and this must be a key down event
  1250 			//
  1251 			EModifierFunc|EModifierKeyUp,
  1252 			0
  1253 			},
  1254 			{
  1255 			//
  1256 			// match an 'e' keypress, convert to an ae ligature (æ)
  1257 			//
  1258 			'e',
  1259 			EMatchKeyCaseInsens
  1260 			},
  1261 			{
  1262 			EStateNormal,			// switch back to state normal (table10)
  1263 			EPassSpecialKeyThru,	// turn keypress into a special character
  1264 			ELatin1LcAe				// this is the character to pass on
  1265 			}
  1266 		},
  1267 		{
  1268 			{
  1269 			EModifierFunc|EModifierKeyUp,
  1270 			0
  1271 			},
  1272 			{
  1273 			'c',
  1274 			EMatchKeyCaseInsens
  1275 			},
  1276 			{
  1277 			EStateNormal,
  1278 			EPassSpecialKeyThru,
  1279 			ELatin1LcCcedilla
  1280 			}
  1281 		},
  1282 		{
  1283 			{
  1284 			EModifierFunc|EModifierKeyUp,
  1285 			0
  1286 			},
  1287 			{
  1288 			's',
  1289 			EMatchKeyCaseInsens
  1290 			},
  1291 			{
  1292 			EStateNormal,
  1293 			EPassSpecialKeyThru,
  1294 			ELatin1EsTset
  1295 			}
  1296 		},
  1297 		{
  1298 			{
  1299 			EModifierFunc|EModifierKeyUp,
  1300 			0
  1301 			},
  1302 			{
  1303 			'o',
  1304 			EMatchKeyCaseInsens
  1305 			},
  1306 			{
  1307 			EStateNormal,
  1308 			EPassSpecialKeyThru,
  1309 			ELatin1LcOslash
  1310 			}
  1311 		},
  1312 		{
  1313 			{
  1314 			EModifierFunc|EModifierKeyUp,
  1315 			0
  1316 			},
  1317 			{
  1318 			'd',
  1319 			EMatchKeyCaseInsens
  1320 			},
  1321 			{
  1322 			EStateNormal,
  1323 			EPassSpecialKeyThru,
  1324 			ELatin1LcThorn
  1325 			}
  1326 		},
  1327 		{
  1328 			{
  1329 			EModifierFunc|EModifierKeyUp,
  1330 			0
  1331 			},
  1332 			{
  1333 			't',
  1334 			EMatchKeyCaseInsens
  1335 			},
  1336 			{
  1337 			EStateNormal,
  1338 			EPassSpecialKeyThru,
  1339 			ELatin1LcSoftTh
  1340 			}
  1341 		},
  1342 		{
  1343 			{
  1344 			EModifierFunc|EModifierKeyUp,
  1345 			0
  1346 			},
  1347 			{
  1348 			'l',
  1349 			EMatchKeyCaseInsens
  1350 			},
  1351 			{
  1352 			EStateNormal,
  1353 			EPassSpecialKeyThru,
  1354 			ELatin1LeftChevron
  1355 			}
  1356 		},
  1357 		{
  1358 			{
  1359 			EModifierFunc|EModifierKeyUp,
  1360 			0
  1361 			},
  1362 			{
  1363 			'r',
  1364 			EMatchKeyCaseInsens
  1365 			},
  1366 			{
  1367 			EStateNormal,
  1368 			EPassSpecialKeyThru,
  1369 			ELatin1RightChevron
  1370 			}
  1371 		},
  1372 		{
  1373 			{
  1374 			EModifierFunc|EModifierKeyUp,
  1375 			0
  1376 			},
  1377 			{
  1378 			'x',
  1379 			EMatchKeyCaseInsens
  1380 			},
  1381 			{
  1382 			EStateNormal,
  1383 			EPassSpecialKeyThru,
  1384 			ELatin1InvExclam
  1385 			}
  1386 		},
  1387 		{
  1388 			{
  1389 			EModifierFunc|EModifierKeyUp,
  1390 			0
  1391 			},
  1392 			{
  1393 			'q',
  1394 			EMatchKeyCaseInsens
  1395 			},
  1396 			{
  1397 			EStateNormal,
  1398 			EPassSpecialKeyThru,
  1399 			ELatin1InvQuest
  1400 			}
  1401 		},
  1402 		{
  1403 			{
  1404 			EModifierFunc|EModifierKeyUp,
  1405 			0
  1406 			},
  1407 			{
  1408 			'a',
  1409 			EMatchKeyCaseInsens
  1410 			},
  1411 			{
  1412 			EStateNormal,
  1413 			EPassSpecialKeyThru,
  1414 			ELatin1LcAo
  1415 			}
  1416 		},
  1417 		{
  1418 			{
  1419 			EModifierFunc|EModifierKeyUp,
  1420 			0
  1421 			},
  1422 			{
  1423 			'p',
  1424 			EMatchKeyCaseInsens
  1425 			},
  1426 			{
  1427 			EStateNormal,
  1428 			EPassSpecialKeyThru,
  1429 			ELatin1Pound
  1430 			}
  1431 		},
  1432 	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  1433 	};
  1434 
  1435 LOCAL_D const SFuncTableEntry table2[]=
  1436 	{
  1437 	//
  1438 	// Table for special keyboard state 2
  1439 	// This state is entered by pressing Fn+z (see table10)
  1440 	//
  1441 	// The table makes certain keys return accented characters
  1442 	// See table1 for an explanation of the contents
  1443 	//
  1444 		{
  1445 			{
  1446 			EModifierFunc|EModifierKeyUp,
  1447 			0
  1448 			},
  1449 			{
  1450 			'a',
  1451 			EMatchKeyCaseInsens
  1452 			},
  1453 			{
  1454 			EStateNormal,
  1455 			EPassSpecialKeyThru,
  1456 			ELatin1LcAumlaut
  1457 			}
  1458 		},
  1459 		{
  1460 			{
  1461 			EModifierFunc|EModifierKeyUp,
  1462 			0
  1463 			},
  1464 			{
  1465 			'e',
  1466 			EMatchKeyCaseInsens
  1467 			},
  1468 			{
  1469 			EStateNormal,
  1470 			EPassSpecialKeyThru,
  1471 			ELatin1LcEumlaut
  1472 			}
  1473 		},
  1474 		{
  1475 			{
  1476 			EModifierFunc|EModifierKeyUp,
  1477 			0
  1478 			},
  1479 			{
  1480 			'i',
  1481 			EMatchKeyCaseInsens
  1482 			},
  1483 			{
  1484 			EStateNormal,
  1485 			EPassSpecialKeyThru,
  1486 			ELatin1LcIumlaut
  1487 			}
  1488 		},
  1489 		{
  1490 			{
  1491 			EModifierFunc|EModifierKeyUp,
  1492 			0
  1493 			},
  1494 			{
  1495 			'o',
  1496 			EMatchKeyCaseInsens
  1497 			},
  1498 			{
  1499 			EStateNormal,
  1500 			EPassSpecialKeyThru,
  1501 			ELatin1LcOumlaut
  1502 			}
  1503 		},
  1504 		{
  1505 			{
  1506 			EModifierFunc|EModifierKeyUp,
  1507 			0
  1508 			},
  1509 			{
  1510 			'u',
  1511 			EMatchKeyCaseInsens
  1512 			},
  1513 			{
  1514 			EStateNormal,
  1515 			EPassSpecialKeyThru,
  1516 			ELatin1LcUumlaut
  1517 			}
  1518 		},
  1519 		{
  1520 			{
  1521 			EModifierFunc|EModifierKeyUp,
  1522 			0
  1523 			},
  1524 			{
  1525 			'y',
  1526 			EMatchKeyCaseInsens
  1527 			},
  1528 			{
  1529 			EStateNormal,
  1530 			EPassSpecialKeyThru,
  1531 			ELatin1LcYumlaut
  1532 			}
  1533 		},
  1534 		{
  1535 			{
  1536 			EModifierFunc|EModifierKeyUp,
  1537 			0
  1538 			},
  1539 			{
  1540 			' ',
  1541 			EMatchKey
  1542 			},
  1543 			{
  1544 			EStateNormal,
  1545 			EPassSpecialKeyThru,
  1546 			ELatin1SpaceUmlaut
  1547 			}
  1548 		},
  1549 	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  1550 	};
  1551 
  1552 LOCAL_D const SFuncTableEntry table3[]=
  1553 	{
  1554 	//
  1555 	// Table for special keyboard state 3
  1556 	// This state is entered by pressing Fn+x (see table10)
  1557 	//
  1558 	// The table makes certain keys return accented characters
  1559 	//
  1560 		{
  1561 			{
  1562 			EModifierFunc|EModifierKeyUp,
  1563 			0
  1564 			},
  1565 			{
  1566 			'a',
  1567 			EMatchKeyCaseInsens
  1568 			},
  1569 			{
  1570 			EStateNormal,
  1571 			EPassSpecialKeyThru,
  1572 			ELatin1LcAgrave
  1573 			}
  1574 		},
  1575 		{
  1576 			{
  1577 			EModifierFunc|EModifierKeyUp,
  1578 			0
  1579 			},
  1580 			{
  1581 			'e',
  1582 			EMatchKeyCaseInsens
  1583 			},
  1584 			{
  1585 			EStateNormal,
  1586 			EPassSpecialKeyThru,
  1587 			ELatin1LcEgrave
  1588 			}
  1589 		},
  1590 		{
  1591 			{
  1592 			EModifierFunc|EModifierKeyUp,
  1593 			0
  1594 			},
  1595 			{
  1596 			'i',
  1597 			EMatchKeyCaseInsens
  1598 			},
  1599 			{
  1600 			EStateNormal,
  1601 			EPassSpecialKeyThru,
  1602 			ELatin1LcIgrave
  1603 			}
  1604 		},
  1605 		{
  1606 			{
  1607 			EModifierFunc|EModifierKeyUp,
  1608 			0
  1609 			},
  1610 			{
  1611 			'o',
  1612 			EMatchKeyCaseInsens
  1613 			},
  1614 			{
  1615 			EStateNormal,
  1616 			EPassSpecialKeyThru,
  1617 			ELatin1LcOgrave
  1618 			}
  1619 		},
  1620 		{
  1621 			{
  1622 			EModifierFunc|EModifierKeyUp,
  1623 			0
  1624 			},
  1625 			{
  1626 			'u',
  1627 			EMatchKeyCaseInsens
  1628 			},
  1629 			{
  1630 			EStateNormal,
  1631 			EPassSpecialKeyThru,
  1632 			ELatin1LcUgrave
  1633 			}
  1634 		},
  1635 		{
  1636 			{
  1637 			EModifierFunc|EModifierKeyUp,
  1638 			0
  1639 			},
  1640 			{
  1641 			' ',
  1642 			EMatchKey
  1643 			},
  1644 			{
  1645 			EStateNormal,
  1646 			EPassSpecialKeyThru,
  1647 			ELatin1SpaceGrave
  1648 			}
  1649 		},
  1650 	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  1651 	};
  1652 
  1653 LOCAL_D const SFuncTableEntry table4[]=
  1654 	{
  1655 	//
  1656 	// Table for special keyboard state 4
  1657 	// This state is entered by pressing Fn+c (see table10)
  1658 	//
  1659 	// The table makes certain keys return accented characters
  1660 	//
  1661 		{
  1662 			{
  1663 			EModifierFunc|EModifierKeyUp,
  1664 			0
  1665 			},
  1666 			{
  1667 			'a',
  1668 			EMatchKeyCaseInsens
  1669 			},
  1670 			{
  1671 			EStateNormal,
  1672 			EPassSpecialKeyThru,
  1673 			ELatin1LcAacute
  1674 			}
  1675 		},
  1676 		{
  1677 			{
  1678 			EModifierFunc|EModifierKeyUp,
  1679 			0
  1680 			},
  1681 			{
  1682 			'e',
  1683 			EMatchKeyCaseInsens
  1684 			},
  1685 			{
  1686 			EStateNormal,
  1687 			EPassSpecialKeyThru,
  1688 			ELatin1LcEacute
  1689 			}
  1690 		},
  1691 		{
  1692 			{
  1693 			EModifierFunc|EModifierKeyUp,
  1694 			0
  1695 			},
  1696 			{
  1697 			'i',
  1698 			EMatchKeyCaseInsens
  1699 			},
  1700 			{
  1701 			EStateNormal,
  1702 			EPassSpecialKeyThru,
  1703 			ELatin1LcIacute
  1704 			}
  1705 		},
  1706 		{
  1707 			{
  1708 			EModifierFunc|EModifierKeyUp,
  1709 			0
  1710 			},
  1711 			{
  1712 			'o',
  1713 			EMatchKeyCaseInsens
  1714 			},
  1715 			{
  1716 			EStateNormal,
  1717 			EPassSpecialKeyThru,
  1718 			ELatin1LcOacute
  1719 			}
  1720 		},
  1721 		{
  1722 			{
  1723 			EModifierFunc|EModifierKeyUp,
  1724 			0
  1725 			},
  1726 			{
  1727 			'u',
  1728 			EMatchKeyCaseInsens
  1729 			},
  1730 			{
  1731 			EStateNormal,
  1732 			EPassSpecialKeyThru,
  1733 			ELatin1LcUacute
  1734 			}
  1735 		},
  1736 		{
  1737 			{
  1738 			EModifierFunc|EModifierKeyUp,
  1739 			0
  1740 			},
  1741 			{
  1742 			'y',
  1743 			EMatchKeyCaseInsens
  1744 			},
  1745 			{
  1746 			EStateNormal,
  1747 			EPassSpecialKeyThru,
  1748 			ELatin1LcYacute
  1749 			}
  1750 		},
  1751 		{
  1752 			{
  1753 			EModifierFunc|EModifierKeyUp,
  1754 			0
  1755 			},
  1756 			{
  1757 			' ',
  1758 			EMatchKey
  1759 			},
  1760 			{
  1761 			EStateNormal,
  1762 			EPassSpecialKeyThru,
  1763 			ELatin1LcSpaceAcute
  1764 			}
  1765 		},
  1766 	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  1767 	};
  1768 
  1769 LOCAL_D const SFuncTableEntry table5[]=
  1770 	{
  1771 	//
  1772 	// Table for special keyboard state 5
  1773 	// This state is entered by pressing Fn+v (see table10)
  1774 	//
  1775 	// The table makes certain keys return accented characters
  1776 	//
  1777 		{
  1778 			{
  1779 			EModifierFunc|EModifierKeyUp,
  1780 			0
  1781 			},
  1782 			{
  1783 			'a',
  1784 			EMatchKeyCaseInsens
  1785 			},
  1786 			{
  1787 			EStateNormal,
  1788 			EPassSpecialKeyThru,
  1789 			ELatin1LcAtilde
  1790 			}
  1791 		},
  1792 		{
  1793 			{
  1794 			EModifierFunc|EModifierKeyUp,
  1795 			0
  1796 			},
  1797 			{
  1798 			'n',
  1799 			EMatchKeyCaseInsens
  1800 			},
  1801 			{
  1802 			EStateNormal,
  1803 			EPassSpecialKeyThru,
  1804 			ELatin1LcNtilde
  1805 			}
  1806 		},
  1807 		{
  1808 			{
  1809 			EModifierFunc|EModifierKeyUp,
  1810 			0
  1811 			},
  1812 			{
  1813 			'o',
  1814 			EMatchKeyCaseInsens
  1815 			},
  1816 			{
  1817 			EStateNormal,
  1818 			EPassSpecialKeyThru,
  1819 			ELatin1LcOtilde
  1820 			}
  1821 		},
  1822 		{
  1823 			{
  1824 			EModifierFunc|EModifierKeyUp,
  1825 			0
  1826 			},
  1827 			{
  1828 			' ',
  1829 			EMatchKey
  1830 			},
  1831 			{
  1832 			EStateNormal,
  1833 			EPassSpecialKeyThru,
  1834 			ELatin1LcSpaceTilde
  1835 			}
  1836 		},
  1837 	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  1838 	};
  1839 
  1840 LOCAL_D const SFuncTableEntry table6[]=
  1841 	{
  1842 	//
  1843 	// Table for special keyboard state 6
  1844 	// This state is entered by pressing Fn+b (see table6)
  1845 	//
  1846 	// The table makes certain keys return accented characters
  1847 	//
  1848 		{
  1849 			{
  1850 			EModifierFunc|EModifierKeyUp,
  1851 			0
  1852 			},
  1853 			{
  1854 			'a',
  1855 			EMatchKeyCaseInsens
  1856 			},
  1857 			{
  1858 			EStateNormal,
  1859 			EPassSpecialKeyThru,
  1860 			ELatin1LcAcirc
  1861 			}
  1862 		},
  1863 		{
  1864 			{
  1865 			EModifierFunc|EModifierKeyUp,
  1866 			0
  1867 			},
  1868 			{
  1869 			'e',
  1870 			EMatchKeyCaseInsens
  1871 			},
  1872 			{
  1873 			EStateNormal,
  1874 			EPassSpecialKeyThru,
  1875 			ELatin1LcEcirc
  1876 			}
  1877 		},
  1878 		{
  1879 			{
  1880 			EModifierFunc|EModifierKeyUp,
  1881 			0
  1882 			},
  1883 			{
  1884 			'i',
  1885 			EMatchKeyCaseInsens
  1886 			},
  1887 			{
  1888 			EStateNormal,
  1889 			EPassSpecialKeyThru,
  1890 			ELatin1LcIcirc
  1891 			}
  1892 		},
  1893 		{
  1894 			{
  1895 			EModifierFunc|EModifierKeyUp,
  1896 			0
  1897 			},
  1898 			{
  1899 			'o',
  1900 			EMatchKeyCaseInsens
  1901 			},
  1902 			{
  1903 			EStateNormal,
  1904 			EPassSpecialKeyThru,
  1905 			ELatin1LcOcirc
  1906 			}
  1907 		},
  1908 		{
  1909 			{
  1910 			EModifierFunc|EModifierKeyUp,
  1911 			0
  1912 			},
  1913 			{
  1914 			'u',
  1915 			EMatchKeyCaseInsens
  1916 			},
  1917 			{
  1918 			EStateNormal,
  1919 			EPassSpecialKeyThru,
  1920 			ELatin1LcUcirc
  1921 			}
  1922 		},
  1923 		{
  1924 			{
  1925 			EModifierFunc|EModifierKeyUp,
  1926 			0
  1927 			},
  1928 			{
  1929 			' ',
  1930 			EMatchKey
  1931 			},
  1932 			{
  1933 			EStateNormal,
  1934 			EPassSpecialKeyThru,
  1935 			ELatin1LcSpaceCirc
  1936 			}
  1937 		},
  1938 	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  1939 	};
  1940 
  1941 //
  1942 // TO DO: (optional)
  1943 //
  1944 // State 7,8,9 aren't used in this example.
  1945 // You can implement them if you want more special states
  1946 //
  1947 
  1948 //LOCAL_D const SFuncTableEntry table7[]=
  1949 //	{
  1950 //	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  1951 //	};
  1952 
  1953 //LOCAL_D const SFuncTableEntry table8[]=
  1954 //	{
  1955 //	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  1956 //	};
  1957 
  1958 //LOCAL_D const SFuncTableEntry table9[]=
  1959 //	{
  1960 //	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  1961 //	};
  1962 
  1963 
  1964 LOCAL_D const SFuncTableEntry table10[]=
  1965 	{
  1966 	//
  1967 	// TO DO: (optional)
  1968 	//
  1969 	// Table keyboard state 10 - the normal state
  1970 	//
  1971 	// This table controls which keys switch into the special states
  1972 	// 0-9, 11 and 12.
  1973 	//
  1974 
  1975 		{ 
  1976 		//
  1977 		// Make sure key-up events are ignored by handling them first and
  1978 		// doing nothing
  1979 		//
  1980 			{
  1981 			EModifierKeyUp,
  1982 			EModifierKeyUp
  1983 			},
  1984 			{
  1985 			EKeyNull,
  1986 			EAnyKey
  1987 			},
  1988 			{
  1989 			EStateUnchanged,
  1990 			EDoNothing,
  1991 			0
  1992 			}
  1993 		},
  1994 		{ 
  1995 		//
  1996 		// Check for ctrl-number presses
  1997 		// This will enter state EStateCtrlDigits (state 12) which allows
  1998 		// entry of a numeric keycode
  1999 		//
  2000 			{
  2001 			EModifierCtrl|EModifierFunc|EModifierKeyUp,
  2002 			EModifierCtrl
  2003 			},
  2004 			{
  2005 			EKeyNull,
  2006 			EAnyDecimalDigit
  2007 			},
  2008 			{
  2009 			EStateDerivedFromDigitEntered,
  2010 			EAddOnCtrlDigit,
  2011 			0
  2012 			}
  2013 		},
  2014 		{
  2015 		//
  2016 		// Any other key events that have not been trapped are just
  2017 		// passed through unchanged
  2018 		//
  2019 			{
  2020 			0,
  2021 			0
  2022 			},
  2023 			{
  2024 			EKeyNull,
  2025 			EAnyKey
  2026 			},
  2027 			{
  2028 			EStateUnchanged,
  2029 			EPassKeyThru,
  2030 			0
  2031 			}
  2032 		}
  2033 	};
  2034 
  2035 //LOCAL_D const SFuncTableEntry table11[]=
  2036 //	{
  2037 //	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  2038 //	};
  2039 
  2040 LOCAL_D const SFuncTableEntry table12[]=
  2041 	{
  2042 	//
  2043 	// Table 12 handles entring digit codes. The keyboard will remain in this
  2044 	// state until the Ctrl key is released
  2045 	//
  2046 		{
  2047 			{
  2048 			//
  2049 			// Look for a key up event
  2050 			//
  2051 			EModifierKeyUp,
  2052 			EModifierKeyUp
  2053 			},
  2054 			{
  2055 			// 
  2056 			// Match either left or right Ctrl key (i.e. this matches a Ctrl key release)
  2057 			//
  2058 			EKeyLeftCtrl,
  2059 			EMatchLeftOrRight
  2060 			},
  2061 			{
  2062 			EStateNormal,			// return to normal state (table10)
  2063 			EPassCtrlDigitsThru,	// and pass through the numeric code we have accumulated
  2064 			0
  2065 			}
  2066 		},
  2067 	TABLE_ENTRY_ANOTHER_CTRL_DIGIT
  2068 	};
  2069 
  2070 
  2071 //
  2072 // TO DO: (optional)
  2073 //
  2074 // Array of state control tables above. If a state is not used set the array 
  2075 // size to zero and the pointer to NULL
  2076 //
  2077 // The tables must be declared here in order from table 0 to table 12
  2078 //
  2079 LOCAL_D const SFuncTable genFuncTables[]=
  2080 	{
  2081 		{
  2082 		//
  2083 		// state 0
  2084 		//
  2085 		0,			// state 0 not used, size = 0
  2086 		NULL		// state 0 not used, pointer = NULL
  2087 		},
  2088 		{
  2089 		//
  2090 		// state 1
  2091 		//
  2092 		ARRAY_LENGTH(table1),		// size of table 1
  2093 		&table1[0]					// pointer to table 1
  2094 		},
  2095 		{
  2096 		//
  2097 		// state 2
  2098 		//
  2099 		ARRAY_LENGTH(table2),
  2100 		&table2[0]
  2101 		},
  2102 		{
  2103 		//
  2104 		// state 3
  2105 		//
  2106 		ARRAY_LENGTH(table3),
  2107 		&table3[0]
  2108 		},
  2109 		{
  2110 		//
  2111 		// state 4
  2112 		//
  2113 		ARRAY_LENGTH(table4),
  2114 		&table4[0]
  2115 		},
  2116 		{
  2117 		//
  2118 		// state 5
  2119 		//
  2120 		ARRAY_LENGTH(table5),
  2121 		&table5[0]
  2122 		},
  2123 		{
  2124 		//
  2125 		// state 6
  2126 		//
  2127 		ARRAY_LENGTH(table6),
  2128 		&table6[0]
  2129 		},
  2130 		{
  2131 		//
  2132 		// state 7
  2133 		//
  2134 		0,
  2135 		NULL
  2136 		},
  2137 		{
  2138 		//
  2139 		// state 8
  2140 		//
  2141 		0,
  2142 		NULL
  2143 		},
  2144 		{
  2145 		//
  2146 		// state 9
  2147 		//
  2148 		0,
  2149 		NULL
  2150 		},
  2151 		{
  2152 		//
  2153 		// state 10
  2154 		//
  2155 		ARRAY_LENGTH(table10),
  2156 		&table10[0]
  2157 		},
  2158 		{
  2159 		//
  2160 		// state 11
  2161 		//
  2162 		0,
  2163 		NULL
  2164 		},
  2165 		{
  2166 		//
  2167 		// state 12
  2168 		//
  2169 		ARRAY_LENGTH(table12),
  2170 		&table12[0]
  2171 		}
  2172 	};
  2173 
  2174 
  2175 //
  2176 // Root of the state modifier tables
  2177 //
  2178 LOCAL_D const SFuncTables FuncTables=
  2179 	{
  2180 		{
  2181 		//
  2182 		// The default processing table
  2183 		//
  2184 		ARRAY_LENGTH(defaultTable),
  2185 		&defaultTable[0]
  2186 		},
  2187 		{
  2188 		//
  2189 		// The modifier control table
  2190 		//
  2191 		ARRAY_LENGTH(modifierTable),
  2192 		&modifierTable[0]
  2193 		},
  2194 	//
  2195 	// The state control tables
  2196 	//
  2197 	ARRAY_LENGTH(genFuncTables),
  2198 	&genFuncTables[0]
  2199 	};
  2200 
  2201 
  2202 //
  2203 // The following exported functions give the key translator access to
  2204 // the control tables above
  2205 //
  2206 EXPORT_C void KeyDataSettings(TRadix &aRadix,TCtrlDigitsTermination &aCtrlDigitsTermination,TInt &aDefaultCtrlDigitsMaxCount,
  2207 							  TInt &aMaximumCtrlDigitsMaxCount)
  2208 	{
  2209 	aRadix=EDecimal;
  2210 	aCtrlDigitsTermination=ETerminationByCtrlUp;
  2211 	aDefaultCtrlDigitsMaxCount=3;
  2212 	aMaximumCtrlDigitsMaxCount=10;
  2213 	}
  2214 
  2215 EXPORT_C void KeyDataFuncTable(SFuncTables &aFuncTables)
  2216 	{
  2217 	aFuncTables=FuncTables;
  2218 	}
  2219 
  2220 EXPORT_C void KeyDataConvTable(SConvTable &aConvTable, TUint &aConvTableFirstScanCode,TUint &aConvTableLastScanCode,
  2221 							 SScanCodeBlockList &aKeypadScanCode,SKeyCodeList &aNonAutorepKeyCodes)
  2222 	{
  2223 	aConvTable=ConvTable;
  2224 	aConvTableFirstScanCode=scanCodeBlock_base[0].firstScanCode;
  2225 	aConvTableLastScanCode=scanCodeBlock_base[ARRAY_LENGTH(scanCodeBlock_base)-1].lastScanCode;
  2226 	aKeypadScanCode=ConvTableKeypadScanCodes;
  2227 	aNonAutorepKeyCodes=ConvTableNonAutorepKeyCodes;
  2228 	}