|
1 /* |
|
2 * Copyright (c) 2002-2006 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: Keymappings etc. customized for Series 60. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include <eikenv.h> |
|
21 #include <eikappui.h> |
|
22 #include <coecntrl.h> |
|
23 #include <coeccntx.h> |
|
24 #include <coecobs.h> |
|
25 #include <bassnd.h> |
|
26 #include <coesndpy.h> |
|
27 #include <hal.h> |
|
28 #include <lcdui.rsg> |
|
29 #include <barsread.h> |
|
30 |
|
31 #include <aknappui.h> |
|
32 #include <aknsoundsystem.h> |
|
33 #include <avkon.hrh> // for Alert Sounds |
|
34 #include <hwrmlight.h> // backlight |
|
35 #include <hwrmvibra.h> // vibra |
|
36 // for layout data in BestImageSize function |
|
37 #include <aknlayoutscalable_avkon.cdl.h> // for layout data |
|
38 // API used Color function - mapping Java color type to Avkon-skinned color |
|
39 #include <AknsUtils.h> |
|
40 |
|
41 // CMIDKeyDecoder API in funcions related to keys |
|
42 #include "CMIDKeyDecoder.h" |
|
43 #include "CMIDUtils.h" |
|
44 #include "CMIDUIManager.h" |
|
45 |
|
46 #ifdef RD_SCALABLE_UI_V2 |
|
47 #include <AknUtils.h> |
|
48 #endif // RD_SCALABLE_UI_V2 |
|
49 |
|
50 #include <e32property.h> |
|
51 #include <AvkonInternalCRKeys.h> |
|
52 #include <centralrepository.h> |
|
53 #include <AknFepInternalCRKeys.h> |
|
54 |
|
55 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
56 #include <PtiEngine.h> |
|
57 #endif //RD_INTELLIGENT_TEXT_INPUT |
|
58 |
|
59 |
|
60 // macros definitions for outputing logs |
|
61 #include <j2me/jdebug.h> |
|
62 |
|
63 // LOCAL CONSTANTS AND MACROS |
|
64 |
|
65 /** |
|
66 *Info messages for Wins Flashbacklight and Vibrate |
|
67 *For development purpose only, not localized |
|
68 */ |
|
69 #if defined(__WINS__) |
|
70 _LIT(KMsgFlashBacklight,"Flash count:"); |
|
71 _LIT(KMsgVibrate,"Vibrating for "); |
|
72 #endif |
|
73 |
|
74 // line feed, carriage return, line separator, paragraph separator |
|
75 _LIT(KSeparators, "\x000a\x000d\x2028\x2029"); |
|
76 |
|
77 // keyboard types |
|
78 _LIT(KKeyboardNone, "None"); |
|
79 _LIT(KKeyboardPhoneKeypad, "PhoneKeypad"); |
|
80 _LIT(KKeyboardFullKeyboard, "FullKeyboard"); |
|
81 _LIT(KKeyboardLimited4x10, "LimitedKeyboard4x10"); |
|
82 _LIT(KKeyboardLimited3x11, "LimitedKeyboard3x11"); |
|
83 _LIT(KKeyboardHalfKeyboard, "HalfKeyboard"); |
|
84 _LIT(KKeyboardCustom, "Custom"); |
|
85 _LIT(KKeyboardUnknown, "Unknown"); |
|
86 |
|
87 |
|
88 // constants for color bits shifting (for creation of 0x00RRGGBB color value) |
|
89 const TInt KRedBitsShift = 16; |
|
90 const TInt KGreenBitsShift = 8; |
|
91 const TInt KBlueBitsShift = 0; |
|
92 |
|
93 // constant for result size used by PTI Engine for mapping keys, this value is |
|
94 // based e.g. on PtiXt9CandidateList implementation |
|
95 |
|
96 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
97 const TInt KPTIEngineResultSize = 32; |
|
98 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
99 |
|
100 |
|
101 // ============================ MEMBER FUNCTIONS =============================== |
|
102 |
|
103 // |
|
104 // |
|
105 // class MMIDUtils |
|
106 |
|
107 // --------------------------------------------------------------------------- |
|
108 // |
|
109 // --------------------------------------------------------------------------- |
|
110 // |
|
111 MMIDUtils* CMIDUtils::NewL(MMIDEnv& aEnv, CMIDUIManager* aUIManager) |
|
112 { |
|
113 CMIDUtils* utils = new(ELeave) CMIDUtils(aEnv, aUIManager); |
|
114 CleanupStack::PushL(utils); |
|
115 utils->ConstructL(); |
|
116 CleanupStack::Pop(utils); |
|
117 return utils; |
|
118 } |
|
119 |
|
120 /** |
|
121 * CAknKeySoundSystem is use to play sounds, |
|
122 * emulator implementation, which does not support |
|
123 * this feature. |
|
124 */ |
|
125 #if defined(__WINSCW__) |
|
126 TBool CMIDUtils::PlaySound(TInt /*aSoundType*/) |
|
127 { |
|
128 return EFalse; |
|
129 } |
|
130 #else // __WINSCW__ |
|
131 |
|
132 /** |
|
133 * CAknKeySoundSystem is use to play sounds |
|
134 */ |
|
135 TBool CMIDUtils::PlaySound(TInt aSoundType) |
|
136 { |
|
137 TInt toneType = -1; |
|
138 switch (aSoundType) |
|
139 { |
|
140 case MMIDAlert::EAlarm: |
|
141 toneType = (TInt) EAvkonSIDInformationTone; |
|
142 break; |
|
143 case MMIDAlert::EConfirmation: |
|
144 toneType = (TInt) EAvkonSIDConfirmationTone; |
|
145 break; |
|
146 case MMIDAlert::EError: |
|
147 toneType = (TInt) EAvkonSIDErrorTone; |
|
148 break; |
|
149 case MMIDAlert::EWarning: |
|
150 toneType = (TInt) EAvkonSIDWarningTone; |
|
151 break; |
|
152 case MMIDAlert::EInfo: |
|
153 toneType = (TInt) EAvkonSIDInformationTone; |
|
154 break; |
|
155 case MMIDAlert::ENone: // No Alerttype set |
|
156 default: |
|
157 toneType = (TInt) EAvkonSIDNoSound; |
|
158 break; |
|
159 } |
|
160 |
|
161 CAknKeySoundSystem* soundSystem = iAvkonAppUi->KeySounds(); |
|
162 if (toneType != -1) |
|
163 { |
|
164 soundSystem->PlaySound(toneType); |
|
165 } |
|
166 return ETrue; |
|
167 } |
|
168 #endif // __WINSCW__ |
|
169 |
|
170 /** |
|
171 * Determines if a key code should be sent to Canvas.keyPressed(int keyCode) |
|
172 */ |
|
173 TBool CMIDUtils::IsJavaKey(TInt aScanCode) |
|
174 { |
|
175 ASSERT(iKeyDecoder); |
|
176 return iKeyDecoder->IsJavaKey(aScanCode); |
|
177 } |
|
178 |
|
179 /** |
|
180 * Maps EPOC scan code to negative key code required by MIDP spec. |
|
181 * For keys that have no corresponding Unicode character, |
|
182 * the implementation must use negative values. |
|
183 */ |
|
184 TInt CMIDUtils::MapNonUnicodeKey(TUint aScanCode) |
|
185 { |
|
186 ASSERT(iKeyDecoder); |
|
187 return iKeyDecoder->MapNonUnicodeKey(aScanCode); |
|
188 } |
|
189 |
|
190 /** |
|
191 * Gets a key code that corresponds to the specified game action on the device. |
|
192 * |
|
193 * Returns zero if aGameAction is not a valid game action. |
|
194 * |
|
195 * @see CMIDKeyDecoder::GetKeyCode() |
|
196 */ |
|
197 TInt CMIDUtils::GetKeyCode(TInt aGameAction) |
|
198 { |
|
199 ASSERT(iKeyDecoder); |
|
200 return iKeyDecoder->GetKeyCode(aGameAction); |
|
201 } |
|
202 |
|
203 /** |
|
204 * Gets an informative key string for a key. The string returned will resemble the text |
|
205 * physically printed on the key. This string is suitable for displaying to the user. |
|
206 * For example, on a device with function keys F1 through F4, calling this method on |
|
207 * the keyCode for the F1 key will return the string "F1". A typical use for this string |
|
208 * will be to compose help text such as "Press F1 to proceed." |
|
209 * |
|
210 * This method will return a non-empty string for every valid key code. |
|
211 * @see CMIDKeyDecoder::GetKeyName() |
|
212 */ |
|
213 void CMIDUtils::GetKeyName(TDes& aText,TInt aKeyCode) |
|
214 { |
|
215 ASSERT(iKeyDecoder); |
|
216 return iKeyDecoder->GetKeyName(aText, aKeyCode); |
|
217 } |
|
218 |
|
219 /** |
|
220 * Gets the game action associated with the given key code of the device. |
|
221 * |
|
222 * Return zero if no game action is associated with this key code. |
|
223 * |
|
224 * @see CMIDKeyDecoder::GameAction() |
|
225 */ |
|
226 TInt CMIDUtils::GetGameAction(TInt aKeyCode) |
|
227 { |
|
228 ASSERT(iKeyDecoder); |
|
229 return iKeyDecoder->GameAction(aKeyCode); |
|
230 } |
|
231 |
|
232 void CMIDUtils::MapJavaToETextChars(HBufC* aText,TBool aSupportLineBreaks) |
|
233 { |
|
234 TPtr text = aText->Des(); |
|
235 TInt pos = text.Length(); |
|
236 for (; pos>0;) |
|
237 { |
|
238 TText& ch=(text)[--pos]; |
|
239 switch (ch) |
|
240 { |
|
241 case '\n': |
|
242 //From 3.0m onwards: If line breaks are not supported, returns ESpace instead of ETabCharacter |
|
243 ch = (TText)(aSupportLineBreaks ? CEditableText::EParagraphDelimiter : CEditableText::ESpace); |
|
244 break; |
|
245 case '\f': |
|
246 //From 3.0m onwards: If line breaks are not supported, returns ESpace instead of ETabCharacter |
|
247 ch = (TText)(aSupportLineBreaks ? CEditableText::EPageBreak : CEditableText::ESpace); |
|
248 break; |
|
249 case '\t': |
|
250 ch = CEditableText::ETabCharacter; |
|
251 break; |
|
252 } |
|
253 } |
|
254 } |
|
255 |
|
256 void CMIDUtils::MapETextToJavaChars(HBufC* aText) |
|
257 { |
|
258 if (!aText) |
|
259 return; |
|
260 TPtr text = aText->Des(); |
|
261 TInt pos = text.Length(); |
|
262 for (; pos>0;) |
|
263 { |
|
264 TText& ch=(text)[--pos]; |
|
265 switch (ch) |
|
266 { |
|
267 case CEditableText::EParagraphDelimiter: |
|
268 ch = '\n'; |
|
269 break; |
|
270 case CEditableText::EPageBreak: |
|
271 ch = '\f'; |
|
272 break; |
|
273 case CEditableText::ETabCharacter: |
|
274 ch = '\t'; |
|
275 break; |
|
276 } |
|
277 } |
|
278 } |
|
279 |
|
280 /** |
|
281 * Looks for first character which indicates text direction such as Arabic character meaning right-to-left. |
|
282 * (similar code can be found in lcdgr) |
|
283 */ |
|
284 TBool CMIDUtils::IsStronglyRightToLeft(HBufC* aText) |
|
285 { |
|
286 TPtr text = aText->Des(); |
|
287 TInt pos; |
|
288 TInt len = text.Length(); |
|
289 for (pos = 0; pos < len; pos++) |
|
290 { |
|
291 TChar ch((text)[pos]); |
|
292 TChar::TCharInfo info; |
|
293 ch.GetInfo(info); |
|
294 switch (info.iBdCategory) |
|
295 { |
|
296 case TChar::ERightToLeft: |
|
297 case TChar::ERightToLeftArabic: |
|
298 case TChar::ERightToLeftEmbedding: |
|
299 case TChar::ERightToLeftOverride: |
|
300 case TChar::EArabicNumber: |
|
301 return true; |
|
302 case TChar::ELeftToRight: |
|
303 return false; |
|
304 default: |
|
305 ; |
|
306 } |
|
307 } |
|
308 return false; |
|
309 } |
|
310 |
|
311 /** |
|
312 * Reverses order of contents of array. |
|
313 */ |
|
314 void CMIDUtils::Reverse(HBufC* aText) |
|
315 { |
|
316 TPtr text = aText->Des(); |
|
317 TInt s = 0; |
|
318 TInt e = text.Length() - 1; |
|
319 while (s < e) |
|
320 { |
|
321 TText t = text[s]; |
|
322 text[s] = text[e]; |
|
323 text[e] = t; |
|
324 ++s; |
|
325 --e; |
|
326 } |
|
327 } |
|
328 |
|
329 /** Some key events should be ignored, for example when opening or closing a device. */ |
|
330 TBool CMIDUtils::IgnoreKeyEvent(TUint aKeyEvent) |
|
331 { |
|
332 return (aKeyEvent == EKeyGripOpen) || |
|
333 (aKeyEvent == EKeyGripClose) || |
|
334 (aKeyEvent == EKeyTwistOpen) || |
|
335 (aKeyEvent == EKeyTwistClose) || |
|
336 (aKeyEvent == EKeyFlipOpen) || |
|
337 (aKeyEvent == EKeyFlipClose) || |
|
338 (aKeyEvent == EKeyQwertyOn) || |
|
339 (aKeyEvent == EKeyQwertyOff); |
|
340 } |
|
341 |
|
342 |
|
343 /** Creates an identical copy of the given bitmap. This utility function is used instead |
|
344 of MMIDBitmapImage::CreateColorBitmapL() because this latter looses transparency information |
|
345 when the display mode is EColor16MA (it blits on a white bitmap...). |
|
346 */ |
|
347 CFbsBitmap* CMIDUtils::CopyBitmapL(CFbsBitmap* aSource) |
|
348 { |
|
349 CFbsBitmap* target = NULL; |
|
350 |
|
351 if (aSource) |
|
352 { |
|
353 target = new(ELeave) CFbsBitmap(); |
|
354 target->Create(aSource->SizeInPixels(), aSource->DisplayMode()); |
|
355 |
|
356 //if there is no memory for new bitmap, target has null adress pointer |
|
357 //and calling Mem::Copy causes a panic. |
|
358 //So if target->DataAdress() returns null pointer, |
|
359 //function leave with KErrNoMemory -> java.lang.OutOfMemoryError is thrown |
|
360 if (!target->DataAddress()) |
|
361 { |
|
362 User::Leave(KErrNoMemory); |
|
363 } |
|
364 |
|
365 TInt nBytes = aSource->SizeInPixels().iHeight * |
|
366 aSource->ScanLineLength(aSource->SizeInPixels().iWidth, aSource->DisplayMode()); |
|
367 |
|
368 target->LockHeap(); |
|
369 Mem::Copy(target->DataAddress(), aSource->DataAddress(), nBytes); |
|
370 target->UnlockHeap(); |
|
371 } |
|
372 |
|
373 return target; |
|
374 } |
|
375 |
|
376 TBool CMIDUtils::IsLineSeparator(const TText aChar) |
|
377 { |
|
378 return (KSeparators().Locate(aChar) != KErrNotFound); |
|
379 } |
|
380 |
|
381 TBool CMIDUtils::HasPointerEvents() |
|
382 { |
|
383 return (HasPen() || HasMouse()); |
|
384 } |
|
385 |
|
386 TBool CMIDUtils::HasPointerMotionEvents() |
|
387 { |
|
388 return (HasPen() || HasMouse()); |
|
389 } |
|
390 |
|
391 TBool CMIDUtils::HasRepeatEvents() |
|
392 { |
|
393 return ETrue; |
|
394 } |
|
395 |
|
396 TBool CMIDUtils::HasPen() |
|
397 { |
|
398 #ifdef RD_SCALABLE_UI_V2 |
|
399 return AknLayoutUtils::PenEnabled(); |
|
400 #else |
|
401 TInt hasPen = EFalse; |
|
402 return hasPen; |
|
403 #endif // RD_SCALABLE_UI_V2 |
|
404 } |
|
405 |
|
406 TBool CMIDUtils::HasMouse() |
|
407 { |
|
408 TInt hasMouse = EFalse; |
|
409 return hasMouse; |
|
410 } |
|
411 |
|
412 TSize CMIDUtils::BestImageSize(TImageType aImageType) const |
|
413 { |
|
414 TAknWindowLineLayout lineLayout; |
|
415 |
|
416 switch (aImageType) |
|
417 { |
|
418 case EListImage: |
|
419 lineLayout = AknLayoutScalable_Avkon::list_single_large_graphic_pane_g1(0).LayoutLine(); |
|
420 break; |
|
421 case EChoiceImage: |
|
422 lineLayout = AknLayoutScalable_Avkon::list_single_2graphic_pane_g1_cp4().LayoutLine(); |
|
423 break; |
|
424 case EAlertImage: |
|
425 lineLayout = AknLayoutScalable_Avkon::popup_midp_note_alarm_window_g1(0).LayoutLine(); |
|
426 break; |
|
427 default: |
|
428 return TSize(); |
|
429 } |
|
430 return TSize(lineLayout.iW, lineLayout.iH); |
|
431 } |
|
432 |
|
433 |
|
434 /** |
|
435 * Requests a flashing effect for the device's backlight |
|
436 * Returns false as the emulator does not support this feature. |
|
437 */ |
|
438 #if defined(__WINSCW__) |
|
439 |
|
440 TBool CMIDUtils::FlashBacklightL(const TTimeIntervalMicroSeconds32& /*aDuration*/) |
|
441 { |
|
442 return EFalse; |
|
443 } |
|
444 |
|
445 #else // __WINSCW__ |
|
446 /** |
|
447 * Requests a flashing effect for the device's backlight |
|
448 * Must return true if the backlight can be controlled by the application |
|
449 */ |
|
450 TBool CMIDUtils::FlashBacklightL(const TTimeIntervalMicroSeconds32& aDuration) |
|
451 { |
|
452 if (!iLight) |
|
453 { |
|
454 iLight = CHWRMLight::NewL(); |
|
455 } |
|
456 // SupportedTargets() returns the supported targets as a bitmap. |
|
457 if ((iLight->SupportedTargets() & |
|
458 CHWRMLight::EPrimaryDisplayAndKeyboard) != |
|
459 CHWRMLight::EPrimaryDisplayAndKeyboard) |
|
460 { |
|
461 return EFalse; |
|
462 } |
|
463 |
|
464 TInt duration = aDuration.Int() / 1000; |
|
465 if (!duration) |
|
466 { |
|
467 // 0 would be infinite |
|
468 duration = 1; |
|
469 } |
|
470 iLight->LightBlinkL(CHWRMLight::EPrimaryDisplayAndKeyboard, |
|
471 duration); |
|
472 return ETrue; |
|
473 } |
|
474 #endif // __WINSCW__ |
|
475 |
|
476 |
|
477 /** |
|
478 * There is no API for vibrate. Left to be customised according to each device |
|
479 * Printing InfoMsg for the user for the duration given to vibrate |
|
480 * Returns false in emulator builds as it does not support this feature. |
|
481 */ |
|
482 #if defined(__WINSCW__) |
|
483 TBool CMIDUtils::Vibrate(const TTimeIntervalMicroSeconds32& /*aDuration*/) |
|
484 { |
|
485 return EFalse; |
|
486 } |
|
487 #else // __WINSCW__ |
|
488 |
|
489 /** |
|
490 * There is no API for vibrate. Left to be customised according to each device |
|
491 * Printing InfoMsg for the user for the duration given to vibrate |
|
492 * Must return true if the vibrator can be controlled by the application |
|
493 */ |
|
494 TBool CMIDUtils::Vibrate(const TTimeIntervalMicroSeconds32& aDuration) |
|
495 { |
|
496 TInt duration = aDuration.Int() / 1000; // convert micro to milli |
|
497 |
|
498 // as this method can't leave, and only returns a boolean, we must |
|
499 // return false if anything goes wrong. |
|
500 |
|
501 if (!iVibra) |
|
502 { |
|
503 TRAPD(err1, iVibra = CHWRMVibra::NewL()); |
|
504 if (err1 != KErrNone) |
|
505 { |
|
506 return EFalse; |
|
507 } |
|
508 } |
|
509 |
|
510 TInt err2 = KErrNone; |
|
511 |
|
512 if (duration) |
|
513 { |
|
514 TRAP(err2, iVibra->StartVibraL(duration)); |
|
515 } |
|
516 else |
|
517 { |
|
518 TRAP(err2, iVibra->StopVibraL()); |
|
519 } |
|
520 |
|
521 if (err2 == KErrNone) |
|
522 { |
|
523 return ETrue; |
|
524 } |
|
525 else |
|
526 { |
|
527 return EFalse; |
|
528 } |
|
529 } |
|
530 #endif // __WINSCW__ |
|
531 |
|
532 /** |
|
533 * Mapping Java color type to Avkon-skinned color. |
|
534 */ |
|
535 TInt CMIDUtils::Color(TColorType aColorSpecifier) |
|
536 { |
|
537 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
538 TRgb rgbColor = 0; |
|
539 TInt result = KErrNone; |
|
540 |
|
541 // get skinned color |
|
542 switch (aColorSpecifier) |
|
543 { |
|
544 case EColorBackground: |
|
545 result = AknsUtils::GetCachedColor(skin, rgbColor, |
|
546 KAknsIIDQsnOtherColors, EAknsCIQsnOtherColorsCG10); |
|
547 break; |
|
548 case EColorForeground: |
|
549 result = AknsUtils::GetCachedColor(skin, rgbColor, |
|
550 KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6); |
|
551 break; |
|
552 case EColorHighlightedBackground: |
|
553 result = AknsUtils::GetCachedColor(skin, rgbColor, |
|
554 KAknsIIDQsnOtherColors, EAknsCIQsnOtherColorsCG14); |
|
555 break; |
|
556 case EColorHighlightedForeground: |
|
557 result = AknsUtils::GetCachedColor(skin, rgbColor, |
|
558 KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG10); |
|
559 break; |
|
560 case EColorBorder: |
|
561 result = AknsUtils::GetCachedColor(skin, rgbColor, |
|
562 KAknsIIDQsnOtherColors, EAknsCIQsnOtherColorsCG12); |
|
563 break; |
|
564 case EColorHighlightedBorder: |
|
565 result = AknsUtils::GetCachedColor(skin, rgbColor, |
|
566 KAknsIIDQsnOtherColors, EAknsCIQsnOtherColorsCG15); |
|
567 break; |
|
568 default: |
|
569 // wrong argument |
|
570 return KErrArgument; |
|
571 } |
|
572 |
|
573 // check result |
|
574 if (result == KErrNone) |
|
575 { |
|
576 return rgbColor.Red() << KRedBitsShift | |
|
577 rgbColor.Green() << KGreenBitsShift | |
|
578 rgbColor.Blue() << KBlueBitsShift; |
|
579 } |
|
580 else |
|
581 { |
|
582 // return black in case of some skinning related problem |
|
583 return 0; |
|
584 } |
|
585 } |
|
586 |
|
587 MMIDUtils::TGraphicsType CMIDUtils::BorderStyle(TBool aHighlighted) |
|
588 { |
|
589 return (aHighlighted) ? ESolid : EDotted; |
|
590 } |
|
591 |
|
592 /** |
|
593 * Return FontSpec for given Font Specifier, Font Spec is chosen for each specifier from exisiting. |
|
594 */ |
|
595 SFontSpec CMIDUtils::FontSpecifierSpecs(MMIDFont::TFontSpecifier aSpecifier) |
|
596 { |
|
597 SFontSpec fontSpec; |
|
598 |
|
599 if (aSpecifier == MMIDFont::EInputText) |
|
600 { |
|
601 fontSpec.iFace = MMIDFont::EProportional; |
|
602 fontSpec.iStyle = MMIDFont::EBold; |
|
603 fontSpec.iSize = MMIDFont::EMedium; |
|
604 } |
|
605 else |
|
606 { |
|
607 fontSpec.iFace = MMIDFont::EProportional; |
|
608 fontSpec.iStyle = MMIDFont::EPlain; |
|
609 fontSpec.iSize = MMIDFont::ESmall; |
|
610 } |
|
611 return fontSpec; |
|
612 } |
|
613 |
|
614 /** |
|
615 * Function fills aText descriptor with name of actual keyboard layout. |
|
616 * Keyboard layout is stored in central repository. Obtained TInt value |
|
617 * is mapped to descriptor: |
|
618 * 0 No Keyboard -> "None" |
|
619 * 1 Keyboard with 12 key -> "PhoneKeypad" |
|
620 * 2 QWERTY 4x12 layout -> "FullKeyboard" |
|
621 * 3 QWERTY 4x10 layout -> "LimitedKeyboard4x10" |
|
622 * 4 QWERTY 3 x 11 layout -> "LimitedKeyboard3x11" |
|
623 * 5 Half QWERTY -> "HalfKeyboard" |
|
624 * 6 Custom QWERTY -> "Custom" |
|
625 * In case of undefined value, aText is empty. |
|
626 */ |
|
627 void CMIDUtils::GetKeyboardTypeName(TDes* aText) |
|
628 { |
|
629 TInt keyboardType = 0; |
|
630 RProperty::Get(KCRUidAvkon, KAknKeyBoardLayout, keyboardType); |
|
631 |
|
632 aText->Zero(); //empty the descriptor |
|
633 switch (keyboardType) |
|
634 { |
|
635 case ENoKeyboard: //No Keyboard |
|
636 aText->Append(KKeyboardNone); |
|
637 break; |
|
638 case EKeyboardWith12Key: //Keyboard with 12 key |
|
639 aText->Append(KKeyboardPhoneKeypad); |
|
640 break; |
|
641 case EQWERTY4x12Layout: //QWERTY 4x12 layout |
|
642 aText->Append(KKeyboardFullKeyboard); |
|
643 break; |
|
644 case EQWERTY4x10Layout: //QWERTY 4x10 layout |
|
645 aText->Append(KKeyboardLimited4x10); |
|
646 break; |
|
647 case EQWERTY3x11Layout: //QWERTY 3 x 11 layout |
|
648 aText->Append(KKeyboardLimited3x11); |
|
649 break; |
|
650 case EHalfQWERTY: //Half QWERTY |
|
651 aText->Append(KKeyboardHalfKeyboard); |
|
652 break; |
|
653 case ECustomQWERTY: //Custom QWERTY |
|
654 aText->Append(KKeyboardCustom); |
|
655 break; |
|
656 default: |
|
657 aText->Append(KKeyboardUnknown); |
|
658 } |
|
659 } |
|
660 |
|
661 /** |
|
662 * Function sets the scan code of the latest key event. |
|
663 */ |
|
664 void CMIDUtils::SetLastKeyEvent(const TKeyEvent& aEvent) |
|
665 { |
|
666 iLastScanCode = aEvent.iScanCode; |
|
667 iModifier = aEvent.iModifiers; |
|
668 } |
|
669 |
|
670 /** |
|
671 * Function returns the scan code of the latest key event. |
|
672 */ |
|
673 TInt CMIDUtils::GetKeyScanCode() |
|
674 { |
|
675 return iLastScanCode; |
|
676 } |
|
677 |
|
678 /** |
|
679 * Function returns modifier value of the latest key event. |
|
680 */ |
|
681 TInt CMIDUtils::GetKeyModifier() |
|
682 { |
|
683 return iModifier; |
|
684 } |
|
685 |
|
686 void CMIDUtils::MappingDataForKey(TKeyEvent& aEvent, TEventCode aType) |
|
687 { |
|
688 if (!iQwertyMode) |
|
689 { |
|
690 return; |
|
691 } |
|
692 |
|
693 TBool issticky = iStickyHandler.HandleKey(aEvent, aType); |
|
694 |
|
695 TUint modifiers = iStickyHandler.Modifiers(); |
|
696 |
|
697 if (!issticky && modifiers == 0) |
|
698 { |
|
699 modifiers = aEvent.iModifiers; |
|
700 } |
|
701 if (!issticky && aType == EEventKeyUp) |
|
702 { |
|
703 iStickyHandler.Reset(); |
|
704 } |
|
705 |
|
706 |
|
707 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
708 TPtiTextCase textCase = EPtiCaseLower; |
|
709 |
|
710 if (modifiers & EModifierShift) |
|
711 { |
|
712 textCase = EPtiCaseUpper; |
|
713 } |
|
714 if (modifiers & EModifierRightFunc) |
|
715 {//EModifierRightFunc in Fn key |
|
716 textCase = EPtiCaseFnLower; |
|
717 } |
|
718 else if (modifiers & EModifierLeftFunc) |
|
719 { |
|
720 textCase = EPtiCaseChrLower; |
|
721 } |
|
722 |
|
723 //If Control key is held, don't use PtiEngine to map keyEvent.iCode |
|
724 if (modifiers & EModifierLeftCtrl || |
|
725 modifiers & EModifierRightCtrl) |
|
726 { |
|
727 iStickyHandler.Reset(); |
|
728 return; |
|
729 } |
|
730 |
|
731 TBuf<KPTIEngineResultSize> mapData; |
|
732 |
|
733 iPtiEngine->MappingDataForKey( |
|
734 (TPtiKey)aEvent.iScanCode, mapData, textCase); |
|
735 |
|
736 if (mapData.Length() > 0) |
|
737 { |
|
738 // set event code to the first mapped |
|
739 aEvent.iCode = mapData[0]; |
|
740 } |
|
741 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
742 |
|
743 } |
|
744 |
|
745 void CMIDUtils::UpdatePTIEngineStatusL() |
|
746 { |
|
747 |
|
748 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
749 |
|
750 RProperty::Get(KCRUidAvkon, KAknQwertyInputModeActive, iQwertyMode); |
|
751 |
|
752 // keyboard layout default value: 0 - No Keyboard |
|
753 TInt keyboardLayout = 0; |
|
754 // Read keyboard layout from central repository |
|
755 RProperty::Get(KCRUidAvkon, KAknKeyBoardLayout, keyboardLayout); |
|
756 |
|
757 TPtiEngineInputMode mode = EPtiEngineInputModeNone; |
|
758 switch (keyboardLayout) |
|
759 { |
|
760 case EPtiKeyboard12Key: |
|
761 mode = EPtiEngineMultitapping; |
|
762 #ifdef RD_JAVA_S60_RELEASE_5_0_IAD |
|
763 CallToJavaPtiVariationL(keyboardLayout); |
|
764 #else |
|
765 iPtiEngine->SetKeyboardType((TPtiKeyboardType)keyboardLayout); |
|
766 #endif |
|
767 break; |
|
768 case EPtiKeyboardQwerty4x12: |
|
769 case EPtiKeyboardQwerty4x10: |
|
770 case EPtiKeyboardQwerty3x11: |
|
771 #ifdef RD_JAVA_S60_RELEASE_5_0_IAD |
|
772 CallToJavaPtiVariationL(keyboardLayout); |
|
773 #else |
|
774 iPtiEngine->SetKeyboardType((TPtiKeyboardType)keyboardLayout); |
|
775 #endif |
|
776 mode = EPtiEngineQwerty; |
|
777 break; |
|
778 case EPtiKeyboardHalfQwerty: |
|
779 #ifdef RD_JAVA_S60_RELEASE_5_0_IAD |
|
780 CallToJavaPtiVariationL(keyboardLayout); |
|
781 #else |
|
782 iPtiEngine->SetKeyboardType((TPtiKeyboardType)keyboardLayout); |
|
783 #endif |
|
784 mode = EPtiEngineHalfQwerty; |
|
785 break; |
|
786 default: |
|
787 break; |
|
788 } |
|
789 // input language default value: 0 (automatic) |
|
790 TInt inputLang = 0; |
|
791 if (iRepository) |
|
792 { |
|
793 TInt ret = iRepository->Get(KAknFepInputTxtLang, inputLang); |
|
794 } |
|
795 |
|
796 // Change input language to western, if input language is Chinese |
|
797 // ELangPrcChinese - 31 |
|
798 // ELangTaiwanChinese - 29 |
|
799 // ELangHongKongChinese - 30 |
|
800 if (iQwertyMode) |
|
801 { |
|
802 if (inputLang == ELangPrcChinese || |
|
803 inputLang == ELangTaiwanChinese || |
|
804 inputLang == ELangHongKongChinese) |
|
805 { |
|
806 inputLang = ELangEnglish; |
|
807 } |
|
808 } |
|
809 TRAPD(err, iPtiEngine->ActivateLanguageL(inputLang, mode)); |
|
810 if (KErrNone != err) |
|
811 { |
|
812 DEBUG_INT("CMIDUtils::UpdatePTIEngineStatusL - ActivateLanguageL leaved with error = %d", err); |
|
813 return; |
|
814 } |
|
815 |
|
816 |
|
817 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
818 |
|
819 } |
|
820 |
|
821 |
|
822 void CMIDUtils::HandleResourceChangedL() |
|
823 { |
|
824 UpdatePTIEngineStatusL(); |
|
825 } |
|
826 |
|
827 void CMIDUtils::HandleForegroundL(TBool aForeground) |
|
828 { |
|
829 if (aForeground) |
|
830 { |
|
831 UpdatePTIEngineStatusL(); |
|
832 } |
|
833 } |
|
834 |
|
835 // --------------------------------------------------------------------------- |
|
836 // |
|
837 // --------------------------------------------------------------------------- |
|
838 // |
|
839 CMIDUtils::CMIDUtils(MMIDEnv& aEnv, CMIDUIManager* aUIManager) |
|
840 : iEnv(&aEnv) |
|
841 , iUIManager(aUIManager) |
|
842 , iScalingData() |
|
843 , iQwertyMode(EFalse) |
|
844 , iStickyKey(0) |
|
845 , iLastScanCode(0) |
|
846 , iModifier(0) |
|
847 {} |
|
848 |
|
849 CMIDUtils::~CMIDUtils() |
|
850 { |
|
851 delete iLight; |
|
852 delete iVibra; |
|
853 |
|
854 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
855 |
|
856 #ifdef RD_JAVA_S60_RELEASE_5_0_IAD |
|
857 iPtiSupportLib.Close(); |
|
858 #endif //RD_JAVA_S60_RELEASE_5_0_IAD |
|
859 |
|
860 delete iPtiEngine; |
|
861 iPtiEngine = NULL; |
|
862 |
|
863 delete iRepository; |
|
864 iRepository = NULL; |
|
865 #endif //RD_INTELLIGENT_TEXT_INPUT |
|
866 |
|
867 } |
|
868 |
|
869 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
870 #ifdef RD_JAVA_S60_RELEASE_5_0_IAD |
|
871 void CMIDUtils::CallToJavaPtiVariationL(TInt aType) |
|
872 { |
|
873 if (!iPtiSupportLib.Handle()) |
|
874 { |
|
875 _LIT(KLibName, "javaptivariation.dll"); |
|
876 iPtiSupportLib.Load(KLibName); |
|
877 } |
|
878 |
|
879 if (iPtiSupportLib.Handle()) |
|
880 { |
|
881 TJavaPtiVariationLibEntry libEntryL = (TJavaPtiVariationLibEntry)iPtiSupportLib.Lookup(1); |
|
882 libEntryL(*iPtiEngine, aType); |
|
883 } |
|
884 } |
|
885 #endif // RD_JAVA_S60_RELEASE_5_0_IAD |
|
886 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
887 |
|
888 // --------------------------------------------------------------------------- |
|
889 // |
|
890 // --------------------------------------------------------------------------- |
|
891 // |
|
892 void CMIDUtils::ConstructL() |
|
893 { |
|
894 ASSERT(iUIManager); |
|
895 iKeyDecoder = iUIManager->OpenKeyDecoderL(); |
|
896 iMenuHandler = iUIManager->GetMenuHandler(); |
|
897 |
|
898 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
899 iPtiEngine = CPtiEngine::NewL(ETrue); |
|
900 iRepository = CRepository::NewL(KCRUidAknFep); |
|
901 UpdatePTIEngineStatusL(); |
|
902 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
903 |
|
904 |
|
905 } |
|
906 |
|
907 TInt CMIDUtils::DoScaling(TInt aNonScaled, TInt aDirection) |
|
908 { |
|
909 DEBUG("TInt CMIDUtils::DoScaling(TInt aNonScaled, TInt aDirection)"); |
|
910 |
|
911 // initial value of return structure |
|
912 TInt scaled = aNonScaled; |
|
913 |
|
914 // get of all needed values for scaling |
|
915 TScalingData data = GetScalingData(); |
|
916 |
|
917 // scaling in entered direction |
|
918 // no scaling if direction is not valid |
|
919 if (aDirection == EHorizontal) |
|
920 { |
|
921 scaled *= data.iRatioX; |
|
922 } |
|
923 else if (aDirection == EVertical) |
|
924 { |
|
925 scaled *= data.iRatioY; |
|
926 } |
|
927 |
|
928 DEBUG_INT("DoScaling scaled %d", scaled); |
|
929 |
|
930 // return of scaled value |
|
931 return scaled; |
|
932 } |
|
933 |
|
934 TPoint CMIDUtils::DoScaling(TPoint aNonScaled) |
|
935 { |
|
936 DEBUG("TPoint CMIDUtils::DoScaling(TPoint aNonScaled)"); |
|
937 |
|
938 // initial value of return structure |
|
939 TPoint scaled = aNonScaled; |
|
940 |
|
941 // get of all needed values for scaling |
|
942 TScalingData data = GetScalingData(); |
|
943 |
|
944 // scaling of point |
|
945 scaled.iX *= data.iRatioX; |
|
946 scaled.iY *= data.iRatioY; |
|
947 |
|
948 DEBUG_INT2("DoScaling scaled %d %d", scaled.iX, scaled.iY); |
|
949 |
|
950 // return of scaled value |
|
951 return scaled; |
|
952 } |
|
953 |
|
954 TPoint CMIDUtils::DoScalingAndPositioning(TPoint aNonScaled) |
|
955 { |
|
956 DEBUG("TPoint CMIDUtils::DoScalingAndPositioning(TPoint aNonScaled)"); |
|
957 |
|
958 // initial value of return structure |
|
959 TPoint scaled = aNonScaled; |
|
960 |
|
961 // get of all needed values for scaling |
|
962 TScalingData data = GetScalingData(); |
|
963 |
|
964 // scaling of point |
|
965 scaled.iX *= data.iRatioX; |
|
966 scaled.iY *= data.iRatioY; |
|
967 |
|
968 // get of canvas origin |
|
969 TSize subtract = data.iScreenSize - data.iCanvasSize; |
|
970 TPoint canvasOrigin = TPoint(subtract.iWidth / 2, subtract.iHeight / 2); |
|
971 |
|
972 // move according to canvas origin |
|
973 scaled += canvasOrigin; |
|
974 |
|
975 DEBUG_INT2("DoScalingAndPositioning scaled %d %d", scaled.iX, scaled.iY); |
|
976 |
|
977 // return of scaled value |
|
978 return scaled; |
|
979 } |
|
980 |
|
981 TRect CMIDUtils::DoScaling(TRect aNonScaled) |
|
982 { |
|
983 DEBUG("TRect CMIDUtils::DoScaling(TRect aNonScaled)"); |
|
984 |
|
985 // initial value of return structure |
|
986 TRect scaled = aNonScaled; |
|
987 |
|
988 // get of all needed values for scaling |
|
989 TScalingData data= GetScalingData(); |
|
990 |
|
991 // scaling of rect |
|
992 scaled.iBr.iX *= data.iRatioX; |
|
993 scaled.iBr.iY *= data.iRatioY; |
|
994 scaled.iTl.iX *= data.iRatioX; |
|
995 scaled.iTl.iY *= data.iRatioY; |
|
996 |
|
997 DEBUG_INT4("DoScaling scaled %d %d", scaled.iBr.iX, scaled.iBr.iY, scaled.iTl.iX, scaled.iTl.iY); |
|
998 |
|
999 // return of scaled value |
|
1000 return scaled; |
|
1001 } |
|
1002 |
|
1003 TRect CMIDUtils::DoScalingAndPositioning(TRect aNonScaled) |
|
1004 { |
|
1005 DEBUG("TRect CMIDUtils::DoScalingAndPositioning(TRect aNonScaled)"); |
|
1006 |
|
1007 // initial value of return structure |
|
1008 TRect scaled = aNonScaled; |
|
1009 |
|
1010 // get of all needed values for scaling |
|
1011 TScalingData data = GetScalingData(); |
|
1012 |
|
1013 // scaling of rect |
|
1014 scaled.iBr.iX *= data.iRatioX; |
|
1015 scaled.iBr.iY *= data.iRatioY; |
|
1016 scaled.iTl.iX *= data.iRatioX; |
|
1017 scaled.iTl.iY *= data.iRatioY; |
|
1018 |
|
1019 // get of canvas origin |
|
1020 TSize subtract = data.iScreenSize - data.iCanvasSize; |
|
1021 TPoint canvasOrigin = TPoint(subtract.iWidth / 2, subtract.iHeight / 2); |
|
1022 |
|
1023 // move according to canvas origin |
|
1024 scaled.Move(canvasOrigin); |
|
1025 |
|
1026 DEBUG_INT4("DoScalingAndPositioning scaled %d %d", scaled.iBr.iX, scaled.iBr.iY, |
|
1027 scaled.iTl.iX, scaled.iTl.iY); |
|
1028 |
|
1029 // return of scaled value |
|
1030 return scaled; |
|
1031 } |
|
1032 |
|
1033 TSize CMIDUtils::DoScaling(TSize aNonScaled) |
|
1034 { |
|
1035 DEBUG("TSize CMIDUtils::DoScaling(TSize aNonScaled)"); |
|
1036 |
|
1037 // initial value of return structure |
|
1038 TSize scaled = aNonScaled; |
|
1039 |
|
1040 // get of all needed values for scaling |
|
1041 TScalingData data = GetScalingData(); |
|
1042 |
|
1043 // scaling of size |
|
1044 scaled.iWidth *= data.iRatioX; |
|
1045 scaled.iHeight *= data.iRatioY; |
|
1046 |
|
1047 DEBUG_INT2("DoScaling scaled %d %d", scaled.iWidth, scaled.iHeight); |
|
1048 |
|
1049 // return of scaled value |
|
1050 return scaled; |
|
1051 } |
|
1052 |
|
1053 TInt CMIDUtils::DoDescaling(TInt aNonScaled, TInt aDirection) |
|
1054 { |
|
1055 DEBUG("TInt CMIDUtils::DoDescaling(TInt aNonScaled, TInt aDirection)"); |
|
1056 |
|
1057 // initial value of return structure |
|
1058 TInt scaled = aNonScaled; |
|
1059 |
|
1060 // get of all needed values for scaling |
|
1061 TScalingData data = GetScalingData(); |
|
1062 |
|
1063 // descaling in entered direction |
|
1064 // no scaling if direction is not valid |
|
1065 if (aDirection == EHorizontal) |
|
1066 { |
|
1067 scaled /= data.iRatioX; |
|
1068 } |
|
1069 else if (aDirection == EVertical) |
|
1070 { |
|
1071 scaled /= data.iRatioY; |
|
1072 } |
|
1073 |
|
1074 DEBUG_INT("DoDescaling scaled %d", scaled); |
|
1075 |
|
1076 // return of descaled value |
|
1077 return scaled; |
|
1078 } |
|
1079 |
|
1080 TPoint CMIDUtils::DoDescaling(TPoint aNonScaled) |
|
1081 { |
|
1082 DEBUG("TPoint CMIDUtils::DoDescaling(TPoint aNonScaled)"); |
|
1083 |
|
1084 // initial value of return structure |
|
1085 TPoint scaled = aNonScaled; |
|
1086 |
|
1087 // get of all needed values for scaling |
|
1088 TScalingData data = GetScalingData(); |
|
1089 |
|
1090 // descaling of point |
|
1091 scaled.iX /= data.iRatioX; |
|
1092 scaled.iY /= data.iRatioY; |
|
1093 |
|
1094 DEBUG_INT2("DoDescaling scaled %d %d", scaled.iX, scaled.iY); |
|
1095 |
|
1096 // return of descaled value |
|
1097 return scaled; |
|
1098 } |
|
1099 |
|
1100 TPoint CMIDUtils::DoDescalingAndPositioning(TPoint aNonScaled) |
|
1101 { |
|
1102 DEBUG("TPoint CMIDUtils::DoDescalingAndPositioning(TPoint aNonScaled)"); |
|
1103 |
|
1104 // initial value of return structure |
|
1105 TPoint scaled = aNonScaled; |
|
1106 |
|
1107 // get of all needed values for scaling |
|
1108 TScalingData data = GetScalingData(); |
|
1109 |
|
1110 // get of canvas origin |
|
1111 TSize subtract = data.iScreenSize - data.iCanvasSize; |
|
1112 TPoint canvasOrigin = TPoint(subtract.iWidth / 2, subtract.iHeight / 2); |
|
1113 |
|
1114 // move according to canvas origin |
|
1115 scaled -= canvasOrigin; |
|
1116 |
|
1117 // descaling of point |
|
1118 scaled.iX /= data.iRatioX; |
|
1119 scaled.iY /= data.iRatioY; |
|
1120 |
|
1121 DEBUG_INT2("DoDescalingAndPositioning scaled %d %d", scaled.iX, scaled.iY); |
|
1122 |
|
1123 // return of descaled value |
|
1124 return scaled; |
|
1125 } |
|
1126 |
|
1127 TRect CMIDUtils::DoDescaling(TRect aNonScaled) |
|
1128 { |
|
1129 DEBUG("TRect CMIDUtils::DoDescaling(TRect aNonScaled)"); |
|
1130 |
|
1131 // initial value of return structure |
|
1132 TRect scaled = aNonScaled; |
|
1133 |
|
1134 // get of all needed values for scaling |
|
1135 TScalingData data = GetScalingData(); |
|
1136 |
|
1137 // descaling of rect |
|
1138 scaled.iBr.iX /= data.iRatioX; |
|
1139 scaled.iBr.iY /= data.iRatioY; |
|
1140 scaled.iTl.iX /= data.iRatioX; |
|
1141 scaled.iTl.iY /= data.iRatioY; |
|
1142 |
|
1143 DEBUG_INT4("DoDescaling scaled %d %d", scaled.iBr.iX, scaled.iBr.iY, scaled.iTl.iX, scaled.iTl.iY); |
|
1144 |
|
1145 // return of descaled value |
|
1146 return scaled; |
|
1147 } |
|
1148 |
|
1149 TRect CMIDUtils::DoDescalingAndPositioning(TRect aNonScaled) |
|
1150 { |
|
1151 DEBUG("TRect CMIDUtils::DoDescalingAndPositioning(TRect aNonScaled)"); |
|
1152 |
|
1153 // initial value of return structure |
|
1154 TRect scaled = aNonScaled; |
|
1155 |
|
1156 // get of all needed values for scaling |
|
1157 TScalingData data = GetScalingData(); |
|
1158 |
|
1159 // get of canvas origin |
|
1160 TSize subtract = data.iScreenSize - data.iCanvasSize; |
|
1161 TPoint canvasOrigin = TPoint(subtract.iWidth / 2, subtract.iHeight / 2); |
|
1162 |
|
1163 // move according to canvas origin |
|
1164 scaled.Move(-canvasOrigin); |
|
1165 |
|
1166 // descaling of rect |
|
1167 scaled.iBr.iX /= data.iRatioX; |
|
1168 scaled.iBr.iY /= data.iRatioY; |
|
1169 scaled.iTl.iX /= data.iRatioX; |
|
1170 scaled.iTl.iY /= data.iRatioY; |
|
1171 |
|
1172 DEBUG_INT4("DoDescalingAndPositioning scaled %d %d", scaled.iBr.iX, scaled.iBr.iY, scaled.iTl.iX, scaled.iTl.iY); |
|
1173 |
|
1174 // return of descaled value |
|
1175 return scaled; |
|
1176 } |
|
1177 |
|
1178 TSize CMIDUtils::DoDescaling(TSize aNonScaled) |
|
1179 { |
|
1180 DEBUG("TSize CMIDUtils::DoDescaling(TSize aNonScaled)"); |
|
1181 TSize scaled = aNonScaled; |
|
1182 |
|
1183 // get of all needed values for scaling |
|
1184 TScalingData data = GetScalingData(); |
|
1185 |
|
1186 // descaling of size |
|
1187 scaled.iWidth /= data.iRatioX; |
|
1188 scaled.iHeight /= data.iRatioY; |
|
1189 |
|
1190 DEBUG_INT2("DoDescaling scaled %d %d", scaled.iWidth, scaled.iHeight); |
|
1191 |
|
1192 // return of descaled value |
|
1193 return scaled; |
|
1194 } |
|
1195 |
|
1196 CMIDUtils::TScalingData CMIDUtils::GetScalingData() |
|
1197 { |
|
1198 // If iScalingData is not initialized, this method will initialized it. |
|
1199 if (iScalingData == TScalingData()) |
|
1200 { |
|
1201 // Create local instance of TScalingData |
|
1202 TScalingData data = TScalingData(); |
|
1203 |
|
1204 // Get actual rect of screen without with eventual OSK. |
|
1205 TRect screenRect =iEnv->Current()->GetCanvasRectFromLaf(); |
|
1206 |
|
1207 // Traslate of rect of screen into size |
|
1208 data.iScreenSize = screenRect.Size(); |
|
1209 |
|
1210 // Check if scaling is is on now. |
|
1211 if (iMenuHandler->IsScalingEffectiveInCurrentScreen()) |
|
1212 { |
|
1213 |
|
1214 // Get original and target size from JAD attributes |
|
1215 data.iOriginalSize = iMenuHandler->GetScalingParameterOrgMIDletScrSize(); |
|
1216 data.iTargetSize = iMenuHandler->GetScalingParameterTargetMIDletScrSize(); |
|
1217 |
|
1218 // Check if JAD attribute allows orientation change during scalling |
|
1219 // is present. If it is present, this switches orientation of original |
|
1220 // size, if it is needed. |
|
1221 if (iMenuHandler->GetScalingParameterScaleMIDletOnOrientSwitch()) |
|
1222 { |
|
1223 // portait |
|
1224 if (data.iScreenSize.iWidth < data.iScreenSize.iHeight) |
|
1225 { |
|
1226 data.iOriginalSize = TSize(Min(data.iOriginalSize.iHeight, |
|
1227 data.iOriginalSize.iWidth), |
|
1228 Max(data.iOriginalSize.iHeight, |
|
1229 data.iOriginalSize.iWidth)); |
|
1230 } |
|
1231 // landscape |
|
1232 else |
|
1233 { |
|
1234 data.iOriginalSize = TSize(Max(data.iOriginalSize.iHeight, |
|
1235 data.iOriginalSize.iWidth), |
|
1236 Min(data.iOriginalSize.iHeight, |
|
1237 data.iOriginalSize.iWidth)); |
|
1238 } |
|
1239 } |
|
1240 |
|
1241 } |
|
1242 |
|
1243 if (data.iTargetSize != TSize()) |
|
1244 { |
|
1245 // When target size is set, then possible horizontal and vertical |
|
1246 // scaling factor are various. And in this case canvas size is |
|
1247 // equal to target size. |
|
1248 data.iRatioX = (TReal) data.iTargetSize.iWidth / data.iOriginalSize.iWidth; |
|
1249 data.iRatioY = (TReal) data.iTargetSize.iHeight / data.iOriginalSize.iHeight; |
|
1250 data.iCanvasSize = data.iTargetSize; |
|
1251 } |
|
1252 else if (data.iOriginalSize != TSize()) |
|
1253 { |
|
1254 // When target size is not set, then only one scaling factor is present. |
|
1255 // It is smaller of horizontal and vertical scaling factors. |
|
1256 // And in this case canvas have size calculated according to |
|
1257 // the scaling factor. |
|
1258 data.iRatioX = (TReal) data.iScreenSize.iWidth / data.iOriginalSize.iWidth; |
|
1259 data.iRatioY = (TReal) data.iScreenSize.iHeight / data.iOriginalSize.iHeight; |
|
1260 TReal ratio = Min(data.iRatioX, data.iRatioY); |
|
1261 data.iRatioX = ratio; |
|
1262 data.iRatioY = ratio; |
|
1263 data.iCanvasSize = TSize(data.iOriginalSize.iWidth * ratio, |
|
1264 data.iOriginalSize.iHeight * ratio); |
|
1265 } |
|
1266 else |
|
1267 { |
|
1268 // When scaling is off, then canvas ocupied whole screen. |
|
1269 data.iCanvasSize = data.iScreenSize; |
|
1270 } |
|
1271 |
|
1272 // Set local variable to iScalingData |
|
1273 iScalingData = data; |
|
1274 } |
|
1275 |
|
1276 return iScalingData; |
|
1277 } |
|
1278 |
|
1279 void CMIDUtils::ResetScalingData() |
|
1280 { |
|
1281 // Firstly is needed set iScaling data to notinicialized value. |
|
1282 iScalingData = TScalingData(); |
|
1283 // Now we can set new scaling data. |
|
1284 iScalingData = GetScalingData(); |
|
1285 } |
|
1286 |
|
1287 // ============================ TStickyKeysHandler =========================== |
|
1288 |
|
1289 CMIDUtils::TStickyKeysHandler::TStickyKeysHandler() |
|
1290 { |
|
1291 ResetState(); |
|
1292 iFnKeyState = EKeyNotActive; |
|
1293 iShiftKeyState = EKeyNotActive; |
|
1294 } |
|
1295 |
|
1296 void CMIDUtils::TStickyKeysHandler::Reset() |
|
1297 { |
|
1298 ResetState(); |
|
1299 iStickyModifier = 0; |
|
1300 // When reseting state, we must take locked sticky keys into account |
|
1301 // If Fn is locked, then after reset Fn still must be added to midifiers |
|
1302 if (iFnKeyState == EKeyLocked) |
|
1303 { |
|
1304 AddFnToStickyModifiers(); |
|
1305 } |
|
1306 else |
|
1307 { |
|
1308 iFnKeyState = EKeyNotActive; |
|
1309 } |
|
1310 |
|
1311 // Fn has higher priority than shift, and only one sticky key might |
|
1312 // be locked at the time |
|
1313 // For half QWERTY we need to process also shift as a regular key when Fn is active |
|
1314 if (iFnKeyState == EKeyNotActive) |
|
1315 { |
|
1316 // Pre-setting shift |
|
1317 switch (iShiftKeyState) |
|
1318 { |
|
1319 case EKeyLocked: |
|
1320 // Shift is locked, so add modifier |
|
1321 AddShiftToStickyModifiers(); |
|
1322 break; |
|
1323 case EKeyActive: |
|
1324 // Shift wasn't locked |
|
1325 iShiftKeyState = EKeyNotActive; |
|
1326 break; |
|
1327 case EKeyNotActiveNext: |
|
1328 // Shift was locked, but should be deactivated for next keypress, |
|
1329 // so add it to modifiers... |
|
1330 AddShiftToStickyModifiers(); |
|
1331 // .. and move back to locked state |
|
1332 iShiftKeyState = EKeyLocked; |
|
1333 break; |
|
1334 default: |
|
1335 iShiftKeyState = EKeyNotActive; |
|
1336 break; |
|
1337 } |
|
1338 } |
|
1339 } |
|
1340 |
|
1341 TBool CMIDUtils::TStickyKeysHandler::HandleKey( |
|
1342 const TKeyEvent& aKeyEvent, TEventCode aType) |
|
1343 { |
|
1344 if (!IsSticky(aKeyEvent)) |
|
1345 { |
|
1346 // Check Fn key |
|
1347 if (aKeyEvent.iModifiers & EModifierRightFunc) |
|
1348 { |
|
1349 iStickyModifier = aKeyEvent.iModifiers; |
|
1350 } |
|
1351 ResetState(); |
|
1352 return EFalse; |
|
1353 } |
|
1354 |
|
1355 // Depending on sticky key state... |
|
1356 switch (iStickyKeyState) |
|
1357 { |
|
1358 case EKeyNotPressed: |
|
1359 // No sticky key was pressed |
|
1360 if (aType == EEventKeyDown) |
|
1361 { |
|
1362 // If key down event arrived, remember it's keycode and |
|
1363 // move to next state (sticky key pressed) |
|
1364 iLastStickyScanCode = aKeyEvent.iScanCode; |
|
1365 iStickyKeyState = EKeyWasPressed; |
|
1366 } |
|
1367 else |
|
1368 { |
|
1369 // Reset handler's state |
|
1370 Reset(); |
|
1371 } |
|
1372 break; |
|
1373 case EKeyWasPressed: |
|
1374 // Sticky key was pressed before |
|
1375 if (aType == EEventKeyUp) |
|
1376 { |
|
1377 // If same sticky key was released as pressed in previous state, |
|
1378 // move to the next state (sticky key released) |
|
1379 if (iLastStickyScanCode == aKeyEvent.iScanCode) |
|
1380 { |
|
1381 iStickyKeyState = EKeyWasReleased; |
|
1382 } |
|
1383 } |
|
1384 else |
|
1385 { |
|
1386 // Reset handler's state |
|
1387 Reset(); |
|
1388 } |
|
1389 break; |
|
1390 default: |
|
1391 Reset(); |
|
1392 break; |
|
1393 } |
|
1394 |
|
1395 TBool wasStickyKey = EFalse; |
|
1396 if (EKeyWasReleased == iStickyKeyState) |
|
1397 { |
|
1398 // Sticky key was pressed and released, so we need to get |
|
1399 // modifiers from scan code. |
|
1400 TUint modifier = ModifierFromScanCode(aKeyEvent.iScanCode); |
|
1401 |
|
1402 // Add/remove modifier to/from stored modifiers |
|
1403 if (iStickyModifier & modifier) |
|
1404 { |
|
1405 iStickyModifier &= ~modifier; |
|
1406 } |
|
1407 else |
|
1408 { |
|
1409 iStickyModifier |= modifier; |
|
1410 } |
|
1411 |
|
1412 ResetState(); |
|
1413 HandleLockableKeys(modifier); |
|
1414 wasStickyKey = ETrue; |
|
1415 } |
|
1416 |
|
1417 return wasStickyKey; |
|
1418 } |
|
1419 |
|
1420 TInt CMIDUtils::TStickyKeysHandler::Modifiers() const |
|
1421 { |
|
1422 return iStickyModifier; |
|
1423 } |
|
1424 |
|
1425 void CMIDUtils::TStickyKeysHandler::ResetState() |
|
1426 { |
|
1427 iLastStickyScanCode = 0; |
|
1428 iStickyKeyState = EKeyNotPressed; |
|
1429 } |
|
1430 |
|
1431 TUint CMIDUtils::TStickyKeysHandler::ModifierFromScanCode(TInt aScanCode) |
|
1432 { |
|
1433 switch (aScanCode) |
|
1434 { |
|
1435 case EStdKeyLeftShift: |
|
1436 return EModifierShift | EModifierLeftShift; |
|
1437 case EStdKeyRightShift: |
|
1438 return EModifierShift | EModifierRightShift; |
|
1439 case EStdKeyLeftAlt: |
|
1440 return EModifierAlt | EModifierLeftAlt; |
|
1441 case EStdKeyRightAlt: |
|
1442 return EModifierAlt | EModifierRightAlt; |
|
1443 case EStdKeyLeftCtrl: |
|
1444 return EModifierCtrl | EModifierLeftCtrl; |
|
1445 case EStdKeyRightCtrl: |
|
1446 return EModifierCtrl | EModifierRightCtrl; |
|
1447 case EStdKeyLeftFunc: |
|
1448 return EModifierLeftFunc; |
|
1449 case EStdKeyRightFunc: |
|
1450 return EModifierFunc | EModifierRightFunc; |
|
1451 default: |
|
1452 return 0; |
|
1453 } |
|
1454 } |
|
1455 |
|
1456 |
|
1457 TBool CMIDUtils::TStickyKeysHandler::IsSticky(const TKeyEvent& aKeyEvent) |
|
1458 { |
|
1459 TBool isStickyKey = EFalse; |
|
1460 switch (aKeyEvent.iScanCode) |
|
1461 { |
|
1462 case EStdKeyLeftFunc: |
|
1463 case EStdKeyLeftShift: |
|
1464 case EStdKeyRightShift: |
|
1465 isStickyKey = !IsFnModifierOn(iStickyModifier) && |
|
1466 !(aKeyEvent.iModifiers & EModifierRightFunc); |
|
1467 break; |
|
1468 case EStdKeyLeftAlt: |
|
1469 case EStdKeyRightAlt: |
|
1470 case EStdKeyLeftCtrl: |
|
1471 case EStdKeyRightCtrl: |
|
1472 case EStdKeyRightFunc: |
|
1473 isStickyKey = ETrue; |
|
1474 break; |
|
1475 default: |
|
1476 break; |
|
1477 } |
|
1478 |
|
1479 return isStickyKey; |
|
1480 } |
|
1481 |
|
1482 void CMIDUtils::TStickyKeysHandler::HandleLockableKeys(TUint aModifiers) |
|
1483 { |
|
1484 if (IsFnModifierOn(aModifiers)) |
|
1485 { |
|
1486 iActualFnModifierValue = 0; |
|
1487 if (aModifiers & EModifierLeftFunc) |
|
1488 { |
|
1489 iActualFnModifierValue = EModifierLeftFunc; |
|
1490 } |
|
1491 if (aModifiers & EModifierRightFunc) |
|
1492 { |
|
1493 iActualFnModifierValue = EModifierRightFunc; |
|
1494 } |
|
1495 HandleFnKey(); |
|
1496 } |
|
1497 |
|
1498 if (IsShiftModifierOn(aModifiers)) |
|
1499 { |
|
1500 iActualShiftModifierValue = 0; |
|
1501 if (aModifiers & EModifierLeftShift) |
|
1502 { |
|
1503 iActualShiftModifierValue = EModifierLeftShift; |
|
1504 } |
|
1505 if (aModifiers & EModifierRightShift) |
|
1506 { |
|
1507 iActualShiftModifierValue = EModifierRightShift; |
|
1508 } |
|
1509 HandleShiftKey(); |
|
1510 } |
|
1511 } |
|
1512 |
|
1513 /** |
|
1514 * Handle event with modifier of Fn key |
|
1515 */ |
|
1516 void CMIDUtils::TStickyKeysHandler::HandleFnKey() |
|
1517 { |
|
1518 switch (iFnKeyState) |
|
1519 { |
|
1520 case EKeyNotActive: |
|
1521 iFnKeyState = EKeyActive; |
|
1522 break; |
|
1523 case EKeyActive: |
|
1524 iFnKeyState = EKeyLocked; |
|
1525 AddFnToStickyModifiers(); |
|
1526 break; |
|
1527 case EKeyLocked: |
|
1528 iFnKeyState = EKeyNotActive; |
|
1529 // If Fn lock is disabled, also disable Shift lock. |
|
1530 iShiftKeyState = EKeyNotActive; |
|
1531 Reset(); |
|
1532 break; |
|
1533 } |
|
1534 } |
|
1535 |
|
1536 /** |
|
1537 * Handle event with modifier of Shift key |
|
1538 */ |
|
1539 void CMIDUtils::TStickyKeysHandler::HandleShiftKey() |
|
1540 { |
|
1541 switch (iShiftKeyState) |
|
1542 { |
|
1543 case EKeyNotActive: |
|
1544 iShiftKeyState = EKeyActive; |
|
1545 break; |
|
1546 case EKeyActive: |
|
1547 iShiftKeyState = EKeyLocked; |
|
1548 AddShiftToStickyModifiers(); |
|
1549 break; |
|
1550 case EKeyLocked: |
|
1551 iStickyModifier = 0; |
|
1552 if (iFnKeyState == EKeyLocked) |
|
1553 { |
|
1554 AddFnToStickyModifiers(); |
|
1555 } |
|
1556 iShiftKeyState = EKeyNotActiveNext; |
|
1557 break; |
|
1558 case EKeyNotActiveNext: |
|
1559 iShiftKeyState = EKeyNotActive; |
|
1560 Reset(); |
|
1561 break; |
|
1562 } |
|
1563 } |
|
1564 |
|
1565 void CMIDUtils::TStickyKeysHandler::AddShiftToStickyModifiers() |
|
1566 { |
|
1567 iStickyModifier |= EModifierShift | iActualShiftModifierValue; |
|
1568 } |
|
1569 |
|
1570 void CMIDUtils::TStickyKeysHandler::AddFnToStickyModifiers() |
|
1571 { |
|
1572 //Chr key (EModifierLeftFunc) is not handled as sticky key because |
|
1573 //it should not function in any special way |
|
1574 if (iActualFnModifierValue != EModifierLeftFunc) |
|
1575 { |
|
1576 iStickyModifier |= EModifierFunc | iActualFnModifierValue; |
|
1577 } |
|
1578 } |
|
1579 |
|
1580 inline TBool CMIDUtils::TStickyKeysHandler::IsFnModifierOn( |
|
1581 const TUint aModifiers) const |
|
1582 { |
|
1583 return aModifiers & EModifierFunc || |
|
1584 aModifiers & EModifierRightFunc; |
|
1585 } |
|
1586 |
|
1587 |
|
1588 inline TBool CMIDUtils::TStickyKeysHandler::IsShiftModifierOn( |
|
1589 const TUint aModifiers) const |
|
1590 { |
|
1591 return aModifiers & EModifierShift || |
|
1592 aModifiers & EModifierLeftShift || |
|
1593 aModifiers & EModifierRightShift; |
|
1594 } |
|
1595 |
|
1596 // End of File |