|
1 /* |
|
2 * Copyright (c) 2005 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: An implementation of a configurable key translation map. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDES |
|
20 #include "AknKeyEventMap.h" |
|
21 #include <e32std.h> |
|
22 #include <e32math.h> |
|
23 #include <barsc.h> |
|
24 #include <barsread.h> |
|
25 #include <bautils.h> |
|
26 #include "AknKeyResource.h" |
|
27 #include <aknkeyeventmap.rsg> |
|
28 #include "AknAnimLogger.h" |
|
29 #include "aknanimdllstd.h" |
|
30 |
|
31 // CONSTANTS |
|
32 #define STRIP_MODS &0x0000FFFF |
|
33 #define GET_MODS &0xFFFF0000 |
|
34 |
|
35 // Key event map resource file. |
|
36 _LIT( KAknKeyTableRsc, "z:\\resource\\AknKeyEventMap.rsc" ); |
|
37 |
|
38 // Publish & Subscribe device mode category. |
|
39 const TInt32 KUidWinservCategoryValue = 0x10003B20; |
|
40 |
|
41 // Publish & Subscribe device mode category as TUid. |
|
42 const TUid KUidWinservCategory = { KUidWinservCategoryValue }; |
|
43 |
|
44 // Always pass policy. |
|
45 _LIT_SECURITY_POLICY_PASS(KAlwaysPassPolicy); |
|
46 |
|
47 // Only system application can access. |
|
48 _LIT_SECURITY_POLICY_S0(KSysapOnlyPolicy, 0x100058F3); |
|
49 |
|
50 // ============================ MEMBER FUNCTIONS =============================== |
|
51 |
|
52 // ----------------------------------------------------------------------------- |
|
53 // CAknKeyEventMap::CAknKeyEventMap |
|
54 // ----------------------------------------------------------------------------- |
|
55 // |
|
56 CAknKeyEventMap::CAknKeyEventMap(CAknAsynchTonePlayer& aSoundSession) |
|
57 : iDownEvents( KAknMaxComboKeys ), iUpEvents( KAknMaxComboKeys ), iSoundSession(aSoundSession) |
|
58 { |
|
59 } |
|
60 |
|
61 // ----------------------------------------------------------------------------- |
|
62 // CAknKeyEventMap::ConstructL |
|
63 // |
|
64 // Initializes member variables, reads the default keytables from a resource |
|
65 // file, instantiates P&S subscriber and opens the door for raw events. |
|
66 // ----------------------------------------------------------------------------- |
|
67 // |
|
68 void CAknKeyEventMap::ConstructL( MAnimGeneralFunctions* aFunctions ) |
|
69 { |
|
70 iFunctions = aFunctions; |
|
71 |
|
72 if ( KAknMaxDeviceMode < 1 || KAknMaxDeviceMode > 15) |
|
73 { |
|
74 __AKNANIMLOGSTRING("CAknKeyEventMap::ConstructL ERROR: must have at least 1 and at most 15 device modes"); |
|
75 User::Leave(KErrGeneral); |
|
76 } |
|
77 |
|
78 iCurrentDeviceMode = KAknModeDefault; |
|
79 iKeyBeacon.iKeyCode = EKeyNull; |
|
80 iKeyBeacon.iEventType = 0; |
|
81 iDownTimer = CPeriodic::New( CActive::EPriorityLow ); |
|
82 iCombos = new (ELeave) RArray<RArray<TUint32>*>( KAknMaxComboKeys ); |
|
83 |
|
84 iRepeatRate = KAknRepeatRate; |
|
85 iKeyPollInterval = static_cast<TTimeIntervalMicroSeconds32>(1000000./iRepeatRate); |
|
86 |
|
87 iConsume = EFalse; |
|
88 iIsCanceled = EFalse; |
|
89 |
|
90 iScanCodeIJustGenerated = -1; |
|
91 |
|
92 // Initialize keymap. |
|
93 const TAknKeyEvent nullEvent = { EKeyNull, EKeyNull, 0 }; |
|
94 for ( TUint j = 0; j < KAknKeyMapRows; j++ ) |
|
95 { |
|
96 for ( TUint i = 0; i < KAknKeyMapColumns; i++ ) |
|
97 { |
|
98 iKeyMap[i][j] = nullEvent; |
|
99 } |
|
100 } |
|
101 |
|
102 // Load the default configuration. |
|
103 TRAPD( ierr, InitializeKeyTableFromResourceL( KAknKeyTableRsc ) ); |
|
104 if ( ierr != KErrNone ) |
|
105 { |
|
106 __AKNANIMLOGSTRING1( "Error initializing the key tables, %d", ierr ); |
|
107 } |
|
108 |
|
109 if ( !IsKeyEventMapEnabled() ) |
|
110 { |
|
111 return; |
|
112 } |
|
113 |
|
114 // Define Publish & Subscribe key |
|
115 TInt err = RProperty::Define( KUidWinservCategory, KAknPSDeviceMode, |
|
116 RProperty::EInt, KAlwaysPassPolicy, KSysapOnlyPolicy ); |
|
117 if ( err != KErrNone ) |
|
118 { |
|
119 __AKNANIMLOGSTRING1("CAknKeyEventMap::ConstrucL() Problem defining The Key %d", err); |
|
120 } |
|
121 |
|
122 // Subscribe to Publish & Subscribe keys |
|
123 err = KErrNone; |
|
124 CAknKefSubscriber *sub = NULL; |
|
125 |
|
126 sub = CAknKefSubscriber::NewL( *this, KUidWinservCategory , KAknPSDeviceMode ); |
|
127 if ( sub ) |
|
128 { |
|
129 err = iKefSubscribers.Append( sub ); |
|
130 if ( err != KErrNone ) |
|
131 { |
|
132 delete sub; |
|
133 __AKNANIMLOGSTRING( "CAknKeyEventMap::ConstructL ERROR: device mode subscription failed." ); |
|
134 // We could stop the boot here, but we can also continue, just without |
|
135 // the device modes. |
|
136 } |
|
137 } |
|
138 } |
|
139 |
|
140 // ----------------------------------------------------------------------------- |
|
141 // CAknKeyEventMap::~CAknKeyEventMap |
|
142 // ----------------------------------------------------------------------------- |
|
143 // |
|
144 CAknKeyEventMap::~CAknKeyEventMap() |
|
145 { |
|
146 __AKNANIMLOGSTRING("CAknKeyEventMap::Destructor entered."); |
|
147 |
|
148 if ( iCombos ) |
|
149 { |
|
150 const TInt count = iCombos->Count(); |
|
151 for ( TInt i = count - 1; i >= 0; i-- ) |
|
152 { |
|
153 (*iCombos)[i]->Close(); |
|
154 delete (*iCombos)[i]; |
|
155 iCombos->Remove(i); |
|
156 } |
|
157 iCombos->Close(); |
|
158 delete iCombos; |
|
159 } |
|
160 |
|
161 delete iDownTimer; |
|
162 |
|
163 iUpEvents.Close(); |
|
164 iDownEvents.Close(); |
|
165 iRepeatRates.Close(); |
|
166 |
|
167 iKefSubscribers.ResetAndDestroy(); |
|
168 iKefSubscribers.Close(); |
|
169 } |
|
170 |
|
171 // ----------------------------------------------------------------------------- |
|
172 // CAknKeyEventMap::IsKeyEventMapEnabled |
|
173 // ----------------------------------------------------------------------------- |
|
174 // |
|
175 TBool CAknKeyEventMap::IsKeyEventMapEnabled() const |
|
176 { |
|
177 return iKeyEventMapEnabled; |
|
178 } |
|
179 |
|
180 // ----------------------------------------------------------------------------- |
|
181 // CAknKeyEventMap::OfferRawEvent |
|
182 // |
|
183 // ----------------------------------------------------------------------------- |
|
184 // |
|
185 TBool CAknKeyEventMap::OfferRawEvent( const TRawEvent& aRawEvent ) |
|
186 { |
|
187 return OfferRawEvent(aRawEvent, EFalse); |
|
188 } |
|
189 |
|
190 // ----------------------------------------------------------------------------- |
|
191 // CAknKeyEventMap::OfferRawEvent |
|
192 // |
|
193 // This is where the raw events end up in, and |
|
194 // where we have to decide what to do with them. |
|
195 // ----------------------------------------------------------------------------- |
|
196 // |
|
197 TBool CAknKeyEventMap::OfferRawEvent( const TRawEvent& aRawEvent, TBool aSilentEvent ) |
|
198 { |
|
199 const TBool downEvent = ( aRawEvent.Type() == TRawEvent::EKeyDown ); |
|
200 const TBool upEvent = ( aRawEvent.Type() == TRawEvent::EKeyUp ); |
|
201 |
|
202 // |
|
203 // Raw events created by this CAknKeyEventMap itself: pass them on. |
|
204 // |
|
205 if ( ( downEvent || upEvent ) && |
|
206 ( aRawEvent.ScanCode() == iScanCodeIJustGenerated ) ) |
|
207 { |
|
208 if ( downEvent ) |
|
209 { |
|
210 // Add this scan code to iUpEvents so we can generate |
|
211 // the appropriate raw UPs when the key press is finished. |
|
212 __AKNANIMLOGSTRING1("CAknKeyEventMap::OfferRawEvent adding %x to iUpEvents", iScanCodeIJustGenerated); |
|
213 TInt err = iUpEvents.Append( iScanCodeIJustGenerated ); |
|
214 if ( err != KErrNone ) // never happened |
|
215 { |
|
216 __AKNANIMLOGSTRING("CAknKeyEventMap::OfferRawEvent ERROR appending up event!"); |
|
217 } |
|
218 } |
|
219 |
|
220 if ( upEvent ) |
|
221 { |
|
222 // would be nice to .Remove() elements from iUpEvents here, |
|
223 // but that'd require another call to ResolveMapping(), |
|
224 // -- .Remove() in CancelProcessingKeyPress() instead. |
|
225 } |
|
226 |
|
227 iScanCodeIJustGenerated = -1; |
|
228 return EFalse; // not further processing for scan codes iJustGenerated. |
|
229 } |
|
230 |
|
231 TInt err = KErrNone; |
|
232 iConsume = EFalse; // very important to set this here. |
|
233 |
|
234 // log arrays |
|
235 for ( TInt i = 0 ; i < iDownEvents.Count() ; i++ ) |
|
236 { |
|
237 __AKNANIMLOGSTRING2("CAknKeyEventMap::OfferRawEvent iDownEvents[%d] = %x", i, iDownEvents[i] ); |
|
238 } |
|
239 for ( TInt i = 0 ; i < iUpEvents.Count() ; i++ ) |
|
240 { |
|
241 __AKNANIMLOGSTRING2("CAknKeyEventMap::OfferRawEvent iUpEvents[%d] = %x", i, iUpEvents[i] ); |
|
242 } |
|
243 |
|
244 // Down events |
|
245 if ( downEvent && aRawEvent.ScanCode() >= 0 ) |
|
246 { |
|
247 iCurrentScanCode = aRawEvent.ScanCode(); |
|
248 iPostMeOnUp.iKeyCode = EKeyNull; |
|
249 iPostMeOnUp.iEventType = 0; |
|
250 __AKNANIMLOGSTRING3( "CAknKeyEventMap::OfferRawEvent KeyDown scancode=%x mods=%x, we're in devicemode=%d", |
|
251 iCurrentScanCode STRIP_MODS, iCurrentScanCode GET_MODS, iCurrentDeviceMode); |
|
252 |
|
253 // Combo support |
|
254 if ( iDownEvents.Count() < KAknMaxComboKeys ) |
|
255 { |
|
256 err = iDownEvents.Append( aRawEvent.ScanCode() STRIP_MODS ); |
|
257 if ( err != KErrNone ) // never happened |
|
258 { |
|
259 __AKNANIMLOGSTRING("CAknKeyEventMap::OfferRawEvent ERROR appending down event!"); |
|
260 } |
|
261 } |
|
262 else |
|
263 { |
|
264 // User is trying to press more simultaneous keys than supported. |
|
265 // We have no problem with that, just ignore it. |
|
266 } |
|
267 |
|
268 // Resolve mapping for this event and set is as the beacon. |
|
269 iKeyBeacon = ResolveMapping(); |
|
270 |
|
271 // Launch a CPeriodic so the duration of the keypress can be known. |
|
272 // There's only one timer; for combos, it measures the time starting |
|
273 // from the first DOWN event of the combo. If usability troubles appear, |
|
274 // try re-starting the timer for each participating key in a combo |
|
275 // (by removing the test against iDownEvents.Count()) |
|
276 if ( iDownEvents.Count() < 2 ) |
|
277 { |
|
278 iKeyPressDuration = 0.0; |
|
279 iDownTimer->Cancel(); |
|
280 iIsCanceled = EFalse; // set this before Start() |
|
281 iDownTimer->Start( iKeyPollInterval, iKeyPollInterval, |
|
282 TCallBack( &KeyPressDuration, (TAny*) this ) ); |
|
283 } |
|
284 |
|
285 if ( iKeyBeacon.iKeyCode > KAknKeyDisabled ) |
|
286 { |
|
287 if ( ( iKeyBeacon.iEventType & KAknIsLongOnly ) ) |
|
288 { |
|
289 // delayed posting of the short event when KAknIsLongOnly |
|
290 iPostMeOnUp = iKeyBeacon; |
|
291 return iConsume; // notice! we're finished with this event. |
|
292 } |
|
293 else |
|
294 { |
|
295 if ( ( iKeyBeacon.iEventType & KAknIsShortKey ) == EFalse ) |
|
296 { |
|
297 PostEvent( EAknPostRaw ); |
|
298 } |
|
299 else |
|
300 { |
|
301 PostEvent( EAknPostKey ); |
|
302 } |
|
303 } |
|
304 } |
|
305 |
|
306 // Emit a keyclick. |
|
307 if ( !aSilentEvent && iKeyBeacon.iKeyCode != KAknKeyDisabled ) |
|
308 { |
|
309 if ( iKeyBeacon.iKeyCode > KAknKeyDisabled ) |
|
310 { |
|
311 iSoundSession.KeyPressed( iKeyBeacon.iKeyCode STRIP_MODS ); |
|
312 } |
|
313 else |
|
314 { |
|
315 iSoundSession.KeyPressed( aRawEvent.ScanCode() STRIP_MODS ); |
|
316 } |
|
317 } |
|
318 |
|
319 return iConsume; // this was set by ResolveMapping |
|
320 } |
|
321 |
|
322 // Up events |
|
323 if ( upEvent ) |
|
324 { |
|
325 iCurrentScanCode = aRawEvent.ScanCode(); |
|
326 __AKNANIMLOGSTRING1("CAknKeyEventMap::OfferRawEvent KeyUp scancode=%x",aRawEvent.ScanCode()); |
|
327 |
|
328 // Check whether this up event finishes a keypress we've been handling. |
|
329 TInt finishesKeyPress = |
|
330 iDownEvents.Find( aRawEvent.ScanCode() STRIP_MODS ); |
|
331 __AKNANIMLOGSTRING1("CAknKeyEventMap::OfferRawEvent finishesKeypress index %d", finishesKeyPress); |
|
332 __AKNANIMLOGSTRING1("CAknKeyEventMap::OfferRawEvent Duration =%f",iKeyPressDuration); |
|
333 |
|
334 // We got an UP for a known DOWN |
|
335 if ( finishesKeyPress != KErrNotFound ) |
|
336 { |
|
337 |
|
338 if ( iPostMeOnUp.iKeyCode > KAknKeyDisabled && !iIsLongKeyPress ) |
|
339 { |
|
340 iKeyBeacon = iPostMeOnUp; |
|
341 if ( ( iKeyBeacon.iEventType & KAknIsShortKey ) == EFalse ) |
|
342 { |
|
343 PostEvent( EAknPostRaw ); |
|
344 } |
|
345 else |
|
346 { |
|
347 PostEvent( EAknPostKey ); |
|
348 } |
|
349 iPostMeOnUp.iKeyCode = EKeyNull; |
|
350 iPostMeOnUp.iEventType = 0; |
|
351 } |
|
352 |
|
353 iKeyBeacon = ResolveMapping(); |
|
354 |
|
355 |
|
356 // Remove key from the down array |
|
357 iDownEvents.Remove( finishesKeyPress ); |
|
358 |
|
359 // if it is mapped on the up array -> generate the up event |
|
360 TInt upKeyPressIndex = KErrNotFound; |
|
361 for ( TInt i = 0 ; i < iUpEvents.Count() ; i++ ) |
|
362 { |
|
363 if ( (iUpEvents[i] STRIP_MODS) == ( iKeyBeacon.iKeyCode STRIP_MODS ) ) |
|
364 { |
|
365 upKeyPressIndex = i; |
|
366 break; |
|
367 } |
|
368 } |
|
369 |
|
370 if ( upKeyPressIndex != KErrNotFound ) |
|
371 { |
|
372 iScanCodeIJustGenerated = iUpEvents[upKeyPressIndex]; |
|
373 TRawEvent rawEvent; |
|
374 rawEvent.Set( TRawEvent::EKeyUp, iScanCodeIJustGenerated ); |
|
375 __AKNANIMLOGSTRING1("CAknKeyEventMap::OfferRawEvent POST RAW UP-EVENT for %x",iScanCodeIJustGenerated); |
|
376 iFunctions->PostRawEvent( rawEvent ) ; |
|
377 iUpEvents.Remove(upKeyPressIndex); |
|
378 iConsume = ETrue; |
|
379 } |
|
380 |
|
381 if ( !iDownEvents.Count() ) |
|
382 { |
|
383 CancelProcessingKeyPress(); |
|
384 } |
|
385 |
|
386 } |
|
387 else // finishesKeyPress == KErrNotFound |
|
388 { |
|
389 // probably a hardware/driver bug, in any case we're |
|
390 // confused now. |
|
391 __AKNANIMLOGSTRING("CAknKeyEventMap::OfferRawEvent INPUT IS CONFUSED: cancel key processing"); |
|
392 CancelProcessingKeyPress(); |
|
393 } |
|
394 } |
|
395 |
|
396 return iConsume; |
|
397 } |
|
398 |
|
399 // ----------------------------------------------------------------------------- |
|
400 // CAknKeyEventMap::CancelProcessingKeyPress |
|
401 // ----------------------------------------------------------------------------- |
|
402 |
|
403 void CAknKeyEventMap::CancelProcessingKeyPress() |
|
404 { |
|
405 iDownTimer->Cancel(); |
|
406 iIsCanceled = ETrue; |
|
407 iDownEvents.Reset(); |
|
408 |
|
409 // be sure to send out all raw upevents or CKeyTranslator |
|
410 // will think the key is still being pressed. |
|
411 TRawEvent rawEvent; |
|
412 while ( iUpEvents.Count() > 0 ) |
|
413 { |
|
414 iScanCodeIJustGenerated = iUpEvents[0]; |
|
415 rawEvent.Set( TRawEvent::EKeyUp, iScanCodeIJustGenerated ); |
|
416 __AKNANIMLOGSTRING1("CAknKeyEventMap::CancelProcessingKeyPress POST RAW UP-EVENT for %x",iScanCodeIJustGenerated); |
|
417 iFunctions->PostRawEvent( rawEvent ) ; |
|
418 iUpEvents.Remove(0); |
|
419 } |
|
420 |
|
421 iUpEvents.Reset(); |
|
422 iRepeats = 0; |
|
423 iKeyPressDuration = 0.0; |
|
424 iIsLongKeyPress = EFalse; |
|
425 __AKNANIMLOGSTRING1("CAknKeyEventMap::CancelProcessingKeyPress Last beacon sent: %x", iKeyBeacon.iKeyCode); |
|
426 iKeyBeacon.iKeyCode = EKeyNull; |
|
427 iKeyBeacon.iEventType = 0; |
|
428 } |
|
429 |
|
430 |
|
431 // ----------------------------------------------------------------------------- |
|
432 // CAknKeyEventMap::HandlePropertyChangedL |
|
433 // |
|
434 // Callback for Publish & Subscribe key events, it tracks |
|
435 // the device mode changes for internal use. |
|
436 // ----------------------------------------------------------------------------- |
|
437 // |
|
438 void CAknKeyEventMap::HandlePropertyChangedL( |
|
439 const TUid& aCategory, |
|
440 const TUint aKey ) |
|
441 { |
|
442 TInt keyValue( 0 ); |
|
443 TInt err = KErrNone; |
|
444 err = RProperty::Get( aCategory, aKey, keyValue ); |
|
445 if ( err == KErrNone ) |
|
446 { |
|
447 switch( aKey ) |
|
448 { |
|
449 case KAknPSDeviceMode: |
|
450 { |
|
451 __AKNANIMLOGSTRING1("CAknKeyEventMap::HandlePropertyChanged VALUE: %d",aKey); |
|
452 iCurrentDeviceMode = keyValue; |
|
453 |
|
454 const TInt count = iRepeatRates.Count(); |
|
455 TUint16 currentMode = iCurrentDeviceMode; |
|
456 for ( TInt ii = 0; ii < count; ii++ ) |
|
457 { |
|
458 const TAknKeyRepeatRate& repeatRate = iRepeatRates[ ii ]; |
|
459 |
|
460 if ( ( currentMode & repeatRate.iModeMask ) == |
|
461 repeatRate.iMode ) |
|
462 { |
|
463 SetRepeatRate( repeatRate.iRate ); |
|
464 ii = count; // exit the loop. |
|
465 } |
|
466 } |
|
467 } |
|
468 break; |
|
469 default: |
|
470 { |
|
471 __AKNANIMLOGSTRING1("CAknKeyEventMap::HandlePropertyChanged GOT A P&S VALUE: %d",aKey); |
|
472 } |
|
473 break; |
|
474 } |
|
475 } |
|
476 } |
|
477 |
|
478 // ----------------------------------------------------------------------------- |
|
479 // CAknKeyEventMap::InitializeKeyTableFromResourceL |
|
480 // ----------------------------------------------------------------------------- |
|
481 // |
|
482 void CAknKeyEventMap::InitializeKeyTableFromResourceL( |
|
483 const TDesC& aConfigFile ) |
|
484 { |
|
485 // Get a handle for the resource file. |
|
486 RFs fsSession; |
|
487 CleanupClosePushL( fsSession ); |
|
488 TInt err = fsSession.Connect(); |
|
489 if ( err != KErrNone ) |
|
490 { |
|
491 User::Leave( err ); |
|
492 } |
|
493 RResourceFile resourceFile; |
|
494 CleanupClosePushL( resourceFile ); |
|
495 |
|
496 // Make sure we have the resource file. |
|
497 if ( BaflUtils::FileExists( fsSession, aConfigFile ) ) |
|
498 { |
|
499 resourceFile.OpenL( fsSession, aConfigFile ); |
|
500 } |
|
501 else |
|
502 { |
|
503 __AKNANIMLOGSTRING( "CAknKeyEventMap::InitializeKeyTableFromResourceL: no configuration file!"); |
|
504 CleanupStack::PopAndDestroy(); // CleanupClosePushL. |
|
505 CleanupStack::PopAndDestroy(); // CleanupClosePushL. |
|
506 return; |
|
507 } |
|
508 |
|
509 // Confirm signature of the resource file. |
|
510 resourceFile.ConfirmSignatureL( 0 ); |
|
511 |
|
512 // Now just get the resource chunk into a heap buffer and give it to a |
|
513 // TResourceReader. |
|
514 HBufC8* res; |
|
515 res = resourceFile.AllocReadLC( R_AVKON_KEY_EVENT_MAP ); |
|
516 |
|
517 TResourceReader theReader; |
|
518 theReader.SetBuffer( res ); |
|
519 |
|
520 // Check version field. |
|
521 const TUint16 version = theReader.ReadUint16(); |
|
522 if ( version != KAknKeyEventVersion1 ) |
|
523 { |
|
524 __AKNANIMLOGSTRING( "CAknKeyEventMap::InitializeKeyTableFromResourceL: key event map disabled!"); |
|
525 CleanupStack::PopAndDestroy( res ); |
|
526 CleanupStack::PopAndDestroy(); // CleanupClosePushL. |
|
527 CleanupStack::PopAndDestroy(); // CleanupClosePushL. |
|
528 return; |
|
529 } |
|
530 |
|
531 iKeyEventMapEnabled = ETrue; |
|
532 theReader.ReadUint16(); // read flags, not in use yet. |
|
533 |
|
534 // Read repeat rates. |
|
535 const TUint count = theReader.ReadUint16(); |
|
536 for ( TInt idx = 0; idx < count; idx++ ) |
|
537 { |
|
538 TUint16 mode = theReader.ReadUint16(); |
|
539 TUint16 modeMask = theReader.ReadUint16(); |
|
540 TUint8 rate = theReader.ReadUint8(); |
|
541 |
|
542 const TAknKeyRepeatRate repeatRate = |
|
543 { |
|
544 mode, |
|
545 modeMask, |
|
546 rate |
|
547 }; |
|
548 |
|
549 User::LeaveIfError( iRepeatRates.Append( repeatRate ) ); |
|
550 } |
|
551 |
|
552 // Parses the resource data |
|
553 CAknKeyResourceArray* keyResourceArray = CAknKeyResourceArray::NewLC(); |
|
554 CArrayPtrFlat<CAknKeyResource>* keyEvents = NULL; |
|
555 keyEvents = keyResourceArray->GetKeyEventsL( theReader ); |
|
556 |
|
557 // At this point we have all the key event info; just put it in its place |
|
558 // in iKeyMap and iCombos. |
|
559 for ( TUint i = 0; i < (TUint)keyEvents->Count(); i++ ) |
|
560 { |
|
561 CAknKeyResource* keyEvent = keyEvents->At(i); |
|
562 |
|
563 if ( keyEvent->GetScanCodes().Count() > 0 ) |
|
564 { |
|
565 if ( (keyEvent->GetKeyCodes().Count() == keyEvent->GetDeviceModes().Count()) |
|
566 && (keyEvent->GetKeyCodes().Count() == keyEvent->GetEventTypes().Count())) |
|
567 { |
|
568 for ( TUint j = 0; |
|
569 j < (TUint)keyEvent->GetKeyCodes().Count(); |
|
570 j++ ) |
|
571 { |
|
572 TUint16 thisMode = keyEvent->GetDeviceModes().At(j); |
|
573 RArray<TUint> theseModes; |
|
574 CleanupClosePushL( theseModes ); |
|
575 |
|
576 ResolveDeviceModeL( |
|
577 theseModes, |
|
578 keyEvent->GetDeviceModes().At(j) ); |
|
579 |
|
580 TUint16 thisType = keyEvent->GetEventTypes().At(j); |
|
581 for ( TUint k = 0; k < (TUint)theseModes.Count(); k++ ) |
|
582 { |
|
583 TAknKeyDefinition thisKey; |
|
584 thisKey.iScanCodes = &(keyEvent->GetScanCodes()); |
|
585 thisKey.iDeviceMode = theseModes[k]; |
|
586 thisKey.iKeyCode = keyEvent->GetKeyCodes().At(j); |
|
587 thisKey.iEventType = thisType; |
|
588 |
|
589 TRAPD( error, SetKeyMappingL( thisKey ) ); |
|
590 if (error != KErrNone) |
|
591 { |
|
592 __AKNANIMLOGSTRING( "CAknKeyEventMap::InitializeKeyTableFromResourceL ERROR setting a mapping"); |
|
593 } |
|
594 } |
|
595 |
|
596 CleanupStack::PopAndDestroy( &theseModes ); |
|
597 } |
|
598 } |
|
599 else |
|
600 { |
|
601 // Keyboard configuration is erroneous! |
|
602 // When multiple keycodes have been defined, they must have |
|
603 // an associated device mode, etc. |
|
604 __AKNANIMLOGSTRING( "CAknKeyEventMap::InitializeKeyTableFromResourceL ERROR: inconsistent data in KEY_EVENT" ); |
|
605 User::Leave( KErrGeneral ); |
|
606 } |
|
607 } |
|
608 else |
|
609 { |
|
610 // Error. No scancodes for the key event. |
|
611 User::Leave( KErrGeneral ); |
|
612 } |
|
613 } |
|
614 |
|
615 // All done! The maps are now ready for use! |
|
616 CleanupStack::PopAndDestroy( 4 ); // keyResourceArray, res, |
|
617 // &resourceFile, &fsSession |
|
618 } |
|
619 |
|
620 // ----------------------------------------------------------------------------- |
|
621 // CAknKeyEventMap::SetRepeatRate |
|
622 // ----------------------------------------------------------------------------- |
|
623 // |
|
624 void CAknKeyEventMap::SetRepeatRate( TUint8 aRepeatRate ) |
|
625 { |
|
626 if ( iRepeatRate > 0 && iRepeatRate < 32 ) |
|
627 { |
|
628 iRepeatRate = aRepeatRate; |
|
629 } |
|
630 } |
|
631 |
|
632 // ----------------------------------------------------------------------------- |
|
633 // CAknKeyEventMap::SetKeyMappingL |
|
634 // |
|
635 // Sets the keycodes in iKeyMap and iCombos for one device mode. |
|
636 // ----------------------------------------------------------------------------- |
|
637 // |
|
638 void CAknKeyEventMap::SetKeyMappingL( const TAknKeyDefinition& aKey ) |
|
639 { |
|
640 if ( aKey.iScanCodes->Count() == 1 ) |
|
641 { |
|
642 // Normal (=single key) mapping |
|
643 if ( (aKey.iEventType & KAknTypeShort) == KAknTypeShort ) |
|
644 { |
|
645 // handle anykey definition for single presses. |
|
646 if ( aKey.iScanCodes->At(0) == KAknAnyKey) |
|
647 { |
|
648 for (TUint j = 0; j < KAknMaxScanCode; j++) |
|
649 { |
|
650 iKeyMap[j][aKey.iDeviceMode].iShortPress = |
|
651 aKey.iKeyCode; |
|
652 iKeyMap[j][aKey.iDeviceMode].iLongPress = |
|
653 aKey.iKeyCode; |
|
654 iKeyMap[j][aKey.iDeviceMode].iEventType |= |
|
655 ResolveEventType ( aKey.iEventType ); |
|
656 } |
|
657 } |
|
658 else |
|
659 { |
|
660 // default is to set iLongPress to same as iShortPress, which in |
|
661 // practice means that the default behavior for long keypresses is |
|
662 // to repeat. |
|
663 iKeyMap[aKey.iScanCodes->At(0)][aKey.iDeviceMode].iShortPress = |
|
664 aKey.iKeyCode; |
|
665 iKeyMap[aKey.iScanCodes->At(0)][aKey.iDeviceMode].iLongPress = |
|
666 aKey.iKeyCode; |
|
667 iKeyMap[aKey.iScanCodes->At(0)][aKey.iDeviceMode].iEventType |= |
|
668 ResolveEventType( aKey.iEventType ); |
|
669 } |
|
670 } |
|
671 else if ( ((aKey.iEventType & KAknTypeLong) == KAknTypeLong) || |
|
672 ((aKey.iEventType & KAknTypeLongOnly) == KAknTypeLongOnly)) |
|
673 { |
|
674 iKeyMap[aKey.iScanCodes->At(0)][aKey.iDeviceMode].iLongPress = |
|
675 aKey.iKeyCode; |
|
676 iKeyMap[aKey.iScanCodes->At(0)][aKey.iDeviceMode].iEventType |= |
|
677 ResolveEventType( aKey.iEventType ); |
|
678 } |
|
679 else |
|
680 { |
|
681 // Ignored. |
|
682 } |
|
683 } |
|
684 else |
|
685 { |
|
686 // Combo mapping |
|
687 RArray<TUint32>* newCombo = |
|
688 new (ELeave) RArray<TUint32>( KAknMaxComboKeys ); |
|
689 TUint i; |
|
690 TInt err = KErrNone; |
|
691 for ( i = 0; i < aKey.iScanCodes->Count(); i++ ) |
|
692 { |
|
693 err = newCombo->Append( aKey.iScanCodes->At(i) ); |
|
694 if ( err != KErrNone ) |
|
695 { |
|
696 User::Leave( err ); // we're trapped, just bail out. |
|
697 } |
|
698 } |
|
699 |
|
700 // For combos, the device mode information is encoded in to the |
|
701 // upper 16 bits of the Key Code value. |
|
702 TUint32 keyMode = aKey.iKeyCode + ( aKey.iDeviceMode << 16 ); |
|
703 newCombo->Insert( keyMode, 0 ); |
|
704 |
|
705 TUint32 eventType = ResolveEventType( aKey.iEventType ); |
|
706 newCombo->Insert( eventType, 1 ); |
|
707 |
|
708 err = iCombos->Append( newCombo ); |
|
709 if ( err != KErrNone ) |
|
710 { |
|
711 User::Leave( KErrNone ); |
|
712 } |
|
713 } |
|
714 } |
|
715 |
|
716 // ----------------------------------------------------------------------------- |
|
717 // CAknKeyEventMap::ResolveEventType |
|
718 // |
|
719 // A conversion between the eventtype representation in the resource file |
|
720 // and iKeyMap. |
|
721 // ----------------------------------------------------------------------------- |
|
722 |
|
723 TUint8 CAknKeyEventMap::ResolveEventType( TUint8 aEventType ) |
|
724 { |
|
725 TUint8 result = 0; |
|
726 |
|
727 if ( (aEventType & (KAknTypeLongOnly)) == KAknTypeLongOnly ) |
|
728 { |
|
729 result |= KAknIsLongOnly; |
|
730 result |= KAknIsLongPress; |
|
731 if ( (aEventType & KAknTypeKey) ) |
|
732 { |
|
733 result |= KAknIsLongKey; |
|
734 } |
|
735 } |
|
736 else if ( (aEventType & KAknTypeLong) == KAknTypeLong ) |
|
737 { |
|
738 result |= KAknIsLongPress; |
|
739 if ( (aEventType & KAknTypeKey) == KAknTypeKey ) |
|
740 { |
|
741 result |= KAknIsLongKey; |
|
742 } |
|
743 } |
|
744 else if ( (aEventType & KAknTypeShort) == KAknTypeShort ) |
|
745 { |
|
746 result = 0; // to be 101% sure |
|
747 if ( (aEventType & KAknTypeKey) == KAknTypeKey ) |
|
748 { |
|
749 result |= KAknIsShortKey; |
|
750 } |
|
751 } |
|
752 |
|
753 return result; |
|
754 } |
|
755 |
|
756 // ----------------------------------------------------------------------------- |
|
757 // CAknKeyEventMap::ResolveDeviceModeLC |
|
758 // |
|
759 // Given a TUint specifying a device mode, this function figures out |
|
760 // which rows of the iKeyMap are affected by a mapping. Only used in |
|
761 // setting up the key tables, not when querying data from them (just use |
|
762 // iCurrentDeviceMode then). |
|
763 // ----------------------------------------------------------------------------- |
|
764 // |
|
765 void CAknKeyEventMap::ResolveDeviceModeL( |
|
766 RArray<TUint>& aModes, |
|
767 TUint16 aMode ) |
|
768 { |
|
769 TInt err; |
|
770 TUint16 myMode = aMode; |
|
771 |
|
772 for ( TUint k = 0; k < KAknKeyMapRows; k++ ) |
|
773 { |
|
774 // The loop index is now tested against aMode to see whether |
|
775 // there should be a non-null value in iKeyMap. |
|
776 |
|
777 if ( k == myMode ) |
|
778 { |
|
779 err = aModes.InsertInOrder( k ); |
|
780 if ( err != KErrNone && err != KErrAlreadyExists ) |
|
781 { |
|
782 User::Leave( err ); // we can't initialize the table. fail. |
|
783 } |
|
784 } |
|
785 } |
|
786 } |
|
787 |
|
788 // ----------------------------------------------------------------------------- |
|
789 // CAknKeyEventMap::GetKeyMapping |
|
790 // |
|
791 // Returns mappings from iKeyMap. |
|
792 // ----------------------------------------------------------------------------- |
|
793 // |
|
794 TAknKeyBeacon CAknKeyEventMap::GetKeyMapping( |
|
795 TUint16 aScanCode, |
|
796 TUint16 aDeviceMode ) |
|
797 { |
|
798 TAknKeyBeacon mapValue = { EKeyNull, 0 }; |
|
799 |
|
800 if ( aScanCode < KAknKeyMapColumns && aDeviceMode < KAknKeyMapRows ) |
|
801 { |
|
802 // Look up the mode specific value, if any |
|
803 if ( iIsLongKeyPress == EFalse ) |
|
804 { |
|
805 mapValue.iKeyCode = iKeyMap[aScanCode][aDeviceMode].iShortPress; |
|
806 } |
|
807 else |
|
808 { |
|
809 mapValue.iKeyCode = iKeyMap[aScanCode][aDeviceMode].iLongPress; |
|
810 } |
|
811 |
|
812 mapValue.iEventType = iKeyMap[aScanCode][aDeviceMode].iEventType; |
|
813 |
|
814 // With this, we always return the default mapping (if any) |
|
815 // unless a mode-specific mapping was found. |
|
816 if ( !mapValue.iKeyCode ) |
|
817 { |
|
818 if ( iIsLongKeyPress == EFalse ) |
|
819 { |
|
820 mapValue.iKeyCode = iKeyMap[aScanCode][ KAknModeDefault ].iShortPress; |
|
821 } |
|
822 else |
|
823 { |
|
824 mapValue.iKeyCode = iKeyMap[aScanCode][ KAknModeDefault ].iLongPress; |
|
825 } |
|
826 mapValue.iEventType = iKeyMap[aScanCode][ KAknModeDefault ].iEventType; |
|
827 } |
|
828 } |
|
829 return mapValue; |
|
830 } |
|
831 |
|
832 // ----------------------------------------------------------------------------- |
|
833 // CAknKeyEventMap::GetComboMapping |
|
834 // |
|
835 // Returns mappings from iCombos. |
|
836 // ----------------------------------------------------------------------------- |
|
837 // |
|
838 TAknKeyBeacon CAknKeyEventMap::GetComboMapping( |
|
839 RArray<TUint32>& aComboCandidate ) |
|
840 { |
|
841 TAknKeyBeacon mapValue = { EKeyNull, 0 }; |
|
842 |
|
843 TUint i; |
|
844 TUint j; |
|
845 |
|
846 // First we check the first index of aComboCandidate |
|
847 // against the second index (= first scancode) of all combo |
|
848 // arrays in iCombos. If they match, then the i'th combo |
|
849 // array in iCombos could match aComboCandidate. |
|
850 // |
|
851 // iCombos[i][0] contains the key code that is to be returned for a |
|
852 // succesful mapping, which introduces the offset-by-one in the following |
|
853 // loops/lookups.also included in [i][0] are the device mode info and the |
|
854 // event type info, both encoded into the upper 16 bits of iCombos[i][0]. |
|
855 |
|
856 RArray<TUint> possibleMatch; // iCombos indices that might match |
|
857 for (i = 0; i < iCombos->Count(); i++) |
|
858 { |
|
859 if ( (*(*iCombos)[i])[2] == aComboCandidate[0] && |
|
860 ((*iCombos)[i])->Count()-2 == aComboCandidate.Count() ) |
|
861 { |
|
862 possibleMatch.Append(i); |
|
863 __AKNANIMLOGSTRING1("CAknKeyEventMap::GetComboMapping ComboCandidate might hit iCombos[%d]",i); |
|
864 } |
|
865 } |
|
866 |
|
867 // If we have possibleMatches, then we just check whether any of |
|
868 // them matches aComboCandidate precisely. For the first match, |
|
869 // we return the keyvalue from the first element of the matching |
|
870 // combo array. |
|
871 if ( possibleMatch.Count() ) |
|
872 { |
|
873 TInt8 isAMatch = -1; |
|
874 for ( i = 0; i < possibleMatch.Count() && isAMatch < 0; i++ ) |
|
875 { |
|
876 // If isAMatch doesn't go to -1 within this loop, |
|
877 // then we got a match. |
|
878 isAMatch = possibleMatch[i]; |
|
879 for ( j = 2; j < (*(*iCombos)[possibleMatch[i]]).Count(); j++ ) |
|
880 { |
|
881 // Try to find all scan codes of the current event |
|
882 // in a combo definition. |
|
883 // NOTE: the order of the remaining scancodes is not matched, |
|
884 // as long as the first scancode is OK, the others can come in |
|
885 // any order. |
|
886 TInt err = KErrNotFound; |
|
887 for ( TInt f = (*(*iCombos)[possibleMatch[i]]).Count()-1; f >= 0 ; f-- ) |
|
888 { |
|
889 if ( (*(*iCombos)[possibleMatch[i]])[f] == aComboCandidate[j-2] ) |
|
890 { |
|
891 err = f; |
|
892 break; |
|
893 } |
|
894 } |
|
895 |
|
896 |
|
897 // err < 2 must be discarded, because the first two elements are |
|
898 // used for device mode & event type data. |
|
899 if ( err == KErrNotFound || err < 2) |
|
900 { |
|
901 // If a scan code cannot be found, this possibleMatch is |
|
902 // not a real match. |
|
903 isAMatch = -1; |
|
904 } |
|
905 } |
|
906 |
|
907 // If we get this far, a matching combination of keys has been |
|
908 // found. Still need to check that the combo type (long/short) and |
|
909 // the active device mode for this combo match those of the current |
|
910 // event. |
|
911 |
|
912 TUint16 comboMode = ((*(*iCombos)[possibleMatch[i]])[0] GET_MODS) >> 16; |
|
913 TUint16 comboType = ((*(*iCombos)[possibleMatch[i]])[1]); |
|
914 |
|
915 // If .. |
|
916 // a matching set of scan codes was found, |
|
917 // but it fails the long/short test, |
|
918 // or it's defined for another device mode |
|
919 if ( isAMatch > -1 && |
|
920 ( iIsLongKeyPress && (!(comboType & KAknIsLongPress) ) || |
|
921 ( ( iCurrentDeviceMode != comboMode ) && ( comboMode != KAknModeDefault ) ) ) ) |
|
922 { |
|
923 isAMatch = -1; |
|
924 } |
|
925 } |
|
926 |
|
927 if ( isAMatch > -1 && isAMatch < iCombos->Count() ) |
|
928 { |
|
929 // The correct return value can be found from the isAMatch'th |
|
930 // combo-mapping's first element. |
|
931 mapValue.iKeyCode = (*(*iCombos)[isAMatch])[0] STRIP_MODS; |
|
932 mapValue.iEventType = (*(*iCombos)[isAMatch])[1]; |
|
933 __AKNANIMLOGSTRING1("CAknKeyEventMap::GetComboMapping ComboCandidate DID hit iCombos[%d]", isAMatch); |
|
934 __AKNANIMLOGSTRING1("CAknKeyEventMap::GetComboMapping mapValue = %d", mapValue.iKeyCode); |
|
935 } |
|
936 } |
|
937 else |
|
938 { |
|
939 mapValue.iKeyCode = EKeyNull; |
|
940 mapValue.iEventType = 0 ; |
|
941 } |
|
942 possibleMatch.Close(); |
|
943 return mapValue; |
|
944 } |
|
945 |
|
946 // ----------------------------------------------------------------------------- |
|
947 // CAknKeyEventMap::ResolveMapping |
|
948 // |
|
949 // A little macro for figuring out how to map the current scan code. |
|
950 // ----------------------------------------------------------------------------- |
|
951 // |
|
952 TAknKeyBeacon CAknKeyEventMap::ResolveMapping() |
|
953 { |
|
954 TAknKeyBeacon keyBeacon = |
|
955 { |
|
956 EKeyNull, 0 |
|
957 }; |
|
958 |
|
959 if ( iDownEvents.Count() > 1 && iDownEvents.Count() <= KAknMaxComboKeys ) |
|
960 { |
|
961 // check that the current key is not disabled in this mode |
|
962 // if it is, then any combo containing this key must be |
|
963 // blocked. |
|
964 TAknKeyBeacon tmp = GetKeyMapping( |
|
965 iCurrentScanCode STRIP_MODS, iCurrentDeviceMode); |
|
966 |
|
967 if (tmp.iKeyCode != KAknKeyDisabled) |
|
968 { |
|
969 keyBeacon = GetComboMapping( iDownEvents ); |
|
970 |
|
971 // If we do not find combo, then try to map a single key. |
|
972 if ( keyBeacon.iKeyCode == EKeyNull ) |
|
973 { |
|
974 __AKNANIMLOGSTRING( "CAknKeyEventMap::ResolveMapping Combo not found. Trying to get single." ); |
|
975 keyBeacon = GetKeyMapping( |
|
976 iCurrentScanCode STRIP_MODS, iCurrentDeviceMode ); |
|
977 } |
|
978 } |
|
979 else |
|
980 { |
|
981 __AKNANIMLOGSTRING("CAknKeyEventMap::ResolveMapping Ignoring combo because component is disabled"); |
|
982 keyBeacon.iKeyCode = KAknKeyDisabled; |
|
983 keyBeacon.iEventType = 0; |
|
984 } |
|
985 } |
|
986 else if ( iDownEvents.Count() == 1 ) |
|
987 { |
|
988 keyBeacon = GetKeyMapping( |
|
989 iCurrentScanCode STRIP_MODS, iCurrentDeviceMode ); |
|
990 } |
|
991 |
|
992 // Always consume succesful mappings, including EKeyDisabled |
|
993 if ( keyBeacon.iKeyCode != EKeyNull ) |
|
994 { |
|
995 iConsume = ETrue; |
|
996 __AKNANIMLOGSTRING1( "CAknKeyEventMap::ResolveMapping mapping found: %x", keyBeacon.iKeyCode ); |
|
997 } |
|
998 else |
|
999 { |
|
1000 __AKNANIMLOGSTRING( "CAknKeyEventMap::ResolveMapping mapping not found" ); |
|
1001 } |
|
1002 |
|
1003 return keyBeacon; |
|
1004 } |
|
1005 |
|
1006 // ----------------------------------------------------------------------------- |
|
1007 // CAknKeyEventMap::KeyPressDuration |
|
1008 // |
|
1009 // Callback for iDownTimer, used to distinguish between short and |
|
1010 // long key presses and to handle repeats. |
|
1011 // ----------------------------------------------------------------------------- |
|
1012 // |
|
1013 TInt CAknKeyEventMap::KeyPressDuration( TAny* aSelf ) |
|
1014 { |
|
1015 if (aSelf != NULL) |
|
1016 { |
|
1017 CAknKeyEventMap* self = reinterpret_cast<CAknKeyEventMap*>(aSelf); |
|
1018 |
|
1019 self->iKeyPressDuration += ((TReal32)self->iKeyPollInterval.Int())/1e6; |
|
1020 |
|
1021 // Distinguish between short and long key presses. |
|
1022 if ( self->iKeyPressDuration < KAknKeyLongThreshold ) |
|
1023 { |
|
1024 // nothing to do. if combo duration measurement is changed |
|
1025 // so that each participating key resets the timer, then |
|
1026 // un-comment the following lines: |
|
1027 // self->iIsLongKeyPress = EFalse; |
|
1028 // self->iKeyBeacon = self->ResolveMapping(); |
|
1029 } |
|
1030 else |
|
1031 { |
|
1032 // Keypress turned out to be a long one |
|
1033 if ( ! self->iIsLongKeyPress && ! self->iIsCanceled ) |
|
1034 { |
|
1035 self->iIsLongKeyPress = ETrue; |
|
1036 self->iKeyBeacon = self->ResolveMapping(); |
|
1037 |
|
1038 // post the KAknTypeLongOnly event |
|
1039 if ( self->iKeyBeacon.iKeyCode > KAknKeyDisabled |
|
1040 && (self->iKeyBeacon.iEventType & KAknIsLongPress)) |
|
1041 { |
|
1042 if ( (self->iKeyBeacon.iEventType & KAknIsLongKey ) ) |
|
1043 { |
|
1044 self->PostEvent( EAknPostKey ); |
|
1045 } |
|
1046 else |
|
1047 { |
|
1048 self->PostEvent( EAknPostRaw ); |
|
1049 } |
|
1050 } |
|
1051 } |
|
1052 } |
|
1053 |
|
1054 // Handle repeats. |
|
1055 if ( self->iKeyPressDuration >= KAknKeyLongThreshold && |
|
1056 self->iKeyBeacon.iKeyCode > KAknKeyDisabled ) |
|
1057 { |
|
1058 if ( ( self->iKeyBeacon.iEventType & KAknIsLongKey ) ) |
|
1059 { |
|
1060 self->iRepeats++; // perhaps don't do this? |
|
1061 self->PostEvent( EAknPostKey ); |
|
1062 } |
|
1063 else |
|
1064 { |
|
1065 __AKNANIMLOGSTRING("CAknKeyEventMap::KeyPressDuration RAW repeat not sent (CKeyTranslator handles that)"); |
|
1066 } |
|
1067 } |
|
1068 |
|
1069 if ( self->iIsCanceled ) |
|
1070 { |
|
1071 self->iDownTimer->Cancel(); |
|
1072 } |
|
1073 } |
|
1074 return KErrNone; |
|
1075 } |
|
1076 |
|
1077 // ----------------------------------------------------------------------------- |
|
1078 // CAknKeyEventMap::PostEvent |
|
1079 // ----------------------------------------------------------------------------- |
|
1080 |
|
1081 void CAknKeyEventMap::PostEvent(TUint aType) |
|
1082 { |
|
1083 switch ( aType ) |
|
1084 { |
|
1085 case EAknPostKey: |
|
1086 TKeyEvent keyEvent; |
|
1087 keyEvent.iCode = iKeyBeacon.iKeyCode; |
|
1088 keyEvent.iScanCode = iCurrentScanCode STRIP_MODS; |
|
1089 keyEvent.iRepeats = iRepeats; |
|
1090 keyEvent.iModifiers = iCurrentScanCode GET_MODS; |
|
1091 iFunctions->PostKeyEvent(keyEvent); |
|
1092 __AKNANIMLOGSTRING1( "CAknKeyEventMap::PostEvent() POST KEY code=%x", keyEvent.iCode); |
|
1093 |
|
1094 break; |
|
1095 |
|
1096 case EAknPostRaw: |
|
1097 default: |
|
1098 TRawEvent rawEvent; |
|
1099 rawEvent.Set(TRawEvent::EKeyDown, (iCurrentScanCode GET_MODS) + iKeyBeacon.iKeyCode ); |
|
1100 iScanCodeIJustGenerated = rawEvent.ScanCode(); |
|
1101 __AKNANIMLOGSTRING1( "CAknKeyEventMap::PostEvent() POST RAW scancode=%x", rawEvent.ScanCode()); |
|
1102 iFunctions->PostRawEvent( rawEvent ); |
|
1103 break; |
|
1104 } |
|
1105 iConsume = ETrue; |
|
1106 } |
|
1107 |
|
1108 |
|
1109 |
|
1110 // End of File |