bluetoothengine/bthid/layouts/src/layout.cpp
changeset 0 f63038272f30
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This is the implementation of application class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32std.h>
       
    20 #include <e32svr.h>
       
    21 #include <e32keys.h>
       
    22 #include <coedef.h>   // for CTRL()
       
    23 
       
    24 //#include "hidkeys.h"   // included from decode.h
       
    25 #include "layout.h"
       
    26 #include "decode.h"
       
    27 #include "modifier.h"
       
    28 #include "hiddebug.h"
       
    29 
       
    30 #include "hidvalues.h"
       
    31 
       
    32 // ----------------------------------------------------------------------
       
    33 // Map HID keyboard usage values (usage page 7) to EPOC raw "scan" codes:
       
    34 
       
    35 const TInt CKeyboardLayout::KRawCodes[] = 
       
    36     {
       
    37     EStdKeyNull,               // 0x00  0   No Event
       
    38     EStdKeyNull,               // 0x01  1   Overrun Error
       
    39     EStdKeyNull,               // 0x02  2   POST Fail
       
    40     EStdKeyNull,               // 0x03  3   ErrorUndefined
       
    41     'A',                       // 0x04  4   a A
       
    42     'B',                       // 0x05  5   b B
       
    43     'C',                       // 0x06  6   c C
       
    44     'D',                       // 0x07  7   d D
       
    45     'E',                       // 0x08  8   e E
       
    46     'F',                       // 0x09  9   f F
       
    47     'G',                       // 0x0A  10  g G
       
    48     'H',                       // 0x0B  11  h H
       
    49     'I',                       // 0x0C  12  i I
       
    50     'J',                       // 0x0D  13  j J
       
    51     'K',                       // 0x0E  14  k K
       
    52     'L',                       // 0x0F  15  l L
       
    53     'M',                       // 0x10  16  m M
       
    54     'N',                       // 0x11  17  n N
       
    55     'O',                       // 0x12  18  o O
       
    56     'P',                       // 0x13  19  p P
       
    57     'Q',                       // 0x14  20  q Q
       
    58     'R',                       // 0x15  21  r R
       
    59     'S',                       // 0x16  22  s S
       
    60     'T',                       // 0x17  23  t T
       
    61     'U',                       // 0x18  24  u U
       
    62     'V',                       // 0x19  25  v V
       
    63     'W',                       // 0x1A  26  w W
       
    64     'X',                       // 0x1B  27  x X
       
    65     'Y',                       // 0x1C  28  y Y
       
    66     'Z',                       // 0x1D  29  z Z
       
    67     '1',                       // 0x1E  30  1 !
       
    68     '2',                       // 0x1F  31  2 @
       
    69     '3',                       // 0x20  32  3 #
       
    70     '4',                       // 0x21  33  4 $ Euro
       
    71     '5',                       // 0x22  34  5 %
       
    72     '6',                       // 0x23  35  6 ^
       
    73     '7',                       // 0x24  36  7 &
       
    74     '8',                       // 0x25  37  8 *
       
    75     '9',                       // 0x26  38  9 (
       
    76     '0',                       // 0x27  39  0 )
       
    77     EStdKeyEnter,              // 0x28  40  Return
       
    78     EStdKeyEscape,             // 0x29  41  Escape
       
    79     EStdKeyBackspace,          // 0x2A  42  Backspace
       
    80     EStdKeyTab,                // 0x2B  43  Tab
       
    81     EStdKeySpace,              // 0x2C  44  Space
       
    82     EStdKeyMinus,              // 0x2D  45  - _
       
    83     EStdKeyEquals,             // 0x2E  46  = +
       
    84     EStdKeySquareBracketLeft,  // 0x2F  47  [ {
       
    85     EStdKeySquareBracketRight, // 0x30  48  ] }
       
    86     EStdKeyBackSlash,          // 0x31  49  US backslash and bar
       
    87     EStdKeyHash,               // 0x32  50  Near the enter key (UK #~)
       
    88     EStdKeySemiColon,          // 0x33  51  ; :
       
    89     EStdKeySingleQuote,        // 0x34  52  UK ' @  (US ' ")
       
    90     EStdKeyXXX,                // 0x35  53  Top left: UK grave/not/bar
       
    91     EStdKeyComma,              // 0x36  54  , <
       
    92     EStdKeyFullStop,           // 0x37  55  . >
       
    93     EStdKeyForwardSlash,       // 0x38  56  / ?
       
    94     EStdKeyCapsLock,           // 0x39  57  Caps Lock
       
    95     EStdKeyF1,                 // 0x3A  58  F1
       
    96     EStdKeyF2,                 // 0x3B  59  F2
       
    97     EStdKeyF3,                 // 0x3C  60  F3
       
    98     EStdKeyF4,                 // 0x3D  61  F4
       
    99     EStdKeyF5,                 // 0x3E  62  F5
       
   100     EStdKeyF6,                 // 0x3F  63  F6
       
   101     EStdKeyF7,                 // 0x40  64  F7
       
   102     EStdKeyF8,                 // 0x41  65  F8
       
   103     EStdKeyF9,                 // 0x42  66  F9
       
   104     EStdKeyF10,                // 0x43  67  F10
       
   105     EStdKeyF11,                // 0x44  68  F11
       
   106     EStdKeyF12,                // 0x45  69  F12
       
   107     EStdKeyPrintScreen,        // 0x46  70  Print Screen
       
   108     EStdKeyScrollLock,         // 0x47  71  Scroll Lock
       
   109     EStdKeyPause,              // 0x48  72  Break (Ctrl-Pause)
       
   110     EStdKeyInsert,             // 0x49  73  Insert
       
   111     EStdKeyHome,               // 0x4A  74  Home
       
   112     EStdKeyPageUp,             // 0x4B  75  Page Up
       
   113     EStdKeyDelete,             // 0x4C  76  Delete
       
   114     EStdKeyEnd,                // 0x4D  77  End
       
   115     EStdKeyPageDown,           // 0x4E  78  Page Down
       
   116     EStdKeyRightArrow,         // 0x4F  79  Right Arrow
       
   117     EStdKeyLeftArrow,          // 0x50  80  Left Arrow
       
   118     EStdKeyDownArrow,          // 0x51  81  Down Arrow
       
   119     EStdKeyUpArrow,            // 0x52  82  Up Arrow
       
   120     EStdKeyNumLock,            // 0x53  83  Num Lock
       
   121     EStdKeyNkpForwardSlash,    // 0x54  84  Keypad /
       
   122     EStdKeyNkpAsterisk,        // 0x55  85  Keypad *
       
   123     EStdKeyNkpMinus,           // 0x56  86  Keypad -
       
   124     EStdKeyNkpPlus,            // 0x57  87  Keypad +
       
   125     EStdKeyNkpEnter,           // 0x58  88  Keypad Enter
       
   126     EStdKeyNkp1,               // 0x59  89  Keypad 1 End
       
   127     EStdKeyNkp2,               // 0x5A  90  Keypad 2 Down
       
   128     EStdKeyNkp3,               // 0x5B  91  Keypad 3 PageDn
       
   129     EStdKeyNkp4,               // 0x5C  92  Keypad 4 Left
       
   130     EStdKeyNkp5,               // 0x5D  93  Keypad 5
       
   131     EStdKeyNkp6,               // 0x5E  94  Keypad 6 Right
       
   132     EStdKeyNkp7,               // 0x5F  95  Keypad 7 Home
       
   133     EStdKeyNkp8,               // 0x60  96  Keypad 8 Up
       
   134     EStdKeyNkp9,               // 0x61  97  Keypad 9 PageUp
       
   135     EStdKeyNkp0,               // 0x62  98  Keypad 0 Insert
       
   136     EStdKeyNkpFullStop,        // 0x63  99  Keypad . Delete
       
   137     EStdKeyBackSlash,          // 0x64  100 Next to LH shift (UK \|)
       
   138     EStdKeyMenu,               // 0x65  101 Application key
       
   139     EStdKeyNull,               // 0x66  102 Keyboard power
       
   140     EStdKeyEquals              // 0x67  103 Keypad =
       
   141     };
       
   142 
       
   143 // ----------------------------------------------------------------------
       
   144 
       
   145 // These apply in any modifier state:
       
   146 
       
   147 const CKeyboardLayout::TUsagePageKey CKeyboardLayout::KEnhancedKeyCodes[] = 
       
   148     {
       
   149     // Usage page, usage ID, Symbian raw code, Symbian key code (unicode)
       
   150     //
       
   151     // Generic functionality:
       
   152     // 
       
   153     { 12, 0x00cd, EStdKeyApplication2, EKeyApplication2 }, // Play/pause (was: EKeyDictaphonePlay)
       
   154     { 12, 0x00b7, EStdKeyApplication3, EKeyApplication3 }, // Stop (was: EKeyDictaphoneStop)
       
   155     { 12, 0x00e9, EStdKeyIncVolume,      EKeyIncVolume },      // Volume -
       
   156     { 12, 0x00ea, EStdKeyDecVolume,      EKeyDecVolume },      // Volume +
       
   157     { 12, 0x0095, EStdKeyHelp,           EKeyHelp },           // Help
       
   158     { 12, 0x019c, EStdKeyDevice2,        EKeyDevice2 },        // Log off
       
   159     //
       
   160     // Map system control power and menu keys to the power key:
       
   161     //
       
   162     { 1,  0x0081, EStdKeyDevice2,        EKeyDevice2 },        // Power down
       
   163     { 1,  0x0082, EStdKeyDevice2,        EKeyDevice2 },        // Sleep
       
   164     { 1,  0x0083, EStdKeyDevice2,        EKeyDevice2 },        // Wake
       
   165     { 1,  0x0084, EStdKeyDevice2,        EKeyDevice2 },        // Context menu
       
   166     { 1,  0x0085, EStdKeyDevice2,        EKeyDevice2 },        // Main menu
       
   167     { 1,  0x0086, EStdKeyDevice2,        EKeyDevice2 },        // App menu
       
   168     //
       
   169     // Map common consumer keys to the application and device key ranges:
       
   170     // (Note that Series 60 AVKON reserves device keys 0-6, and app key 0.)
       
   171     // (Also, we're reserving EStdKeyApplication1 for FEP symbol menu)
       
   172     //
       
   173     { 12, 0x00e2, EStdKeyApplication3, EKeyApplication3 }, // Mute				(was: EkeyApplication2)
       
   174     { 12, 0x00b5, EStdKeyApplication4, EKeyApplication4 }, // Next track 	(Was: EKeyApplication3)
       
   175     { 12, 0x00b6, EStdKeyApplication5, EKeyApplication5 }, // Prev track	(was: EKeyApplication4)
       
   176     { 12, 0x021a, EStdKeyApplication5, EKeyApplication5 }, // Undo
       
   177     { 12, 0x0279, EStdKeyApplication6, EKeyApplication6 }, // Redo
       
   178     { 12, 0x0183, EStdKeyApplication7, EKeyApplication7 }, // Media
       
   179     { 12, 0x0223, EStdKeyF1, EKeyF1 					}, // Web/Home [WAP] was: EKeyApplication8
       
   180     { 12, 0x0199, EStdKeyApplication9, EKeyApplication9 }, // Messenger [SMS]
       
   181     { 12, 0x018a, EStdKeyF2, EKeyF2 }, 					   // Mail [Email] was: EKeyApplicationA
       
   182     { 12, 0x0192, EStdKeyApplicationC, EKeyApplicationB }, // Calculator
       
   183     { 12, 0x01ab, EStdKeyApplicationD, EKeyApplicationD }, // Spell
       
   184     { 12, 0x0207, EStdKeyApplicationE, EKeyApplicationE }, // Save
       
   185     { 12, 0x0208, EStdKeyApplicationF, EKeyApplicationF }, // Print
       
   186     { 12, 0x0201, EStdKeyDevice7,      EKeyDevice7 },      // New
       
   187     { 12, 0x0202, EStdKeyDevice8,      EKeyDevice8 },      // Open
       
   188     { 12, 0x0203, EStdKeyDevice9,      EKeyDevice9 },      // Close
       
   189     { 12, 0x0289, EStdKeyDeviceA,      EKeyDeviceA },      // Reply
       
   190     { 12, 0x028b, EStdKeyDeviceB,      EKeyDeviceB },      // Fwd
       
   191     { 12, 0x028C, EStdKeyDeviceC,      EKeyDeviceC },      // Send
       
   192     { 12, 0x01a7, EStdKeyDeviceD,      EKeyDeviceD },      // My Docs [Notepad]
       
   193     { 12, 0x01b6, EStdKeyDeviceE,      EKeyDeviceE },      // My Pics
       
   194     { 12, 0x01b7, EStdKeyDeviceF,      EKeyDeviceF }       // My Music
       
   195     };
       
   196 
       
   197 // ----------------------------------------------------------------------
       
   198 
       
   199  TUint16 CKeyboardLayout::TranslateKey(TInt aHidKey, 
       
   200     TInt aUsagePage, THidModifier aModifiers, TLockKeys aLockKeys) const
       
   201     {
       
   202     if (aUsagePage == EUsagePageKeyboard)
       
   203         {
       
   204         return TranslateKeyboardKey(aHidKey, aModifiers, aLockKeys);
       
   205         }
       
   206     else
       
   207         {
       
   208         return TranslateOtherKey(aHidKey, aUsagePage, aModifiers, aLockKeys);
       
   209         }
       
   210     }
       
   211 
       
   212 // ----------------------------------------------------------------------
       
   213 
       
   214 TUint16 CKeyboardLayout::TranslateKeyboardKey(TInt aHidKey, 
       
   215     THidModifier aModifiers, TLockKeys aLockKeys) const
       
   216     {
       
   217     // For most layouts, right alt (AltGr) is defined to have the
       
   218     // same effect as ctrl-alt:
       
   219     //
       
   220     if (AltGrIsControlAlt() && aModifiers.RightAlt())
       
   221         {
       
   222         aModifiers.Merge(THidModifier::ELeftControl);
       
   223         }
       
   224 
       
   225     // Caps lock and num lock usually just invert the behaviour of
       
   226     // the shift key:
       
   227     //
       
   228     if ((aLockKeys.iCapsLock && ChangesWithCapsLock(aHidKey, aModifiers)) ||
       
   229         (!aLockKeys.iNumLock && ChangesWithNumLock(aHidKey)))
       
   230         {
       
   231         aModifiers.InvertShift();
       
   232         }
       
   233 
       
   234     // All standard layouts avoid control and shift-control modifiers.
       
   235     // We map the standard control and shift-control key combinations
       
   236     // to Symbian shortcut key codes:
       
   237     //
       
   238     TUint16 unicode = 0;
       
   239 
       
   240     if (aModifiers.Control() && !aModifiers.Alt())
       
   241         {
       
   242         // Symbian Knowledgebase articles FAQ-0507 and FAQ-0511 say
       
   243         // that this is the correct way to handle control keys so
       
   244         // that keyboard shortcuts (such as ctrl-x) will work:
       
   245         
       
   246         const TInt KCtrlMin = 4;   // aA
       
   247         const TInt KCtrlMax = 29;  // zZ
       
   248             
       
   249         if ((aHidKey >= KCtrlMin) && (aHidKey <= KCtrlMax))
       
   250             {
       
   251             unicode = static_cast<TUint16>(CTRL(
       
   252                 Unicode(aHidKey, THidModifier(0))));
       
   253             }
       
   254         }
       
   255 
       
   256     // If the key wasn't a standard control or shift-control
       
   257     // combination:
       
   258     // 
       
   259     if (unicode == 0)
       
   260         {
       
   261         unicode = Unicode(aHidKey, aModifiers);
       
   262         }
       
   263 
       
   264     return unicode;
       
   265     }
       
   266 
       
   267 // ----------------------------------------------------------------------
       
   268 
       
   269  TBool CKeyboardLayout::ChangesWithCapsLock(TInt aHidKey,
       
   270     THidModifier aModifiers) const
       
   271     {
       
   272     // For most layouts Caps Lock only changes those keys in the
       
   273     // standard A..Z positions:
       
   274     //
       
   275     const TInt KCapsLockKeysMin = 4;   // aA
       
   276     const TInt KCapsLockKeysMax = 29;  // zZ
       
   277 
       
   278     TBool inRange = (aHidKey >= KCapsLockKeysMin) && 
       
   279         (aHidKey <= KCapsLockKeysMax);
       
   280 
       
   281     // The standard behaviour is that Caps Lock shouldn't have any
       
   282     // effect on alt-ctrl ("Alt Gr") modified keys:
       
   283     //
       
   284     TBool altGr = aModifiers.Control() && aModifiers.Alt();
       
   285 
       
   286     return !altGr && inRange;
       
   287     }
       
   288 
       
   289 // ----------------------------------------------------------------------
       
   290 
       
   291  TBool CKeyboardLayout::ChangesWithNumLock(TInt aHidKey) const
       
   292     {
       
   293     // Num Lock only ever affects a standard subset of the keypad keys:
       
   294 
       
   295     const TInt KNumLockMin = 89;  // Keypad End
       
   296     const TInt KNumLockMax = 99;  // Keypad Delete
       
   297 
       
   298     return (aHidKey >= KNumLockMin) && (aHidKey <= KNumLockMax);
       
   299     }
       
   300 
       
   301 // ----------------------------------------------------------------------
       
   302 
       
   303  TBool CKeyboardLayout::AltGrIsControlAlt() const
       
   304     {
       
   305     return ETrue;
       
   306     }
       
   307 
       
   308 // ----------------------------------------------------------------------
       
   309 
       
   310  TBool CKeyboardLayout::IsDeadKey(TInt /*aUnicodeKey*/) const
       
   311     {
       
   312     return EFalse;
       
   313     }
       
   314 
       
   315  TUint16 CKeyboardLayout::FindCombiningChar(
       
   316     TUint16 /*aDeadKeyUnicode*/, TUint16 /*aUnicodeKey*/) const
       
   317     {
       
   318     return 0;
       
   319     }
       
   320 
       
   321 // ----------------------------------------------------------------------
       
   322 
       
   323  TBool CKeyboardLayout::IsRepeatingKey(TInt aUnicodeKey) const
       
   324     {
       
   325     const TInt KNoRepeatKeys[] = 
       
   326         {
       
   327         // The modifier and lock keys:
       
   328         EKeyLeftShift,
       
   329         EKeyRightShift,
       
   330         EKeyLeftAlt,
       
   331         EKeyRightAlt,
       
   332         EKeyLeftCtrl,
       
   333         EKeyRightCtrl,
       
   334         EKeyLeftFunc,
       
   335         EKeyRightFunc,
       
   336         EKeyCapsLock,
       
   337         EKeyNumLock,
       
   338         EKeyScrollLock,
       
   339 
       
   340         // Other keys that toggle:
       
   341         EKeyPause,
       
   342         EKeyInsert,
       
   343 
       
   344         // Some special cases:
       
   345         EKeyEscape,
       
   346         EKeyPrintScreen
       
   347         };
       
   348 
       
   349     const TInt KNumberOfNoRepeatKeys = 
       
   350         (sizeof (KNoRepeatKeys)) / (sizeof (TInt));
       
   351 
       
   352     TBool match = EFalse;
       
   353     
       
   354     for (TInt i=0; i<KNumberOfNoRepeatKeys; ++i)
       
   355         {
       
   356         if (aUnicodeKey == KNoRepeatKeys[i])
       
   357             {
       
   358             match = ETrue;
       
   359             }
       
   360         }
       
   361 
       
   362     return !match;
       
   363     }
       
   364 
       
   365 // ----------------------------------------------------------------------
       
   366 
       
   367 TUint16 CKeyboardLayout::TranslateOtherKey(TInt aHidKey, 
       
   368     TInt aUsagePage, THidModifier, TLockKeys) const
       
   369     {
       
   370     static const TInt KEnhancedKeyCodesSize = 
       
   371         (sizeof (KEnhancedKeyCodes)) / (sizeof (TUsagePageKey));
       
   372 
       
   373     TUint16 unicode = 0;
       
   374 
       
   375     for (TInt i=0; (unicode == 0) && (i<KEnhancedKeyCodesSize); ++i)
       
   376         {
       
   377         if ((aHidKey == KEnhancedKeyCodes[i].iHidId)
       
   378             && (aUsagePage == KEnhancedKeyCodes[i].iHidPage))
       
   379             {
       
   380             unicode = KEnhancedKeyCodes[i].iCode;
       
   381             }
       
   382         }
       
   383 
       
   384     return unicode;
       
   385     }
       
   386 
       
   387 // ----------------------------------------------------------------------
       
   388 
       
   389  TInt CKeyboardLayout::RawScanCode(TInt aHidKey, 
       
   390     TInt aUsagePage, THidModifier aModifiers) const
       
   391     {
       
   392     TInt result = EStdKeyNull;
       
   393 
       
   394     if (aUsagePage == EUsagePageKeyboard)
       
   395         {
       
   396         result = CheckChangingKeys(aHidKey, aModifiers);
       
   397         
       
   398         if (result == EStdKeyNull)
       
   399             {
       
   400             const TInt KRawCodesSize = (sizeof (KRawCodes)) / (sizeof (TInt));
       
   401             if (aHidKey < KRawCodesSize)
       
   402                 {
       
   403                 result = KRawCodes[aHidKey];
       
   404                 }
       
   405             else
       
   406                 {
       
   407                 result = CheckModifierKeys(aHidKey);
       
   408                 }
       
   409             }
       
   410         }
       
   411     else
       
   412         {
       
   413         result = CheckSpecialRawCode(aHidKey, aUsagePage);
       
   414         }
       
   415     
       
   416     return result;
       
   417     }
       
   418 
       
   419 TInt CKeyboardLayout::CheckChangingKeys(TInt aHidKey, THidModifier aModifiers)
       
   420     {
       
   421     // Handle any key that changes scan code depending on the modifier
       
   422     // state:
       
   423 
       
   424     // All these special cases only apply to the keyboard usage page:
       
   425     const TInt KTabKey = 0x2B;
       
   426     if ((aHidKey == KTabKey) && aModifiers.AltOnly())
       
   427         {
       
   428         // Application switch key:
       
   429         return EStdKeyApplication0;
       
   430         }
       
   431     
       
   432     const TInt KDelKey = 0x4c;
       
   433     const TInt KKeypadDelKey = 0x63;
       
   434     if (((aHidKey == KDelKey) || (aHidKey == KKeypadDelKey))
       
   435         && (aModifiers.Fold() == THidModifier::EAltCtrl))
       
   436         {
       
   437         // Power key:
       
   438         return EStdKeyDevice2;
       
   439         }
       
   440         
       
   441     const TInt KEnterKey = 0x28;
       
   442     const TInt KKeypadEnterKey = 0x58;
       
   443     if (((aHidKey == KEnterKey) || (aHidKey == KKeypadEnterKey))
       
   444         && (aModifiers.ShiftOnly() || aModifiers.ControlOnly()))
       
   445         {
       
   446         // OK key:
       
   447         return EStdKeyDevice3;
       
   448         }
       
   449 
       
   450     const TInt KLeftGuiKey = 0xe3;
       
   451     if (aHidKey == KLeftGuiKey)
       
   452         {
       
   453         // Call create or left softkey:
       
   454         return aModifiers.Shift() ? EStdKeyYes : EStdKeyDevice0;
       
   455         }
       
   456 
       
   457     const TInt KRightGuiKey = 0xe7;
       
   458     const TInt KMenuKey = 0x65;
       
   459     if ((aHidKey == KRightGuiKey) || (aHidKey == KMenuKey))
       
   460         {
       
   461         // Call end or right softkey:
       
   462         return aModifiers.Shift() ? EStdKeyNo : EStdKeyDevice1;
       
   463         }
       
   464 
       
   465     return EStdKeyNull;
       
   466     }
       
   467 
       
   468 TInt CKeyboardLayout::CheckModifierKeys(TInt aHidKey)
       
   469     {
       
   470     const TInt KModifierCodes[] =
       
   471         {
       
   472         EStdKeyLeftCtrl,   // HID code 0xe0 224
       
   473         EStdKeyLeftShift,  //          0xe1 225
       
   474         EStdKeyLeftAlt,    //          0xe2 226
       
   475         EStdKeyLeftFunc,   //          0xe3 227 (overridden by left sofkey)
       
   476         EStdKeyRightCtrl,  //          0xe4 228
       
   477         EStdKeyRightShift, //          0xe5 229
       
   478         EStdKeyRightAlt,   //          0xe6 230
       
   479         EStdKeyRightFunc   //          0xe7 231 (overridden by right sofkey)
       
   480         };
       
   481 
       
   482     const TInt KHidIdLeftCtrl = 0xe0;
       
   483     const TInt KHidIdRightFunc = 0xe7;
       
   484 
       
   485     TInt result = EStdKeyNull;
       
   486 
       
   487     if ((aHidKey >= KHidIdLeftCtrl) && (aHidKey <= KHidIdRightFunc))
       
   488         {
       
   489         result = KModifierCodes[aHidKey - KHidIdLeftCtrl];
       
   490         }
       
   491 
       
   492     return result;
       
   493     }
       
   494 
       
   495 TInt CKeyboardLayout::CheckSpecialRawCode(TInt aHidKey, TInt aUsagePage)
       
   496     {
       
   497     static const TInt KEnhancedKeyCodesSize = 
       
   498         (sizeof (KEnhancedKeyCodes)) / (sizeof (TUsagePageKey));
       
   499 
       
   500     TInt scanCode = EStdKeyNull;
       
   501 
       
   502     for (TInt i=0; (scanCode == EStdKeyNull) && (i<KEnhancedKeyCodesSize); ++i)
       
   503         {
       
   504         if ((aHidKey == KEnhancedKeyCodes[i].iHidId)
       
   505             && (aUsagePage == KEnhancedKeyCodes[i].iHidPage))
       
   506             {
       
   507             scanCode = KEnhancedKeyCodes[i].iScanCode;
       
   508             }
       
   509         }
       
   510 
       
   511     return scanCode;
       
   512     }
       
   513 
       
   514 // ----------------------------------------------------------------------
       
   515 
       
   516  CStandardKeyboardLayout::CStandardKeyboardLayout(
       
   517     const TInt* aColumnMap, TInt aMapSize,
       
   518     const TUint16* aKeyCodes, TInt aTableSize,
       
   519     const TSpecialKey* aSpecialCases)
       
   520     : iColumnMap(aColumnMap), iKeyCodes(aKeyCodes),
       
   521       iNumColumns(aMapSize / sizeof (TInt)), 
       
   522       iNumKeys(aTableSize / (sizeof (TUint16) * iNumColumns)), 
       
   523       iSpecialCases(aSpecialCases)
       
   524     {
       
   525     // nothing else to do
       
   526     }
       
   527 
       
   528  TUint16 CStandardKeyboardLayout::Unicode(TInt aHidKey, 
       
   529     THidModifier aModifiers) const
       
   530     {
       
   531     TUint16 unicode = 0;
       
   532     TUint8 foldedModifiers = aModifiers.Fold();
       
   533 
       
   534     if ((aHidKey >= 0) && (aHidKey < iNumKeys))
       
   535         {
       
   536         for (TInt i=0; i<iNumColumns; ++i)
       
   537             {
       
   538             if (iColumnMap[i] == foldedModifiers)
       
   539                 unicode = iKeyCodes[(aHidKey * iNumColumns) + i];
       
   540             }
       
   541         }
       
   542 
       
   543     if ((unicode == 0) && iSpecialCases)
       
   544         {
       
   545         unicode = FindSpecialKey(iSpecialCases, aHidKey, foldedModifiers);
       
   546         }
       
   547         
       
   548     return unicode;
       
   549     }
       
   550 
       
   551  TUint16 CStandardKeyboardLayout::FindSpecialKey(
       
   552     const TSpecialKey* aMap, TInt aHidKey, TUint8 aFoldedModifiers)
       
   553     {
       
   554     // Look for this HID key code in the appropriate special key
       
   555     // key table. A zero key code means "end of table".
       
   556 
       
   557     TUint16 keyCode = 0;
       
   558     for (TInt i=0; (keyCode == 0) && (aMap[i].iHidKey != 0); ++i)
       
   559         {
       
   560         if ((aHidKey == aMap[i].iHidKey) 
       
   561             && (aFoldedModifiers == aMap[i].iFoldedModifiers))
       
   562             {
       
   563             keyCode = aMap[i].iUnicode;
       
   564             }
       
   565         }
       
   566     
       
   567     return keyCode;
       
   568     }
       
   569 
       
   570 // ----------------------------------------------------------------------
       
   571 
       
   572  CDeadKeyLayout::CDeadKeyLayout(const TInt* aColumnMap, 
       
   573     TInt aMapSize, const TUint16* aKeyCodes, TInt aTableSize,
       
   574     const TSpecialKey* aSpecialCases, const TIndexPair* aDeadKeyIndex)
       
   575     : CStandardKeyboardLayout(aColumnMap, aMapSize, aKeyCodes,
       
   576         aTableSize, aSpecialCases), iDeadKeyIndex(aDeadKeyIndex)
       
   577     {
       
   578     // nothing else to do
       
   579     }
       
   580 
       
   581  TBool CDeadKeyLayout::IsDeadKey(TInt aUnicodeKey) const
       
   582     {
       
   583     TBool match = EFalse;
       
   584     
       
   585     for (TInt i=0; !match && (iDeadKeyIndex[i].iUnicode != 0); ++i)
       
   586         {
       
   587         match = (aUnicodeKey == iDeadKeyIndex[i].iUnicode);
       
   588         }
       
   589     
       
   590     DBG(RDebug::Print(_L("[HID]\tCDeadKeyLayout::IsDeadKey(0x%08x:0x%04x) = %d"),
       
   591       iDeadKeyIndex, aUnicodeKey, match));
       
   592 
       
   593     return match;
       
   594     }
       
   595 
       
   596  TUint16 CDeadKeyLayout::FindCombiningChar(TUint16 aDeadKeyUnicode,
       
   597     TUint16 aUnicodeKey) const
       
   598     {
       
   599     const TKeyPair* map = 0;
       
   600     for (TInt i=0; (map == 0) && (iDeadKeyIndex[i].iUnicode != 0); ++i)
       
   601         {
       
   602         if (aDeadKeyUnicode == iDeadKeyIndex[i].iUnicode)
       
   603             map = iDeadKeyIndex[i].iMap;
       
   604         }
       
   605 
       
   606     TUint16 comboChar = 0;
       
   607     if (map != 0)
       
   608         {
       
   609         // Look for this base character code in the appropriate dead
       
   610         // key table.  (NB. A zero base code means "end of table".)
       
   611         //
       
   612         for (TInt j=0; (comboChar==0) && (map[j].iBaseChar != 0); ++j)
       
   613             {
       
   614             if (aUnicodeKey == map[j].iBaseChar)
       
   615                 {
       
   616                 comboChar = map[j].iComboChar;
       
   617                 }
       
   618             }
       
   619         }
       
   620     
       
   621     return comboChar;
       
   622     }
       
   623 
       
   624 // ----------------------------------------------------------------------