|
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 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
707 TPtiTextCase textCase = EPtiCaseLower; |
|
708 |
|
709 if (modifiers & EModifierShift) |
|
710 { |
|
711 textCase = EPtiCaseUpper; |
|
712 } |
|
713 if (modifiers & EModifierRightFunc) |
|
714 { |
|
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 #ifdef RD_JAVA_S60_RELEASE_9_2 |
|
734 // Set keyboard type/layout just before mapping the key |
|
735 TRAPD(err, SetPtiKeyboardL()); |
|
736 if (err != KErrNone) |
|
737 { |
|
738 DEBUG_INT("CMIDUtils::MappingDataForKey - SetPtiKeyboardL leaved with error = %d", err); |
|
739 } |
|
740 #endif // RD_JAVA_S60_RELEASE_9_2 |
|
741 |
|
742 iPtiEngine->MappingDataForKey( |
|
743 (TPtiKey)aEvent.iScanCode, mapData, textCase); |
|
744 |
|
745 if (mapData.Length() > 0) |
|
746 { |
|
747 // set event code to the first mapped |
|
748 aEvent.iCode = mapData[0]; |
|
749 } |
|
750 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
751 } |
|
752 |
|
753 void CMIDUtils::UpdatePTIEngineStatusL() |
|
754 { |
|
755 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
756 RProperty::Get(KCRUidAvkon, KAknQwertyInputModeActive, iQwertyMode); |
|
757 |
|
758 // Read keyboard layout from central repository |
|
759 RProperty::Get(KCRUidAvkon, KAknKeyBoardLayout, iPtiKeyboardType); |
|
760 SetPtiKeyboardL(); |
|
761 |
|
762 TPtiEngineInputMode mode = EPtiEngineInputModeNone; |
|
763 switch (iPtiKeyboardType) |
|
764 { |
|
765 case EPtiKeyboard12Key: |
|
766 mode = EPtiEngineMultitapping; |
|
767 break; |
|
768 case EPtiKeyboardQwerty4x12: |
|
769 case EPtiKeyboardQwerty4x10: |
|
770 case EPtiKeyboardQwerty3x11: |
|
771 mode = EPtiEngineQwerty; |
|
772 break; |
|
773 case EPtiKeyboardHalfQwerty: |
|
774 mode = EPtiEngineHalfQwerty; |
|
775 break; |
|
776 default: |
|
777 break; |
|
778 } |
|
779 |
|
780 // input language default value: 0 (automatic) |
|
781 TInt inputLang = 0; |
|
782 if (iRepository) |
|
783 { |
|
784 TInt ret = iRepository->Get(KAknFepInputTxtLang, inputLang); |
|
785 } |
|
786 |
|
787 // Change input language to western, if input language is Chinese |
|
788 // ELangPrcChinese - 31 |
|
789 // ELangTaiwanChinese - 29 |
|
790 // ELangHongKongChinese - 30 |
|
791 if (iQwertyMode) |
|
792 { |
|
793 if (inputLang == ELangPrcChinese || |
|
794 inputLang == ELangTaiwanChinese || |
|
795 inputLang == ELangHongKongChinese) |
|
796 { |
|
797 inputLang = ELangEnglish; |
|
798 } |
|
799 } |
|
800 |
|
801 TRAPD(err, iPtiEngine->ActivateLanguageL(inputLang, mode)); |
|
802 if (KErrNone != err) |
|
803 { |
|
804 DEBUG_INT("CMIDUtils::UpdatePTIEngineStatusL - ActivateLanguageL leaved with error = %d", err); |
|
805 return; |
|
806 } |
|
807 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
808 } |
|
809 |
|
810 void CMIDUtils::HandleResourceChangedL() |
|
811 { |
|
812 UpdatePTIEngineStatusL(); |
|
813 } |
|
814 |
|
815 void CMIDUtils::HandleForegroundL(TBool aForeground) |
|
816 { |
|
817 if (aForeground) |
|
818 { |
|
819 UpdatePTIEngineStatusL(); |
|
820 } |
|
821 } |
|
822 |
|
823 // --------------------------------------------------------------------------- |
|
824 // |
|
825 // --------------------------------------------------------------------------- |
|
826 // |
|
827 CMIDUtils::CMIDUtils(MMIDEnv& aEnv, CMIDUIManager* aUIManager) |
|
828 : iEnv(&aEnv) |
|
829 , iUIManager(aUIManager) |
|
830 , iScalingData() |
|
831 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
832 , iPtiKeyboardType(EPtiKeyboardNone) |
|
833 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
834 , iQwertyMode(EFalse) |
|
835 , iStickyKey(0) |
|
836 , iLastScanCode(0) |
|
837 , iModifier(0) |
|
838 , iScalingDataInitialized(EFalse) |
|
839 {} |
|
840 |
|
841 CMIDUtils::~CMIDUtils() |
|
842 { |
|
843 delete iLight; |
|
844 delete iVibra; |
|
845 |
|
846 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
847 |
|
848 #ifdef RD_JAVA_S60_RELEASE_5_0_IAD |
|
849 iPtiSupportLib.Close(); |
|
850 #endif //RD_JAVA_S60_RELEASE_5_0_IAD |
|
851 |
|
852 delete iPtiEngine; |
|
853 iPtiEngine = NULL; |
|
854 |
|
855 delete iRepository; |
|
856 iRepository = NULL; |
|
857 #endif //RD_INTELLIGENT_TEXT_INPUT |
|
858 } |
|
859 |
|
860 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
861 #ifdef RD_JAVA_S60_RELEASE_5_0_IAD |
|
862 void CMIDUtils::CallToJavaPtiVariationL(TInt aType) |
|
863 { |
|
864 if (!iPtiSupportLib.Handle()) |
|
865 { |
|
866 _LIT(KLibName, "javaptivariation.dll"); |
|
867 iPtiSupportLib.Load(KLibName); |
|
868 } |
|
869 |
|
870 if (iPtiSupportLib.Handle()) |
|
871 { |
|
872 TJavaPtiVariationLibEntry libEntryL = (TJavaPtiVariationLibEntry)iPtiSupportLib.Lookup(1); |
|
873 libEntryL(*iPtiEngine, aType); |
|
874 } |
|
875 } |
|
876 #endif // RD_JAVA_S60_RELEASE_5_0_IAD |
|
877 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
878 |
|
879 // --------------------------------------------------------------------------- |
|
880 // |
|
881 // --------------------------------------------------------------------------- |
|
882 // |
|
883 void CMIDUtils::ConstructL() |
|
884 { |
|
885 ASSERT(iUIManager); |
|
886 iKeyDecoder = iUIManager->OpenKeyDecoderL(); |
|
887 iMenuHandler = iUIManager->GetMenuHandler(); |
|
888 |
|
889 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
890 iPtiEngine = CPtiEngine::NewL(ETrue); |
|
891 iRepository = CRepository::NewL(KCRUidAknFep); |
|
892 UpdatePTIEngineStatusL(); |
|
893 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
894 |
|
895 |
|
896 } |
|
897 |
|
898 TInt CMIDUtils::DoScaling(TInt aNonScaled, TInt aDirection) |
|
899 { |
|
900 DEBUG("TInt CMIDUtils::DoScaling(TInt aNonScaled, TInt aDirection)"); |
|
901 |
|
902 // initial value of return structure |
|
903 TInt scaled = aNonScaled; |
|
904 |
|
905 // get of all needed values for scaling |
|
906 TScalingData data = GetScalingData(); |
|
907 |
|
908 // scaling in entered direction |
|
909 // no scaling if direction is not valid |
|
910 if (aDirection == EHorizontal) |
|
911 { |
|
912 scaled *= data.iRatioX; |
|
913 } |
|
914 else if (aDirection == EVertical) |
|
915 { |
|
916 scaled *= data.iRatioY; |
|
917 } |
|
918 |
|
919 DEBUG_INT("DoScaling processed %d", scaled); |
|
920 |
|
921 // return of scaled value |
|
922 return scaled; |
|
923 } |
|
924 |
|
925 TPoint CMIDUtils::DoScaling(TPoint aNonScaled) |
|
926 { |
|
927 DEBUG("TPoint CMIDUtils::DoScaling(TPoint aNonScaled)"); |
|
928 |
|
929 // initial value of return structure |
|
930 TPoint scaled = aNonScaled; |
|
931 |
|
932 // get of all needed values for scaling |
|
933 TScalingData data = GetScalingData(); |
|
934 |
|
935 // scaling of point |
|
936 scaled.iX *= data.iRatioX; |
|
937 scaled.iY *= data.iRatioY; |
|
938 |
|
939 DEBUG_INT2("DoScaling processed %d %d", scaled.iX, scaled.iY); |
|
940 |
|
941 // return of scaled value |
|
942 return scaled; |
|
943 } |
|
944 |
|
945 TPoint CMIDUtils::DoScalingAndPositioning(TPoint aNonScaled) |
|
946 { |
|
947 DEBUG("TPoint CMIDUtils::DoScalingAndPositioning(TPoint aNonScaled)"); |
|
948 |
|
949 // initial value of return structure |
|
950 TPoint scaled = aNonScaled; |
|
951 |
|
952 // get of all needed values for scaling |
|
953 TScalingData data = GetScalingData(); |
|
954 |
|
955 // scaling of point |
|
956 scaled.iX *= data.iRatioX; |
|
957 scaled.iY *= data.iRatioY; |
|
958 |
|
959 // get of canvas origin |
|
960 TSize subtract = data.iScreenSize - data.iCanvasSize; |
|
961 TPoint canvasOrigin = TPoint(subtract.iWidth / 2, subtract.iHeight / 2); |
|
962 |
|
963 // move according to canvas origin |
|
964 scaled += canvasOrigin; |
|
965 |
|
966 DEBUG_INT2("DoScalingAndPositioning processed %d %d", |
|
967 scaled.iX, scaled.iY); |
|
968 |
|
969 // return of scaled value |
|
970 return scaled; |
|
971 } |
|
972 |
|
973 TRect CMIDUtils::DoScaling(TRect aNonScaled) |
|
974 { |
|
975 DEBUG("TRect CMIDUtils::DoScaling(TRect aNonScaled)"); |
|
976 |
|
977 // initial value of return structure |
|
978 TRect scaled = aNonScaled; |
|
979 |
|
980 // get of all needed values for scaling |
|
981 TScalingData data= GetScalingData(); |
|
982 |
|
983 // scaling of rect |
|
984 scaled.iBr.iX *= data.iRatioX; |
|
985 scaled.iBr.iY *= data.iRatioY; |
|
986 scaled.iTl.iX *= data.iRatioX; |
|
987 scaled.iTl.iY *= data.iRatioY; |
|
988 |
|
989 DEBUG_INT4("DoScaling processed %d %d", |
|
990 scaled.iBr.iX, scaled.iBr.iY, scaled.iTl.iX, scaled.iTl.iY); |
|
991 |
|
992 // return of scaled value |
|
993 return scaled; |
|
994 } |
|
995 |
|
996 TRect CMIDUtils::DoScalingAndPositioning(TRect aNonScaled) |
|
997 { |
|
998 DEBUG("TRect CMIDUtils::DoScalingAndPositioning(TRect aNonScaled)"); |
|
999 |
|
1000 // initial value of return structure |
|
1001 TRect scaled = aNonScaled; |
|
1002 |
|
1003 // get of all needed values for scaling |
|
1004 TScalingData data = GetScalingData(); |
|
1005 |
|
1006 // scaling of rect |
|
1007 scaled.iBr.iX *= data.iRatioX; |
|
1008 scaled.iBr.iY *= data.iRatioY; |
|
1009 scaled.iTl.iX *= data.iRatioX; |
|
1010 scaled.iTl.iY *= data.iRatioY; |
|
1011 |
|
1012 // get of canvas origin |
|
1013 TSize subtract = data.iScreenSize - data.iCanvasSize; |
|
1014 TPoint canvasOrigin = TPoint(subtract.iWidth / 2, subtract.iHeight / 2); |
|
1015 |
|
1016 // move according to canvas origin |
|
1017 scaled.Move(canvasOrigin); |
|
1018 |
|
1019 DEBUG_INT4("DoScalingAndPositioning processed %d %d", |
|
1020 scaled.iBr.iX, scaled.iBr.iY, scaled.iTl.iX, scaled.iTl.iY); |
|
1021 |
|
1022 // return of scaled value |
|
1023 return scaled; |
|
1024 } |
|
1025 |
|
1026 TSize CMIDUtils::DoScaling(TSize aNonScaled) |
|
1027 { |
|
1028 DEBUG("TSize CMIDUtils::DoScaling(TSize aNonScaled)"); |
|
1029 |
|
1030 // initial value of return structure |
|
1031 TSize scaled = aNonScaled; |
|
1032 |
|
1033 // get of all needed values for scaling |
|
1034 TScalingData data = GetScalingData(); |
|
1035 |
|
1036 // scaling of size |
|
1037 scaled.iWidth *= data.iRatioX; |
|
1038 scaled.iHeight *= data.iRatioY; |
|
1039 |
|
1040 DEBUG_INT2("DoScaling processed %d %d", scaled.iWidth, scaled.iHeight); |
|
1041 |
|
1042 // return of scaled value |
|
1043 return scaled; |
|
1044 } |
|
1045 |
|
1046 TInt CMIDUtils::DoDescaling(TInt aNonScaled, TInt aDirection) |
|
1047 { |
|
1048 DEBUG("TInt CMIDUtils::DoDescaling(TInt aNonScaled, TInt aDirection)"); |
|
1049 |
|
1050 // initial value of return structure |
|
1051 TInt scaled = aNonScaled; |
|
1052 |
|
1053 // get of all needed values for scaling |
|
1054 TScalingData data = GetScalingData(); |
|
1055 |
|
1056 // descaling in entered direction |
|
1057 // no scaling if direction is not valid |
|
1058 if (aDirection == EHorizontal) |
|
1059 { |
|
1060 scaled /= data.iRatioX; |
|
1061 } |
|
1062 else if (aDirection == EVertical) |
|
1063 { |
|
1064 scaled /= data.iRatioY; |
|
1065 } |
|
1066 |
|
1067 DEBUG_INT("DoDescaling processed %d", scaled); |
|
1068 |
|
1069 // return of descaled value |
|
1070 return scaled; |
|
1071 } |
|
1072 |
|
1073 TPoint CMIDUtils::DoDescaling(TPoint aNonScaled) |
|
1074 { |
|
1075 DEBUG("TPoint CMIDUtils::DoDescaling(TPoint aNonScaled)"); |
|
1076 |
|
1077 // initial value of return structure |
|
1078 TPoint scaled = aNonScaled; |
|
1079 |
|
1080 // get of all needed values for scaling |
|
1081 TScalingData data = GetScalingData(); |
|
1082 |
|
1083 // descaling of point |
|
1084 scaled.iX /= data.iRatioX; |
|
1085 scaled.iY /= data.iRatioY; |
|
1086 |
|
1087 DEBUG_INT2("DoDescaling processed %d %d", scaled.iX, scaled.iY); |
|
1088 |
|
1089 // return of descaled value |
|
1090 return scaled; |
|
1091 } |
|
1092 |
|
1093 TPoint CMIDUtils::DoDescalingAndPositioning(TPoint aNonScaled) |
|
1094 { |
|
1095 DEBUG("TPoint CMIDUtils::DoDescalingAndPositioning(TPoint aNonScaled)"); |
|
1096 |
|
1097 // initial value of return structure |
|
1098 TPoint scaled = aNonScaled; |
|
1099 |
|
1100 // get of all needed values for scaling |
|
1101 TScalingData data = GetScalingData(); |
|
1102 |
|
1103 // get of canvas origin |
|
1104 TSize subtract = data.iScreenSize - data.iCanvasSize; |
|
1105 TPoint canvasOrigin = TPoint(subtract.iWidth / 2, subtract.iHeight / 2); |
|
1106 |
|
1107 // move according to canvas origin |
|
1108 scaled -= canvasOrigin; |
|
1109 |
|
1110 // descaling of point |
|
1111 scaled.iX /= data.iRatioX; |
|
1112 scaled.iY /= data.iRatioY; |
|
1113 |
|
1114 DEBUG_INT2("DoDescalingAndPositioning processed %d %d", |
|
1115 scaled.iX, scaled.iY); |
|
1116 |
|
1117 // return of descaled value |
|
1118 return scaled; |
|
1119 } |
|
1120 |
|
1121 TRect CMIDUtils::DoDescaling(TRect aNonScaled) |
|
1122 { |
|
1123 DEBUG("TRect CMIDUtils::DoDescaling(TRect aNonScaled)"); |
|
1124 |
|
1125 // initial value of return structure |
|
1126 TRect scaled = aNonScaled; |
|
1127 |
|
1128 // get of all needed values for scaling |
|
1129 TScalingData data = GetScalingData(); |
|
1130 |
|
1131 // descaling of rect |
|
1132 scaled.iBr.iX /= data.iRatioX; |
|
1133 scaled.iBr.iY /= data.iRatioY; |
|
1134 scaled.iTl.iX /= data.iRatioX; |
|
1135 scaled.iTl.iY /= data.iRatioY; |
|
1136 |
|
1137 DEBUG_INT4("DoDescaling processed %d %d", |
|
1138 scaled.iBr.iX, scaled.iBr.iY, scaled.iTl.iX, scaled.iTl.iY); |
|
1139 |
|
1140 // return of descaled value |
|
1141 return scaled; |
|
1142 } |
|
1143 |
|
1144 TRect CMIDUtils::DoDescalingAndPositioning(TRect aNonScaled) |
|
1145 { |
|
1146 DEBUG("TRect CMIDUtils::DoDescalingAndPositioning(TRect aNonScaled)"); |
|
1147 |
|
1148 // initial value of return structure |
|
1149 TRect scaled = aNonScaled; |
|
1150 |
|
1151 // get of all needed values for scaling |
|
1152 TScalingData data = GetScalingData(); |
|
1153 |
|
1154 // get of canvas origin |
|
1155 TSize subtract = data.iScreenSize - data.iCanvasSize; |
|
1156 TPoint canvasOrigin = TPoint(subtract.iWidth / 2, subtract.iHeight / 2); |
|
1157 |
|
1158 // move according to canvas origin |
|
1159 scaled.Move(-canvasOrigin); |
|
1160 |
|
1161 // descaling of rect |
|
1162 scaled.iBr.iX /= data.iRatioX; |
|
1163 scaled.iBr.iY /= data.iRatioY; |
|
1164 scaled.iTl.iX /= data.iRatioX; |
|
1165 scaled.iTl.iY /= data.iRatioY; |
|
1166 |
|
1167 DEBUG_INT4("DoDescalingAndPositioning processed %d %d", |
|
1168 scaled.iBr.iX, scaled.iBr.iY, scaled.iTl.iX, scaled.iTl.iY); |
|
1169 |
|
1170 // return of descaled value |
|
1171 return scaled; |
|
1172 } |
|
1173 |
|
1174 TSize CMIDUtils::DoDescaling(TSize aNonScaled) |
|
1175 { |
|
1176 DEBUG("TSize CMIDUtils::DoDescaling(TSize aNonScaled)"); |
|
1177 TSize scaled = aNonScaled; |
|
1178 |
|
1179 // get of all needed values for scaling |
|
1180 TScalingData data = GetScalingData(); |
|
1181 |
|
1182 // descaling of size |
|
1183 scaled.iWidth /= data.iRatioX; |
|
1184 scaled.iHeight /= data.iRatioY; |
|
1185 |
|
1186 DEBUG_INT2("DoDescaling processed %d %d", scaled.iWidth, scaled.iHeight); |
|
1187 |
|
1188 // return of descaled value |
|
1189 return scaled; |
|
1190 } |
|
1191 |
|
1192 CMIDUtils::TScalingData CMIDUtils::GetScalingData() |
|
1193 { |
|
1194 UpdateScalingData(); |
|
1195 return iScalingData; |
|
1196 } |
|
1197 |
|
1198 void CMIDUtils::UpdateScalingData() |
|
1199 { |
|
1200 // Create local instance of TScalingData |
|
1201 TScalingData data = TScalingData(); |
|
1202 |
|
1203 // |
|
1204 iScalingDataInitialized = ETrue; |
|
1205 |
|
1206 // Get actual rect of screen without with eventual OSK. |
|
1207 // Empty rect is OK. |
|
1208 MMIDDisplayable* current = iEnv->Current(); |
|
1209 TRect screenRect; |
|
1210 if (current) |
|
1211 { |
|
1212 screenRect = current->GetCanvasRectFromLaf(); |
|
1213 } |
|
1214 else |
|
1215 { |
|
1216 // No displayable is current. It will be initialized in other time. |
|
1217 iScalingDataInitialized=EFalse; |
|
1218 return; |
|
1219 } |
|
1220 |
|
1221 // Traslate of rect of screen into size |
|
1222 data.iScreenSize = screenRect.Size(); |
|
1223 |
|
1224 // Check if scaling is ON now. |
|
1225 if (iMenuHandler->IsScalingEnabled()) |
|
1226 { |
|
1227 |
|
1228 // Get original and target size from JAD attributes |
|
1229 data.iOriginalSize = iMenuHandler->GetScalingParameterOrgMIDletScrSize(); |
|
1230 data.iTargetSize = iMenuHandler->GetScalingParameterTargetMIDletScrSize(); |
|
1231 |
|
1232 // Check if JAD attribute allows orientation change during scalling |
|
1233 // is present. If it is present, this switches orientation of original |
|
1234 // size, if it is needed. |
|
1235 if (iMenuHandler->GetScalingParameterScaleMIDletOnOrientSwitch()) |
|
1236 { |
|
1237 // portait |
|
1238 if (data.iScreenSize.iWidth < data.iScreenSize.iHeight) |
|
1239 { |
|
1240 data.iOriginalSize = TSize(Min(data.iOriginalSize.iHeight, |
|
1241 data.iOriginalSize.iWidth), |
|
1242 Max(data.iOriginalSize.iHeight, |
|
1243 data.iOriginalSize.iWidth)); |
|
1244 } |
|
1245 // landscape |
|
1246 else |
|
1247 { |
|
1248 data.iOriginalSize = TSize(Max(data.iOriginalSize.iHeight, |
|
1249 data.iOriginalSize.iWidth), |
|
1250 Min(data.iOriginalSize.iHeight, |
|
1251 data.iOriginalSize.iWidth)); |
|
1252 } |
|
1253 } |
|
1254 |
|
1255 } |
|
1256 |
|
1257 if (data.iTargetSize != TSize()) |
|
1258 { |
|
1259 // When target size is set, then possible horizontal and vertical |
|
1260 // scaling factor are various. And in this case canvas size is |
|
1261 // equal to target size. |
|
1262 data.iRatioX = (TReal) data.iTargetSize.iWidth / data.iOriginalSize.iWidth; |
|
1263 data.iRatioY = (TReal) data.iTargetSize.iHeight / data.iOriginalSize.iHeight; |
|
1264 data.iCanvasSize = data.iTargetSize; |
|
1265 } |
|
1266 else if (data.iOriginalSize != TSize()) |
|
1267 { |
|
1268 // When target size is not set, then only one scaling factor is present. |
|
1269 // It is smaller of horizontal and vertical scaling factors. |
|
1270 // And in this case canvas have size calculated according to |
|
1271 // the scaling factor. |
|
1272 data.iRatioX = (TReal) data.iScreenSize.iWidth / data.iOriginalSize.iWidth; |
|
1273 data.iRatioY = (TReal) data.iScreenSize.iHeight / data.iOriginalSize.iHeight; |
|
1274 TReal ratio = Min(data.iRatioX, data.iRatioY); |
|
1275 data.iRatioX = ratio; |
|
1276 data.iRatioY = ratio; |
|
1277 data.iCanvasSize = TSize(data.iOriginalSize.iWidth * ratio, |
|
1278 data.iOriginalSize.iHeight * ratio); |
|
1279 } |
|
1280 else |
|
1281 { |
|
1282 // When scaling is off, then canvas ocupied whole screen. |
|
1283 data.iCanvasSize = data.iScreenSize; |
|
1284 } |
|
1285 |
|
1286 // Set local variable to iScalingData |
|
1287 iScalingData = data; |
|
1288 } |
|
1289 |
|
1290 // ============================ TStickyKeysHandler =========================== |
|
1291 |
|
1292 CMIDUtils::TStickyKeysHandler::TStickyKeysHandler() |
|
1293 { |
|
1294 ResetState(); |
|
1295 iFnKeyState = EKeyNotActive; |
|
1296 iShiftKeyState = EKeyNotActive; |
|
1297 } |
|
1298 |
|
1299 void CMIDUtils::TStickyKeysHandler::Reset() |
|
1300 { |
|
1301 ResetState(); |
|
1302 iStickyModifier = 0; |
|
1303 // When reseting state, we must take locked sticky keys into account |
|
1304 // If Fn is locked, then after reset Fn still must be added to midifiers |
|
1305 if (iFnKeyState == EKeyLocked) |
|
1306 { |
|
1307 AddFnToStickyModifiers(); |
|
1308 } |
|
1309 else |
|
1310 { |
|
1311 iFnKeyState = EKeyNotActive; |
|
1312 } |
|
1313 |
|
1314 // Fn has higher priority than shift, and only one sticky key might |
|
1315 // be locked at the time |
|
1316 // For half QWERTY we need to process also shift as a regular key when Fn is active |
|
1317 if (iFnKeyState == EKeyNotActive) |
|
1318 { |
|
1319 // Pre-setting shift |
|
1320 switch (iShiftKeyState) |
|
1321 { |
|
1322 case EKeyLocked: |
|
1323 // Shift is locked, so add modifier |
|
1324 AddShiftToStickyModifiers(); |
|
1325 break; |
|
1326 case EKeyActive: |
|
1327 // Shift wasn't locked |
|
1328 iShiftKeyState = EKeyNotActive; |
|
1329 break; |
|
1330 case EKeyNotActiveNext: |
|
1331 // Shift was locked, but should be deactivated for next keypress, |
|
1332 // so add it to modifiers... |
|
1333 AddShiftToStickyModifiers(); |
|
1334 // .. and move back to locked state |
|
1335 iShiftKeyState = EKeyLocked; |
|
1336 break; |
|
1337 default: |
|
1338 iShiftKeyState = EKeyNotActive; |
|
1339 break; |
|
1340 } |
|
1341 } |
|
1342 } |
|
1343 |
|
1344 TBool CMIDUtils::TStickyKeysHandler::HandleKey( |
|
1345 const TKeyEvent& aKeyEvent, TEventCode aType) |
|
1346 { |
|
1347 if (!IsSticky(aKeyEvent)) |
|
1348 { |
|
1349 // Check Fn key |
|
1350 if (aKeyEvent.iModifiers & EModifierRightFunc) |
|
1351 { |
|
1352 iStickyModifier = aKeyEvent.iModifiers; |
|
1353 } |
|
1354 ResetState(); |
|
1355 return EFalse; |
|
1356 } |
|
1357 |
|
1358 // Depending on sticky key state... |
|
1359 switch (iStickyKeyState) |
|
1360 { |
|
1361 case EKeyNotPressed: |
|
1362 // No sticky key was pressed |
|
1363 if (aType == EEventKeyDown) |
|
1364 { |
|
1365 // If key down event arrived, remember it's keycode and |
|
1366 // move to next state (sticky key pressed) |
|
1367 iLastStickyScanCode = aKeyEvent.iScanCode; |
|
1368 iStickyKeyState = EKeyWasPressed; |
|
1369 } |
|
1370 else |
|
1371 { |
|
1372 // Reset handler's state |
|
1373 Reset(); |
|
1374 } |
|
1375 break; |
|
1376 case EKeyWasPressed: |
|
1377 // Sticky key was pressed before |
|
1378 if (aType == EEventKeyUp) |
|
1379 { |
|
1380 // If same sticky key was released as pressed in previous state, |
|
1381 // move to the next state (sticky key released) |
|
1382 if (iLastStickyScanCode == aKeyEvent.iScanCode) |
|
1383 { |
|
1384 iStickyKeyState = EKeyWasReleased; |
|
1385 } |
|
1386 } |
|
1387 else |
|
1388 { |
|
1389 // Reset handler's state |
|
1390 Reset(); |
|
1391 } |
|
1392 break; |
|
1393 default: |
|
1394 Reset(); |
|
1395 break; |
|
1396 } |
|
1397 |
|
1398 TBool wasStickyKey = EFalse; |
|
1399 if (EKeyWasReleased == iStickyKeyState) |
|
1400 { |
|
1401 // Sticky key was pressed and released, so we need to get |
|
1402 // modifiers from scan code. |
|
1403 TUint modifier = ModifierFromScanCode(aKeyEvent.iScanCode); |
|
1404 |
|
1405 // Add/remove modifier to/from stored modifiers |
|
1406 if (iStickyModifier & modifier) |
|
1407 { |
|
1408 iStickyModifier &= ~modifier; |
|
1409 } |
|
1410 else |
|
1411 { |
|
1412 iStickyModifier |= modifier; |
|
1413 } |
|
1414 |
|
1415 ResetState(); |
|
1416 HandleLockableKeys(modifier); |
|
1417 wasStickyKey = ETrue; |
|
1418 } |
|
1419 |
|
1420 return wasStickyKey; |
|
1421 } |
|
1422 |
|
1423 TInt CMIDUtils::TStickyKeysHandler::Modifiers() const |
|
1424 { |
|
1425 return iStickyModifier; |
|
1426 } |
|
1427 |
|
1428 void CMIDUtils::TStickyKeysHandler::ResetState() |
|
1429 { |
|
1430 iLastStickyScanCode = 0; |
|
1431 iStickyKeyState = EKeyNotPressed; |
|
1432 } |
|
1433 |
|
1434 TUint CMIDUtils::TStickyKeysHandler::ModifierFromScanCode(TInt aScanCode) |
|
1435 { |
|
1436 switch (aScanCode) |
|
1437 { |
|
1438 case EStdKeyLeftShift: |
|
1439 return EModifierShift | EModifierLeftShift; |
|
1440 case EStdKeyRightShift: |
|
1441 return EModifierShift | EModifierRightShift; |
|
1442 case EStdKeyLeftAlt: |
|
1443 return EModifierAlt | EModifierLeftAlt; |
|
1444 case EStdKeyRightAlt: |
|
1445 return EModifierAlt | EModifierRightAlt; |
|
1446 case EStdKeyLeftCtrl: |
|
1447 return EModifierCtrl | EModifierLeftCtrl; |
|
1448 case EStdKeyRightCtrl: |
|
1449 return EModifierCtrl | EModifierRightCtrl; |
|
1450 case EStdKeyLeftFunc: |
|
1451 return EModifierLeftFunc; |
|
1452 case EStdKeyRightFunc: |
|
1453 return EModifierFunc | EModifierRightFunc; |
|
1454 default: |
|
1455 return 0; |
|
1456 } |
|
1457 } |
|
1458 |
|
1459 |
|
1460 TBool CMIDUtils::TStickyKeysHandler::IsSticky(const TKeyEvent& aKeyEvent) |
|
1461 { |
|
1462 TBool isStickyKey = EFalse; |
|
1463 switch (aKeyEvent.iScanCode) |
|
1464 { |
|
1465 case EStdKeyLeftFunc: |
|
1466 case EStdKeyLeftShift: |
|
1467 case EStdKeyRightShift: |
|
1468 isStickyKey = !IsFnModifierOn(iStickyModifier) && |
|
1469 !(aKeyEvent.iModifiers & EModifierRightFunc); |
|
1470 break; |
|
1471 case EStdKeyLeftAlt: |
|
1472 case EStdKeyRightAlt: |
|
1473 case EStdKeyLeftCtrl: |
|
1474 case EStdKeyRightCtrl: |
|
1475 case EStdKeyRightFunc: |
|
1476 isStickyKey = ETrue; |
|
1477 break; |
|
1478 default: |
|
1479 break; |
|
1480 } |
|
1481 |
|
1482 return isStickyKey; |
|
1483 } |
|
1484 |
|
1485 void CMIDUtils::TStickyKeysHandler::HandleLockableKeys(TUint aModifiers) |
|
1486 { |
|
1487 if (IsFnModifierOn(aModifiers)) |
|
1488 { |
|
1489 iActualFnModifierValue = 0; |
|
1490 if (aModifiers & EModifierLeftFunc) |
|
1491 { |
|
1492 iActualFnModifierValue = EModifierLeftFunc; |
|
1493 } |
|
1494 if (aModifiers & EModifierRightFunc) |
|
1495 { |
|
1496 iActualFnModifierValue = EModifierRightFunc; |
|
1497 } |
|
1498 HandleFnKey(); |
|
1499 } |
|
1500 |
|
1501 if (IsShiftModifierOn(aModifiers)) |
|
1502 { |
|
1503 iActualShiftModifierValue = 0; |
|
1504 if (aModifiers & EModifierLeftShift) |
|
1505 { |
|
1506 iActualShiftModifierValue = EModifierLeftShift; |
|
1507 } |
|
1508 if (aModifiers & EModifierRightShift) |
|
1509 { |
|
1510 iActualShiftModifierValue = EModifierRightShift; |
|
1511 } |
|
1512 HandleShiftKey(); |
|
1513 } |
|
1514 } |
|
1515 |
|
1516 /** |
|
1517 * Handle event with modifier of Fn key |
|
1518 */ |
|
1519 void CMIDUtils::TStickyKeysHandler::HandleFnKey() |
|
1520 { |
|
1521 switch (iFnKeyState) |
|
1522 { |
|
1523 case EKeyNotActive: |
|
1524 iFnKeyState = EKeyActive; |
|
1525 break; |
|
1526 case EKeyActive: |
|
1527 iFnKeyState = EKeyLocked; |
|
1528 AddFnToStickyModifiers(); |
|
1529 break; |
|
1530 case EKeyLocked: |
|
1531 iFnKeyState = EKeyNotActive; |
|
1532 // If Fn lock is disabled, also disable Shift lock. |
|
1533 iShiftKeyState = EKeyNotActive; |
|
1534 Reset(); |
|
1535 break; |
|
1536 } |
|
1537 } |
|
1538 |
|
1539 /** |
|
1540 * Handle event with modifier of Shift key |
|
1541 */ |
|
1542 void CMIDUtils::TStickyKeysHandler::HandleShiftKey() |
|
1543 { |
|
1544 switch (iShiftKeyState) |
|
1545 { |
|
1546 case EKeyNotActive: |
|
1547 iShiftKeyState = EKeyActive; |
|
1548 break; |
|
1549 case EKeyActive: |
|
1550 iShiftKeyState = EKeyLocked; |
|
1551 AddShiftToStickyModifiers(); |
|
1552 break; |
|
1553 case EKeyLocked: |
|
1554 iStickyModifier = 0; |
|
1555 if (iFnKeyState == EKeyLocked) |
|
1556 { |
|
1557 AddFnToStickyModifiers(); |
|
1558 } |
|
1559 iShiftKeyState = EKeyNotActiveNext; |
|
1560 break; |
|
1561 case EKeyNotActiveNext: |
|
1562 iShiftKeyState = EKeyNotActive; |
|
1563 Reset(); |
|
1564 break; |
|
1565 } |
|
1566 } |
|
1567 |
|
1568 void CMIDUtils::TStickyKeysHandler::AddShiftToStickyModifiers() |
|
1569 { |
|
1570 iStickyModifier |= EModifierShift | iActualShiftModifierValue; |
|
1571 } |
|
1572 |
|
1573 void CMIDUtils::TStickyKeysHandler::AddFnToStickyModifiers() |
|
1574 { |
|
1575 //Chr key (EModifierLeftFunc) is not handled as sticky key because |
|
1576 //it should not function in any special way |
|
1577 if (iActualFnModifierValue != EModifierLeftFunc) |
|
1578 { |
|
1579 iStickyModifier |= EModifierFunc | iActualFnModifierValue; |
|
1580 } |
|
1581 } |
|
1582 |
|
1583 inline TBool CMIDUtils::TStickyKeysHandler::IsFnModifierOn( |
|
1584 const TUint aModifiers) const |
|
1585 { |
|
1586 return aModifiers & EModifierFunc || |
|
1587 aModifiers & EModifierRightFunc; |
|
1588 } |
|
1589 |
|
1590 |
|
1591 inline TBool CMIDUtils::TStickyKeysHandler::IsShiftModifierOn( |
|
1592 const TUint aModifiers) const |
|
1593 { |
|
1594 return aModifiers & EModifierShift || |
|
1595 aModifiers & EModifierLeftShift || |
|
1596 aModifiers & EModifierRightShift; |
|
1597 } |
|
1598 |
|
1599 TBool CMIDUtils::IsScalingEnabled() |
|
1600 { |
|
1601 // If iScalingData is not initialized, we do it. |
|
1602 if (!iScalingDataInitialized) |
|
1603 { |
|
1604 UpdateScalingData(); |
|
1605 } |
|
1606 |
|
1607 //If iOrgMIDletScrSize has been initialized then scaling is on. |
|
1608 //It's enough to check either height or width only. |
|
1609 return (iScalingData.iOriginalSize.iHeight != 0); |
|
1610 } |
|
1611 |
|
1612 TRect CMIDUtils::GetOnScreenCanvasRect() |
|
1613 { |
|
1614 if (!iScalingDataInitialized) |
|
1615 { |
|
1616 UpdateScalingData(); |
|
1617 } |
|
1618 |
|
1619 TSize subtract = iScalingData.iScreenSize - iScalingData.iCanvasSize; |
|
1620 TPoint canvasOrigin = TPoint(subtract.iWidth / 2, subtract.iHeight / 2); |
|
1621 return TRect(canvasOrigin, iScalingData.iCanvasSize); |
|
1622 } |
|
1623 |
|
1624 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
1625 void CMIDUtils::SetPtiKeyboardL() |
|
1626 { |
|
1627 #ifdef RD_JAVA_S60_RELEASE_5_0_IAD |
|
1628 CallToJavaPtiVariationL(iPtiKeyboardType); |
|
1629 #else |
|
1630 if (iPtiEngine) |
|
1631 { |
|
1632 iPtiEngine->SetKeyboardType((TPtiKeyboardType)iPtiKeyboardType); |
|
1633 } |
|
1634 #endif // RD_JAVA_S60_RELEASE_5_0_IAD |
|
1635 } |
|
1636 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
1637 |
|
1638 // End of File |