|
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 // ---------------------------------------------------------------------- |