javauis/lcdui_akn/lcdui/src/CMIDUtils.cpp
branchRCL_3
changeset 66 2455ef1f5bbc
equal deleted inserted replaced
65:ae942d28ec0e 66:2455ef1f5bbc
       
     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