javauis/lcdui_akn/lcdui/src/CMIDCanvas.cpp
branchRCL_3
changeset 14 04becd199f91
child 17 0fd27995241b
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2003-2009 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:  CMIDCanvas - Implements the native part of the Canvas class.
       
    15 *
       
    16 */
       
    17 
       
    18 // Using auto_ptr
       
    19 #include <memory>
       
    20 
       
    21 // API used for getting the layout for the network indicator bitmap and for
       
    22 // retrieving info if pen is enabled (in CMIDCanvas::HandlePointerEventL
       
    23 // function).
       
    24 #include <AknUtils.h>
       
    25 
       
    26 // Using Layout_Meta_Data::IsLandscapeOrientation()
       
    27 #include <layoutmetadata.cdl.h>
       
    28 
       
    29 
       
    30 // Using CRepository class used in CMIDCanvas::IsNetworkIndicatorEnabledL
       
    31 // function.
       
    32 #include <centralrepository.h>
       
    33 #ifdef RD_JAVA_NGA_ENABLED
       
    34 #include <logger.h>
       
    35 #include <e32cmn.h>
       
    36 #include <EGL/egl.h>
       
    37 #include <GLES/gl.h>
       
    38 #endif // RD_JAVA_NGA_ENABLED
       
    39 
       
    40 
       
    41 // Using debug macros.
       
    42 #include <j2me/jdebug.h>
       
    43 
       
    44 // OMJ storage
       
    45 #include <securitystoragedatadefs.h>
       
    46 #include <javastorageentry.h>
       
    47 #include <javastorage.h>
       
    48 #include <javastoragenames.h>
       
    49 #include <javauid.h>
       
    50 #include <javasymbianoslayer.h>
       
    51 
       
    52 #include "javaoslayer.h"
       
    53 
       
    54 // Using constants for S60 LCDUI Plugin internal keys.
       
    55 #include "S60LCDUIInternalCRKeys.h"
       
    56 
       
    57 #include "CMIDCanvas.h"
       
    58 
       
    59 // Using CMIDUIManager for iKeyDecoder and iScaler initialization.
       
    60 #include "CMIDUIManager.h"
       
    61 
       
    62 // Using CMIDScaler as member iScaler.
       
    63 #include "CMIDScaler.h"
       
    64 
       
    65 // Using CMIDKeyDecoder as member iKeyDecoder.
       
    66 #include "CMIDKeyDecoder.h"
       
    67 
       
    68 // Using CMIDNetworkIndicator as member iNetworkIndicator.
       
    69 #include "CMIDNetworkIndicator.h"
       
    70 
       
    71 // Using CMIDCallIndicator as member iCallIndicator.
       
    72 #include "CMIDCallIndicator.h"
       
    73 
       
    74 // Using CMIDRemConObserver as memeber iRemConObserver.
       
    75 #include "CMIDRemConObserver.h"
       
    76 
       
    77 
       
    78 #ifdef RD_TACTILE_FEEDBACK
       
    79 // Using CMIDTactileFeedbackExtension as member iTactileFeedback.
       
    80 #include "CMIDTactileFeedbackExtension.h"
       
    81 #endif // RD_TACTILE_FEEDBACK
       
    82 
       
    83 #include "MMIDCustomComponent.h"
       
    84 
       
    85 // Using CoreUiAvkonLcdui for the splash screen
       
    86 #include "coreuiavkonlcdui.h"
       
    87 
       
    88 #ifdef DEFER_BITBLT
       
    89 const TInt KEstCyclesPerPixel = 32;
       
    90 #endif // DEFER_BITBLT
       
    91 
       
    92 const TInt KAllowedTimeBetweenDragEvents = 50000; // 50ms
       
    93 
       
    94 // Used with component controls
       
    95 const TInt KComponentMainControl = 0;
       
    96 const TInt KComponentFocusedNone = -1;
       
    97 
       
    98 // Using enumeration TFocusState.
       
    99 #include "MMIDTextEditor.h"
       
   100 
       
   101 #ifdef RD_JAVA_NGA_ENABLED
       
   102 // Max dimension for openGL texture, must be power of 2
       
   103 const TInt KMaxBlitSize = 256;
       
   104 const TInt KTexturesCount = 1;
       
   105 const TInt KBytesPerPixel = 4;
       
   106 const TInt KPhoneScreen = 0;
       
   107 // The color that is used to clear the framebuffer when
       
   108 // mixing 3D & 2D rendering
       
   109 #define KTransparentClearColor TRgb(0x000000, 0x0)
       
   110 #define KOpaqueClearColor      TRgb(0xFFFFFF, 0xFF)
       
   111 
       
   112 #ifdef _DEBUG
       
   113 #define ASSERT_GL() AssertGL()
       
   114 #else
       
   115 #define ASSERT_GL()
       
   116 #endif
       
   117 
       
   118 #endif // RD_JAVA_NGA_ENABLED
       
   119 
       
   120 #define KZeroSize TSize()
       
   121 
       
   122 
       
   123 // ---------------------------------------------------------------------------
       
   124 // TBitBltData
       
   125 // BitBlt buffer data datatype.
       
   126 // ---------------------------------------------------------------------------
       
   127 //
       
   128 struct TBitBltData
       
   129 {
       
   130     TRect iRect;
       
   131 };
       
   132 
       
   133 
       
   134 // ======== LOCAL FUNCTIONS ========
       
   135 
       
   136 // ---------------------------------------------------------------------------
       
   137 // BitBltData
       
   138 // Get BitBlt buffer data from buffered operation passed to buffer processor.
       
   139 // Used in CMIDCanvas::ProcessL function.
       
   140 // ---------------------------------------------------------------------------
       
   141 //
       
   142 inline const TBitBltData& BitBltData(const TMIDBufferOp* aOp)
       
   143 {
       
   144     ASSERT(aOp->Size() >= TInt(1 + (
       
   145                                    sizeof(TBitBltData) / sizeof(TMIDBufferOp))));
       
   146 
       
   147     return *static_cast< const TBitBltData* >(aOp->Data());
       
   148 }
       
   149 
       
   150 
       
   151 // ---------------------------------------------------------------------------
       
   152 // IsDownScaling
       
   153 // Check if downscaling in use.
       
   154 // @param aSourceSize Source rect size.
       
   155 // @param aDestRect Destination rect.
       
   156 // ---------------------------------------------------------------------------
       
   157 //
       
   158 inline TBool IsDownScaling(const TSize& aSourceSize, const TRect& aDestRect)
       
   159 {
       
   160     return (aSourceSize.iWidth > aDestRect.Width() ||
       
   161             aSourceSize.iHeight > aDestRect.Height());
       
   162 }
       
   163 
       
   164 
       
   165 // ======== MEMBER FUNCTIONS ========
       
   166 
       
   167 // ---------------------------------------------------------------------------
       
   168 // CMIDCanvas::NewL
       
   169 // Two-phased constructor. Use this method to create a CMIDCanvas instance.
       
   170 // ---------------------------------------------------------------------------
       
   171 //
       
   172 CMIDCanvas* CMIDCanvas::NewL(
       
   173     MMIDEnv& aEnv,
       
   174     CCoeControl& aWindow,
       
   175     MMIDComponent::TType aComponentType,
       
   176     TBool aUpdateRequired)
       
   177 {
       
   178     CMIDCanvas* self = new(ELeave) CMIDCanvas(aEnv,
       
   179             aComponentType,
       
   180             aUpdateRequired);
       
   181 
       
   182     CleanupStack::PushL(self);
       
   183     self->ConstructL(aWindow);
       
   184     CleanupStack::Pop(self);
       
   185 
       
   186     return self;
       
   187 }
       
   188 
       
   189 
       
   190 // ---------------------------------------------------------------------------
       
   191 // CMIDCanvas::~CMIDCanvas
       
   192 // Destructor.
       
   193 // ---------------------------------------------------------------------------
       
   194 //
       
   195 CMIDCanvas::~CMIDCanvas()
       
   196 {
       
   197     DEBUG("+ CMIDCanvas::~CMIDCanvas");
       
   198 
       
   199     // Notify custom components that this container is disposing.
       
   200     TInt customCount = iCustomComponents.Count();
       
   201 
       
   202     for (TInt i = 0; i < customCount; i++)
       
   203     {
       
   204         iCustomComponents[i]->CustomComponentContainerDisposing();
       
   205     }
       
   206 
       
   207     // Close the array. Objects are not owned.
       
   208     iCustomComponents.Close();
       
   209 
       
   210     // Inform all listeners
       
   211     TInt contentsCount(iDirectContents.Count());
       
   212 
       
   213     for (TInt j = 0; j < contentsCount; j++)
       
   214     {
       
   215         iDirectContents[j]->MdcContainerDestroyed();
       
   216     }
       
   217 
       
   218     iDirectContents.Reset();
       
   219 
       
   220     // Unregister the component from the observer
       
   221     // if it were previously registered from MdcAddContent.
       
   222     iEnv.ToLcduiObserver().UnregisterControl(*this);
       
   223 
       
   224 #ifdef CANVAS_DIRECT_ACCESS
       
   225     StopDirectAccess();
       
   226     delete iDirectAccess;
       
   227 #endif // CANVAS_DIRECT_ACCESS
       
   228 
       
   229     // Network indicator
       
   230     if (iNetworkIndicator)
       
   231     {
       
   232         iNetworkIndicator->Close(); // Use cancel here.
       
   233         delete iNetworkIndicator;
       
   234     }
       
   235 
       
   236     // Call indicator
       
   237     if (iCallIndicator)
       
   238     {
       
   239         iCallIndicator->Cancel();
       
   240         delete iCallIndicator;
       
   241     }
       
   242 
       
   243     // Canvas removes itself from the CMIDRemConObserver.
       
   244     ASSERT(iKeyDecoder);
       
   245 
       
   246     if (iRemConObserver && iKeyDecoder->MediaKeysEnabled())
       
   247     {
       
   248         iRemConObserver->RemoveMediaKeysListener(this);
       
   249     }
       
   250 
       
   251     if (iDisplayable)
       
   252     {
       
   253         if (iScaler)
       
   254         {
       
   255             iDisplayable->GetUIManager()->CloseScaler(iScaler);
       
   256         }
       
   257 
       
   258         // Displayable is notified about content control deletion.
       
   259         iDisplayable->NotifyContentDestroyed();
       
   260     }
       
   261 
       
   262 #ifdef CANVAS_DOUBLE_BUFFER
       
   263     if (iFrameBuffer)
       
   264     {
       
   265         iEnv.ReleaseCanvasFrameBuffer((*this), iFrameBuffer);
       
   266         iFrameBuffer = NULL;
       
   267     }
       
   268 
       
   269     delete iFrameContext;
       
   270     iFrameContext = NULL;
       
   271     delete iFrameDevice;
       
   272     iFrameDevice = NULL;
       
   273 #endif // CANVAS_DOUBLE_BUFFER
       
   274 
       
   275 #ifdef RD_TACTILE_FEEDBACK
       
   276     delete iTactileFeedback;
       
   277 #endif // RD_TACTILE_FEEDBACK
       
   278 
       
   279     if (iPointerEventSuppressor)
       
   280     {
       
   281         delete iPointerEventSuppressor;
       
   282         iPointerEventSuppressor = NULL;
       
   283     }
       
   284 
       
   285 #ifdef RD_JAVA_NGA_ENABLED
       
   286     CloseEgl();
       
   287     DisposePixelSource();
       
   288     delete[] iTexturePixels;
       
   289     delete[] iVertexArray;
       
   290     delete[] iTriangleStrip;
       
   291 #endif // RD_JAVA_NGA_ENABLED
       
   292     DEBUG("- CMIDCanvas::~CMIDCanvas");
       
   293 }
       
   294 
       
   295 
       
   296 // ---------------------------------------------------------------------------
       
   297 // CMIDCanvas::FullScreen
       
   298 // Set fullscreen mode on/off.
       
   299 // ---------------------------------------------------------------------------
       
   300 //
       
   301 void CMIDCanvas::FullScreen(TBool aFullScreen)
       
   302 {
       
   303     DEBUG_INT("CMIDCanvas::FullScreen(%d) ++--", aFullScreen);
       
   304     if (iFullScreen != aFullScreen)
       
   305     {
       
   306         iFullScreen = aFullScreen;
       
   307         // We have to inform all components on this Canvas.
       
   308         if (iCustomComponents.Count() > 0)
       
   309         {
       
   310             for (int i = 0; i < iCustomComponents.Count(); i++)
       
   311             {
       
   312                 iCustomComponents[i]->HandleFullscreenModeChange();
       
   313             }
       
   314         }
       
   315     }
       
   316 }
       
   317 
       
   318 
       
   319 // ---------------------------------------------------------------------------
       
   320 // CMIDCanvas::IsScalingOn
       
   321 // Tells whether scaling is on or off.
       
   322 // ---------------------------------------------------------------------------
       
   323 //
       
   324 TBool CMIDCanvas::IsScalingOn()
       
   325 {
       
   326     return iScalingOn;
       
   327 }
       
   328 
       
   329 
       
   330 // ---------------------------------------------------------------------------
       
   331 // CMIDCanvas::SelectionKeyCompatibility
       
   332 // Tells whether application attribute
       
   333 // Nokia-MIDlet-S60-Selection-Key-Compatibility is set true or not.
       
   334 // ---------------------------------------------------------------------------
       
   335 //
       
   336 TBool CMIDCanvas::SelectionKeyCompatibility()
       
   337 {
       
   338     return iS60SelectionKeyCompatibility;
       
   339 }
       
   340 
       
   341 // ---------------------------------------------------------------------------
       
   342 // CMIDCanvas::CountComponentControls
       
   343 // (other items are commented in the header file)
       
   344 // ---------------------------------------------------------------------------
       
   345 //
       
   346 TInt CMIDCanvas::CountComponentControls() const
       
   347 {
       
   348     return iCustomComponentsControlCount;
       
   349 }
       
   350 
       
   351 // ---------------------------------------------------------------------------
       
   352 // CMIDCanvas::ComponentControl
       
   353 // (other items are commented in the header file)
       
   354 // ---------------------------------------------------------------------------
       
   355 //
       
   356 CCoeControl* CMIDCanvas::ComponentControl(TInt aIndex) const
       
   357 {
       
   358     TInt index = 0;
       
   359 
       
   360     TInt count = iCustomComponents.Count();
       
   361 
       
   362     for (int i = 0; i < count; i++)
       
   363     {
       
   364         TInt compoundCount =
       
   365             iCustomComponents[i]->CustomComponentControlCount();
       
   366 
       
   367         for (int j = 0; j < compoundCount; j++)
       
   368         {
       
   369             if (index == aIndex)
       
   370             {
       
   371                 return iCustomComponents[i]->CustomComponentControl(j);
       
   372             }
       
   373 
       
   374             index++;
       
   375         }
       
   376     }
       
   377 
       
   378     return NULL;
       
   379 }
       
   380 
       
   381 // ---------------------------------------------------------------------------
       
   382 // CMIDCanvas::SetFocusedComponent
       
   383 // (other items are commented in the header file)
       
   384 // ---------------------------------------------------------------------------
       
   385 //
       
   386 void CMIDCanvas::SetFocusedComponent(MMIDCustomComponent* aComponent)
       
   387 {
       
   388     if (aComponent == NULL)
       
   389     {
       
   390         iFocusedComponent = KComponentFocusedNone;
       
   391         iPressedComponent = NULL;
       
   392     }
       
   393     else
       
   394     {
       
   395         TInt count = iCustomComponents.Count();
       
   396         TInt index = iCustomComponents.Find(aComponent);
       
   397         if ((index != KErrNotFound) && (iFocusedComponent != index))
       
   398         {
       
   399             iFocusedComponent = index;
       
   400         }
       
   401     }
       
   402 }
       
   403 
       
   404 // ---------------------------------------------------------------------------
       
   405 // From class CCoeControl.
       
   406 // CMIDCanvas::OfferKeyEventL
       
   407 // Process a key event. We ask the java environment to translate the key event
       
   408 // and we send it java side only if the translation allows it. The translation
       
   409 // is controlled by CMIDKeyDecoder via its interface to the java environment.
       
   410 // CBA keys are special. We only try and send them java side if we are full
       
   411 // screen and have no commands nor CommandListener, as stated in the specs.
       
   412 // Otherwise - if we are full screen with at least one command and
       
   413 // CommandListener we display the options menu or if we are not full screen
       
   414 // we simply return so that the CBA will process the key event and display the
       
   415 // options menu if needed. Note that in this context MSK is considered to be a
       
   416 // softkey, it must not be delivered as a key event to the Java side.
       
   417 // ---------------------------------------------------------------------------
       
   418 //
       
   419 TKeyResponse CMIDCanvas::OfferKeyEventL(
       
   420     const TKeyEvent& aEvent,
       
   421     TEventCode aType)
       
   422 {
       
   423     DEBUG("+ CMIDCanvas::OfferKeyEventL");
       
   424 
       
   425     DEBUG_INT(
       
   426         "+ CMIDCanvas::OfferKeyEventL - received TKeyEvent: iCode = %d",
       
   427         aEvent.iCode);
       
   428 
       
   429     DEBUG_INT(
       
   430         "+ CMIDCanvas::OfferKeyEventL - received TKeyEvent: iModifiers = %d",
       
   431         aEvent.iModifiers);
       
   432 
       
   433     DEBUG_INT(
       
   434         "+ CMIDCanvas::OfferKeyEventL - received TKeyEvent: iRepeats = %d",
       
   435         aEvent.iRepeats);
       
   436 
       
   437     DEBUG_INT(
       
   438         "+ CMIDCanvas::OfferKeyEventL - received TKeyEvent: iScanCode = %d",
       
   439         aEvent.iScanCode);
       
   440 
       
   441     TKeyResponse response = EKeyWasNotConsumed;
       
   442 
       
   443     if ((iFocusedComponent != KComponentFocusedNone) &&
       
   444             (iFocusedComponent < iCustomComponents.Count()) &&
       
   445             (iCustomComponents[iFocusedComponent]->
       
   446              CustomComponentControl(KComponentMainControl)->IsVisible()))
       
   447     {
       
   448         // Traversal check
       
   449         if ((aType == EEventKeyDown) &&
       
   450                 (((aEvent.iCode == EKeyUpArrow) ||
       
   451                   (aEvent.iCode == EKeyDownArrow)) ||
       
   452                  ((aEvent.iScanCode == EStdKeyUpArrow) ||
       
   453                   (aEvent.iScanCode == EStdKeyDownArrow))))
       
   454         {
       
   455             // Traversing is not allowed when editing with VKB
       
   456             if (iDisplayable && !iDisplayable->IsVKBOnScreen())
       
   457             {
       
   458                 iCustomComponents[iFocusedComponent]->TraverseL(aEvent);
       
   459                 response = EKeyWasConsumed;
       
   460             }
       
   461         }
       
   462 
       
   463         if (response != EKeyWasConsumed)
       
   464         {
       
   465             // Passing the keyevent to focused component
       
   466             response = iCustomComponents[iFocusedComponent]->
       
   467                        CustomComponentControl(KComponentMainControl)->
       
   468                        OfferKeyEventL(aEvent, aType);
       
   469         }
       
   470     }
       
   471 
       
   472     // Check if the key event was consumed by the child control.
       
   473     if (response == EKeyWasConsumed)
       
   474     {
       
   475         DEBUG_INT(
       
   476             "CMIDCanvas::OfferKeyEventL - key consumed by custom control: %d",
       
   477             iFocusedComponent);
       
   478 
       
   479         // Return response.
       
   480         return response;
       
   481     }
       
   482 
       
   483 
       
   484     DEBUG("CMIDCanvas::OfferKeyEventL, \
       
   485 event not consumed by any custom component");
       
   486 
       
   487     TInt keycode = aEvent.iScanCode;
       
   488 
       
   489     // If there is additional selection key mapping (e.g. to Enter key) and
       
   490     // scan code of delivered key is this additional key, flag is set to ETrue
       
   491     TBool additionalSelectionKey =
       
   492         (iKeyDecoder->AdditionalSelectionKeyMappingCode() != 0) &&
       
   493         (keycode == iKeyDecoder->AdditionalSelectionKeyMappingCode());
       
   494 
       
   495     if (keycode == EStdKeyDevice0 ||
       
   496             keycode == EStdKeyDevice1 ||
       
   497             keycode == EStdKeyDevice3 ||
       
   498             additionalSelectionKey)
       
   499     {
       
   500         // CBA keys
       
   501 
       
   502         // In S60SelectionKeyCompatibility mode turned on and MSK pressed
       
   503         // don't map any command, send key event to Java.
       
   504         if (iS60SelectionKeyCompatibility &&
       
   505                 (keycode == EStdKeyDevice3 || additionalSelectionKey))
       
   506         {
       
   507             SendKeyEventToJavaSideL(aEvent, aType);
       
   508             DEBUG("- CMIDCanvas::OfferKeyEventL = key was not consumed");
       
   509             return EKeyWasNotConsumed;
       
   510         }
       
   511 
       
   512         if (iDisplayable && !iDisplayable->IsFullScreenMode())
       
   513         {
       
   514             // Pressing selection key is handled in CEikCba so that command
       
   515             // mapped to selection (MSK) key is invoked from there.
       
   516             // But CEikCba doesn't handle additional selection key
       
   517             // mapping, so it is done here.
       
   518             if (additionalSelectionKey && aType == EEventKey)
       
   519             {
       
   520                 iDisplayable->ProcessMSKCommandL();
       
   521             }
       
   522             else if (aType == EEventKeyDown && keycode == EStdKeyDevice3)
       
   523             {
       
   524                 CMIDMenuHandler* menuHandler = iDisplayable->MenuHandler();
       
   525 
       
   526                 // If there is no additional selection key mapping
       
   527                 // and scan code of delivered key is MSK then show menu,
       
   528                 // used when ENavigationKeysFire or MSK were pressed
       
   529                 if (iDisplayable->NumCommandsForOkOptionsMenu() == 0
       
   530                         && menuHandler)
       
   531                 {
       
   532                     menuHandler->ProcessCommandL(EAknSoftkeyEmpty);
       
   533                 }
       
   534                 else if (iDisplayable->NumCommandsForOkOptionsMenu() > 0
       
   535                          && menuHandler)
       
   536                 {
       
   537                     menuHandler->ProcessCommandL(EAknSoftkeyContextOptions);
       
   538                 }
       
   539             }
       
   540 
       
   541             // Not a full screen mode, return so that the CBA gets the event.
       
   542             DEBUG("- CMIDCanvas::OfferKeyEventL = key was not consumed");
       
   543             return EKeyWasNotConsumed;
       
   544         }
       
   545 
       
   546         if (iDisplayable && iDisplayable->IsFullScreenMode()  &&
       
   547                 iDisplayable->IsCommandListenerSet() &&
       
   548                 iDisplayable->CommandCount() > 0)
       
   549         {
       
   550             CMIDMenuHandler* menuHandler = iDisplayable->MenuHandler();
       
   551 
       
   552             // If full screen and command listener is set and there are
       
   553             // Commands added to Canvas, then options menu is displayed.
       
   554             if (aType == EEventKey && menuHandler)
       
   555             {
       
   556                 menuHandler->ShowMenuL(
       
   557                     CMIDMenuHandler::EOptionsMenu);
       
   558             }
       
   559 
       
   560             DEBUG("- CMIDCanvas::OfferKeyEventL = key was not consumed");
       
   561             return EKeyWasNotConsumed;
       
   562         }
       
   563     }
       
   564 
       
   565     SendKeyEventToJavaSideL(aEvent, aType);
       
   566 
       
   567     DEBUG("- CMIDCanvas::OfferKeyEventL = key was not consumed");
       
   568     return EKeyWasNotConsumed;
       
   569 }
       
   570 
       
   571 
       
   572 // ---------------------------------------------------------------------------
       
   573 // From class MMIDComponent.
       
   574 // CMIDCanvas::Dispose
       
   575 // Invoked by the framework to clean up resources.
       
   576 // ---------------------------------------------------------------------------
       
   577 //
       
   578 void CMIDCanvas::Dispose()
       
   579 {
       
   580     delete this;
       
   581 }
       
   582 
       
   583 
       
   584 // ---------------------------------------------------------------------------
       
   585 // From class MMIDComponent.
       
   586 // CMIDCanvas::Type
       
   587 // Always returns the type MMIDComponent::ECanvas as component type.
       
   588 // ---------------------------------------------------------------------------
       
   589 //
       
   590 MMIDComponent::TType CMIDCanvas::Type() const
       
   591 {
       
   592     return MMIDComponent::ECanvas;
       
   593 }
       
   594 
       
   595 
       
   596 // ---------------------------------------------------------------------------
       
   597 // From class MMIDComponent.
       
   598 // CMIDCanvas::Processor
       
   599 // Always returns this-> as buffer processor associated with this component.
       
   600 // ---------------------------------------------------------------------------
       
   601 //
       
   602 MMIDBufferProcessor* CMIDCanvas::Processor()
       
   603 {
       
   604     return this;
       
   605 }
       
   606 
       
   607 
       
   608 // ---------------------------------------------------------------------------
       
   609 // From class MMIDCanvas.
       
   610 // CMIDCanvas::Control
       
   611 // Returns a reference to the CCoeControl corresponding to this canvas.
       
   612 // ---------------------------------------------------------------------------
       
   613 //
       
   614 CCoeControl& CMIDCanvas::Control()
       
   615 {
       
   616     return *this;
       
   617 }
       
   618 
       
   619 
       
   620 // ---------------------------------------------------------------------------
       
   621 // From class MMIDCanvas.
       
   622 // CMIDCanvas::FrameBuffer
       
   623 // Returns a pointer to the frame buffer. If double buffering is supported
       
   624 // this method must not return NULL. There is no ownership transfer.
       
   625 // ---------------------------------------------------------------------------
       
   626 //
       
   627 CFbsBitmap* CMIDCanvas::FrameBuffer() const
       
   628 {
       
   629 #ifdef CANVAS_DOUBLE_BUFFER
       
   630     return iFrameBuffer;
       
   631 #else
       
   632     return NULL;
       
   633 #endif // CANVAS_DOUBLE_BUFFER
       
   634 }
       
   635 
       
   636 
       
   637 // ---------------------------------------------------------------------------
       
   638 // From class MMIDCanvas.
       
   639 // CMIDCanvas::ContentSize
       
   640 // Returns the size of the canvas content.
       
   641 // ---------------------------------------------------------------------------
       
   642 //
       
   643 TSize CMIDCanvas::ContentSize() const
       
   644 {
       
   645     return iContentSize;
       
   646 }
       
   647 
       
   648 
       
   649 // ---------------------------------------------------------------------------
       
   650 // From class MMIDCanvas.
       
   651 // CMIDCanvas::PauseDirectAccess
       
   652 // Disables temporarily direct screen access.
       
   653 // This method should be called to disable direct screen access when a popup
       
   654 // menu is about to be displayed. This is a workaround for menu's failing to
       
   655 // correctly draw their shadows on Techview and other UI's that have floating
       
   656 // menubars.
       
   657 // ---------------------------------------------------------------------------
       
   658 //
       
   659 void CMIDCanvas::PauseDirectAccess()
       
   660 {
       
   661 #ifdef CANVAS_DIRECT_ACCESS
       
   662     StopDirectAccess();
       
   663 #endif // CANVAS_DIRECT_ACCESS
       
   664 
       
   665     iFlags |= EDirectPaused;
       
   666 }
       
   667 
       
   668 
       
   669 // ---------------------------------------------------------------------------
       
   670 // From class MMIDCanvas.
       
   671 // CMIDCanvas::ResumeDirectAccess
       
   672 // Re-enables direct screen access.
       
   673 // To be called when the menu has disappeared.
       
   674 // ---------------------------------------------------------------------------
       
   675 //
       
   676 void CMIDCanvas::ResumeDirectAccess()
       
   677 {
       
   678     iFlags &= ~EDirectPaused;
       
   679 
       
   680 #ifdef CANVAS_DIRECT_ACCESS
       
   681     StartDirectAccess();
       
   682 #endif // CANVAS_DIRECT_ACCESS
       
   683 }
       
   684 
       
   685 
       
   686 // ---------------------------------------------------------------------------
       
   687 // From class MMIDCanvas.
       
   688 // CMIDCanvas::SuppressKeys
       
   689 // Switch off key event posting. Game keys will still be tracked, but
       
   690 // keyPressed()/keyReleased() callbacks will not be called.
       
   691 // ---------------------------------------------------------------------------
       
   692 //
       
   693 void CMIDCanvas::SuppressKeys()
       
   694 {
       
   695     iFlags &= ~EPostKeyEvents;
       
   696     iEnv.ResetKeys();
       
   697 }
       
   698 
       
   699 
       
   700 // ---------------------------------------------------------------------------
       
   701 // From class MMIDCanvas.
       
   702 // CMIDCanvas::GameActions
       
   703 // Returns the latched state of the game action keys.
       
   704 // ---------------------------------------------------------------------------
       
   705 //
       
   706 TUint32 CMIDCanvas::GameActions()
       
   707 {
       
   708     TUint32 latch = (iGameKeyLatch | iGameKeyState);
       
   709     iGameKeyLatch = 0;
       
   710     return latch;
       
   711 }
       
   712 
       
   713 
       
   714 // ---------------------------------------------------------------------------
       
   715 // From class MMIDCanvas.
       
   716 // CMIDCanvas::DirectContainer
       
   717 // Returns a direct container on which video can be rendered.
       
   718 // ---------------------------------------------------------------------------
       
   719 //
       
   720 MDirectContainer& CMIDCanvas::DirectContainer()
       
   721 {
       
   722     return *this;
       
   723 }
       
   724 
       
   725 
       
   726 // ---------------------------------------------------------------------------
       
   727 // From class MMIDCanvas.
       
   728 // CMIDCanvas::DrawBackground
       
   729 // Draw a background image.
       
   730 // ---------------------------------------------------------------------------
       
   731 //
       
   732 void CMIDCanvas::DrawBackground(
       
   733     CBitmapContext& aGc, const TPoint& aPosition, const TSize& aSize)
       
   734 {
       
   735     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   736     MAknsControlContext* cc = iDisplayable->BackGroundControlContext();
       
   737 
       
   738     AknsDrawUtils::DrawBackground(
       
   739         skin, cc, NULL, aGc, aPosition, aSize, KAknsDrawParamDefault);
       
   740 }
       
   741 
       
   742 
       
   743 // ---------------------------------------------------------------------------
       
   744 // From class MMIDCanvas.
       
   745 // CMIDCanvas::IsGameCanvas
       
   746 // Returns the type of Canvas object.
       
   747 // ---------------------------------------------------------------------------
       
   748 //
       
   749 TBool CMIDCanvas::IsGameCanvas() const
       
   750 {
       
   751     return iIsGameCanvas;
       
   752 }
       
   753 
       
   754 
       
   755 // ---------------------------------------------------------------------------
       
   756 // From class MMIDCanvas.
       
   757 // Gets the Network indicator location for fullscreen
       
   758 // If not in fullscreenmode EFalse is returned
       
   759 // ---------------------------------------------------------------------------
       
   760 //
       
   761 TBool CMIDCanvas::NetworkIndicatorLocation(
       
   762     TPoint& aPosition,
       
   763     TSize& aSize) const
       
   764 {
       
   765     if (iFullScreen)
       
   766     {
       
   767         if (iNetworkIndicator)
       
   768         {
       
   769             iNetworkIndicator->GetLocation(aPosition, aSize);
       
   770             return ETrue;
       
   771         }
       
   772     }
       
   773     return EFalse;
       
   774 }
       
   775 
       
   776 
       
   777 #ifdef RD_TACTILE_FEEDBACK
       
   778 // ---------------------------------------------------------------------------
       
   779 // From MMIDCancas.
       
   780 // CMIDCanvas::TactileFeedbackComponent
       
   781 // Retutrns this as tactile feedback component.
       
   782 // ---------------------------------------------------------------------------
       
   783 //
       
   784 MMIDTactileFeedbackComponent* CMIDCanvas::TactileFeedbackComponent()
       
   785 {
       
   786     return this;
       
   787 }
       
   788 #endif // RD_TACTILE_FEEDBACK
       
   789 
       
   790 #ifdef RD_JAVA_NGA_ENABLED
       
   791 
       
   792 // ---------------------------------------------------------------------------
       
   793 // From class MMIDBufferProcessor.
       
   794 // CMIDCanvas::ProcessL
       
   795 // Process a block of commands, updating read pointer as you go.
       
   796 // ---------------------------------------------------------------------------
       
   797 //
       
   798 TBool CMIDCanvas::ProcessL(
       
   799     const TMIDBufferOp*& aRead,
       
   800     const TMIDBufferOp* aEnd,
       
   801     TInt& /* aCycles */,
       
   802     java::util::Monitor* aMonitor)
       
   803 {
       
   804     if (!iForeground)
       
   805     {
       
   806         DEBUG("CMIDCanvas::ProcessL() - not foreground");
       
   807         ASSERT(!iAlfMonitor);
       
   808         aRead = aEnd;
       
   809         return EFalse;
       
   810     }
       
   811 
       
   812     switch (aRead->OpCode())
       
   813     {
       
   814     case EDrwOpcM3GContentStart:
       
   815     {
       
   816         if (!iM3GContent &&
       
   817                 i3DAccelerated &&
       
   818                 iDirectContents.Count() == 0)
       
   819         {
       
   820             DEBUG("CMIDCanvas::ProcessL - M3G content start");
       
   821             iM3GContent = ETrue;
       
   822             iM3GStart = ETrue;
       
   823 
       
   824             // First time when M3G content is drawn =>
       
   825             // switch to EGL surface drawing.
       
   826             // Pixel source must be disposed first.
       
   827             DisposePixelSource();
       
   828             OpenEglL();
       
   829 
       
   830             // if we are scaling with m3g and HW acceleration
       
   831             // create a pbuffer surface to be used with m3g rendering
       
   832             if (iScalingOn && iFullScreen)
       
   833             {
       
   834                 CreatePBufferSurfaceL();
       
   835             }
       
   836             // Draw all framebuffer content to EGL surface.
       
   837             iUpperUpdateRect = TRect(Size());
       
   838             UpdateEglContent();
       
   839         }
       
   840     }
       
   841     break;
       
   842     case EDrwOpcBitBltRect:
       
   843     {
       
   844         const TBitBltData& data = BitBltData(aRead);
       
   845         UpdateL(data.iRect);
       
   846     }
       
   847     break;
       
   848     case EDrwOpcBitBlt:
       
   849     {
       
   850         UpdateL(iViewRect);
       
   851     }
       
   852     break;
       
   853     case EDrwOpcFirstPaint:
       
   854     {
       
   855         java::ui::CoreUiAvkonLcdui::getInstance().getJavaUiAppUi()->stopStartScreen();
       
   856     }
       
   857     break;
       
   858     default:
       
   859         User::Leave(KErrNotSupported);
       
   860         break;
       
   861     }
       
   862 
       
   863     aRead += aRead->Size();
       
   864     ASSERT(aRead == aEnd);
       
   865 
       
   866     // iFrameReady tells if this is async operation.
       
   867     // In async case CMIDBuffer waits until canvas
       
   868     // gets callback from Alf.
       
   869     // See CMIDBuffer.cpp and ProduceNewFrameL()
       
   870     if (iFrameReady)
       
   871     {
       
   872         iAlfMonitor = aMonitor;
       
   873     }
       
   874     return iFrameReady;
       
   875 }
       
   876 
       
   877 #else // RD_JAVA_NGA_ENABLED 
       
   878 
       
   879 // ---------------------------------------------------------------------------
       
   880 // From class MMIDBufferProcessor.
       
   881 // CMIDCanvas::ProcessL
       
   882 // Process a block of commands, updating read pointer as you go.
       
   883 // ---------------------------------------------------------------------------
       
   884 //
       
   885 TBool CMIDCanvas::ProcessL(
       
   886     const TMIDBufferOp*& aRead,
       
   887     const TMIDBufferOp* aEnd,
       
   888     TInt& aCycles,
       
   889     TRequestStatus* /* aStatus */)
       
   890 {
       
   891     DEBUG("+ CMIDCanvas::ProcessL");
       
   892 
       
   893 #ifdef CANVAS_DOUBLE_BUFFER
       
   894     while (aRead < aEnd)
       
   895     {
       
   896         switch (aRead->OpCode())
       
   897         {
       
   898         case EDrwOpcBitBlt:
       
   899         {
       
   900             TSize size = iFrameBuffer->SizeInPixels();
       
   901 
       
   902 #ifdef DEFER_BITBLT
       
   903             aCycles -= BitBltCycles(size);
       
   904 
       
   905             if (aCycles < 0)
       
   906             {
       
   907                 return EFalse;
       
   908             }
       
   909 #endif // DEFER_BITBLT
       
   910 
       
   911             Update(TRect(size));
       
   912         }
       
   913         break;
       
   914 
       
   915         case EDrwOpcBitBltRect:
       
   916         {
       
   917             const TBitBltData& data = BitBltData(aRead);
       
   918             TRect rect = data.iRect;
       
   919 
       
   920             // This is needed to avoid artifacting after orientation switch.
       
   921             // While changing orientation, wrong rect was not updated.
       
   922             if (iWndUpdate && (rect.Size() != iViewRect.Size())
       
   923                     && !iScalingOn)
       
   924             {
       
   925                 break;
       
   926             }
       
   927 
       
   928             TRect frameRect(iFrameBuffer->SizeInPixels());
       
   929 
       
   930             rect.Intersection(frameRect);
       
   931 
       
   932 #ifdef DEFER_BITBLT
       
   933             aCycles -= BitBltCycles(rect.Size());
       
   934 
       
   935             if (aCycles < 0)
       
   936             {
       
   937                 return EFalse;
       
   938             }
       
   939 #endif // DEFER_BITBLT
       
   940 
       
   941             Update(rect);
       
   942         }
       
   943         break;
       
   944         case EDrwOpcFirstPaint:
       
   945         {
       
   946             java::ui::CoreUiAvkonLcdui::getInstance().getJavaUiAppUi()->stopStartScreen();
       
   947         }
       
   948         break;
       
   949         default:
       
   950             User::Leave(KErrNotSupported);
       
   951             break;
       
   952         }
       
   953 
       
   954         aRead += aRead->Size();
       
   955     }
       
   956 #endif // CANVAS_DOUBLE_BUFFER
       
   957 
       
   958     DEBUG("- CMIDCanvas::ProcessL");
       
   959 
       
   960     return EFalse;
       
   961 }
       
   962 #endif // RD_JAVA_NGA_ENABLED
       
   963 
       
   964 
       
   965 // ---------------------------------------------------------------------------
       
   966 // From class MMIDBufferProcessor.
       
   967 // CMIDCanvas::AbortAsync
       
   968 // Does nothing.
       
   969 // ---------------------------------------------------------------------------
       
   970 //
       
   971 void CMIDCanvas::AbortAsync()
       
   972 {
       
   973     // nop
       
   974 }
       
   975 
       
   976 
       
   977 #ifdef CANVAS_DIRECT_ACCESS
       
   978 // ---------------------------------------------------------------------------
       
   979 // From class MAbortDirectScreenAccess.
       
   980 // CMIDCanvas::AbortNow
       
   981 // This function is called by the window server when direct screen access
       
   982 // must stop (for example because a dialogue is moved in front of the area
       
   983 // where direct screen access is taking place).
       
   984 // ---------------------------------------------------------------------------
       
   985 //
       
   986 void CMIDCanvas::AbortNow(
       
   987     RDirectScreenAccess::TTerminationReasons /* aReasons */)
       
   988 {
       
   989     StopDirectAccess();
       
   990 }
       
   991 
       
   992 
       
   993 // ---------------------------------------------------------------------------
       
   994 // From class MDirectScreenAccess.
       
   995 // CMIDCanvas::Restart
       
   996 // This function is called by the window server as soon as direct screen
       
   997 // access can resume.
       
   998 // ---------------------------------------------------------------------------
       
   999 //
       
  1000 void CMIDCanvas::Restart(
       
  1001     RDirectScreenAccess::TTerminationReasons /* aReasons */)
       
  1002 {
       
  1003     StartDirectAccess();
       
  1004 }
       
  1005 #endif // CANVAS_DIRECT_ACCESS
       
  1006 
       
  1007 
       
  1008 // ---------------------------------------------------------------------------
       
  1009 // From class MDirectContainer.
       
  1010 // CMIDCanvas::MdcAddContent
       
  1011 // Set the content of this direct container.
       
  1012 // ---------------------------------------------------------------------------
       
  1013 //
       
  1014 void CMIDCanvas::MdcAddContent(MDirectContent* aContent)
       
  1015 {
       
  1016     TInt error = iDirectContents.Append(aContent);
       
  1017 
       
  1018     __ASSERT_DEBUG(error == KErrNone, User::Invariant());
       
  1019 
       
  1020     // Register this control to observer
       
  1021     // in order to provide possibility  to call
       
  1022     // methods from another than LCDUI ES thread.
       
  1023     // Unregistration is done in destructor.
       
  1024 #ifdef RD_JAVA_NGA_ENABLED
       
  1025     iEnv.ToLcduiObserver().RegisterControl(*this, this);
       
  1026 #else
       
  1027     iEnv.ToLcduiObserver().RegisterControl(*this);
       
  1028 #endif
       
  1029 }
       
  1030 
       
  1031 
       
  1032 // ---------------------------------------------------------------------------
       
  1033 // From class MDirectContainer.
       
  1034 // CMIDCanvas::MdcRemoveContent
       
  1035 // Remove the content from this direct container. This will called when
       
  1036 // the Player is closed.
       
  1037 // ---------------------------------------------------------------------------
       
  1038 //
       
  1039 void CMIDCanvas::MdcRemoveContent(MDirectContent* aContent)
       
  1040 {
       
  1041     TInt index = iDirectContents.Find(aContent);
       
  1042 
       
  1043     if (index != KErrNotFound)
       
  1044     {
       
  1045         iDirectContents.Remove(index);
       
  1046         if (iDirectContents.Count() == 0)
       
  1047         {
       
  1048             iRestoreContentWhenUnfaded = EFalse;
       
  1049         }
       
  1050     }
       
  1051 }
       
  1052 
       
  1053 
       
  1054 // ---------------------------------------------------------------------------
       
  1055 // From class MDirectContainer.
       
  1056 // CMIDCanvas::MdcAddContentBounds
       
  1057 // Adds a rectangle to be excluded from redrawing.
       
  1058 // ---------------------------------------------------------------------------
       
  1059 //
       
  1060 void CMIDCanvas::MdcAddContentBounds(const TRect& aRect)
       
  1061 {
       
  1062     if (iDisplayable)
       
  1063     {
       
  1064         iDisplayable->AddDirectContentArea(aRect);
       
  1065     }
       
  1066 }
       
  1067 
       
  1068 
       
  1069 // ---------------------------------------------------------------------------
       
  1070 // From class MDirectContainer.
       
  1071 // CMIDCanvas::MdcRemoveContentBounds
       
  1072 // Removes a rectangle to be excluded from redrawing.
       
  1073 // ---------------------------------------------------------------------------
       
  1074 //
       
  1075 void CMIDCanvas::MdcRemoveContentBounds(const TRect& aRect)
       
  1076 {
       
  1077     if (iDisplayable)
       
  1078     {
       
  1079         iDisplayable->RemoveDirectContentArea(aRect);
       
  1080     }
       
  1081 }
       
  1082 
       
  1083 
       
  1084 // ---------------------------------------------------------------------------
       
  1085 // From class MDirectContainer.
       
  1086 // CMIDCanvas::MdcContainerWindowRect()
       
  1087 // ---------------------------------------------------------------------------
       
  1088 //
       
  1089 TRect CMIDCanvas::MdcContainerWindowRect() const
       
  1090 {
       
  1091     // CMIDCanvas has the size of the window always
       
  1092     return MdcContentBounds();
       
  1093 }
       
  1094 
       
  1095 
       
  1096 // ---------------------------------------------------------------------------
       
  1097 // From class MDirectContainer.
       
  1098 // CMIDCanvas::MdcContainerVisibility
       
  1099 // Get the visiblity of this direct container.
       
  1100 // ---------------------------------------------------------------------------
       
  1101 //
       
  1102 TBool CMIDCanvas::MdcContainerVisibility() const
       
  1103 {
       
  1104     return iDisplayable->IsVisible();
       
  1105 }
       
  1106 
       
  1107 
       
  1108 // ---------------------------------------------------------------------------
       
  1109 // From class MDirectContainer.
       
  1110 // CMIDCanvas::MdcContentBounds
       
  1111 // Get the bounds of the area that the content of this direct container can
       
  1112 // occupy.
       
  1113 // Return content rect in screen co-ordinates. Position is stored in
       
  1114 // member variable because CCoeControl::PositionRelativeToScreen cannot
       
  1115 // be called from another thread.
       
  1116 // ---------------------------------------------------------------------------
       
  1117 //
       
  1118 TRect CMIDCanvas::MdcContentBounds() const
       
  1119 {
       
  1120     return TRect(iPositionRelativeToScreen, Size());
       
  1121 }
       
  1122 
       
  1123 
       
  1124 // ---------------------------------------------------------------------------
       
  1125 // From class MDirectContainer.
       
  1126 // CMIDCanvas::MdcItemContentRect
       
  1127 // Get the area on the Item on which content can be displayed.
       
  1128 // This should only be called when the direct content is displayed on an Item,
       
  1129 // so always panic if it is called on Canvas.
       
  1130 // ---------------------------------------------------------------------------
       
  1131 //
       
  1132 void CMIDCanvas::MdcItemContentRect(
       
  1133     TRect& /* aContentRect */,
       
  1134     TRect& /* aScreenRect */) const
       
  1135 {
       
  1136     __ASSERT_DEBUG(EFalse, User::Invariant());
       
  1137 }
       
  1138 
       
  1139 
       
  1140 // ---------------------------------------------------------------------------
       
  1141 // From class MDirectContainer.
       
  1142 // CMIDCanvas::MdcHandlePointerEventL
       
  1143 // Allows a control created for direct container content display to pass on
       
  1144 // pointer events.
       
  1145 // Though this is the leaving function nothing can leave actually.
       
  1146 // ---------------------------------------------------------------------------
       
  1147 //
       
  1148 void CMIDCanvas::MdcHandlePointerEventL(TPointerEvent& /* aPointerEvent */)
       
  1149 {
       
  1150     __ASSERT_DEBUG(EFalse, User::Invariant());
       
  1151 }
       
  1152 
       
  1153 
       
  1154 // ---------------------------------------------------------------------------
       
  1155 // From class MDirectContainer.
       
  1156 // CMIDCanvas::MdcFlushContainer
       
  1157 // Flush the direct container content.
       
  1158 // ---------------------------------------------------------------------------
       
  1159 //
       
  1160 void CMIDCanvas::MdcFlushContainer(const TRect& aRect)
       
  1161 {
       
  1162     // Flush the framebuffer on screen
       
  1163     iEnv.ToLcduiObserver().FlushControl(*this, aRect);
       
  1164 }
       
  1165 
       
  1166 
       
  1167 // ---------------------------------------------------------------------------
       
  1168 // From class MDirectContainer.
       
  1169 // CMIDCanvas::MdcGetDSAResources
       
  1170 // Invokes callback aConsumer->MdcDSAResourcesCallback in LCDUI thread.
       
  1171 // ---------------------------------------------------------------------------
       
  1172 //
       
  1173 void CMIDCanvas::MdcGetDSAResources(MUiEventConsumer& aConsumer)
       
  1174 {
       
  1175     // May run in non-LCDUI ES thread
       
  1176     // Invoke the callback running in LCDUI ES thread
       
  1177     iEnv.ToLcduiObserver().InvokeDSAResourcesCallback(*this, aConsumer);
       
  1178 }
       
  1179 
       
  1180 
       
  1181 // ---------------------------------------------------------------------------
       
  1182 // From class MDirectContainer.
       
  1183 // CMIDCanvas::MdcGetUICallback
       
  1184 // Invokes callback aConsumer->MdcUICallback in LCDUI thread.
       
  1185 // ---------------------------------------------------------------------------
       
  1186 //
       
  1187 void CMIDCanvas::MdcGetUICallback(
       
  1188     MUiEventConsumer& aConsumer,
       
  1189     TInt aCallbackId)
       
  1190 {
       
  1191     // May run in non-LCDUI ES thread
       
  1192     // Invoke the callback running in LCDUI ES thread
       
  1193     iEnv.ToLcduiObserver().InvokeUICallback(aConsumer, aCallbackId);
       
  1194 }
       
  1195 
       
  1196 #ifdef RD_JAVA_NGA_ENABLED
       
  1197 // ---------------------------------------------------------------------------
       
  1198 // From class MDirectContainer.
       
  1199 // CMIDCanvas::MdcNotifyContentAdded
       
  1200 // Notification about added direct content, called in LCDUI thread.
       
  1201 // Canvas needs to dispose pixel source before MMAPI adds video surface
       
  1202 // to canvas window. Pixel source cannot be disposed in MdcAddContent
       
  1203 // because it may be called in MMAPI thread.
       
  1204 // ---------------------------------------------------------------------------
       
  1205 //
       
  1206 void CMIDCanvas::MdcNotifyContentAdded()
       
  1207 {
       
  1208     DisposePixelSource();
       
  1209     CloseEgl();
       
  1210 }
       
  1211 #endif // RD_JAVA_NGA_ENABLED
       
  1212 
       
  1213 
       
  1214 // ---------------------------------------------------------------------------
       
  1215 // From class MMIDMediaKeysListener.
       
  1216 // CMIDCanvas::HandleMediaKeyEvent
       
  1217 // This method is called when a media key has been pressed.
       
  1218 // ---------------------------------------------------------------------------
       
  1219 //
       
  1220 void CMIDCanvas::HandleMediaKeyEvent(TMIDKeyEvent& aKeyEvent)
       
  1221 {
       
  1222     if (PostKeyEvents())
       
  1223     {
       
  1224         DEBUG_INT3(
       
  1225             "CMIDCanvas::HandleMediaKeyEvent - PostKeyEvent() - \
       
  1226 JAVA code %d type %d repeats %d",
       
  1227             aKeyEvent.iKeyCode,
       
  1228             aKeyEvent.iEvents,
       
  1229             aKeyEvent.iRepeats);
       
  1230 
       
  1231         iEnv.PostKeyEvent(*this, aKeyEvent);
       
  1232     }
       
  1233 }
       
  1234 
       
  1235 
       
  1236 #ifdef RD_TACTILE_FEEDBACK
       
  1237 // ---------------------------------------------------------------------------
       
  1238 // From class MMIDTactileFeedbackComponent.
       
  1239 // CMIDCanvas::UpdateTactileFeedback
       
  1240 // Update tactile feedback areas.
       
  1241 // ---------------------------------------------------------------------------
       
  1242 //
       
  1243 void CMIDCanvas::UpdateTactileFeedback()
       
  1244 {
       
  1245     TInt areaCount = iTactileFeedback->GetAreasCount();
       
  1246 
       
  1247     for (TInt i = 0; i < areaCount; i++)
       
  1248     {
       
  1249         CMIDTactileFeedbackExtension::FeedbackArea* area =
       
  1250             iTactileFeedback->GetArea(i);
       
  1251 
       
  1252         TRect physicalRect = area->rect;
       
  1253 
       
  1254         iTactileFeedback->SetFeedbackArea(area->id,
       
  1255                                           physicalRect,
       
  1256                                           (TInt)area->style);
       
  1257     }
       
  1258 }
       
  1259 
       
  1260 
       
  1261 // ---------------------------------------------------------------------------
       
  1262 // From class MMIDTactileFeedbackComponent.
       
  1263 // CMIDCanvas::RegisterFeedbackArea
       
  1264 // Register feedback area.
       
  1265 // ---------------------------------------------------------------------------
       
  1266 //
       
  1267 void CMIDCanvas::RegisterFeedbackArea(TInt aId, TRect aRect, TInt aStyle)
       
  1268 {
       
  1269     iTactileFeedback->RegisterFeedbackArea(aId, aRect, aStyle);
       
  1270 }
       
  1271 
       
  1272 
       
  1273 // ---------------------------------------------------------------------------
       
  1274 // From class MMIDTactileFeedbackComponent.
       
  1275 // CMIDCanvas::UnregisterFeedbackArea
       
  1276 // Unregister feedback area.
       
  1277 // ---------------------------------------------------------------------------
       
  1278 //
       
  1279 void CMIDCanvas::UnregisterFeedbackArea(TInt aId)
       
  1280 {
       
  1281     iTactileFeedback->UnregisterFeedbackArea(aId);
       
  1282 }
       
  1283 
       
  1284 
       
  1285 // ---------------------------------------------------------------------------
       
  1286 // From class MMIDTactileFeedbackComponent.
       
  1287 // CMIDCanvas::UnregisterFeedbackForControl
       
  1288 // Unregister feedback for the control.
       
  1289 // ---------------------------------------------------------------------------
       
  1290 //
       
  1291 void CMIDCanvas::UnregisterFeedbackForControl()
       
  1292 {
       
  1293     iTactileFeedback->UnregisterFeedbackForControl();
       
  1294 }
       
  1295 
       
  1296 
       
  1297 // ---------------------------------------------------------------------------
       
  1298 // From class MMIDTactileFeedbackComponent.
       
  1299 // CMIDCanvas::MoveAreaToFirstPriority
       
  1300 // Move area to first priority.
       
  1301 // ---------------------------------------------------------------------------
       
  1302 //
       
  1303 void CMIDCanvas::MoveAreaToFirstPriority(TInt aId)
       
  1304 {
       
  1305     iTactileFeedback->MoveAreaToFirstPriority(aId);
       
  1306 }
       
  1307 #endif // RD_TACTILE_FEEDBACK
       
  1308 
       
  1309 // ---------------------------------------------------------------------------
       
  1310 // CMIDCanvas::RegisterComponentL
       
  1311 // Registers a new custom component to this container.
       
  1312 // (other items are commented in the header file)
       
  1313 // ---------------------------------------------------------------------------
       
  1314 //
       
  1315 void CMIDCanvas::RegisterComponentL(MMIDCustomComponent* aComponent)
       
  1316 {
       
  1317     DEBUG("CMIDCanvas::RegisterComponentL +");
       
  1318 
       
  1319     if (iCustomComponents.Find(aComponent) == KErrNotFound)
       
  1320     {
       
  1321         DEBUG("CMIDCanvas::RegisterComponentL, registering new");
       
  1322 
       
  1323         iCustomComponents.Append(aComponent);
       
  1324 
       
  1325         // Update custom components count in order to improve
       
  1326         // the performance when counting components
       
  1327         iCustomComponentsControlCount +=
       
  1328             aComponent->CustomComponentControlCount();
       
  1329 
       
  1330     }
       
  1331 
       
  1332     DEBUG("CMIDCanvas::RegisterComponentL -");
       
  1333 }
       
  1334 
       
  1335 // ---------------------------------------------------------------------------
       
  1336 // CMIDCanvas::UnregisterComponent
       
  1337 // Unregisters an existing custom component from this container.
       
  1338 // (other items are commented in the header file)
       
  1339 // ---------------------------------------------------------------------------
       
  1340 //
       
  1341 void CMIDCanvas::UnregisterComponent(MMIDCustomComponent* aComponent)
       
  1342 {
       
  1343     DEBUG("CMIDCanvas::UnregisterComponent +");
       
  1344 
       
  1345     TInt index = iCustomComponents.Find(aComponent);
       
  1346 
       
  1347     if (index != KErrNotFound)
       
  1348     {
       
  1349         // Update of iFocusedComponent index.
       
  1350         if (index < iFocusedComponent)
       
  1351         {
       
  1352             iFocusedComponent--;
       
  1353         }
       
  1354         else if (index == iFocusedComponent)
       
  1355         {
       
  1356             iFocusedComponent = KComponentFocusedNone;
       
  1357         }
       
  1358 
       
  1359         if ((iPressedComponent) && (iPressedComponent == aComponent))
       
  1360         {
       
  1361             iPressedComponent = NULL;
       
  1362         }
       
  1363 
       
  1364         iCustomComponents.Remove(index);
       
  1365         // Compress the array to keep the object indexes in order.
       
  1366         iCustomComponents.Compress();
       
  1367         // Update custom components count in order to improve
       
  1368         // the performance when counting components
       
  1369         iCustomComponentsControlCount -=
       
  1370             aComponent->CustomComponentControlCount();
       
  1371 
       
  1372         // Redraw the whole canvas.
       
  1373         DrawDeferred();
       
  1374     }
       
  1375 
       
  1376     DEBUG("CMIDCanvas::UnregisterComponent -");
       
  1377 }
       
  1378 
       
  1379 // ---------------------------------------------------------------------------
       
  1380 // CMIDCanvas::IsFullScreen
       
  1381 // (other items are commented in the header file)
       
  1382 // ---------------------------------------------------------------------------
       
  1383 //
       
  1384 TBool CMIDCanvas::IsFullScreen() const
       
  1385 {
       
  1386     return iFullScreen;
       
  1387 }
       
  1388 
       
  1389 // ---------------------------------------------------------------------------
       
  1390 // CMIDCanvas::SetComponentIndexL
       
  1391 // Changes the index of the specified custom component.
       
  1392 // (other items are commented in the header file)
       
  1393 // ---------------------------------------------------------------------------
       
  1394 //
       
  1395 void CMIDCanvas::SetComponentIndexL(
       
  1396     MMIDCustomComponent* aComponent,
       
  1397     TInt aNewIndex)
       
  1398 {
       
  1399     DEBUG("CMIDCanvas::SetComponentIndexL +");
       
  1400 
       
  1401     // Adjust the index if it is out of bounds.
       
  1402     TInt count = iCustomComponents.Count();
       
  1403     if (aNewIndex >= count)
       
  1404     {
       
  1405         aNewIndex = count - 1;
       
  1406     }
       
  1407 
       
  1408     // The index must not be negative.
       
  1409     __ASSERT_DEBUG(aNewIndex >= 0, User::Invariant());
       
  1410 
       
  1411     TInt index = iCustomComponents.Find(aComponent);
       
  1412 
       
  1413     // Do not adjust the position if there is no need for it
       
  1414     // or if the component does not exist in the array.
       
  1415     if (index != KErrNotFound && index != aNewIndex)
       
  1416     {
       
  1417         // Update index of focused component
       
  1418 
       
  1419         if (index == iFocusedComponent)
       
  1420         {
       
  1421             iFocusedComponent = aNewIndex;
       
  1422         }
       
  1423         else if ((iFocusedComponent < index) && (iFocusedComponent >= aNewIndex))
       
  1424         {
       
  1425             iFocusedComponent++;
       
  1426         }
       
  1427         else if ((iFocusedComponent > index) && (iFocusedComponent <= aNewIndex))
       
  1428         {
       
  1429             iFocusedComponent--;
       
  1430         }
       
  1431 
       
  1432         // Remove the old index from the components array.
       
  1433         iCustomComponents.Remove(index);
       
  1434 
       
  1435         // Add the component to the new index. Note that the array
       
  1436         // should contain memory for all the components since
       
  1437         // Remove should not decrease the memory used by the array
       
  1438         // Therefore, the following operation is leave-safe and
       
  1439         // return value is ignored intentionally.
       
  1440         iCustomComponents.Insert(aComponent, aNewIndex);
       
  1441 
       
  1442         // Redraw the whole canvas.
       
  1443         DrawDeferred();
       
  1444     }
       
  1445 
       
  1446     DEBUG("CMIDCanvas::SetComponentIndexL -");
       
  1447 }
       
  1448 
       
  1449 // ---------------------------------------------------------------------------
       
  1450 // CMIDCanvas::ComponentIndex
       
  1451 // Returns the index of the given component in this container.
       
  1452 // (other items are commented in the header file)
       
  1453 // ---------------------------------------------------------------------------
       
  1454 //
       
  1455 TInt CMIDCanvas::ComponentIndex(MMIDCustomComponent* aComponent) const
       
  1456 {
       
  1457     DEBUG("CMIDCanvas::ComponentIndex");
       
  1458 
       
  1459     return iCustomComponents.Find(aComponent);
       
  1460 }
       
  1461 
       
  1462 // ---------------------------------------------------------------------------
       
  1463 // CMIDCanvas::PostEvent
       
  1464 // Post an event to Java side.
       
  1465 // ---------------------------------------------------------------------------
       
  1466 //
       
  1467 TBool CMIDCanvas::PostEvent(
       
  1468     TEventType aType,
       
  1469     TInt aData0,
       
  1470     TInt aData1) const
       
  1471 {
       
  1472     return iEnv.PostJavaEvent(const_cast< CMIDCanvas& >(*this),
       
  1473                               EDisplayable,
       
  1474                               aType,
       
  1475                               aData0,
       
  1476                               aData1,
       
  1477                               0);
       
  1478 }
       
  1479 
       
  1480 #ifdef RD_JAVA_NGA_ENABLED
       
  1481 
       
  1482 // ---------------------------------------------------------------------------
       
  1483 // CMIDCanvas::Update
       
  1484 // Update screen from frame buffer.
       
  1485 // ---------------------------------------------------------------------------
       
  1486 //
       
  1487 void CMIDCanvas::UpdateL(const TRect& aRect)
       
  1488 {
       
  1489     // Drawing Network indicator only when Update is called.
       
  1490     if (iFullScreen && iNetworkIndicator)
       
  1491     {
       
  1492         iNetworkIndicator->SetDrawIndicator(ETrue);
       
  1493     }
       
  1494 
       
  1495     // iRestoreContentWhenUnfaded is used when Canvas should be faded
       
  1496     // DrawNow need to be called, otherwise  Canvas will be unfaded
       
  1497     if (iDirectContents.Count() == 0 && !iRestoreContentWhenUnfaded && IsFocused())
       
  1498     {
       
  1499         // In case direct content content was removed
       
  1500         // from canvas, recreate pixel source here
       
  1501         if (!iAlfCompositionPixelSource &&
       
  1502                 !IsEglAvailable())
       
  1503         {
       
  1504             InitPixelSourceL();
       
  1505         }
       
  1506         DrawWindowNgaL(aRect);
       
  1507     }
       
  1508     else
       
  1509     {
       
  1510         // Must draw via CCoeControl framework
       
  1511         DrawNow(aRect);
       
  1512     }
       
  1513 
       
  1514     // This is needed to avoid artifacting after orientation switch.
       
  1515     // It is called once after orientation change.
       
  1516     if (iWndUpdate)
       
  1517     {
       
  1518         iWndUpdate = EFalse;
       
  1519     }
       
  1520 }
       
  1521 
       
  1522 #else // !RD_JAVA_NGA_ENABLED
       
  1523 // ---------------------------------------------------------------------------
       
  1524 // CMIDCanvas::Update
       
  1525 // Update screen from frame buffer.
       
  1526 // ---------------------------------------------------------------------------
       
  1527 //
       
  1528 void CMIDCanvas::Update(const TRect& aRect)
       
  1529 {
       
  1530     DEBUG("- CMIDCanvas::Update");
       
  1531 
       
  1532 #ifdef CANVAS_DOUBLE_BUFFER
       
  1533     if (IsVisible())
       
  1534     {
       
  1535         // Drawing Network indicator only when Update is called.
       
  1536         if (iFullScreen && iNetworkIndicator)
       
  1537         {
       
  1538             iNetworkIndicator->SetDrawIndicator(ETrue);
       
  1539         }
       
  1540 
       
  1541 #ifdef CANVAS_DIRECT_ACCESS
       
  1542         // Check if some direct screen content is drawn.
       
  1543         if (iDirectContents.Count() > 0)
       
  1544         {
       
  1545             // There is some direct screen content drawn, DSA is not free for
       
  1546             // us at the moment.
       
  1547             DrawNow(aRect);
       
  1548         }
       
  1549         else
       
  1550         {
       
  1551             // No direct screen content is drawn, so we can try to use DSA.
       
  1552             StartDirectAccess();
       
  1553 
       
  1554             if (iDirectGc)
       
  1555             {
       
  1556                 // DSA is ready to use, draw directly.
       
  1557                 DrawDirect(aRect);
       
  1558             }
       
  1559             else
       
  1560 #endif // CANVAS_DIRECT_ACCESS
       
  1561             {
       
  1562                 ActivateGc();
       
  1563                 DrawWindow(aRect);
       
  1564                 DeactivateGc();
       
  1565             }
       
  1566 #ifdef CANVAS_DIRECT_ACCESS
       
  1567         }
       
  1568 #endif // CANVAS_DIRECT_ACCESS
       
  1569 
       
  1570         // This is needed to avoid artifacting after orientation switch.
       
  1571         // It is called once after orientation change.
       
  1572         if (iWndUpdate)
       
  1573         {
       
  1574             iWndUpdate = EFalse;
       
  1575         }
       
  1576     }
       
  1577 #endif // CANVAS_DOUBLE_BUFFER
       
  1578 
       
  1579     DEBUG("+ CMIDCanvas::Update");
       
  1580 }
       
  1581 
       
  1582 #endif // RD_JAVA_NGA_ENABLED
       
  1583 
       
  1584 // ---------------------------------------------------------------------------
       
  1585 // CMIDCanvas::PrepareDraw
       
  1586 // Prepare drawing. Used in DrawWindow and DrawDirect.
       
  1587 // aWindowRect is in bitmap coords.
       
  1588 // ---------------------------------------------------------------------------
       
  1589 //
       
  1590 inline void CMIDCanvas::PrepareDraw(
       
  1591     CGraphicsContext& aGc, TRect& aWinRect) const
       
  1592 {
       
  1593     const TRect rect = Rect();
       
  1594 #ifdef RD_JAVA_NGA_ENABLED
       
  1595     if (iDirectContents.Count() > 0)
       
  1596     {
       
  1597 
       
  1598         // Content may be centered in which case we need to clear the background.
       
  1599         if (rect != iViewRect)
       
  1600         {
       
  1601             // Clear background with black if centered.
       
  1602             aGc.SetBrushColor(KRgbBlack);
       
  1603             aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1604 
       
  1605             DrawUtils::ClearBetweenRects(aGc, rect, iViewRect);
       
  1606         }
       
  1607     }
       
  1608 #else
       
  1609     // Content may be centered in which case we need to clear the background.
       
  1610     if (rect != iViewRect)
       
  1611     {
       
  1612         // Clear background with black if centered.
       
  1613         aGc.SetBrushColor(KRgbBlack);
       
  1614         aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1615 
       
  1616         DrawUtils::ClearBetweenRects(aGc, rect, iViewRect);
       
  1617     }
       
  1618 #endif // RD_JAVA_NGA_ENABLED
       
  1619 
       
  1620     if (iFullScreen && iNetworkIndicator)
       
  1621     {
       
  1622         // Network indicator or call indicator is drawn to the off-screen
       
  1623         // buffer if connection is open.
       
  1624         iNetworkIndicator->DrawNetworkIndicator(
       
  1625             *iFrameContext, aWinRect, iViewRect);
       
  1626     }
       
  1627 
       
  1628     if (iViewRect.Size() == iContentSize)
       
  1629     {
       
  1630         // Transform the source rect to window coords.
       
  1631         aWinRect.Move(iViewRect.iTl);
       
  1632 
       
  1633         // Clip to viewport.
       
  1634         aWinRect.Intersection(iViewRect);
       
  1635     }
       
  1636     else
       
  1637     {
       
  1638         aWinRect = iViewRect;
       
  1639     }
       
  1640 }
       
  1641 
       
  1642 
       
  1643 #ifdef RD_JAVA_NGA_ENABLED
       
  1644 // ---------------------------------------------------------------------------
       
  1645 // CMIDCanvas::DrawWindowNgaL
       
  1646 // Draw using pixel source of EGL surface depending on what canvas content
       
  1647 // has been drawn.
       
  1648 // ---------------------------------------------------------------------------
       
  1649 //
       
  1650 void CMIDCanvas::DrawWindowNgaL(const TRect& aRect)
       
  1651 {
       
  1652     ASSERT(IsEglAvailable() || iAlfCompositionPixelSource);
       
  1653 
       
  1654     if (iFullScreen && iNetworkIndicator)
       
  1655     {
       
  1656         TRect windowRect(aRect);
       
  1657         iNetworkIndicator->DrawNetworkIndicator(
       
  1658             *iFrameContext, windowRect, iViewRect);
       
  1659     }
       
  1660 
       
  1661     if (!IsEglAvailable())
       
  1662     {
       
  1663         // No M3G content, use pixel source
       
  1664         ActivatePixelSourceL();
       
  1665         DEBUG("CMIDCanvas::Draw - Pixel Source activated");
       
  1666     }
       
  1667     else // M3G content, use EGL surface
       
  1668     {
       
  1669         // Invalidates window so that wserv does not
       
  1670         // draw window content on top our EGL surface.
       
  1671         // This is needed only once when starting to use EGL surface.
       
  1672         if (iM3GStart)
       
  1673         {
       
  1674             DEBUG("CMIDCanvas::DrawWindow - invalidate");
       
  1675             Window().Invalidate();
       
  1676             iM3GStart = EFalse;
       
  1677         }
       
  1678 
       
  1679         if (iScalingOn && iFullScreen)
       
  1680         {
       
  1681             SetCurrentEglType(EEglPbuffer);
       
  1682             BlitFrameBufferPixels();
       
  1683             SetCurrentEglType(EEglWindow);
       
  1684             if (iWndUpdate)
       
  1685             {
       
  1686                 DEBUG("CMIDCanvas::DrawWindowNgaL() - clearing window surface");
       
  1687                 ClearEglSurface(EEglWindow);
       
  1688             }
       
  1689             BlitPBufferScaledToWindowSurface();
       
  1690         }
       
  1691         else
       
  1692         {
       
  1693             SetCurrentEglType(EEglWindow);
       
  1694             BlitFrameBufferPixels();
       
  1695         }
       
  1696 
       
  1697         if (eglSwapBuffers(iEglDisplay, iEglWindowSurface) == EGL_FALSE)
       
  1698         {
       
  1699             ELOG1(EJavaUI, "eglSwapBuffers() failed, eglError=%d", eglGetError());
       
  1700             ASSERT(EFalse);
       
  1701         }
       
  1702         SetCurrentEglType(EEglNone);
       
  1703     }
       
  1704 }
       
  1705 #endif // RD_JAVA_NGA_ENABLED
       
  1706 
       
  1707 
       
  1708 #ifdef CANVAS_DOUBLE_BUFFER
       
  1709 // ---------------------------------------------------------------------------
       
  1710 // CMIDCanvas::DrawWindow
       
  1711 // Draw through Window server using native frame buffer.
       
  1712 // ---------------------------------------------------------------------------
       
  1713 //
       
  1714 void CMIDCanvas::DrawWindow(const TRect& aRect) const
       
  1715 {
       
  1716     DEBUG("CMIDCanvas::DrawWindow ++");
       
  1717     ASSERT(iFrameBuffer);
       
  1718 
       
  1719     CWindowGc& gc = SystemGc();
       
  1720 
       
  1721     // If EColor16MA display mode is used, graphics context needs to set its
       
  1722     // draw mode to EDrawModeWriteAlpha for just to copy an alpha channel and
       
  1723     // not to do any blending.
       
  1724     if (iFrameBuffer->DisplayMode() == EColor16MA)
       
  1725     {
       
  1726         gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
       
  1727     }
       
  1728 
       
  1729     TRect windowRect(aRect);
       
  1730     PrepareDraw(gc, windowRect);
       
  1731 
       
  1732     // Check if Canvas scaling is used.
       
  1733     if (iViewRect.Size() == iContentSize)
       
  1734     {
       
  1735         DEBUG("DrawWindow - Not scaled - BitBlt");
       
  1736         gc.BitBlt(windowRect.iTl, iFrameBuffer, windowRect);
       
  1737     }
       
  1738     else if (IsDownScaling(iContentSize, iViewRect))
       
  1739     {
       
  1740         DEBUG("DrawWindow - Downscaling - BitBlt");
       
  1741         gc.BitBlt(windowRect.iTl, iFrameBuffer, windowRect.Size());
       
  1742     }
       
  1743     // Upscaling
       
  1744     else if (iScaler)
       
  1745     {
       
  1746         iFrameBuffer->LockHeap();
       
  1747         TUint32* pixelData = iFrameBuffer->DataAddress();
       
  1748 
       
  1749         // Scale the framebuffer content.
       
  1750         CFbsBitmap* map = iScaler->Process(
       
  1751                               iFrameBuffer->DisplayMode(),
       
  1752                               pixelData,
       
  1753                               iContentSize.iWidth,
       
  1754                               iContentSize.iHeight,
       
  1755                               iFrameBuffer->SizeInPixels().iWidth - iContentSize.iWidth,
       
  1756                               iViewRect.Width(),
       
  1757                               iViewRect.Height());
       
  1758 
       
  1759         iFrameBuffer->UnlockHeap();
       
  1760 
       
  1761         if (map)
       
  1762         {
       
  1763             DEBUG("DrawWindow - Upscaling - BitBlt - map ok");
       
  1764             gc.BitBlt(windowRect.iTl, map, windowRect.Size());
       
  1765         }
       
  1766         else
       
  1767         {
       
  1768             DEBUG("DrawWindow - Upscaling - DrawBitmap - no map");
       
  1769             gc.DrawBitmap(windowRect, iFrameBuffer, iContentSize);
       
  1770         }
       
  1771     }
       
  1772 
       
  1773 #ifdef RD_JAVA_NGA_ENABLED
       
  1774     iCoeEnv->WsSession().Finish();
       
  1775 #endif
       
  1776 
       
  1777     DEBUG("CMIDCanvas::DrawWindow --");
       
  1778 }
       
  1779 #endif // CANVAS_DOUBLE_BUFFER
       
  1780 
       
  1781 
       
  1782 #ifdef CANVAS_DIRECT_ACCESS
       
  1783 // ---------------------------------------------------------------------------
       
  1784 // CMIDCanvas::StartDirectAccess
       
  1785 // Start Direct Screen Access.
       
  1786 // ---------------------------------------------------------------------------
       
  1787 //
       
  1788 void CMIDCanvas::StartDirectAccess()
       
  1789 {
       
  1790     // If DSA is not enabled or paused, or direct GC already exists just get
       
  1791     // out of here.
       
  1792     if (!DirectEnabled() || DirectPaused() || iDirectGc)
       
  1793     {
       
  1794         return;
       
  1795     }
       
  1796 
       
  1797     CCoeAppUi& appUi = *static_cast< CCoeAppUi* >(ControlEnv()->AppUi());
       
  1798 
       
  1799     if (appUi.IsDisplayingMenuOrDialog())
       
  1800     {
       
  1801         return;
       
  1802     }
       
  1803 
       
  1804     TRAPD(err, RestartL());
       
  1805 
       
  1806     if (KErrNone != err)
       
  1807     {
       
  1808         StopDirectAccess();
       
  1809     }
       
  1810     else
       
  1811     {
       
  1812         if (iDcDsaToStart && iDirectGc)
       
  1813         {
       
  1814             // Resume DSA for all direct contents
       
  1815             iDcDsaToStart = EFalse;
       
  1816             TInt contentsCount(iDirectContents.Count());
       
  1817 
       
  1818             for (TInt j = 0; j < contentsCount; j++)
       
  1819             {
       
  1820                 iDirectContents[j]->MdcResumeDSA();
       
  1821             }
       
  1822         }
       
  1823     }
       
  1824 }
       
  1825 
       
  1826 
       
  1827 // ---------------------------------------------------------------------------
       
  1828 // CMIDCanvas::StopDirectAccess
       
  1829 // Stop Direct Screen Access.
       
  1830 // ---------------------------------------------------------------------------
       
  1831 //
       
  1832 void CMIDCanvas::StopDirectAccess()
       
  1833 {
       
  1834     iDirectGc = NULL;
       
  1835     if (!iDcDsaToStart)
       
  1836     {
       
  1837         // Abort direct DSA for all direct contents
       
  1838 
       
  1839         TInt contentsCount(iDirectContents.Count());
       
  1840 
       
  1841         if (contentsCount > 0)
       
  1842         {
       
  1843             iDcDsaToStart = ETrue;
       
  1844         }
       
  1845 
       
  1846         for (TInt j = 0; j < contentsCount; j++)
       
  1847         {
       
  1848             iDirectContents[j]->MdcAbortDSA();
       
  1849         }
       
  1850     }
       
  1851 
       
  1852     if (iDirectAccess)
       
  1853     {
       
  1854         iDirectAccess->Cancel();
       
  1855     }
       
  1856 }
       
  1857 
       
  1858 
       
  1859 // ---------------------------------------------------------------------------
       
  1860 // CMIDCanvas::RestartL
       
  1861 // Restart Direct Screen Access.
       
  1862 // ---------------------------------------------------------------------------
       
  1863 //
       
  1864 void CMIDCanvas::RestartL()
       
  1865 {
       
  1866     ASSERT(DirectEnabled());
       
  1867     ASSERT(iDirectAccess);
       
  1868 
       
  1869     if (!iDirectAccess->IsActive())
       
  1870     {
       
  1871         iDirectAccess->StartL();
       
  1872     }
       
  1873 
       
  1874     iDirectGc = NULL;
       
  1875 
       
  1876     if (iDirectAccess->DrawingRegion()->Count() == 1)
       
  1877     {
       
  1878         // Check that the drawing region is fully visibile (not covered)
       
  1879         TRect drawableRect((*iDirectAccess->DrawingRegion())[0]);
       
  1880         TRect canvasRect(PositionRelativeToScreen(), Size());
       
  1881 
       
  1882         drawableRect.Intersection(canvasRect);
       
  1883 
       
  1884         // Check that the drawing region has the proper size
       
  1885         if (drawableRect == canvasRect)
       
  1886         {
       
  1887             // Prepare context for actual drawing
       
  1888             iDirectGc = iDirectAccess->Gc();
       
  1889 
       
  1890             // Direct draw is using only BitBlt and DrawBitmap so we can
       
  1891             // always use EDrawModeWriteAlpha draw mode to optimize drawing
       
  1892             // process. If EColor16MA display mode is used, graphics context
       
  1893             // needs to set its draw mode to EDrawModeWriteAlpha to just copy
       
  1894             // an alpha channel and not do any blending.
       
  1895             if (iFrameBuffer->DisplayMode() == EColor16MA)
       
  1896             {
       
  1897                 iDirectGc->SetDrawMode(
       
  1898                     CGraphicsContext::EDrawModeWriteAlpha);
       
  1899             }
       
  1900         }
       
  1901     }
       
  1902 }
       
  1903 
       
  1904 
       
  1905 // ---------------------------------------------------------------------------
       
  1906 // CMIDCanvas::DrawDirect
       
  1907 // Draw using Direct Screen Access.
       
  1908 // aRect is in framebuffer coords.
       
  1909 // ---------------------------------------------------------------------------
       
  1910 //
       
  1911 void CMIDCanvas::DrawDirect(const TRect& aRect) const
       
  1912 {
       
  1913     DEBUG("+ CMIDCanvas::DrawDirect");
       
  1914 
       
  1915     ASSERT(DirectEnabled());
       
  1916     ASSERT(iDirectGc);
       
  1917     ASSERT(iDirectAccess);
       
  1918     ASSERT(iFrameBuffer);
       
  1919 
       
  1920     // Visible region in screen coordinates. Should only contain a single clip
       
  1921     // rect otherwise direct access should have aborted.
       
  1922     const RRegion& visibleRegion = *(iDirectAccess->DrawingRegion());
       
  1923 
       
  1924     ASSERT(visibleRegion.Count() == 1);
       
  1925 
       
  1926     TRect windowRect(aRect);
       
  1927     PrepareDraw(*iDirectGc, windowRect);
       
  1928 
       
  1929     // Check if Canvas scaling is used.
       
  1930     if (iViewRect == iContentSize)
       
  1931     {
       
  1932         // No scaling, plain draw.
       
  1933         DEBUG("DrawDirect - NotScaled");
       
  1934         iDirectGc->BitBlt(windowRect.iTl, iFrameBuffer, windowRect);
       
  1935     }
       
  1936     else if (IsDownScaling(iContentSize, iViewRect))
       
  1937     {
       
  1938         DEBUG("DrawDirect - Downscaling");
       
  1939         iDirectGc->BitBlt(windowRect.iTl, iFrameBuffer, windowRect.Size());
       
  1940     }
       
  1941     // Upscaling
       
  1942     else if (iScaler)
       
  1943     {
       
  1944         iFrameBuffer->LockHeap();
       
  1945         TUint32* pixelData = iFrameBuffer->DataAddress();
       
  1946 
       
  1947         // Scale the framebuffer content.
       
  1948         CFbsBitmap* map = iScaler->Process(
       
  1949                               iFrameBuffer->DisplayMode(),
       
  1950                               pixelData,
       
  1951                               iContentSize.iWidth,
       
  1952                               iContentSize.iHeight,
       
  1953                               iFrameBuffer->SizeInPixels().iWidth - iContentSize.iWidth,
       
  1954                               iViewRect.Width(),
       
  1955                               iViewRect.Height());
       
  1956 
       
  1957         iFrameBuffer->UnlockHeap();
       
  1958 
       
  1959         if (map)
       
  1960         {
       
  1961             DEBUG("DrawDirect - Upscaling - BitBlt - map ok");
       
  1962             iDirectGc->BitBlt(windowRect.iTl, map, windowRect.Size());
       
  1963         }
       
  1964         else
       
  1965         {
       
  1966             DEBUG("DrawDirect - Upscaling - DrawBitmap - no map");
       
  1967             iDirectGc->DrawBitmap(windowRect, iFrameBuffer, iContentSize);
       
  1968         }
       
  1969     }
       
  1970 
       
  1971     if (UpdateRequired())
       
  1972     {
       
  1973         windowRect.Move(PositionRelativeToScreen());
       
  1974         windowRect.Intersection(visibleRegion.RectangleList()[0]);
       
  1975 
       
  1976         // Direct screen drawing does not show up on some devices unless the
       
  1977         // screen device Update() method is called.
       
  1978         iUpdateRegion.Clear();
       
  1979         iUpdateRegion.AddRect(windowRect);
       
  1980         iDirectAccess->ScreenDevice()->Update(iUpdateRegion);
       
  1981     }
       
  1982 
       
  1983     DEBUG("- CMIDCanvas::DrawDirect");
       
  1984 }
       
  1985 #endif //CANVAS_DIRECT_ACCESS
       
  1986 
       
  1987 
       
  1988 // ---------------------------------------------------------------------------
       
  1989 // From class CCoeControl.
       
  1990 // CMIDCanvas::HandleResourceChange
       
  1991 // Resource change handling.
       
  1992 // ---------------------------------------------------------------------------
       
  1993 //
       
  1994 void CMIDCanvas::HandleResourceChange(TInt aType)
       
  1995 {
       
  1996     if (aType == KEikInputLanguageChange)
       
  1997     {
       
  1998         if ((iFocusedComponent != KComponentFocusedNone) &&
       
  1999                 (iFocusedComponent < iCustomComponents.Count()))
       
  2000         {
       
  2001             iCustomComponents[iFocusedComponent]->
       
  2002             CustomComponentControl(KComponentMainControl)->
       
  2003             HandleResourceChange(aType);
       
  2004         }
       
  2005     }
       
  2006     if (aType == KEikDynamicLayoutVariantSwitch)
       
  2007     {
       
  2008         // If orientation change is done,
       
  2009         // then we have to inform all components about it.
       
  2010         if (iFocusedComponent != KComponentFocusedNone &&
       
  2011                 iFullScreen)
       
  2012         {
       
  2013             for (int i = 0; i < iCustomComponents.Count(); i++)
       
  2014             {
       
  2015                 iCustomComponents[i]->HandleResolutionChange();
       
  2016             }
       
  2017         }
       
  2018     }
       
  2019     else if ((aType == KEikMessageUnfadeWindows) ||
       
  2020              (aType == KEikMessageFadeAllWindows))
       
  2021     {
       
  2022         iLastFadeMessage = aType;
       
  2023     }
       
  2024     else if ((aType == KEikMessageWindowsFadeChange) &&
       
  2025              ((iLastFadeMessage == KEikMessageUnfadeWindows) ||
       
  2026               (iLastFadeMessage == KEikMessageFadeAllWindows)))
       
  2027     {
       
  2028         TInt contentsCount(iDirectContents.Count());
       
  2029 
       
  2030         switch (iLastFadeMessage)
       
  2031         {
       
  2032         case KEikMessageUnfadeWindows:
       
  2033             iRestoreContentWhenUnfaded = EFalse;
       
  2034 
       
  2035 #ifdef CANVAS_DIRECT_ACCESS
       
  2036             ResumeDirectAccess();
       
  2037 #endif // CANVAS_DIRECT_ACCESS
       
  2038 
       
  2039             for (TInt j = 0; j < contentsCount; j++)
       
  2040             {
       
  2041                 iDirectContents[j]->MdcContainerVisibilityChanged(ETrue);
       
  2042             }
       
  2043             break;
       
  2044 
       
  2045         case KEikMessageFadeAllWindows:
       
  2046             iRestoreContentWhenUnfaded = ETrue;
       
  2047 
       
  2048 #ifdef CANVAS_DIRECT_ACCESS
       
  2049             PauseDirectAccess();
       
  2050 #endif // CANVAS_DIRECT_ACCESS
       
  2051 
       
  2052             for (TInt j = 0; j < contentsCount; j++)
       
  2053             {
       
  2054                 iDirectContents[j]->MdcContainerVisibilityChanged(EFalse);
       
  2055             }
       
  2056             break;
       
  2057         }
       
  2058         iLastFadeMessage = 0;
       
  2059     }
       
  2060 }
       
  2061 
       
  2062 #ifdef RD_SCALABLE_UI_V2
       
  2063 // ---------------------------------------------------------------------------
       
  2064 // CMIDCanvas::HandlePointerEventInControlsL
       
  2065 // Pointer events handling in controls.
       
  2066 // ---------------------------------------------------------------------------
       
  2067 //
       
  2068 TBool CMIDCanvas::HandlePointerEventInControlsL(
       
  2069     const TPointerEvent& aPointerEvent)
       
  2070 {
       
  2071     TBool inControl = EFalse;
       
  2072 
       
  2073     switch (aPointerEvent.iType)
       
  2074     {
       
  2075     case TPointerEvent::EButton1Down:
       
  2076     case TPointerEvent::EButton2Down:
       
  2077     case TPointerEvent::EButton3Down:
       
  2078         // Pointer pressed
       
  2079         if ((iFocusedComponent > KComponentFocusedNone)&&
       
  2080                 (iFocusedComponent < iCustomComponents.Count()) &&
       
  2081                 (PointerEventInControl(iCustomComponents[iFocusedComponent],
       
  2082                                        aPointerEvent.iPosition)))
       
  2083         {
       
  2084             // Store the control for receiving pointer events until release
       
  2085             iPressedComponent = iCustomComponents[iFocusedComponent];
       
  2086             // Pass the pointer event
       
  2087             iPressedComponent->CustomComponentControl
       
  2088             (KComponentMainControl)->HandlePointerEventL(aPointerEvent);
       
  2089             inControl = ETrue;
       
  2090         }
       
  2091         break;
       
  2092     case TPointerEvent::EButton1Up:
       
  2093     case TPointerEvent::EButton2Up:
       
  2094     case TPointerEvent::EButton3Up:
       
  2095         // Pointer released
       
  2096         if ((iPressedComponent) && (PointerEventInControl(iPressedComponent,
       
  2097                                     aPointerEvent.iPosition)))
       
  2098         {
       
  2099             // Pass the pointer event
       
  2100             iPressedComponent->CustomComponentControl
       
  2101             (KComponentMainControl)->HandlePointerEventL(aPointerEvent);
       
  2102             iPressedComponent = NULL;
       
  2103             inControl = ETrue;
       
  2104         }
       
  2105         break;
       
  2106     case TPointerEvent::EDrag:
       
  2107         if (iPressedComponent)
       
  2108         {
       
  2109             iPressedComponent->ProcessPointerEventL(aPointerEvent);
       
  2110             inControl = ETrue;
       
  2111         }
       
  2112         break;
       
  2113     default:
       
  2114         break;
       
  2115     }
       
  2116     return inControl;
       
  2117 }
       
  2118 
       
  2119 // ---------------------------------------------------------------------------
       
  2120 // CMIDCanvas::PointerEventInControl
       
  2121 // Pointer events checking.
       
  2122 // ---------------------------------------------------------------------------
       
  2123 //
       
  2124 TBool CMIDCanvas::PointerEventInControl(MMIDCustomComponent* aControl,
       
  2125                                         TPoint aPoint)
       
  2126 {
       
  2127     TBool inControl = EFalse;
       
  2128     TInt compoundCount = aControl->CustomComponentControlCount();
       
  2129     for (int j = 0; j < compoundCount; j++)
       
  2130     {
       
  2131         // Check if the pointer event position is in visible control's
       
  2132         // area.
       
  2133         if (aControl->CustomComponentControl(j)->IsVisible())
       
  2134         {
       
  2135             inControl |= aControl->CustomComponentControl(j)->
       
  2136                          Rect().Contains(aPoint);
       
  2137         }
       
  2138     }
       
  2139     return inControl;
       
  2140 }
       
  2141 
       
  2142 // ---------------------------------------------------------------------------
       
  2143 // From class CCoeControl.
       
  2144 // CMIDCanvas::HandlePointerEventL
       
  2145 // Pointer events handling.
       
  2146 // ---------------------------------------------------------------------------
       
  2147 //
       
  2148 void CMIDCanvas::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  2149 {
       
  2150     if (AknLayoutUtils::PenEnabled())
       
  2151     {
       
  2152         TPoint point = aPointerEvent.iPosition;
       
  2153         TInt count = iCustomComponents.Count();
       
  2154         TBool consumed = EFalse;
       
  2155 
       
  2156         // Long tap not allowed in full screen mode.
       
  2157         if (!iFullScreen)
       
  2158         {
       
  2159             consumed = iDisplayable->TryDetectLongTapL(aPointerEvent);
       
  2160         }
       
  2161 
       
  2162         if (!consumed && (iFocusedComponent != KComponentFocusedNone) &&
       
  2163                 (iCustomComponents[iFocusedComponent]->IsTouchEnabled()))
       
  2164         {
       
  2165             consumed = HandlePointerEventInControlsL(aPointerEvent);
       
  2166         }
       
  2167 
       
  2168         if (!consumed)
       
  2169         {
       
  2170             // Points are counted from 0 to width - 1, resp. height -1,
       
  2171             // so we compute maxima for points coordinates based
       
  2172             // on native view size and java canvas size.
       
  2173             TSize nativeMaxCoords = iViewRect.Size() - TSize(1, 1);
       
  2174             TSize javaMaxCoords = iContentSize - TSize(1, 1);
       
  2175 
       
  2176             // Transform point to content coordinates.
       
  2177             //
       
  2178             // iViewRect.iTl                -> (0, 0)
       
  2179             // iViewRect.iBr - TSize(1, 1)  -> (iContentSize.iWidth - 1,
       
  2180             //                                  iContentSize.iHeight - 1)
       
  2181             point -= iViewRect.iTl;
       
  2182 
       
  2183             if (javaMaxCoords != nativeMaxCoords)
       
  2184             {
       
  2185                 point.iX = (point.iX * javaMaxCoords.iWidth) /
       
  2186                            nativeMaxCoords.iWidth;
       
  2187                 point.iY = (point.iY * javaMaxCoords.iHeight) /
       
  2188                            nativeMaxCoords.iHeight;
       
  2189             }
       
  2190 
       
  2191             TEventType type;
       
  2192             TTime now;
       
  2193 
       
  2194             switch (aPointerEvent.iType)
       
  2195             {
       
  2196             case TPointerEvent::EButton1Down:
       
  2197             case TPointerEvent::EButton2Down:
       
  2198             case TPointerEvent::EButton3Down:
       
  2199                 type = EPointerPressed;
       
  2200                 iPointerPressedCoordinates = TPoint(point.iX, point.iY);
       
  2201                 if (point.iX >= 0 && point.iX <= javaMaxCoords.iWidth &&
       
  2202                         point.iY >= 0 && point.iY <= javaMaxCoords.iHeight)
       
  2203                 {
       
  2204                     // Translated point is inside of java canvas
       
  2205                     iDragEventsStartedInside = ETrue;
       
  2206                 }
       
  2207                 break;
       
  2208             case TPointerEvent::EButton1Up:
       
  2209             case TPointerEvent::EButton2Up:
       
  2210             case TPointerEvent::EButton3Up:
       
  2211                 type = EPointerReleased;
       
  2212                 if (iPointerEventSuppressionOngoing)
       
  2213                 {
       
  2214                     point.iX = iPointerPressedCoordinates.iX;
       
  2215                     point.iY = iPointerPressedCoordinates.iY;
       
  2216                 }
       
  2217                 break;
       
  2218             case TPointerEvent::EDrag:
       
  2219                 type = EPointerDragged;
       
  2220                 // If pointerEventSuppressor time is set to 0 don't do any
       
  2221                 // drag event filtering. (default time here is 500ms and it
       
  2222                 // can be changed with JAD parameter
       
  2223                 // Nokia-MIDlet-Tap-Detection-Options)
       
  2224                 if (iPESTimeInMilliseconds != 0)
       
  2225                 {
       
  2226                     now.HomeTime();
       
  2227                     if (now.MicroSecondsFrom(iPreviousDragTimeStamp) <
       
  2228                             KAllowedTimeBetweenDragEvents)
       
  2229                     {
       
  2230                         // Ignore drag event because time between drags is
       
  2231                         // shorter than allowed interval.
       
  2232                         return;
       
  2233                     }
       
  2234                     else
       
  2235                     {
       
  2236                         iPreviousDragTimeStamp = now;
       
  2237                     }
       
  2238                 }
       
  2239                 break;
       
  2240             default:
       
  2241                 type = ENoType;
       
  2242             }
       
  2243 
       
  2244             // Pointer Event Suppressor for helping tap detection with finger
       
  2245             // usage
       
  2246             if (iPointerEventSuppressor->SuppressPointerEvent(aPointerEvent))
       
  2247             {
       
  2248                 iPointerEventSuppressionOngoing = ETrue;
       
  2249                 return;
       
  2250             }
       
  2251             else
       
  2252             {
       
  2253                 iPointerEventSuppressionOngoing = EFalse;
       
  2254             }
       
  2255 
       
  2256             // To have the cursor on focused control
       
  2257             if (iFocusedComponent != KComponentFocusedNone)
       
  2258             {
       
  2259                 iCustomComponents[iFocusedComponent]->
       
  2260                 CustomComponentControl(KComponentMainControl)->
       
  2261                 SetFocus(ETrue);
       
  2262             }
       
  2263 
       
  2264             // Ignore pointer events outside of Canvas content.
       
  2265             if (!iDragEventsStartedInside)
       
  2266             {
       
  2267                 return;
       
  2268             }
       
  2269 
       
  2270             PostEvent(type, point.iX, point.iY);
       
  2271 
       
  2272             // Flag is reset, if release event happened. However reset
       
  2273             // has to be done after event is sent to java, because of possible
       
  2274             // dragging, which started inside of canvas. In this case
       
  2275             // also release event should be delivered to java
       
  2276             if (type == EPointerReleased)
       
  2277             {
       
  2278                 iDragEventsStartedInside = EFalse;
       
  2279             }
       
  2280         }
       
  2281     }
       
  2282 }
       
  2283 #endif // RD_SCALABLE_UI_V2
       
  2284 
       
  2285 
       
  2286 // ---------------------------------------------------------------------------
       
  2287 // From class CCoeControl.
       
  2288 // CMIDCanvas::FocusChanged
       
  2289 // Change of focus.
       
  2290 // ---------------------------------------------------------------------------
       
  2291 //
       
  2292 void CMIDCanvas::FocusChanged(TDrawNow /* aDrawNow */)
       
  2293 {
       
  2294     DEBUG("+ CMIDCanvas::FocusChanged");
       
  2295 
       
  2296     iEnv.ResetKeys();
       
  2297     iGameKeyState = 0;
       
  2298     iGameKeyLatch = 0;
       
  2299 
       
  2300     TInt contentsCount(iDirectContents.Count());
       
  2301 
       
  2302     if (IsFocused())
       
  2303     {
       
  2304 #ifdef CANVAS_DIRECT_ACCESS
       
  2305         ResumeDirectAccess();
       
  2306 #endif // CANVAS_DIRECT_ACCESS
       
  2307 
       
  2308         if (!iRestoreContentWhenUnfaded)
       
  2309         {
       
  2310             for (TInt j = 0; j < contentsCount; j++)
       
  2311             {
       
  2312                 iDirectContents[j]->MdcContainerVisibilityChanged(ETrue);
       
  2313             }
       
  2314         }
       
  2315 
       
  2316         // To have cursor on focused control.
       
  2317         if ((iFocusedComponent != KComponentFocusedNone) &&
       
  2318                 (iFocusedComponent < iCustomComponents.Count()))
       
  2319         {
       
  2320             iCustomComponents[iFocusedComponent]->
       
  2321             CustomComponentControl(KComponentMainControl)->
       
  2322             SetFocus(ETrue);
       
  2323         }
       
  2324         // Redraw the canvas after unfading
       
  2325         DrawDeferred();
       
  2326 
       
  2327 #ifdef RD_JAVA_NGA_ENABLED
       
  2328         // To avoid situation when Canvas is redrawn but black area remains
       
  2329         if (iAlfCompositionPixelSource)
       
  2330         {
       
  2331             TRAPD(err, ActivatePixelSourceL());
       
  2332             if (err != KErrNone)
       
  2333             {
       
  2334                 DEBUG_INT("CMIDCanvas::FocusChanged - ActivatePixelSourceL error %d", err);
       
  2335             }
       
  2336         }
       
  2337 #endif // RD_JAVA_NGA_ENABLED
       
  2338 
       
  2339     }
       
  2340     else
       
  2341     {
       
  2342 #ifdef CANVAS_DIRECT_ACCESS
       
  2343         PauseDirectAccess();
       
  2344 #endif // CANVAS_DIRECT_ACCESS
       
  2345 
       
  2346         if (!iRestoreContentWhenUnfaded)
       
  2347         {
       
  2348             for (TInt j = 0; j < contentsCount; j++)
       
  2349             {
       
  2350                 iDirectContents[j]->MdcContainerVisibilityChanged(EFalse);
       
  2351             }
       
  2352         }
       
  2353 
       
  2354         // To  cursor on focused control.
       
  2355         if ((iFocusedComponent != KComponentFocusedNone) &&
       
  2356                 (iFocusedComponent < iCustomComponents.Count()))
       
  2357         {
       
  2358             iCustomComponents[iFocusedComponent]->
       
  2359             CustomComponentControl(KComponentMainControl)->
       
  2360             SetFocus(EFalse);
       
  2361         }
       
  2362         // Repaint to ensure that fading will be displayed correctly for Alert
       
  2363         // or PopupTextBox when DSA is paused.
       
  2364         DrawDeferred();
       
  2365     }
       
  2366 
       
  2367     DEBUG("- CMIDCanvas::FocusChanged");
       
  2368 }
       
  2369 
       
  2370 
       
  2371 // ---------------------------------------------------------------------------
       
  2372 // From class CCoeControl.
       
  2373 // CMIDCanvas::SizeChanged
       
  2374 // Change of size.
       
  2375 // ---------------------------------------------------------------------------
       
  2376 //
       
  2377 void CMIDCanvas::SizeChanged()
       
  2378 {
       
  2379     DEBUG("+ CMIDCanvas::SizeChanged");
       
  2380 
       
  2381     TSize controlSize = Size();
       
  2382 
       
  2383     // Position in screen co-ordinates changes when mode (full/normal) is
       
  2384     // changed.
       
  2385     iPositionRelativeToScreen = PositionRelativeToScreen();
       
  2386     TRect contentBounds = TRect(iPositionRelativeToScreen, controlSize);
       
  2387 
       
  2388     // If JAD attribute Nokia-MIDlet-Original-Display-Size for graphics
       
  2389     // scaling is defined, the iContentSize must follow it.
       
  2390     TSize orientedOrgMIDletScrSize(OrientedOrgMIDletScrSize());
       
  2391 
       
  2392     if (contentBounds != iOldContentBounds)
       
  2393     {
       
  2394         iOldContentBounds = contentBounds;
       
  2395 
       
  2396         TSize contentSize;
       
  2397 
       
  2398         if (iFullScreen && (orientedOrgMIDletScrSize != controlSize))
       
  2399         {
       
  2400             contentSize = orientedOrgMIDletScrSize;
       
  2401         }
       
  2402 
       
  2403         if (contentSize == KZeroSize)
       
  2404         {
       
  2405             contentSize = controlSize;
       
  2406         }
       
  2407 
       
  2408         if ((contentSize != iContentSize) || iScalingOn)
       
  2409         {
       
  2410             iContentSize = contentSize;
       
  2411 
       
  2412 #ifdef RD_JAVA_NGA_ENABLED
       
  2413             HandleSizeChanged();
       
  2414 #endif // RD_JAVA_NGA_ENABLED
       
  2415             PostEvent(ESizeChanged, iContentSize.iWidth, iContentSize.iHeight);
       
  2416         }
       
  2417 
       
  2418 #ifdef CANVAS_DIRECT_ACCESS
       
  2419         // Stop direct screen access to avoid restarting
       
  2420         // of direct content DSA during MdcContentBoundsChanged.
       
  2421         // DSA is resumed by Layout method.
       
  2422         StopDirectAccess();
       
  2423 #endif // CANVAS_DIRECT_ACCESS
       
  2424 
       
  2425         // Inform all listeners.
       
  2426         TInt contentsCount(iDirectContents.Count());
       
  2427 
       
  2428         for (TInt j = 0; j < contentsCount; j++)
       
  2429         {
       
  2430             iDirectContents[j]->MdcContentBoundsChanged(contentBounds);
       
  2431             iDirectContents[j]->MdcContainerWindowRectChanged(MdcContainerWindowRect());
       
  2432         }
       
  2433 
       
  2434         // We cannot determine whether the control size actually did change or
       
  2435         // not, so we have to do the layout no matter what.
       
  2436         Layout();
       
  2437     }
       
  2438     DEBUG("- CMIDCanvas::SizeChanged");
       
  2439 }
       
  2440 
       
  2441 
       
  2442 // ---------------------------------------------------------------------------
       
  2443 // From class CCoeControl.
       
  2444 // CMIDCanvas::PositionChanged
       
  2445 // Change of position.
       
  2446 // ---------------------------------------------------------------------------
       
  2447 //
       
  2448 void CMIDCanvas::PositionChanged()
       
  2449 {
       
  2450     Layout();
       
  2451 }
       
  2452 
       
  2453 #ifdef RD_JAVA_NGA_ENABLED
       
  2454 // ---------------------------------------------------------------------------
       
  2455 // From class CCoeControl.
       
  2456 // CMIDCanvas::Draw
       
  2457 // Drawing.
       
  2458 // ---------------------------------------------------------------------------
       
  2459 //
       
  2460 void CMIDCanvas::Draw(const TRect& aRect) const
       
  2461 {
       
  2462     if (!iStartUpTraceDone)
       
  2463     {
       
  2464         java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw starts", -1, -1);
       
  2465     }
       
  2466     DEBUG("CMIDCanvas::Draw ++");
       
  2467 
       
  2468     // While changing the orientation method DrawWindow() not called,
       
  2469     // variable iWndUpdate is set to True. If iWndUpdate is True
       
  2470     // DrawWindow() is called from method Update()
       
  2471     // This is needed to avoid artifacting after orientation switch.
       
  2472     TBool landscape = Layout_Meta_Data::IsLandscapeOrientation();
       
  2473 
       
  2474     if (iLandscape != landscape)
       
  2475     {
       
  2476         iLandscape = landscape;
       
  2477         iWndUpdate = ETrue;
       
  2478     }
       
  2479     else
       
  2480     {
       
  2481         // iRestoreContentWhenUnfaded is used when Canvas should be faded
       
  2482         // DrawWindow need to be called, otherwise  Canvas will be unfaded
       
  2483         // Sometimes iRestoreContentWhenUnfaded is not set yet and Canvas
       
  2484         // already lost focus, then IsFocused is used
       
  2485         if (iDirectContents.Count() > 0 || iRestoreContentWhenUnfaded || !IsFocused())
       
  2486         {
       
  2487             DrawWindow(aRect);
       
  2488         }
       
  2489         else if (iAlfCompositionPixelSource)
       
  2490         {
       
  2491             CMIDCanvas* myself = const_cast<CMIDCanvas*>(this);
       
  2492             TRAP_IGNORE(myself->ActivatePixelSourceL());
       
  2493         }
       
  2494         iWndUpdate = EFalse;
       
  2495     }
       
  2496 
       
  2497     if (!iStartUpTraceDone)
       
  2498     {
       
  2499         java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw ends", -1, -1);
       
  2500         iStartUpTraceDone = ETrue;
       
  2501     }
       
  2502     DEBUG("CMIDCanvas::Draw --");
       
  2503 }
       
  2504 #else // !RD_JAVA_NGA_ENABLED
       
  2505 
       
  2506 // ---------------------------------------------------------------------------
       
  2507 // From class CCoeControl.
       
  2508 // CMIDCanvas::Draw
       
  2509 // Drawing.
       
  2510 // ---------------------------------------------------------------------------
       
  2511 //
       
  2512 void CMIDCanvas::Draw(const TRect& aRect) const
       
  2513 {
       
  2514     if (!iStartUpTraceDone)
       
  2515     {
       
  2516         java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw starts", -1, -1);
       
  2517     }
       
  2518     DEBUG("+ CMIDCanvas::Draw");
       
  2519 
       
  2520 #ifdef CANVAS_DOUBLE_BUFFER
       
  2521     ASSERT(iFrameBuffer);
       
  2522 #endif // CANVAS_DOUBLE_BUFFER
       
  2523 
       
  2524 #ifdef CANVAS_ASYNC_PAINT
       
  2525     TRect rect(aRect);
       
  2526 
       
  2527     rect.Intersection(iViewRect);
       
  2528     rect.Move(-iViewRect.iTl);
       
  2529 
       
  2530     TSize size(rect.Size());
       
  2531 
       
  2532     TInt posPacked  = (rect.iTl.iX << 16) | (rect.iTl.iY);
       
  2533     TInt sizePacked = (size.iWidth << 16) | (size.iHeight);
       
  2534 
       
  2535     PostEvent(EPaint, posPacked, sizePacked);
       
  2536 #else
       
  2537 #ifdef CANVAS_DOUBLE_BUFFER
       
  2538 
       
  2539 // While changing the orientation method DrawWindow() not called,
       
  2540 // variable iWndUpdate is set to True. If iWndUpdate is True
       
  2541 // DrawWindow() is called from method Update()
       
  2542 // This is needed to avoid artifacting after orientation switch.
       
  2543 TBool landscape = Layout_Meta_Data::IsLandscapeOrientation();
       
  2544 
       
  2545 if (iLandscape != landscape)
       
  2546 {
       
  2547     iLandscape = landscape;
       
  2548     iWndUpdate = ETrue;
       
  2549 }
       
  2550 else
       
  2551 {
       
  2552 #ifdef CANVAS_DIRECT_ACCESS
       
  2553     // Check if DSA is ready and not used by some other client.
       
  2554     if (iDirectGc && !iDirectContents.Count() && !DirectPaused())
       
  2555     {
       
  2556         DrawDirect(aRect);   // Draw directly to screen.
       
  2557     }
       
  2558     else
       
  2559     {
       
  2560 #endif // CANVAS_DIRECT_ACCESS
       
  2561         DrawWindow(aRect);   // Bitblt via window server.
       
  2562 #ifdef CANVAS_DIRECT_ACCESS
       
  2563     }
       
  2564 #endif // CANVAS_DIRECT_ACCESS
       
  2565 
       
  2566     iWndUpdate = EFalse;
       
  2567 }
       
  2568 #endif // CANVAS_DOUBLE_BUFFER
       
  2569 #endif // CANVAS_ASYNC_PAINT
       
  2570 
       
  2571     if (!iStartUpTraceDone)
       
  2572     {
       
  2573         java::util::JavaOsLayer::startUpTrace("MIDP: CMIDCanvas::Draw ends", -1, -1);
       
  2574         iStartUpTraceDone = ETrue;
       
  2575     }
       
  2576     DEBUG("- CMIDCanvas::Draw");
       
  2577 }
       
  2578 #endif // RD_JAVA_NGA_ENABLED
       
  2579 
       
  2580 // ---------------------------------------------------------------------------
       
  2581 // CMIDCanvas::CMIDCanvas
       
  2582 // C++ constructor.
       
  2583 // ---------------------------------------------------------------------------
       
  2584 //
       
  2585 CMIDCanvas::CMIDCanvas(
       
  2586     MMIDEnv& aEnv,
       
  2587     MMIDComponent::TType aComponentType,
       
  2588 #ifdef CANVAS_DIRECT_ACCESS
       
  2589     TBool /*aUpdateRequired*/
       
  2590 #else
       
  2591     TBool aUpdateRequired
       
  2592 #endif // CANVAS_DIRECT_ACCESS
       
  2593 ) :
       
  2594         CCoeControl()
       
  2595         ,iEnv(aEnv)
       
  2596 #ifdef CANVAS_DOUBLE_BUFFER
       
  2597         ,iFrameBuffer(NULL)
       
  2598 #endif // CANVAS_DOUBLE_BUFFER
       
  2599         ,iIsGameCanvas((
       
  2600                            aComponentType == MMIDComponent::EGameCanvas ? ETrue : EFalse))
       
  2601         ,iFlags(EPostKeyEvents)
       
  2602         ,iFullScreen(EFalse)
       
  2603         ,iScalingOn(EFalse)
       
  2604         ,iS60SelectionKeyCompatibility(EFalse)
       
  2605         ,iRestoreContentWhenUnfaded(EFalse)
       
  2606         ,iLastFadeMessage(0)
       
  2607 #ifdef CANVAS_DIRECT_ACCESS
       
  2608         ,iDcDsaToStart(EFalse)
       
  2609 #endif // CANVAS_DIRECT_ACCESS
       
  2610         ,iDragEventsStartedInside(EFalse)
       
  2611 {
       
  2612     DEBUG("+ CMIDCanvas::CMIDCanvas - EDirectEnabled");
       
  2613 
       
  2614 #ifdef CANVAS_DIRECT_ACCESS
       
  2615     iFlags |= (EDirectPaused | EDirectEnabled | EUpdateRequired);
       
  2616 #else
       
  2617 
       
  2618 #if defined( __WINS__ ) || defined( __WINSCW__ )
       
  2619     aUpdateRequired = ETrue;
       
  2620 #endif
       
  2621 
       
  2622     if (aUpdateRequired)
       
  2623     {
       
  2624         iFlags |= EUpdateRequired;
       
  2625     }
       
  2626 #endif // CANVAS_DIRECT_ACCESS
       
  2627 
       
  2628     //Default values for PointerEventSuppressor
       
  2629     iPESPointerMovementInTwips = CMIDUIManager::EPESPointerMovementInTwips;
       
  2630     iPESTimeInMilliseconds = CMIDUIManager:: EPESTimeInMilliseconds;
       
  2631 
       
  2632     DEBUG("- CMIDCanvas::CMIDCanvas");
       
  2633 }
       
  2634 
       
  2635 
       
  2636 // ---------------------------------------------------------------------------
       
  2637 // CMIDCanvas::ConstructL
       
  2638 // Symbian 2nd phase constructor can leave.
       
  2639 // ---------------------------------------------------------------------------
       
  2640 //
       
  2641 void CMIDCanvas::ConstructL(CCoeControl& aWindow)
       
  2642 {
       
  2643     SetContainerWindowL(aWindow);
       
  2644 
       
  2645     iFocusedComponent = KComponentFocusedNone;
       
  2646     iPressedComponent = NULL;
       
  2647     iOrgMIDletScrSize = TSize();
       
  2648     iTargetMIDletScrSize = TSize();
       
  2649 
       
  2650 #ifdef CANVAS_DOUBLE_BUFFER
       
  2651     // Create a framebuffer large enough for full screen mode.
       
  2652     // In normal mode we will waste the border pixels. This may be offset in
       
  2653     // future by sharing the framebuffer between displayables.
       
  2654     //
       
  2655     // Allow dynamic changing of screen modes find the
       
  2656     // largest available screen size to allocate a frame buffer big enough to
       
  2657     // deal with all screen modes;
       
  2658     CWsScreenDevice* device  = ControlEnv()->ScreenDevice();
       
  2659     TInt noModes = device->NumScreenModes();
       
  2660     TPixelsAndRotation pixelAndRot;
       
  2661     TSize frameBufferSize(0, 0);
       
  2662 
       
  2663     for (TInt ii=0 ; ii < noModes; ++ii)
       
  2664     {
       
  2665         device->GetScreenModeSizeAndRotation(ii, pixelAndRot);
       
  2666 
       
  2667         if (frameBufferSize.iHeight < pixelAndRot.iPixelSize.iHeight)
       
  2668         {
       
  2669             frameBufferSize.iHeight = pixelAndRot.iPixelSize.iHeight;
       
  2670         }
       
  2671 
       
  2672         if (frameBufferSize.iWidth < pixelAndRot.iPixelSize.iWidth)
       
  2673         {
       
  2674             frameBufferSize.iWidth = pixelAndRot.iPixelSize.iWidth;
       
  2675         }
       
  2676     }
       
  2677 
       
  2678     DEBUG_INT2("Canvas FrameBuffer Size: Width: %d,  Height %d",
       
  2679                frameBufferSize.iWidth, frameBufferSize.iHeight);
       
  2680 
       
  2681     CreateFrameBufferL(frameBufferSize);
       
  2682 
       
  2683     if (iFrameBuffer)
       
  2684     {
       
  2685         iFrameDevice = CFbsBitmapDevice::NewL(iFrameBuffer);
       
  2686         User::LeaveIfError(iFrameDevice->CreateContext(iFrameContext));
       
  2687     }
       
  2688 
       
  2689     // Set iLandscape set as True according to landscape orientation mode
       
  2690     // and initialize iWndUpdat. iWndUpdat variable notify us, when
       
  2691     // orienation was changed
       
  2692     iLandscape = Layout_Meta_Data::IsLandscapeOrientation();
       
  2693     iWndUpdate = EFalse;
       
  2694 
       
  2695 #endif // CANVAS_DOUBLE_BUFFER
       
  2696 
       
  2697     SetScalingFactors();
       
  2698 
       
  2699     if (iScalingOn)
       
  2700     {
       
  2701         // We need iScaler only when scaling is on.
       
  2702         iScaler = iDisplayable->GetUIManager()->OpenScalerL();
       
  2703     }
       
  2704 
       
  2705 #ifdef CANVAS_DIRECT_ACCESS
       
  2706     ResumeDirectAccess();
       
  2707 #endif // CANVAS_DIRECT_ACCESS
       
  2708 
       
  2709     if (IsNetworkIndicatorEnabledL())
       
  2710     {
       
  2711         iNetworkIndicator = CMIDNetworkIndicator::NewL(this);
       
  2712 
       
  2713         // Initialize and set active CallIndicator to receive notification
       
  2714         // when voiceline status changes.
       
  2715         iCallIndicator = CMIDCallIndicator::NewL(iNetworkIndicator);
       
  2716         iCallIndicator->SetActiveLocal();
       
  2717     }
       
  2718 
       
  2719     iKeyDecoder = iDisplayable->GetUIManager()->OpenKeyDecoderL();
       
  2720     ASSERT(iKeyDecoder);
       
  2721 
       
  2722     // Canvas listens Media key events if CMIDRemConObserver is initialized
       
  2723     // and media keys keys are enabled.
       
  2724     iRemConObserver = iKeyDecoder->GetRemConObserver();
       
  2725     if (iRemConObserver && iKeyDecoder->MediaKeysEnabled())
       
  2726     {
       
  2727         iRemConObserver->AddMediaKeysListenerL(this);
       
  2728     }
       
  2729 
       
  2730     // Set S60 Selection Key Compatibility to provide MSK key events to
       
  2731     // canvas.
       
  2732     iS60SelectionKeyCompatibility = iEnv.MidletAttributeIsSetToVal(
       
  2733                                         LcduiMidletAttributes::KAttribS60SelectionKeyCompatibility,
       
  2734                                         LcduiMidletAttributeValues::KTrueValue);
       
  2735 
       
  2736     if (iDisplayable)
       
  2737     {
       
  2738         iDisplayable->SetS60SelectionKeyCompatibility(
       
  2739             iS60SelectionKeyCompatibility);
       
  2740     }
       
  2741 
       
  2742 #ifdef RD_TACTILE_FEEDBACK
       
  2743     // Create a CMIDTactileFeedbackExtension in case tactile feedback is
       
  2744     // supported.
       
  2745     iTactileFeedback = new(ELeave) CMIDTactileFeedbackExtension(this, 1);
       
  2746 #endif // RD_TACTILE_FEEDBACK
       
  2747 
       
  2748     //Create PointerEventSuppressor with default values or JAD parameter defined values
       
  2749     iPointerEventSuppressor = CAknPointerEventSuppressor::NewL();
       
  2750     TInt pointerMovementInPixels =
       
  2751         ControlEnv()->ScreenDevice()->HorizontalTwipsToPixels(iPESPointerMovementInTwips);
       
  2752     TSize suppressorValues =
       
  2753         iDisplayable->GetUIManager()->ReadPointerEventSuppressorValues();
       
  2754     if (!(suppressorValues.iWidth == KPESErrorValue &&
       
  2755             suppressorValues.iHeight == KPESErrorValue))
       
  2756     {
       
  2757         iPESTimeInMilliseconds = suppressorValues.iHeight;
       
  2758         pointerMovementInPixels =
       
  2759             ControlEnv()->ScreenDevice()->HorizontalTwipsToPixels(suppressorValues.iWidth);
       
  2760     }
       
  2761     iPointerEventSuppressor->SetMaxTapDuration(iPESTimeInMilliseconds * 1000);
       
  2762     iPointerEventSuppressor->SetMaxTapMove(TSize(pointerMovementInPixels,
       
  2763                                            pointerMovementInPixels));
       
  2764 
       
  2765 #ifdef RD_JAVA_NGA_ENABLED
       
  2766     iForeground = EFalse;
       
  2767     iEglDisplay = EGL_NO_DISPLAY;
       
  2768     iEglWindowSurface = EGL_NO_SURFACE;
       
  2769     iEglWindowSurfaceContext = EGL_NO_CONTEXT;
       
  2770     iEglPbufferSurface = EGL_NO_SURFACE;
       
  2771     iEglPbufferSurfaceContext = EGL_NO_CONTEXT;
       
  2772     iPbufferTexture = 0;
       
  2773 
       
  2774     i3DAccelerated =
       
  2775         iEnv.IsHardwareAcceleratedL(MMIDEnv::EHardware3D) > 0;
       
  2776 
       
  2777     InitPixelSourceL();
       
  2778 #endif // RD_JAVA_NGA_ENABLED        
       
  2779 }
       
  2780 
       
  2781 
       
  2782 // ---------------------------------------------------------------------------
       
  2783 // CMIDCanvas::SetContainerWindowL
       
  2784 // Set the container window.
       
  2785 // ---------------------------------------------------------------------------
       
  2786 //
       
  2787 void CMIDCanvas::SetContainerWindowL(const CCoeControl& aWindow)
       
  2788 {
       
  2789 #ifdef CANVAS_DIRECT_ACCESS
       
  2790     StopDirectAccess();
       
  2791 
       
  2792     if (iDirectAccess)
       
  2793     {
       
  2794         delete iDirectAccess;
       
  2795         iDirectAccess = NULL;
       
  2796     }
       
  2797 #endif // CANVAS_DIRECT_ACCESS
       
  2798 
       
  2799     iDisplayable = (CMIDDisplayable*) &aWindow;
       
  2800     CCoeControl::SetContainerWindowL(aWindow);
       
  2801     Window().SetBackgroundColor();
       
  2802 
       
  2803 #ifdef RD_SCALABLE_UI_V2
       
  2804     Window().SetPointerGrab(ETrue);
       
  2805 #endif // RD_SCALABLE_UI_V2
       
  2806 
       
  2807 #ifdef CANVAS_DIRECT_ACCESS
       
  2808     if (DirectEnabled())
       
  2809     {
       
  2810         RWsSession& session = ControlEnv()->WsSession();
       
  2811         CWsScreenDevice* device = ControlEnv()->ScreenDevice();
       
  2812 
       
  2813         iDirectAccess = CDirectScreenAccess::NewL(
       
  2814                             session, *device, *DrawableWindow(), *this);
       
  2815     }
       
  2816 #endif // CANVAS_DIRECT_ACCESS
       
  2817 
       
  2818     // Position in screen co-ordinates is first time available when container
       
  2819     // window is set.
       
  2820     iPositionRelativeToScreen = PositionRelativeToScreen();
       
  2821 }
       
  2822 
       
  2823 
       
  2824 // ---------------------------------------------------------------------------
       
  2825 // CMIDCanvas::SendKeyEventToJavaSideL
       
  2826 // Send key event to Java side.
       
  2827 // ---------------------------------------------------------------------------
       
  2828 //
       
  2829 void CMIDCanvas::SendKeyEventToJavaSideL(
       
  2830     const TKeyEvent& aEvent, TEventCode aType)
       
  2831 {
       
  2832     DEBUG("+ CMIDCanvas::SendKeyEventToJavaSideL");
       
  2833     TMIDKeyEvent event;
       
  2834 
       
  2835     // See if the key can be sent java side.
       
  2836     DEBUG_INT2("CMIDCanvas::PostKeyEvent - SOS code %d SOS type %d",
       
  2837                aEvent.iCode,
       
  2838                aType);
       
  2839 
       
  2840     // map key event data
       
  2841     TKeyEvent wsEvent = aEvent;
       
  2842 
       
  2843     DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - received TKeyEvent: iCode = %d", aEvent.iCode);
       
  2844     DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - received TKeyEvent: iModifiers = %d", aEvent.iModifiers);
       
  2845     DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - received TKeyEvent: iRepeats = %d", aEvent.iRepeats);
       
  2846     DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - received TKeyEvent: iScanCode = %d", aEvent.iScanCode);
       
  2847 
       
  2848     iEnv.MappingDataForKey(wsEvent, aType);
       
  2849 
       
  2850     DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - mapped TKeyEvent: iCode = %d", aEvent.iCode);
       
  2851     DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - mapped TKeyEvent: iModifiers = %d", aEvent.iModifiers);
       
  2852     DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - mapped TKeyEvent: iRepeats = %d", aEvent.iRepeats);
       
  2853     DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - mapped TKeyEvent: iScanCode = %d", aEvent.iScanCode);
       
  2854 
       
  2855     //See if the key can be sent java side.
       
  2856     if (iEnv.TranslateKeyL(event, wsEvent, aType))
       
  2857     {
       
  2858         DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - translated TMIDKeyEvent: iEvents = %d", event.iEvents);
       
  2859         DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - translated TMIDKeyEvent: iKeyCode = %d", event.iKeyCode);
       
  2860         DEBUG_INT("+ CMIDCanvas::SendKeyEventToJavaSideL - translated TMIDKeyEvent: iRepeats = %d", event.iRepeats);
       
  2861 
       
  2862         ASSERT(iKeyDecoder);
       
  2863 
       
  2864         TInt gameAction = iKeyDecoder->GameAction(event.iKeyCode);
       
  2865 
       
  2866         if (0 != gameAction)
       
  2867         {
       
  2868             if (event.iEvents & TMIDKeyEvent::EPressed)
       
  2869             {
       
  2870                 GamePress(gameAction);
       
  2871             }
       
  2872 
       
  2873             if (event.iEvents & TMIDKeyEvent::EReleased)
       
  2874             {
       
  2875                 GameRelease(gameAction);
       
  2876             }
       
  2877         }
       
  2878 
       
  2879         if (PostKeyEvents() || (0 == gameAction))
       
  2880         {
       
  2881             DEBUG_INT2(
       
  2882                 "CMIDCanvas::PostKeyEvent - JAVA code %d JAVA type %d",
       
  2883                 event.iKeyCode,
       
  2884                 event.iEvents);
       
  2885 
       
  2886             // 9-way Navigation Support
       
  2887             // Send two arrow events generated when press diagonal direction
       
  2888             switch (event.iKeyCode)
       
  2889             {
       
  2890                 //KeyLeftUpArrow
       
  2891             case EKeyLeftUpArrow:
       
  2892             {
       
  2893                 TMIDKeyEvent pevent;
       
  2894                 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyUpArrow);
       
  2895                 pevent.iEvents = event.iEvents;
       
  2896                 pevent.iRepeats = event.iRepeats;
       
  2897                 iEnv.PostKeyEvent(*this, pevent);
       
  2898                 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyLeftArrow);
       
  2899                 pevent.iEvents = event.iEvents;
       
  2900                 pevent.iRepeats = event.iRepeats;
       
  2901                 iEnv.PostKeyEvent(*this, pevent);
       
  2902                 break;
       
  2903             }
       
  2904             //KeyRightUpArrow
       
  2905             case EKeyRightUpArrow:
       
  2906             {
       
  2907                 TMIDKeyEvent pevent;
       
  2908                 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyUpArrow);
       
  2909                 pevent.iEvents = event.iEvents;
       
  2910                 pevent.iRepeats = event.iRepeats;
       
  2911                 iEnv.PostKeyEvent(*this, pevent);
       
  2912                 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyRightArrow);
       
  2913                 pevent.iEvents = event.iEvents;
       
  2914                 pevent.iRepeats = event.iRepeats;
       
  2915                 iEnv.PostKeyEvent(*this, pevent);
       
  2916                 break;
       
  2917             }
       
  2918             //KeyRightDownArrow
       
  2919             case EKeyRightDownArrow:
       
  2920             {
       
  2921                 TMIDKeyEvent pevent;
       
  2922                 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyDownArrow);
       
  2923                 pevent.iEvents = event.iEvents;
       
  2924                 pevent.iRepeats = event.iRepeats;
       
  2925                 iEnv.PostKeyEvent(*this, pevent);
       
  2926                 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyRightArrow);
       
  2927                 pevent.iEvents = event.iEvents;
       
  2928                 pevent.iRepeats = event.iRepeats;
       
  2929                 iEnv.PostKeyEvent(*this, pevent);
       
  2930                 break;
       
  2931             }
       
  2932             //KeyLeftDownArrow
       
  2933             case EKeyLeftDownArrow:
       
  2934             {
       
  2935                 TMIDKeyEvent pevent;
       
  2936                 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyDownArrow);
       
  2937                 pevent.iEvents = event.iEvents;
       
  2938                 pevent.iRepeats = event.iRepeats;
       
  2939                 iEnv.PostKeyEvent(*this, pevent);
       
  2940                 pevent.iKeyCode = iKeyDecoder->MapNonUnicodeKey(EStdKeyLeftArrow);
       
  2941                 pevent.iEvents = event.iEvents;
       
  2942                 pevent.iRepeats = event.iRepeats;
       
  2943                 iEnv.PostKeyEvent(*this, pevent);
       
  2944                 break;
       
  2945             }
       
  2946             default:
       
  2947                 iEnv.PostKeyEvent(*this, event);
       
  2948             }
       
  2949         }
       
  2950     }
       
  2951     DEBUG("- CMIDCanvas::SendKeyEventToJavaSideL");
       
  2952 }
       
  2953 
       
  2954 
       
  2955 #ifdef CANVAS_DOUBLE_BUFFER
       
  2956 // ---------------------------------------------------------------------------
       
  2957 // CMIDCanvas::CreateFrameBufferL
       
  2958 // Create frame buffer.
       
  2959 // ---------------------------------------------------------------------------
       
  2960 //
       
  2961 void CMIDCanvas::CreateFrameBufferL(const TSize& aSize)
       
  2962 {
       
  2963     DEBUG_INT2("+ CMIDCanvas::CreateFrameBufferL( %D, %D)",
       
  2964                aSize.iWidth,
       
  2965                aSize.iHeight);
       
  2966 
       
  2967     iFrameBuffer = iEnv.ReserveCanvasFrameBufferL((*this), aSize);
       
  2968 
       
  2969     DEBUG("- CMIDCanvas::CreateFrameBufferL");
       
  2970 }
       
  2971 #endif // CANVAS_DOUBLE_BUFFER
       
  2972 
       
  2973 
       
  2974 #ifdef DEFER_BITBLT
       
  2975 // ---------------------------------------------------------------------------
       
  2976 // CMIDCanvas::BitBltCycles
       
  2977 // Get BitBlt cycles count.
       
  2978 // ---------------------------------------------------------------------------
       
  2979 //
       
  2980 TInt CMIDCanvas::BitBltCycles(const TSize& aSize) const
       
  2981 {
       
  2982     TInt cycles = (aSize.iWidth * aSize.iHeight * KEstCyclesPerPixel);
       
  2983 
       
  2984     if (cycles < KMinOpCycles) cycles = KMinOpCycles;
       
  2985     if (cycles > KMaxOpCycles) cycles = KMaxOpCycles;
       
  2986 
       
  2987     return cycles;
       
  2988 }
       
  2989 #endif // DEFER_BITBLT
       
  2990 
       
  2991 
       
  2992 // ---------------------------------------------------------------------------
       
  2993 // CMIDCanvas::Layout
       
  2994 // Layout Canvas control.
       
  2995 // ---------------------------------------------------------------------------
       
  2996 //
       
  2997 void CMIDCanvas::Layout()
       
  2998 {
       
  2999     DEBUG("+ CMIDCanvas::Layout");
       
  3000 #ifdef CANVAS_DIRECT_ACCESS
       
  3001     StopDirectAccess();
       
  3002 #endif // CANVAS_DIRECT_ACCESS
       
  3003 
       
  3004     TRect rect(Rect());
       
  3005     TSize size(rect.Size());
       
  3006     TSize viewSize;
       
  3007 
       
  3008     if (iFullScreen)
       
  3009     {
       
  3010 #ifdef RD_JAVA_NGA_ENABLED
       
  3011         if (iScalingOn)
       
  3012         {
       
  3013             // Translate to screen coordinates.
       
  3014             rect.Move(iPositionRelativeToScreen);
       
  3015         }
       
  3016 #endif // RD_JAVA_NGA_ENABLED
       
  3017 
       
  3018         if (iNetworkIndicator)
       
  3019         {
       
  3020             // Refresh the layout data for network indicator.
       
  3021             iNetworkIndicator->GetLayoutData();
       
  3022         }
       
  3023 
       
  3024         // Get original MIDlet size which eventually reflects display
       
  3025         // orientation.
       
  3026         TSize orientedOrgMIDletScrSize(OrientedOrgMIDletScrSize());
       
  3027 
       
  3028         // If Nokia-MIDlet-Target-Display-Size is defined, Canvas will be
       
  3029         // scaled to that size.
       
  3030         if (iTargetMIDletScrSize != KZeroSize)
       
  3031         {
       
  3032             viewSize = iTargetMIDletScrSize;
       
  3033         }
       
  3034 
       
  3035         // If optional JAD parameter Nokia-MIDlet-Target-Display-Size is NOT
       
  3036         // defined and Nokia-MIDlet-Original-Display-Size is defined to
       
  3037         // smaller size than the device's screen size, we will scale the
       
  3038         // Canvas to fit the screen without changing aspect ratio.
       
  3039         // If the aspect ratio of Nokia-MIDlet-Original-Display-Size is not
       
  3040         // same as the display has, we need to leave black borders to both
       
  3041         // sides or up and down.
       
  3042         else if (
       
  3043             (orientedOrgMIDletScrSize.iWidth != 0) &&
       
  3044             (orientedOrgMIDletScrSize.iHeight != 0))
       
  3045         {
       
  3046             TReal widthScalingFactor =
       
  3047                 (TReal)size.iWidth /
       
  3048                 (TReal)orientedOrgMIDletScrSize.iWidth;
       
  3049 
       
  3050             TReal heightScalingFactor =
       
  3051                 (TReal)size.iHeight /
       
  3052                 (TReal)orientedOrgMIDletScrSize.iHeight;
       
  3053 
       
  3054             // Aspect ratio of MIDlet is same as display.
       
  3055             if (widthScalingFactor == heightScalingFactor)
       
  3056             {
       
  3057                 viewSize.SetSize(size.iWidth, size.iHeight);
       
  3058             }
       
  3059             // Aspect ratio of MIDlet is "wider" than display.
       
  3060             else if (widthScalingFactor < heightScalingFactor)
       
  3061             {
       
  3062                 viewSize.SetSize(size.iWidth,
       
  3063                                  widthScalingFactor * iContentSize.iHeight);
       
  3064             }
       
  3065             //Aspect ratio of MIDlet is "narrower" than display.
       
  3066             else
       
  3067             {
       
  3068                 viewSize.SetSize(heightScalingFactor * iContentSize.iWidth,
       
  3069                                  size.iHeight);
       
  3070             }
       
  3071         }
       
  3072         // If JAD parameters for graphics scaling are not defined, Canvas
       
  3073         // won't be scaled.
       
  3074         else
       
  3075         {
       
  3076             viewSize = iContentSize;
       
  3077         }
       
  3078     }
       
  3079     // If Canvas is not in full screen mode, it won't be scaled.
       
  3080     else
       
  3081     {
       
  3082         viewSize = iContentSize;
       
  3083     }
       
  3084 
       
  3085     TSize border = (size - viewSize);
       
  3086     TBool center = ((border.iWidth != 0) || (border.iHeight != 0));
       
  3087     TPoint viewPos = rect.iTl;
       
  3088 
       
  3089     // Compute position of view rect in window.
       
  3090     //
       
  3091     // If content does not fill the control, center it, but try
       
  3092     // to keep the left hand pixel of content aligned to a word
       
  3093     // boundary of screen memory to enable faster blts.
       
  3094     if (center)
       
  3095     {
       
  3096         viewPos.iX += border.iWidth  / 2;
       
  3097         viewPos.iY += border.iHeight / 2;
       
  3098 
       
  3099         const TPoint screenPos = PositionRelativeToScreen();
       
  3100 
       
  3101         // Align to 4-pixel boundary - this is overkill but covers both
       
  3102         // EColor256 and EColor4K. Should query graphics plugin for the
       
  3103         // alignment.
       
  3104         const TInt KAlignBoundary = 4;
       
  3105         TInt alignment = KAlignBoundary
       
  3106                          - ((viewPos.iX + screenPos.iX) & 0x3);
       
  3107 
       
  3108         // This alignment change is made to keep canvas as more center
       
  3109         // as it is possible. Alignment can have values between 0 and 4
       
  3110         // so if it have value more than 2, there is a -4 subtraction
       
  3111         // to prevent moving canvas too much to right side of display.
       
  3112         if (alignment > 2)
       
  3113         {
       
  3114             alignment -= KAlignBoundary;
       
  3115         }
       
  3116 
       
  3117         viewPos.iX += alignment;
       
  3118 
       
  3119         // Fallback to original position - we'll just have to take the
       
  3120         // unaligned bitblt performance hit.
       
  3121         if (viewPos.iX < rect.iTl.iX ||
       
  3122                 (viewPos.iX + viewSize.iWidth) > rect.iBr.iX)
       
  3123         {
       
  3124             viewPos.iX -= alignment;
       
  3125         }
       
  3126     }
       
  3127 
       
  3128     iViewRect = TRect(viewPos, viewSize);
       
  3129 
       
  3130 #ifdef CANVAS_DIRECT_ACCESS
       
  3131     StartDirectAccess();
       
  3132 #endif // CANVAS_DIRECT_ACCESS
       
  3133 #ifdef RD_JAVA_NGA_ENABLED
       
  3134     // To avoid situation when Orientation was changed and black screen is shown
       
  3135     TRAPD(err, UpdateL(iViewRect));
       
  3136     if (err != KErrNone)
       
  3137     {
       
  3138         DEBUG_INT("CMIDCanvas::Layout - update error %d", err);
       
  3139     }
       
  3140 #endif // RD_JAVA_NGA_ENABLED
       
  3141 
       
  3142     TInt contentsCount(iDirectContents.Count());
       
  3143 
       
  3144     for (TInt j = 0; j < contentsCount; j++)
       
  3145     {
       
  3146         iDirectContents[j]->MdcContentBoundsChanged(
       
  3147             TRect(PositionRelativeToScreen(), Size()));
       
  3148     }
       
  3149 
       
  3150     DEBUG_PROFILE("CMIDCanvas::Layout Canvas up and running \n");
       
  3151     DEBUG("- CMIDCanvas::Layout");
       
  3152 }
       
  3153 
       
  3154 
       
  3155 #ifdef CANVAS_DIRECT_ACCESS
       
  3156 // ---------------------------------------------------------------------------
       
  3157 // CMIDCanvas::DirectEnabled
       
  3158 // Tells whether Direct Screen Access is enabled or disabled.
       
  3159 // ---------------------------------------------------------------------------
       
  3160 //
       
  3161 inline TBool CMIDCanvas::DirectEnabled() const
       
  3162 {
       
  3163     return iFlags & EDirectEnabled;
       
  3164 }
       
  3165 
       
  3166 
       
  3167 // ---------------------------------------------------------------------------
       
  3168 // CMIDCanvas::DirectPaused
       
  3169 // Tells whether Direct Screen Access is paused or not.
       
  3170 // ---------------------------------------------------------------------------
       
  3171 //
       
  3172 inline TBool CMIDCanvas::DirectPaused() const
       
  3173 {
       
  3174     return iFlags & EDirectPaused;
       
  3175 }
       
  3176 
       
  3177 
       
  3178 // ---------------------------------------------------------------------------
       
  3179 // CMIDCanvas::UpdateRequired
       
  3180 // Tells whether update is required or not.
       
  3181 // ---------------------------------------------------------------------------
       
  3182 //
       
  3183 inline TBool CMIDCanvas::UpdateRequired() const
       
  3184 {
       
  3185     return iFlags & EUpdateRequired;
       
  3186 }
       
  3187 #endif //CANVAS_DIRECT_ACCESS
       
  3188 
       
  3189 
       
  3190 // ---------------------------------------------------------------------------
       
  3191 // CMIDCanvas::PostKeyEvents
       
  3192 // Tells whether posting of key events is enabled or disabled.
       
  3193 // ---------------------------------------------------------------------------
       
  3194 //
       
  3195 inline TBool CMIDCanvas::PostKeyEvents() const
       
  3196 {
       
  3197     return iFlags & EPostKeyEvents;
       
  3198 }
       
  3199 
       
  3200 
       
  3201 // ---------------------------------------------------------------------------
       
  3202 // CMIDCanvas::GamePress
       
  3203 // Process game press action.
       
  3204 // ---------------------------------------------------------------------------
       
  3205 //
       
  3206 void CMIDCanvas::GamePress(TInt aGameAction)
       
  3207 {
       
  3208     const TInt gameBit = 1 << aGameAction;
       
  3209     iGameKeyState |= gameBit;
       
  3210     iGameKeyLatch |= iGameKeyState;
       
  3211 }
       
  3212 
       
  3213 
       
  3214 // ---------------------------------------------------------------------------
       
  3215 // CMIDCanvas::GameRelease
       
  3216 // Process game release action.
       
  3217 // ---------------------------------------------------------------------------
       
  3218 //
       
  3219 void CMIDCanvas::GameRelease(TInt aGameAction)
       
  3220 {
       
  3221     const TInt gameBit = 1 << aGameAction;
       
  3222     iGameKeyState &= ~ gameBit;
       
  3223     iGameKeyLatch |= iGameKeyState;
       
  3224 }
       
  3225 
       
  3226 
       
  3227 // ---------------------------------------------------------------------------
       
  3228 // CMIDCanvas::SetScalingFactors
       
  3229 // Sets MIDlet's original size and target size resolutions if those are
       
  3230 // defined in JAD or manifest. If attribute is missing or it's not defined
       
  3231 // correctly, the value will be 0,0. This value is later used as an "error
       
  3232 // value".
       
  3233 // ---------------------------------------------------------------------------
       
  3234 //
       
  3235 void CMIDCanvas::SetScalingFactors()
       
  3236 {
       
  3237     CMIDMenuHandler* menuHandler = iDisplayable->MenuHandler();
       
  3238 
       
  3239     ASSERT(menuHandler);
       
  3240 
       
  3241     iScalingOn = menuHandler->IsScalingEnabled();
       
  3242 
       
  3243     iOrgMIDletScrSize = menuHandler->GetScalingParameterOrgMIDletScrSize();
       
  3244 
       
  3245     iTargetMIDletScrSize =
       
  3246         menuHandler->GetScalingParameterTargetMIDletScrSize();
       
  3247 
       
  3248     iScaleMIDletOnOrientSwitch =
       
  3249         menuHandler->GetScalingParameterScaleMIDletOnOrientSwitch();
       
  3250 }
       
  3251 
       
  3252 
       
  3253 // ---------------------------------------------------------------------------
       
  3254 // CMIDCanvas::OrientedOrgMIDletScrSize
       
  3255 // Returns original MIDlet screen size with regards to display orientation.
       
  3256 // ---------------------------------------------------------------------------
       
  3257 //
       
  3258 TSize CMIDCanvas::OrientedOrgMIDletScrSize() const
       
  3259 {
       
  3260     // Ensure that scaling and scaling-on-orientation-switch is enabled.
       
  3261     if (iScalingOn && iScaleMIDletOnOrientSwitch)
       
  3262     {
       
  3263         TSize orientedSize;
       
  3264 
       
  3265         // Ensure that original size is defined as portrait.
       
  3266         if (iOrgMIDletScrSize.iWidth < iOrgMIDletScrSize.iHeight)
       
  3267         {
       
  3268             orientedSize = iOrgMIDletScrSize;
       
  3269         }
       
  3270         else
       
  3271         {
       
  3272             orientedSize.iWidth = iOrgMIDletScrSize.iHeight;
       
  3273             orientedSize.iHeight = iOrgMIDletScrSize.iWidth;
       
  3274         }
       
  3275 
       
  3276         // Change original size orientation if actuall display orientation
       
  3277         // is landscape.
       
  3278         if (Layout_Meta_Data::IsLandscapeOrientation())
       
  3279         {
       
  3280             TInt swap = orientedSize.iWidth;
       
  3281             orientedSize.iWidth = orientedSize.iHeight;
       
  3282             orientedSize.iHeight = swap;
       
  3283         }
       
  3284 
       
  3285         return orientedSize;
       
  3286     }
       
  3287     else
       
  3288     {
       
  3289         return iOrgMIDletScrSize;
       
  3290     }
       
  3291 }
       
  3292 
       
  3293 // ---------------------------------------------------------------------------
       
  3294 // CMIDCanvas::IsNetworkIndicatorEnabledL
       
  3295 // Check if the network indicator should be shown in Canvas.
       
  3296 // ---------------------------------------------------------------------------
       
  3297 //
       
  3298 TBool CMIDCanvas::IsNetworkIndicatorEnabledL() const
       
  3299 {
       
  3300     if (RProcess().SecureId().iId != 0x102033E6)
       
  3301     {
       
  3302         // For standalone type apps we don't show indicator.
       
  3303         return EFalse;
       
  3304     }
       
  3305     TBool enabled = ETrue; // Return ETrue by default.
       
  3306 
       
  3307     std::auto_ptr<java::storage::JavaStorage> js(java::storage::JavaStorage::createInstance());
       
  3308     java::storage::JavaStorageApplicationEntry_t entries;
       
  3309     try
       
  3310     {
       
  3311         js->open();
       
  3312         java::util::Uid uid;
       
  3313         TUidToUid(iEnv.MidletSuiteUid(), uid);
       
  3314         js->read(java::storage::MIDP_PACKAGE_TABLE, uid, entries);
       
  3315         js->close();
       
  3316     }
       
  3317     catch (java::storage::JavaStorageException& ex)
       
  3318     {
       
  3319         DEBUG_INT("CMIDCanvas::IsNetworkIndicatorEnabledL: JavaStorage error: \
       
  3320             reading MIDP_PACKAGE_TABLE failed, error code = %D", ex.mStatus);
       
  3321     }
       
  3322     java::storage::JavaStorageEntry attribute;
       
  3323     attribute.setEntry(java::storage::SECURITY_DOMAIN_CATEGORY, L"");
       
  3324     java::storage::JavaStorageApplicationEntry_t::const_iterator findIterator = entries.find(attribute);
       
  3325     std::wstring res = L"";
       
  3326     if (findIterator != entries.end())
       
  3327     {
       
  3328         res = (*findIterator).entryValue();
       
  3329     }
       
  3330     entries.clear();
       
  3331 
       
  3332     if (res == MANUFACTURER_DOMAIN_CATEGORY)
       
  3333     {
       
  3334         enabled = EFalse;
       
  3335     }
       
  3336     else if (res == OPERATOR_DOMAIN_CATEGORY)
       
  3337     {
       
  3338         // Read the central repository key to find out if the
       
  3339         // network indicator should be shown for midlets in
       
  3340         // operator domain.
       
  3341         CRepository* repository = NULL;
       
  3342         TRAPD(err, repository = CRepository::NewL(KCRUidMidpLcdui));
       
  3343 
       
  3344         if (err == KErrNone)
       
  3345         {
       
  3346             err = repository->Get(KShowCanvasNetIndicatorInOperatorDomain, enabled);
       
  3347             if (err != KErrNone)
       
  3348             {
       
  3349                 DEBUG_INT("CMIDCanvas::IsNetworkIndicatorEnabledL: \
       
  3350                     reading CenRep key failed, error code = %D", err);
       
  3351             }
       
  3352         }
       
  3353 
       
  3354         delete repository;
       
  3355         repository = NULL;
       
  3356     }
       
  3357 
       
  3358     return enabled;
       
  3359 }
       
  3360 
       
  3361 #ifdef RD_JAVA_NGA_ENABLED
       
  3362 
       
  3363 // ---------------------------------------------------------------------------
       
  3364 // CMIDCanvas::HandleForeground
       
  3365 // Relases resources in graphics HW (=pixel source or EGL resources)
       
  3366 // when going to background.
       
  3367 // ---------------------------------------------------------------------------
       
  3368 //
       
  3369 void CMIDCanvas::HandleForeground(TBool aForeground)
       
  3370 {
       
  3371     DEBUG_INT("CMIDCanvas::HandleForeground(%d) ++", aForeground);
       
  3372     iForeground = aForeground;
       
  3373 
       
  3374     if (!iForeground)
       
  3375     {
       
  3376         if (IsEglAvailable())
       
  3377         {
       
  3378             if (iEglOccupied)
       
  3379             {
       
  3380                 DEBUG("CMIDCanvas::HandleForeground() - egl - pending dispose");
       
  3381                 iEglPendingDispose = ETrue;
       
  3382             }
       
  3383             else
       
  3384             {
       
  3385                 CloseEgl();
       
  3386             }
       
  3387         }
       
  3388 
       
  3389         SuspendPixelSource();
       
  3390     }
       
  3391     DEBUG("CMIDCanvas::HandleForeground --");
       
  3392 }
       
  3393 
       
  3394 // ---------------------------------------------------------------------------
       
  3395 // CMIDCanvas::InitPixelSourceL()
       
  3396 // ---------------------------------------------------------------------------
       
  3397 //
       
  3398 void CMIDCanvas::InitPixelSourceL()
       
  3399 {
       
  3400     if (iAlfCompositionPixelSource)
       
  3401     {
       
  3402         return;
       
  3403     }
       
  3404     iPixelSourceSuspended = ETrue;
       
  3405     TBool modeSupported = EFalse;
       
  3406     switch (iFrameBuffer->DisplayMode())
       
  3407     {
       
  3408     case EColor16MU:
       
  3409         modeSupported = ETrue;
       
  3410         iAlfBufferAttributes.iFormat =
       
  3411             MAlfBufferProvider::ESourceFormatXRGB_8888;
       
  3412         break;
       
  3413     case EColor16MA:
       
  3414         modeSupported = ETrue;
       
  3415         iAlfBufferAttributes.iFormat =
       
  3416             MAlfBufferProvider::ESourceFormatARGB_8888;
       
  3417         break;
       
  3418     case EColor16MAP:
       
  3419         modeSupported = ETrue;
       
  3420         iAlfBufferAttributes.iFormat =
       
  3421             MAlfBufferProvider::ESourceFormatARGB_8888_PRE;
       
  3422         break;
       
  3423     default:
       
  3424         break;
       
  3425     }
       
  3426 
       
  3427     if (modeSupported)
       
  3428     {
       
  3429         iAlfCompositionPixelSource = CAlfCompositionPixelSource::NewL(*this, &Window());
       
  3430 
       
  3431         iAlfBufferAttributes.iWidth  = iContentSize.iWidth;
       
  3432         iAlfBufferAttributes.iHeight = iContentSize.iHeight;
       
  3433         iAlfBufferAttributes.iStride =  iAlfBufferAttributes.iWidth * KBytesPerPixel;
       
  3434         iAlfBufferAttributes.iAlignment = 32;
       
  3435     }
       
  3436 }
       
  3437 
       
  3438 // ---------------------------------------------------------------------------
       
  3439 // CMIDCanvas::DisposePixelSource
       
  3440 // ---------------------------------------------------------------------------
       
  3441 //
       
  3442 void CMIDCanvas::DisposePixelSource()
       
  3443 {
       
  3444     DEBUG("CMIDCanvas::DisposePixelSource ++");
       
  3445     NotifyMonitor();
       
  3446     if (iAlfCompositionPixelSource)
       
  3447     {
       
  3448         DEBUG("CMIDCanvas::DisposePixelSource - delete alf");
       
  3449         iAlfCompositionPixelSource->Suspend();
       
  3450         delete iAlfCompositionPixelSource;
       
  3451         iAlfCompositionPixelSource = NULL;
       
  3452     }
       
  3453     DEBUG("CMIDCanvas::DisposePixelSource --");
       
  3454 }
       
  3455 
       
  3456 // ---------------------------------------------------------------------------
       
  3457 // CMIDCanvas::ActivatePixelSourceL
       
  3458 // In scaling case need to call SetExtent() again if pixel source was suspended.
       
  3459 // ---------------------------------------------------------------------------
       
  3460 //
       
  3461 void CMIDCanvas::ActivatePixelSourceL()
       
  3462 {
       
  3463     ASSERT(iAlfCompositionPixelSource);
       
  3464 
       
  3465     if (iDirectContents.Count() > 0)
       
  3466     {
       
  3467         return;
       
  3468     }
       
  3469 
       
  3470     iAlfCompositionPixelSource->ActivateSyncL();
       
  3471     iFrameReady = ETrue;
       
  3472 
       
  3473     if (iPixelSourceSuspended)
       
  3474     {
       
  3475         iPixelSourceSuspended = EFalse;
       
  3476         if (iFullScreen && iScalingOn)
       
  3477         {
       
  3478             iAlfCompositionPixelSource->SetExtent(iViewRect, KPhoneScreen);
       
  3479         }
       
  3480     }
       
  3481 }
       
  3482 
       
  3483 // ---------------------------------------------------------------------------
       
  3484 // CMIDCanvas::SuspendPixelSource
       
  3485 // ---------------------------------------------------------------------------
       
  3486 //
       
  3487 void CMIDCanvas::SuspendPixelSource()
       
  3488 {
       
  3489     NotifyMonitor();
       
  3490     if (iAlfCompositionPixelSource)
       
  3491     {
       
  3492         iAlfCompositionPixelSource->Suspend();
       
  3493         iPixelSourceSuspended = ETrue;
       
  3494     }
       
  3495 }
       
  3496 
       
  3497 // ---------------------------------------------------------------------------
       
  3498 // CMIDCanvas::NotifyMonitor
       
  3499 // CMIDCanvas::ProcessL() is asyncronous when CAlfCompositionPixelSource is used.
       
  3500 // This notiCMIDBuffer's monitor so that waiting Java thread is resumed.
       
  3501 // ---------------------------------------------------------------------------
       
  3502 //
       
  3503 void CMIDCanvas::NotifyMonitor()
       
  3504 {
       
  3505     if (iAlfMonitor)
       
  3506     {
       
  3507         iAlfMonitor->notify();
       
  3508         iAlfMonitor = NULL;
       
  3509     }
       
  3510     iFrameReady = EFalse;
       
  3511 }
       
  3512 
       
  3513 // ---------------------------------------------------------------------------
       
  3514 // From MAlfBufferProvider
       
  3515 // CMIDCanvas::ProduceNewFrameL
       
  3516 // Callback from CAlfCompositionPixelSource. Copy RGB data from framebuffer
       
  3517 // to pixel source's buffer. Return ETrue if we have a frame ready,
       
  3518 // EFalse otherwise.
       
  3519 // ---------------------------------------------------------------------------
       
  3520 //
       
  3521 TBool CMIDCanvas::ProduceNewFrameL(const TRegion& aVisibleRegion, TUint8*& aBuffer)
       
  3522 {
       
  3523     DEBUG_INT("CMIDCanvas::ProduceNewFrameL (thread=%d) ++", RThread().Id().Id());
       
  3524     TRect bbox(aVisibleRegion.BoundingRect());
       
  3525     DEBUG_INT4("CMIDCanvas::ProduceNewFrameL - visible region(x=%d, y=%d, w=%d, h=%d) ++",
       
  3526                bbox.iTl.iX, bbox.iTl.iY, bbox.Width(), bbox.Height());
       
  3527 
       
  3528     // If iDirectContents.Count() > 0, canvas hasn't received
       
  3529     // MdcNotifyContentAdded in LCDUI thread yet.
       
  3530     if (!iFrameReady || iDirectContents.Count() > 0)
       
  3531     {
       
  3532         DEBUG("CMIDCanvas::ProduceNewFrameL - FRAME IS NOT READY --");
       
  3533         NotifyMonitor();
       
  3534         return EFalse;
       
  3535     }
       
  3536 
       
  3537     NotifyMonitor();
       
  3538 
       
  3539     TUint8* from = (TUint8*)iFrameBuffer->DataAddress();
       
  3540 
       
  3541     TBool downScaling = IsDownScaling(iContentSize, iViewRect);
       
  3542     TInt width =  downScaling ? iViewRect.Width()  : iContentSize.iWidth;
       
  3543     TInt height = downScaling ? iViewRect.Height() : iContentSize.iHeight;
       
  3544 
       
  3545     TUint bytes = width * KBytesPerPixel;
       
  3546     TInt scanLength = CFbsBitmap::ScanLineLength(
       
  3547                           iFrameBuffer->SizeInPixels().iWidth, iFrameBuffer->DisplayMode());
       
  3548 
       
  3549     for (TInt y = 0; y < height; ++y)
       
  3550     {
       
  3551         Mem::Copy(aBuffer, from, bytes);
       
  3552         aBuffer += iAlfBufferAttributes.iStride;
       
  3553         from += scanLength;
       
  3554     }
       
  3555 
       
  3556     DEBUG("CMIDCanvas::ProduceNewFrameL --");
       
  3557     return ETrue;
       
  3558 }
       
  3559 
       
  3560 // ---------------------------------------------------------------------------
       
  3561 // From MAlfBufferProvider
       
  3562 // CMIDCanvas::BufferAttributes
       
  3563 // Called by CAlfCompositionPixelSource to get the size of RGB data.
       
  3564 // ---------------------------------------------------------------------------
       
  3565 //
       
  3566 MAlfBufferProvider::TBufferCreationAttributes& CMIDCanvas::BufferAttributes()
       
  3567 {
       
  3568     DEBUG_INT2("CMIDCanvas::BufferAttributes - iContentSize(w=%d, h=%d) ++",
       
  3569                iContentSize.iWidth, iContentSize.iHeight);
       
  3570 
       
  3571     TBool downScaling = IsDownScaling(iContentSize, iViewRect);
       
  3572     iAlfBufferAttributes.iWidth  = downScaling ? iViewRect.Width() : iContentSize.iWidth;
       
  3573     iAlfBufferAttributes.iHeight = downScaling ? iViewRect.Height() : iContentSize.iHeight;
       
  3574 
       
  3575     iAlfBufferAttributes.iStride = iAlfBufferAttributes.iWidth * KBytesPerPixel;
       
  3576     return iAlfBufferAttributes;
       
  3577 }
       
  3578 
       
  3579 // ---------------------------------------------------------------------------
       
  3580 // From MAlfBufferProvider
       
  3581 // CMIDCanvas::ContextAboutToSuspend
       
  3582 // Notification from Alf.
       
  3583 // ---------------------------------------------------------------------------
       
  3584 //
       
  3585 void CMIDCanvas::ContextAboutToSuspend()
       
  3586 {
       
  3587     DEBUG("CMIDCanvas::ContextAboutToSuspend() ++");
       
  3588     NotifyMonitor();
       
  3589     iPixelSourceSuspended = ETrue;
       
  3590     DEBUG("CMIDCanvas::ContextAboutToSuspend() --");
       
  3591 }
       
  3592 
       
  3593 // ---------------------------------------------------------------------------
       
  3594 // From MAlfBufferProvider
       
  3595 // CMIDCanvas::OnActivation
       
  3596 // Notification from Alf.
       
  3597 // ---------------------------------------------------------------------------
       
  3598 //
       
  3599 void CMIDCanvas::OnActivation()
       
  3600 {
       
  3601     DEBUG("CMIDCanvas::OnActivation()++--");
       
  3602 }
       
  3603 
       
  3604 
       
  3605 // ---------------------------------------------------------------------------
       
  3606 // CMIDCanvas::OpenEglL
       
  3607 // Creates EGL window surface and context. Only 32 bit display modes are
       
  3608 // supported.
       
  3609 // ---------------------------------------------------------------------------
       
  3610 //
       
  3611 void CMIDCanvas::OpenEglL()
       
  3612 {
       
  3613     if (IsEglAvailable())
       
  3614     {
       
  3615         return;
       
  3616     }
       
  3617 
       
  3618     DEBUG("CMIDCanvas::OpenEglL() ++");
       
  3619 
       
  3620     if (iEglDisplay == EGL_NO_DISPLAY)
       
  3621     {
       
  3622         iEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
       
  3623 
       
  3624         // Initializing an already initialized display has no effect.
       
  3625         // eglTerminate is not called in LCDUI side ever, only by M3G
       
  3626         if (eglInitialize(iEglDisplay, NULL, NULL) == EGL_FALSE)
       
  3627         {
       
  3628             ELOG1(EJavaUI, "eglInitialize() failed, eglError=%d", eglGetError());
       
  3629             User::Leave(KErrNotSupported);
       
  3630         }
       
  3631     }
       
  3632 
       
  3633     RWindow& window = Window();
       
  3634     // Choose the buffer size based on the Window's display mode.
       
  3635     TDisplayMode displayMode = window.DisplayMode();
       
  3636     TInt bufferSize = 0;
       
  3637     switch (displayMode)
       
  3638     {
       
  3639     case(EColor16MU):
       
  3640     case(EColor16MA):
       
  3641     case(EColor16MAP):
       
  3642         bufferSize = 32;
       
  3643         break;
       
  3644     default:
       
  3645         ELOG1(EJavaUI, "CMIDCanvas::OpenEglL(): unsupported window display mode %d",
       
  3646               displayMode);
       
  3647         User::Leave(KErrNotSupported);
       
  3648         break;
       
  3649     }
       
  3650 
       
  3651     EGLint surfaceType = EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
       
  3652 
       
  3653     const EGLint attributeList[] =
       
  3654     {
       
  3655         EGL_SURFACE_TYPE, surfaceType,
       
  3656         EGL_RED_SIZE, 8,
       
  3657         EGL_GREEN_SIZE, 8,
       
  3658         EGL_BLUE_SIZE, 8,
       
  3659         EGL_ALPHA_SIZE, 8,
       
  3660         EGL_BUFFER_SIZE, bufferSize,
       
  3661         EGL_TRANSPARENT_TYPE, EGL_NONE,
       
  3662         EGL_DEPTH_SIZE, 16,
       
  3663         EGL_NONE
       
  3664     };
       
  3665 
       
  3666     EGLint numConfigs = 0;
       
  3667 
       
  3668     // Choose the best EGLConfig that matches the desired properties.
       
  3669     if ((eglChooseConfig(iEglDisplay, attributeList, &iEglConfig, 1, &numConfigs) == EGL_FALSE) ||
       
  3670             numConfigs == 0)
       
  3671     {
       
  3672         ELOG1(EJavaUI, "eglChooseConfig() failed, eglError=%d", eglGetError());
       
  3673         User::Leave(KErrNotSupported);
       
  3674     }
       
  3675 
       
  3676     // Check that surface content is preserved in swap, otherwise the
       
  3677     // game canvas content cannot be preserved.
       
  3678     eglGetConfigAttrib(iEglDisplay, iEglConfig, EGL_SURFACE_TYPE, &surfaceType);
       
  3679     if (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT == 0)
       
  3680     {
       
  3681         ELOG(EJavaUI, "Egl config does not support EGL_SWAP_BEHAVIOR_PRESERVED_BIT");
       
  3682         User::Leave(KErrNotSupported);
       
  3683     }
       
  3684 
       
  3685     // Create a window surface where the graphics are blitted.
       
  3686     // Pass the Native Window handle to egl.
       
  3687     iEglWindowSurface = eglCreateWindowSurface(iEglDisplay, iEglConfig, (void*)&window, NULL);
       
  3688     if (iEglWindowSurface == EGL_NO_SURFACE)
       
  3689     {
       
  3690         ELOG1(EJavaUI, "eglCreateWindowSurface() failed, eglError=%d", eglGetError());
       
  3691         User::Leave(KErrNoMemory);
       
  3692     }
       
  3693     // Need to preserve surface content after swapping
       
  3694     eglSurfaceAttrib(iEglDisplay, iEglWindowSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
       
  3695 
       
  3696     CreateEglContext();
       
  3697     ClearEglSurface(EEglWindow);
       
  3698 
       
  3699     // Allocate memory for ARGB->RGBA conversion needed by
       
  3700     // openGL texture
       
  3701     if (!iTexturePixels)
       
  3702     {
       
  3703         iTexturePixels = new(ELeave) TUint8[KMaxBlitSize * KMaxBlitSize * KBytesPerPixel];
       
  3704     }
       
  3705     glDisable(GL_DEPTH_TEST);
       
  3706     glDisable(GL_LIGHTING);
       
  3707     glEnableClientState(GL_VERTEX_ARRAY);
       
  3708     if (!iVertexArray)
       
  3709     {
       
  3710         iVertexArray = new(ELeave) GLshort[8];
       
  3711     }
       
  3712     if (!iTriangleStrip)
       
  3713     {
       
  3714         iTriangleStrip = new(ELeave) GLubyte[4];
       
  3715         iTriangleStrip[0] = 0;
       
  3716         iTriangleStrip[1] = 1;
       
  3717         iTriangleStrip[2] = 3;
       
  3718         iTriangleStrip[3] = 2;
       
  3719     }
       
  3720     DEBUG("CMIDCanvas::OpenEglL() --");
       
  3721 }
       
  3722 
       
  3723 // ---------------------------------------------------------------------------
       
  3724 // CMIDCanvas::CloseEgl
       
  3725 // Destroys EGL contexts and surfaces.
       
  3726 // ---------------------------------------------------------------------------
       
  3727 //
       
  3728 void CMIDCanvas::CloseEgl()
       
  3729 {
       
  3730     DEBUG("CMIDCanvas::CloseEglL() ++");
       
  3731 
       
  3732     iM3GContent = EFalse;
       
  3733     iM3GStart = EFalse;
       
  3734     iEglPendingResize = EFalse;
       
  3735     iEglPendingDispose = EFalse;
       
  3736 
       
  3737     if (iEglDisplay == EGL_NO_DISPLAY)
       
  3738     {
       
  3739         return;
       
  3740     }
       
  3741 
       
  3742     // MIDlet might draw only 2D after this =>
       
  3743     // need to set frame buffer opaque to be compatible with
       
  3744     // blending methods in Lcdgd. UpdateOffScreenBitmapL() does this
       
  3745     // for GameCanvas.
       
  3746     if (!IsGameCanvas() && iFrameContext)
       
  3747     {
       
  3748         iFrameContext->SetBrushColor(KOpaqueClearColor);
       
  3749         iFrameContext->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
       
  3750         iFrameContext->Clear();
       
  3751     }
       
  3752 
       
  3753     // Take a snapshot from window surface to the frame buffer.
       
  3754     TRAPD(err, UpdateOffScreenBitmapL(EFalse));
       
  3755     if (err != KErrNone)
       
  3756     {
       
  3757         DEBUG("CMIDCanvas::CloseEgl() - UpdateOffScreenBitmapL() failed");
       
  3758     }
       
  3759 
       
  3760     // make sure the we have no current target
       
  3761     // so that surfaces and contexts are destoyed immediately
       
  3762     SetCurrentEglType(EEglNone);
       
  3763 
       
  3764     // If pbuffer has been created dispose that here
       
  3765     if (iEglPbufferSurfaceContext != EGL_NO_CONTEXT ||
       
  3766             iEglPbufferSurface != EGL_NO_SURFACE)
       
  3767     {
       
  3768         DisposePBufferSurface();
       
  3769     }
       
  3770 
       
  3771     if (iEglWindowSurfaceContext != EGL_NO_CONTEXT)
       
  3772     {
       
  3773         eglDestroyContext(iEglDisplay, iEglWindowSurfaceContext);
       
  3774         iEglWindowSurfaceContext = EGL_NO_CONTEXT;
       
  3775     }
       
  3776     if (iEglWindowSurface != EGL_NO_SURFACE)
       
  3777     {
       
  3778         eglDestroySurface(iEglDisplay, iEglWindowSurface);
       
  3779         iEglWindowSurface = EGL_NO_SURFACE;
       
  3780     }
       
  3781 
       
  3782     DEBUG("CMIDCanvas::CloseEglL() --");
       
  3783 }
       
  3784 
       
  3785 // ---------------------------------------------------------------------------
       
  3786 // CMIDCanvas::CreateEglContext
       
  3787 // (Re)create EGL context
       
  3788 // ---------------------------------------------------------------------------
       
  3789 //
       
  3790 void CMIDCanvas::CreateEglContext()
       
  3791 {
       
  3792     if (iEglWindowSurfaceContext != EGL_NO_CONTEXT)
       
  3793     {
       
  3794         SetCurrentEglType(EEglNone);
       
  3795         eglDestroyContext(iEglDisplay, iEglWindowSurfaceContext);
       
  3796         iEglWindowSurfaceContext = EGL_NO_CONTEXT;
       
  3797     }
       
  3798     // Create a rendering context
       
  3799     iEglWindowSurfaceContext = eglCreateContext(iEglDisplay, iEglConfig, EGL_NO_CONTEXT, NULL);
       
  3800     if (iEglWindowSurfaceContext == EGL_NO_CONTEXT)
       
  3801     {
       
  3802         ELOG1(EJavaUI, "eglCreateContext() failed, eglError=%d", eglGetError());
       
  3803     }
       
  3804 }
       
  3805 
       
  3806 // ---------------------------------------------------------------------------
       
  3807 // CMIDCanvas::SetCurrentEglType
       
  3808 // Sets the current EGL context and surface.
       
  3809 // ---------------------------------------------------------------------------
       
  3810 //
       
  3811 TBool CMIDCanvas::SetCurrentEglType(TEglType aType)
       
  3812 {
       
  3813     EGLBoolean res = EGL_TRUE;
       
  3814     if (aType == EEglPbuffer)
       
  3815     {
       
  3816         res = eglMakeCurrent(
       
  3817                   iEglDisplay, iEglPbufferSurface, iEglPbufferSurface, iEglPbufferSurfaceContext);
       
  3818     }
       
  3819     else if (aType == EEglWindow)
       
  3820     {
       
  3821         res = eglMakeCurrent(
       
  3822                   iEglDisplay, iEglWindowSurface, iEglWindowSurface, iEglWindowSurfaceContext);
       
  3823     }
       
  3824     else
       
  3825     {
       
  3826         res = eglMakeCurrent(
       
  3827                   iEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
       
  3828     }
       
  3829     if (res == EGL_FALSE)
       
  3830     {
       
  3831         ELOG1(EJavaUI, "eglMakeCurrent() failed, eglError=%s", GetEglError(eglGetError()).Ptr());
       
  3832     }
       
  3833     return (res == EGL_FALSE ? EFalse : ETrue);
       
  3834 }
       
  3835 
       
  3836 // ---------------------------------------------------------------------------
       
  3837 // CMIDCanvas::GetCurrentEgl
       
  3838 // Gets the current EGL type
       
  3839 // ---------------------------------------------------------------------------
       
  3840 //
       
  3841 CMIDCanvas::TEglType CMIDCanvas::GetCurrentEglType()
       
  3842 {
       
  3843     EGLSurface surface = eglGetCurrentSurface(EGL_READ);
       
  3844     if (surface == EGL_NO_SURFACE)
       
  3845     {
       
  3846         return EEglNone;
       
  3847     }
       
  3848     else if (surface == iEglPbufferSurface)
       
  3849     {
       
  3850         return EEglPbuffer;
       
  3851     }
       
  3852     else
       
  3853     {
       
  3854         return EEglWindow;
       
  3855     }
       
  3856 }
       
  3857 
       
  3858 // ---------------------------------------------------------------------------
       
  3859 // CMIDCanvas::GetEglSurfaceSize
       
  3860 // Returns size of the EGL surface.
       
  3861 // ---------------------------------------------------------------------------
       
  3862 //
       
  3863 TSize CMIDCanvas::GetEglSurfaceSize(EGLSurface aSurface)
       
  3864 {
       
  3865     TSize sz;
       
  3866     if (aSurface == EGL_NO_SURFACE)
       
  3867     {
       
  3868         aSurface = iEglWindowSurface;
       
  3869         if (iScalingOn && iFullScreen)
       
  3870         {
       
  3871             aSurface = iEglPbufferSurface;
       
  3872         }
       
  3873     }
       
  3874     if (!(eglQuerySurface(iEglDisplay, aSurface, EGL_WIDTH, &sz.iWidth) &&
       
  3875             eglQuerySurface(iEglDisplay, aSurface, EGL_HEIGHT, &sz.iHeight)))
       
  3876     {
       
  3877         sz.SetSize(0, 0);
       
  3878     }
       
  3879     DEBUG_INT2("CMIDCanvas::GetEglSurfaceSizeL() - w=%d, h=%d", sz.iWidth, sz.iHeight);
       
  3880     return sz;
       
  3881 }
       
  3882 
       
  3883 // ---------------------------------------------------------------------------
       
  3884 // CMIDCanvas::HandleSizeChanged()
       
  3885 // EGL cannot handle window resize upwards and in this case we need to
       
  3886 // recreate the surface. If recreation is needed (and M3G is not using our
       
  3887 // surface) EGL context and surface are destoryed here and recreated in
       
  3888 // next ProcessL() when M3G_CONTENT_START is recieved from Java side.
       
  3889 // ---------------------------------------------------------------------------
       
  3890 //
       
  3891 void CMIDCanvas::HandleSizeChanged()
       
  3892 {
       
  3893     DEBUG("CMIDCanvas::HandleSizeChanged ++");
       
  3894 
       
  3895     SuspendPixelSource();
       
  3896 
       
  3897     if (IsEglAvailable())
       
  3898     {
       
  3899         TSize surfaceSize = GetEglSurfaceSize(iEglWindowSurface);
       
  3900         TSize controlSize = Size();
       
  3901         if (surfaceSize.iHeight < controlSize.iHeight ||
       
  3902                 surfaceSize.iWidth < controlSize.iWidth)
       
  3903         {
       
  3904             // Check if egl surface is currently occupied.
       
  3905             if (iEglOccupied)
       
  3906             {
       
  3907                 // Delayed resizing. It is done when the ReleaseEglSurface method
       
  3908                 // is called.
       
  3909                 DEBUG("CMIDCanvas::HandleSizeChanged - egl - resize pending");
       
  3910                 iEglPendingResize = ETrue;
       
  3911             }
       
  3912             else
       
  3913             {
       
  3914                 DEBUG("CMIDCanvas::SizeChanged - close egl");
       
  3915                 // Surface recreation is done in next ProcessL() call
       
  3916                 CloseEgl();
       
  3917             }
       
  3918         }
       
  3919     }
       
  3920     DEBUG("CMIDCanvas::HandleSizeChanged --");
       
  3921 }
       
  3922 
       
  3923 // ---------------------------------------------------------------------------
       
  3924 // From MMIDComponentNgaExtension
       
  3925 // CMIDCanvas::UpdateEglContent
       
  3926 // Renders current 2D content in frame buffer as an OpenGL texture to
       
  3927 // EGL surface. If scaling is on, renders to pbuffer, otherwise to window surface.
       
  3928 // Called from M3G (via CMIDGraphics) when EGL surface needs to be updated with
       
  3929 // 2D content. This will not be called if M3G Background is used for clearing
       
  3930 // entire canvas area.
       
  3931 // ---------------------------------------------------------------------------
       
  3932 //
       
  3933 void CMIDCanvas::UpdateEglContent()
       
  3934 {
       
  3935     if (!IsEglAvailable())
       
  3936     {
       
  3937         return;
       
  3938     }
       
  3939 
       
  3940     DEBUG("CMIDCanvas::UpdateEglContent() ++");
       
  3941 
       
  3942     // If scaling update framebuffer to pbuffer, otherwise to windowsurface
       
  3943     if (iScalingOn && iFullScreen)
       
  3944     {
       
  3945         SetCurrentEglType(EEglPbuffer);
       
  3946     }
       
  3947     else
       
  3948     {
       
  3949         SetCurrentEglType(EEglWindow);
       
  3950     }
       
  3951     BlitFrameBufferPixels();
       
  3952     SetCurrentEglType(EEglNone);
       
  3953 
       
  3954     DEBUG("CMIDCanvas::UpdateEglContent() --");
       
  3955 }
       
  3956 
       
  3957 // ---------------------------------------------------------------------------
       
  3958 // From MMIDComponentNgaExtension
       
  3959 // CMIDCanvas::IsEglAvailable
       
  3960 // Return ETrue, if EGL based drawing is in use.
       
  3961 // ---------------------------------------------------------------------------
       
  3962 //
       
  3963 TBool CMIDCanvas::IsEglAvailable()
       
  3964 {
       
  3965     return (iEglWindowSurface != EGL_NO_SURFACE);
       
  3966 }
       
  3967 
       
  3968 // ---------------------------------------------------------------------------
       
  3969 // From MMIDComponentNgaExtension
       
  3970 // CMIDCanvas::BindEglSurface
       
  3971 // Called from M3G (via CMIDGraphics) when M3G binds to canvas
       
  3972 // graphics rendering target.
       
  3973 // ---------------------------------------------------------------------------
       
  3974 //
       
  3975 EGLSurface CMIDCanvas::BindEglSurface()
       
  3976 {
       
  3977     if (IsEglAvailable())
       
  3978     {
       
  3979         iEglOccupied = ETrue;
       
  3980     }
       
  3981 
       
  3982     if (iScalingOn && iFullScreen)
       
  3983     {
       
  3984         return iEglPbufferSurface;
       
  3985     }
       
  3986     return iEglWindowSurface;
       
  3987 }
       
  3988 
       
  3989 // ---------------------------------------------------------------------------
       
  3990 // From MMIDComponentNgaExtension
       
  3991 // CMIDCanvas::ReleaseEglSurface
       
  3992 // Called from M3G (via CMIDGraphics) when M3G releases canvas
       
  3993 // graphics rendering target.
       
  3994 // ---------------------------------------------------------------------------
       
  3995 //
       
  3996 void CMIDCanvas::ReleaseEglSurface()
       
  3997 {
       
  3998     iEglOccupied = EFalse;
       
  3999     if (IsEglAvailable())
       
  4000     {
       
  4001         // Pending dispose. Egl context must be released.
       
  4002         if (iEglPendingDispose)
       
  4003         {
       
  4004             DEBUG("CMIDCanvas::ReleaseEglSurface() - dispose egl");
       
  4005             CloseEgl();
       
  4006         }
       
  4007         else if (iEglPendingResize)
       
  4008         {
       
  4009             DEBUG("CMIDCanvas::ReleaseEglSurface() - pending resize");
       
  4010             HandleSizeChanged();
       
  4011         }
       
  4012         ClearFrameBuffer();
       
  4013     }
       
  4014 }
       
  4015 
       
  4016 // ---------------------------------------------------------------------------
       
  4017 // From MMIDComponentNgaExtension
       
  4018 // CMIDCanvas::UpdateOffScreenBitmap()
       
  4019 // ---------------------------------------------------------------------------
       
  4020 //
       
  4021 void CMIDCanvas::UpdateOffScreenBitmapL(TBool aForced)
       
  4022 {
       
  4023     if (IsEglAvailable() && iFrameContext && (IsGameCanvas() || aForced))
       
  4024     {
       
  4025         DEBUG("CMIDCanvas::UpdateOffScreenBitmapL() ++");
       
  4026 
       
  4027         UpdateEglContent();
       
  4028 
       
  4029         EGLSurface surface = EGL_NO_SURFACE;
       
  4030         TEglType current = GetCurrentEglType();
       
  4031 
       
  4032         if (iScalingOn && iFullScreen)
       
  4033         {
       
  4034             SetCurrentEglType(EEglPbuffer);
       
  4035             surface = iEglPbufferSurface;
       
  4036         }
       
  4037         else
       
  4038         {
       
  4039             SetCurrentEglType(EEglWindow);
       
  4040             surface = iEglWindowSurface;
       
  4041         }
       
  4042 
       
  4043         CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
       
  4044         CleanupStack::PushL(bitmap);
       
  4045         User::LeaveIfError(bitmap->Create(
       
  4046                                GetEglSurfaceSize(surface), iEnv.DisplayMode()));
       
  4047 
       
  4048         if (EGL_FALSE == eglCopyBuffers(iEglDisplay, surface, bitmap))
       
  4049         {
       
  4050             ELOG1(EJavaUI, "eglCopyBuffers() failed, eglError=%s",
       
  4051                   GetEglError(eglGetError()).Ptr());
       
  4052             User::Leave(KErrUnknown);
       
  4053         }
       
  4054 
       
  4055         // Make framebuffer opaque
       
  4056         iFrameContext->SetBrushColor(KOpaqueClearColor);
       
  4057         iFrameContext->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
       
  4058         iFrameContext->Clear();
       
  4059 
       
  4060         iFrameContext->BitBlt(TPoint(), bitmap);
       
  4061         CleanupStack::PopAndDestroy();
       
  4062         SetCurrentEglType(current);
       
  4063 
       
  4064         // Make sure that full Canvas area
       
  4065         // is made transparent in next ClearFrameBuffer() call.
       
  4066         // This is needed in case UpdateOffScreenBitmapL is called
       
  4067         // from Nokia UI API
       
  4068         iUpperUpdateRect = TRect(Size());
       
  4069 
       
  4070         DEBUG("CMIDCanvas::UpdateOffScreenBitmapL() --");
       
  4071     }
       
  4072 }
       
  4073 
       
  4074 // ---------------------------------------------------------------------------
       
  4075 // From MMIDComponentNgaExtension
       
  4076 // CMIDCanvas::UpdateOffScreenBitmap()
       
  4077 // ---------------------------------------------------------------------------
       
  4078 //
       
  4079 TBool CMIDCanvas::FillEglSurface(const TRect& aRect, const TRgb& aColor)
       
  4080 {
       
  4081     if (!IsEglAvailable() ||
       
  4082             !iUpperUpdateRect.IsEmpty() ||
       
  4083             !iLowerUpdateRect.IsEmpty())
       
  4084     {
       
  4085         return EFalse;
       
  4086     }
       
  4087     TSize sz(this->GetEglSurfaceSize());
       
  4088     if (aRect.Width() >= sz.iWidth && aRect.Height() >= sz.iHeight)
       
  4089     {
       
  4090         return ClearEglSurface(EEglNone, &aColor);
       
  4091     }
       
  4092     TEglType current = GetCurrentEglType();
       
  4093     if (iScalingOn && iFullScreen)
       
  4094     {
       
  4095         if (current != EEglPbuffer)
       
  4096         {
       
  4097             SetCurrentEglType(EEglPbuffer);
       
  4098         }
       
  4099     }
       
  4100     else if (current != EEglWindow)
       
  4101     {
       
  4102         SetCurrentEglType(EEglWindow);
       
  4103     }
       
  4104     InitOpenGl(ETrue);
       
  4105     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
       
  4106     glVertexPointer(2, GL_SHORT, 0, iVertexArray);
       
  4107     iVertexArray[0] = aRect.iTl.iX;
       
  4108     iVertexArray[1] = aRect.iTl.iY;
       
  4109 
       
  4110     iVertexArray[2] = aRect.iBr.iX;
       
  4111     iVertexArray[3] = aRect.iTl.iY;
       
  4112 
       
  4113     iVertexArray[4] = iVertexArray[2];
       
  4114     iVertexArray[5] = aRect.iBr.iY;
       
  4115 
       
  4116     iVertexArray[6] = iVertexArray[0];
       
  4117     iVertexArray[7] = iVertexArray[5];
       
  4118 
       
  4119     glColor4f(
       
  4120         aColor.Red() / 255.0f, aColor.Green() / 255.0f,
       
  4121         aColor.Blue() / 255.0f, aColor.Alpha() / 255.0f);
       
  4122 
       
  4123     glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, iTriangleStrip);
       
  4124     SetCurrentEglType(EEglNone);
       
  4125     return ETrue;
       
  4126 }
       
  4127 
       
  4128 // ---------------------------------------------------------------------------
       
  4129 // From CMIDCanvas
       
  4130 // CMIDCanvas::ClearEglSurface
       
  4131 // ---------------------------------------------------------------------------
       
  4132 //
       
  4133 TBool CMIDCanvas::ClearEglSurface(
       
  4134     CMIDCanvas::TEglType aSurfaceType, const TRgb* aRgba)
       
  4135 {
       
  4136     if (!IsEglAvailable())
       
  4137     {
       
  4138         return EFalse;
       
  4139     }
       
  4140     TEglType current = GetCurrentEglType();
       
  4141     if (aSurfaceType == EEglNone || aRgba == NULL)
       
  4142     {
       
  4143         if (iScalingOn && iFullScreen)
       
  4144         {
       
  4145             if (aSurfaceType == EEglNone)
       
  4146             {
       
  4147                 aSurfaceType = EEglPbuffer;
       
  4148             }
       
  4149             if (aRgba == NULL)
       
  4150             {
       
  4151                 glClearColor(0.f, 0.f, 0.f, 1.f);
       
  4152             }
       
  4153         }
       
  4154         else
       
  4155         {
       
  4156             if (aSurfaceType == EEglNone)
       
  4157             {
       
  4158                 aSurfaceType = EEglWindow;
       
  4159             }
       
  4160             if (aRgba == NULL)
       
  4161             {
       
  4162                 glClearColor(1.f, 1.f, 1.f, 1.f);
       
  4163             }
       
  4164         }
       
  4165     }
       
  4166     SetCurrentEglType(aSurfaceType);
       
  4167     if (aRgba != NULL)
       
  4168     {
       
  4169         glClearColor(
       
  4170             aRgba->Red() / 255.f, aRgba->Green() / 255.0f,
       
  4171             aRgba->Blue() / 255.0f, aRgba->Alpha() / 255.0f);
       
  4172     }
       
  4173     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       
  4174     SetCurrentEglType(current);
       
  4175     return ETrue;
       
  4176 }
       
  4177 
       
  4178 // ---------------------------------------------------------------------------
       
  4179 // From MMIDCanvas
       
  4180 // CMIDCanvas::UpdateRect
       
  4181 // Notifies canvas about which areas have been updated with 2D content.
       
  4182 // ---------------------------------------------------------------------------
       
  4183 //
       
  4184 void CMIDCanvas::UpdateRect(const TRect& aRect)
       
  4185 {
       
  4186     if (aRect.IsEmpty())
       
  4187     {
       
  4188         return;
       
  4189     }
       
  4190 
       
  4191     TRect rect(aRect);
       
  4192     TRect canvasRect = IsDownScaling(iContentSize, iViewRect) ?
       
  4193                        TRect(iViewRect.Size()) : TRect(iContentSize);
       
  4194     rect.Intersection(canvasRect);
       
  4195 
       
  4196     // Update the member rects
       
  4197     if (iUpperUpdateRect.Intersects(rect))
       
  4198     {
       
  4199         iUpperUpdateRect.BoundingRect(rect);
       
  4200     }
       
  4201     else if (iLowerUpdateRect.Intersects(rect))
       
  4202     {
       
  4203         iLowerUpdateRect.BoundingRect(rect);
       
  4204     }
       
  4205     // If rect is fully in the lower half of canvas,
       
  4206     // merge it with iLowerUpdateRect, otherwise with iUpperUpdateRect
       
  4207     else if (rect.iTl.iY > canvasRect.Height() / 2)
       
  4208     {
       
  4209         if (iLowerUpdateRect.IsEmpty())
       
  4210         {
       
  4211             iLowerUpdateRect = rect;
       
  4212         }
       
  4213         else
       
  4214         {
       
  4215             iLowerUpdateRect.BoundingRect(rect);
       
  4216         }
       
  4217     }
       
  4218     else
       
  4219     {
       
  4220         if (iUpperUpdateRect.IsEmpty())
       
  4221         {
       
  4222             iUpperUpdateRect = rect;
       
  4223         }
       
  4224         else
       
  4225         {
       
  4226             iUpperUpdateRect.BoundingRect(rect);
       
  4227         }
       
  4228     }
       
  4229 }
       
  4230 
       
  4231 // ---------------------------------------------------------------------------
       
  4232 // CMIDCanvas::BlitFrameBufferPixels
       
  4233 // Sets up OpenGL state for 2D texture rendering and renders the textures for
       
  4234 // updated frame buffer areas by calling BlitSubRect().
       
  4235 // ---------------------------------------------------------------------------
       
  4236 //
       
  4237 void CMIDCanvas::BlitFrameBufferPixels()
       
  4238 {
       
  4239     if (iUpperUpdateRect.IsEmpty() && iLowerUpdateRect.IsEmpty())
       
  4240     {
       
  4241         return;
       
  4242     }
       
  4243     InitOpenGl();
       
  4244     // Must use this blending function because frame buffer
       
  4245     // content is in pre-multiplied ARGB format.
       
  4246     // See alpha blending in Lcdgd, lcdc16ma.cpp.
       
  4247     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
       
  4248 
       
  4249     glEnable(GL_ALPHA_TEST);
       
  4250     glAlphaFunc(GL_GREATER, 0.0f);
       
  4251 
       
  4252     // Disable any stray state we don't want
       
  4253     glDisable(GL_CULL_FACE);
       
  4254     glDisableClientState(GL_NORMAL_ARRAY);
       
  4255     glDisableClientState(GL_COLOR_ARRAY);
       
  4256     glDisable(GL_LIGHTING);
       
  4257     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
       
  4258     glDepthMask(GL_FALSE);
       
  4259     glDepthFunc(GL_ALWAYS);
       
  4260 
       
  4261     ASSERT_GL();
       
  4262 
       
  4263     if (iUpperUpdateRect.Intersects(iLowerUpdateRect))
       
  4264     {
       
  4265         iUpperUpdateRect.BoundingRect(iLowerUpdateRect);
       
  4266         iLowerUpdateRect = TRect();
       
  4267         BlitSubRect(iUpperUpdateRect);
       
  4268     }
       
  4269     else
       
  4270     {
       
  4271         BlitSubRect(iUpperUpdateRect);
       
  4272         BlitSubRect(iLowerUpdateRect);
       
  4273     }
       
  4274 
       
  4275     ClearFrameBuffer();
       
  4276 }
       
  4277 
       
  4278 // ---------------------------------------------------------------------------
       
  4279 // CMIDCanvas::InitOpenGl
       
  4280 // Initiazes OpenGL before 2d rendering
       
  4281 // ---------------------------------------------------------------------------
       
  4282 //
       
  4283 TSize CMIDCanvas::InitOpenGl(TBool aTopLeftOrigo, const TRect* aRect)
       
  4284 {
       
  4285     // scaling is on the framebuffer is blitted to pbuffer instead of
       
  4286     // window surface so get the size of appropriate surface for
       
  4287     // setting correct values for viewport, projection etc.
       
  4288     TSize size = GetEglSurfaceSize();
       
  4289     glViewport(0, 0, size.iWidth, size.iHeight);
       
  4290     if (aRect)
       
  4291     {
       
  4292         glScissor(aRect->iTl.iX, aRect->iTl.iY, aRect->Width(), aRect->Height());
       
  4293     }
       
  4294     else
       
  4295     {
       
  4296         glScissor(0, 0, size.iWidth, size.iHeight);
       
  4297     }
       
  4298     glEnable(GL_BLEND);
       
  4299     glMatrixMode(GL_PROJECTION);
       
  4300     glLoadIdentity();
       
  4301     // Checks where the origo should be
       
  4302     if (aTopLeftOrigo)
       
  4303     {
       
  4304         // Top-left
       
  4305         glOrthof(0, TReal32(size.iWidth), TReal32(size.iHeight), 0.f, -1.f, 1.f);
       
  4306     }
       
  4307     else
       
  4308     {
       
  4309         // Bottom-left
       
  4310         glOrthox(0, size.iWidth << 16, 0, size.iHeight << 16, -1 << 16, 1 << 16);
       
  4311     }
       
  4312     glMatrixMode(GL_MODELVIEW);
       
  4313     glLoadIdentity();
       
  4314     glDisable(GL_DEPTH_TEST);
       
  4315     glEnableClientState(GL_VERTEX_ARRAY);
       
  4316     glDisable(GL_LIGHTING);
       
  4317     glDepthMask(GL_FALSE);
       
  4318     glDepthFunc(GL_ALWAYS);
       
  4319     return size;
       
  4320 }
       
  4321 
       
  4322 // ---------------------------------------------------------------------------
       
  4323 // CMIDCanvas::BlitSubRect
       
  4324 // OpenGL texture dimensions must be powers of 2. Devides aRect into smaller
       
  4325 // areas for texture rendering so that texture dimensions won't exceed
       
  4326 // KMaxBlitSize.
       
  4327 // ---------------------------------------------------------------------------
       
  4328 //
       
  4329 void CMIDCanvas::BlitSubRect(const TRect& aRect)
       
  4330 {
       
  4331     if (aRect.IsEmpty())
       
  4332     {
       
  4333         return;
       
  4334     }
       
  4335 
       
  4336     // OpenGL coordinate origin is in bottom left corner of screen
       
  4337     TInt yOffset = iContentSize.iHeight - aRect.iBr.iY;
       
  4338     TInt xOffset = aRect.iTl.iX;
       
  4339     TInt width   = aRect.Width();
       
  4340     TInt height  = aRect.Height();
       
  4341 
       
  4342     TInt canvasHeight = iContentSize.iHeight;
       
  4343 
       
  4344     TInt xBlits = (width == KMaxBlitSize) ? 1 : (width / KMaxBlitSize) + 1;
       
  4345     TInt yBlits = (height == KMaxBlitSize) ? 1 : (height / KMaxBlitSize) + 1;
       
  4346 
       
  4347     TInt stride = iFrameBuffer->ScanLineLength(
       
  4348                       iFrameBuffer->SizeInPixels().iWidth, iFrameBuffer->DisplayMode());
       
  4349 
       
  4350     for (TInt yBlit = 0; yBlit < yBlits; ++yBlit)
       
  4351     {
       
  4352         for (TInt xBlit = 0; xBlit < xBlits; ++xBlit)
       
  4353         {
       
  4354 
       
  4355             TInt xStart = xOffset + xBlit * KMaxBlitSize;
       
  4356             TInt yStart = yOffset + yBlit * KMaxBlitSize;
       
  4357             TInt xSize = Min(KMaxBlitSize, width - (xStart - xOffset));
       
  4358             TInt ySize = Min(KMaxBlitSize, height - (yStart - yOffset));
       
  4359 
       
  4360             // The first rectangle will be in bottom left corner,
       
  4361             // then rectangle is moved right and upwards.
       
  4362             // OpenGL y-coordinate increases upwards.
       
  4363             TInt srcOffset = (canvasHeight - (yStart + ySize)) * stride +
       
  4364                              xStart * KBytesPerPixel;
       
  4365 
       
  4366             BlitSubRectTexture(xStart, yStart, xSize, ySize, stride,
       
  4367                                (TUint8*)iFrameBuffer->DataAddress() + srcOffset);
       
  4368         }
       
  4369     }
       
  4370 }
       
  4371 
       
  4372 
       
  4373 // ---------------------------------------------------------------------------
       
  4374 // CMIDCanvas::BlitSubRectTexture
       
  4375 // Creates OpenGL texture from the pixels passed as a parameter and draws
       
  4376 // texture to the current EGL surface.
       
  4377 // ---------------------------------------------------------------------------
       
  4378 //
       
  4379 void CMIDCanvas::BlitSubRectTexture(TInt aXOffset, TInt aYOffset,
       
  4380                                     TInt aWidth, TInt aHeight,
       
  4381                                     TInt aStride, const TUint8* aPixels)
       
  4382 {
       
  4383     DEBUG_INT4("BlitSubRectTextureL: aXOffset=%d, aYOffset=%d, aWidth=%d, aHeight=%d",
       
  4384                aXOffset, aYOffset, aWidth, aHeight);
       
  4385     DEBUG_INT("BlitSubRectTextureL: aStride=%d", aStride);
       
  4386 
       
  4387     ASSERT((aWidth > 0) && (aWidth <= 256));
       
  4388     ASSERT((aHeight > 0) && (aHeight <= 256));
       
  4389     ASSERT(iTexturePixels);
       
  4390     ASSERT_GL();
       
  4391 
       
  4392     TInt tileWidth = KMaxBlitSize;
       
  4393     TInt tileHeight = KMaxBlitSize;
       
  4394 
       
  4395     // Tweak tile size to avoid using excessive amounts of memory for
       
  4396     // portions outside the blit area
       
  4397     while (tileWidth >= aWidth * 2)
       
  4398     {
       
  4399         tileWidth >>= 1;
       
  4400         tileHeight <<= 1;
       
  4401     }
       
  4402 
       
  4403     while (tileHeight >= aHeight * 2)
       
  4404     {
       
  4405         tileHeight >>= 1;
       
  4406     }
       
  4407 
       
  4408     glActiveTexture(GL_TEXTURE0);
       
  4409     glEnable(GL_TEXTURE_2D);
       
  4410 
       
  4411     TUint tempTexObj[KTexturesCount];
       
  4412     glGenTextures(KTexturesCount, tempTexObj);
       
  4413 
       
  4414     glBindTexture(GL_TEXTURE_2D, tempTexObj[0]);
       
  4415 
       
  4416     glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
       
  4417 
       
  4418     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
       
  4419     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
       
  4420 
       
  4421     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
       
  4422                  tileWidth, tileHeight, 0,
       
  4423                  GL_RGBA, GL_UNSIGNED_BYTE, NULL);
       
  4424 
       
  4425     // Raise out-of-memory if OpenGL ran out of resources
       
  4426     GLint err = glGetError();
       
  4427     if (err == GL_OUT_OF_MEMORY)
       
  4428     {
       
  4429         glDeleteTextures(KTexturesCount, tempTexObj);
       
  4430         DEBUG("CMIDCanvas::BlitSubRectTexture(): Out of memory when creating OpenGL texture");
       
  4431         return;
       
  4432     }
       
  4433     else if (err != GL_NO_ERROR)
       
  4434     {
       
  4435         ELOG1(EJavaUI, "CMIDCanvas::BlitSubRectTexture(): GL error after glTexImage2D(): %d", err);
       
  4436         ASSERT(EFalse);
       
  4437     }
       
  4438 
       
  4439     // Set up texture and vertex coordinate arrays for the image tiles
       
  4440     const TUint8 tc[8] = { 0, 0, 0, 1, 1, 0, 1, 1 };
       
  4441     GLshort pos[8];
       
  4442 
       
  4443     glClientActiveTexture(GL_TEXTURE0);
       
  4444     glTexCoordPointer(2, GL_BYTE, 0, tc);
       
  4445     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
       
  4446     glVertexPointer(2, GL_SHORT, 0, pos);
       
  4447     glEnableClientState(GL_VERTEX_ARRAY);
       
  4448     glMatrixMode(GL_TEXTURE);
       
  4449     glLoadIdentity();
       
  4450     glMatrixMode(GL_MODELVIEW);
       
  4451 
       
  4452     ASSERT_GL();
       
  4453 
       
  4454     glBindTexture(GL_TEXTURE_2D, tempTexObj[0]);
       
  4455     TUint8* dst =  iTexturePixels;
       
  4456     const TUint8* src = aPixels;
       
  4457 
       
  4458     TInt h = aHeight;
       
  4459 
       
  4460     if (tileWidth > aWidth ||
       
  4461             tileHeight > aHeight)
       
  4462     {
       
  4463         // Clear the pixel data with transparent for case where
       
  4464         // actual texture data does not cover the full tile.
       
  4465         // This should be actually done with glClear().
       
  4466         Mem::FillZ(dst, tileWidth * tileHeight * KBytesPerPixel);
       
  4467         dst += tileWidth * (tileHeight - aHeight) * KBytesPerPixel;
       
  4468     }
       
  4469 
       
  4470     while (h-- > 0)
       
  4471     {
       
  4472         ConvertPixels((TUint32*)src, dst, aWidth);
       
  4473         src += aStride;
       
  4474         dst += tileWidth * KBytesPerPixel;
       
  4475     }
       
  4476 
       
  4477     glTexSubImage2D(GL_TEXTURE_2D, 0,
       
  4478                     0, 0,
       
  4479                     tileWidth, tileHeight,
       
  4480                     GL_RGBA, GL_UNSIGNED_BYTE, iTexturePixels);
       
  4481 
       
  4482     // If scaling is on and pbuffer is used, the framebuffer contents
       
  4483     // must be positioned to the top part of the puffer as m3g renders
       
  4484     // there as well, thus 2D and 3D content are correctly on top of each other
       
  4485     if (iScalingOn && iFullScreen)
       
  4486     {
       
  4487         TSize pbufferSize = GetEglSurfaceSize(iEglPbufferSurface);
       
  4488         TInt offset = pbufferSize.iHeight - iContentSize.iHeight;
       
  4489 
       
  4490         pos[0] = (GLshort)aXOffset;
       
  4491         pos[1] = (GLshort)(tileHeight + aYOffset + offset);
       
  4492         pos[2] = pos[0];
       
  4493         pos[3] = (GLshort)aYOffset + offset;
       
  4494         pos[4] = (GLshort)(tileWidth + aXOffset);
       
  4495         pos[5] = pos[1];
       
  4496         pos[6] = pos[4];
       
  4497         pos[7] = pos[3];
       
  4498     }
       
  4499     else
       
  4500     {
       
  4501         pos[0] = (GLshort)aXOffset;
       
  4502         pos[1] = (GLshort)(tileHeight + aYOffset);
       
  4503         pos[2] = pos[0];
       
  4504         pos[3] = (GLshort)aYOffset;
       
  4505         pos[4] = (GLshort)(tileWidth + aXOffset);
       
  4506         pos[5] = pos[1];
       
  4507         pos[6] = pos[4];
       
  4508         pos[7] = pos[3];
       
  4509     }
       
  4510 
       
  4511     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
       
  4512 
       
  4513     // release resources
       
  4514     glDeleteTextures(KTexturesCount, tempTexObj);
       
  4515     ASSERT_GL();
       
  4516 }
       
  4517 
       
  4518 // ---------------------------------------------------------------------------
       
  4519 // CMIDCanvas::CreatePBufferSurfaceL
       
  4520 // Create EGL pbuffer to be used in scaling case.
       
  4521 // ---------------------------------------------------------------------------
       
  4522 //
       
  4523 void CMIDCanvas::CreatePBufferSurfaceL()
       
  4524 {
       
  4525     DEBUG("CMIDCanvas::CreatePBufferSurface() ++");
       
  4526     ASSERT(iEglDisplay != EGL_NO_DISPLAY);
       
  4527 
       
  4528     RWindow& window = Window();
       
  4529 
       
  4530     // Choose the buffer size based on the Window's display mode.
       
  4531     TDisplayMode displayMode = window.DisplayMode();
       
  4532     TInt bufferSize = 0;
       
  4533     switch (displayMode)
       
  4534     {
       
  4535     case(EColor16MU):
       
  4536     case(EColor16MA):
       
  4537     case(EColor16MAP):
       
  4538         bufferSize = 32;
       
  4539         break;
       
  4540     default:
       
  4541         ELOG1(EJavaUI, "CMIDCanvas::OpenEglL(): unsupported window display mode %d",
       
  4542               displayMode);
       
  4543         User::Leave(KErrNotSupported);
       
  4544         break;
       
  4545     }
       
  4546 
       
  4547     // Set the desired properties for the EGLSurface
       
  4548     const EGLint attributeList[] =
       
  4549     {
       
  4550         EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
       
  4551         EGL_RED_SIZE, 8,
       
  4552         EGL_GREEN_SIZE, 8,
       
  4553         EGL_BLUE_SIZE, 8,
       
  4554         EGL_ALPHA_SIZE, 8,
       
  4555         EGL_BUFFER_SIZE, bufferSize,
       
  4556         EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
       
  4557         EGL_TRANSPARENT_TYPE, EGL_NONE,
       
  4558         EGL_DEPTH_SIZE, 16,
       
  4559         EGL_NONE
       
  4560     };
       
  4561 
       
  4562     EGLConfig bestConfig;
       
  4563     EGLint numConfigs = 0;
       
  4564 
       
  4565     // Choose the best EGLConfig that matches the desired properties.
       
  4566     if (!eglChooseConfig(iEglDisplay, attributeList, &bestConfig, 1, &numConfigs) ||
       
  4567             numConfigs == 0)
       
  4568     {
       
  4569         ELOG1(EJavaUI, "eglChooseConfig() for pbuffer failed, eglError=%d", eglGetError());
       
  4570         User::Leave(KErrNotSupported);
       
  4571     }
       
  4572 
       
  4573     // find buffer size based on the framebuffer size
       
  4574     // pbuffer size must be power of two so that it can be bound
       
  4575     // as texture image
       
  4576     TInt width = 2;
       
  4577     TInt height = 2;
       
  4578 
       
  4579     while (width < iContentSize.iWidth)
       
  4580     {
       
  4581         width <<= 1;
       
  4582     }
       
  4583     while (height < iContentSize.iHeight)
       
  4584     {
       
  4585         height <<= 1;
       
  4586     }
       
  4587 
       
  4588     DEBUG_INT4("CMIDCanvas::CreatePBufferSurface - pbuffer size resolved as (width=%d, height=%d), contentSize(%d, %d)",
       
  4589                width, height, iContentSize.iWidth, iContentSize.iHeight);
       
  4590 
       
  4591     // Special attributes in order for binding this surface as texture image
       
  4592     EGLint attrib[] =
       
  4593     {
       
  4594         EGL_WIDTH, width,
       
  4595         EGL_HEIGHT, height,
       
  4596         EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
       
  4597         EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
       
  4598         EGL_MIPMAP_TEXTURE, EGL_TRUE,
       
  4599         EGL_NONE
       
  4600     };
       
  4601 
       
  4602     iEglPbufferSurface = eglCreatePbufferSurface(iEglDisplay, bestConfig, attrib);
       
  4603     if (iEglPbufferSurface == EGL_NO_SURFACE)
       
  4604     {
       
  4605         ELOG1(EJavaUI, "eglCreatePbufferSurface() failed, eglError=%d", eglGetError());
       
  4606         User::Leave(KErrNoMemory);
       
  4607     }
       
  4608 
       
  4609     // Create a rendering context
       
  4610     iEglPbufferSurfaceContext = eglCreateContext(iEglDisplay, bestConfig, NULL, NULL);
       
  4611     if (iEglPbufferSurfaceContext == EGL_NO_CONTEXT)
       
  4612     {
       
  4613         ELOG1(EJavaUI, "eglCreateContext() for pbuffer failed, eglError=%d", eglGetError());
       
  4614         User::Leave(KErrNoMemory);
       
  4615     }
       
  4616 
       
  4617     DEBUG("CMIDCanvas::CreatePBufferSurface() --");
       
  4618 }
       
  4619 
       
  4620 // ---------------------------------------------------------------------------
       
  4621 // CMIDCanvas::DisposePBufferSurface
       
  4622 // Destroys EGL pbuffer surface and context.
       
  4623 // ---------------------------------------------------------------------------
       
  4624 //
       
  4625 void CMIDCanvas::DisposePBufferSurface()
       
  4626 {
       
  4627     if (iEglPbufferSurfaceContext != EGL_NO_CONTEXT)
       
  4628     {
       
  4629         eglDestroyContext(iEglDisplay, iEglPbufferSurfaceContext);
       
  4630         iEglPbufferSurfaceContext = EGL_NO_CONTEXT;
       
  4631 
       
  4632         // textures are destoyed along with the context so it's safe
       
  4633         // set texture name to zero
       
  4634         iPbufferTexture = 0;
       
  4635     }
       
  4636     if (iEglPbufferSurface != EGL_NO_SURFACE)
       
  4637     {
       
  4638         eglDestroySurface(iEglDisplay, iEglPbufferSurface);
       
  4639         iEglPbufferSurface = EGL_NO_SURFACE;
       
  4640     }
       
  4641 }
       
  4642 
       
  4643 // ---------------------------------------------------------------------------
       
  4644 // CMIDCanvas::BlitPBufferScaledToWindowSurface
       
  4645 // In scaling case renders and scales pbuffer content (=canvas 2D + 3D
       
  4646 // content in orig size) to EGL window surface.
       
  4647 // ---------------------------------------------------------------------------
       
  4648 //
       
  4649 void CMIDCanvas::BlitPBufferScaledToWindowSurface()
       
  4650 {
       
  4651     DEBUG("CMIDCanvas::BlitPBufferScaledToWindowSurface() ++");
       
  4652 
       
  4653     // Get screen size for setting clips and
       
  4654     // parallel projection correctly
       
  4655     TRect screenRect = Rect();
       
  4656     TInt width = screenRect.Width();
       
  4657     TInt height = screenRect.Height();
       
  4658 
       
  4659     glScissor(0, 0, width, height);
       
  4660     glViewport(0, 0, width, height);
       
  4661     glMatrixMode(GL_PROJECTION);
       
  4662     glLoadIdentity();
       
  4663 
       
  4664     glOrthox(0, width << 16,
       
  4665              0, height << 16,
       
  4666              -1 << 16, 1 << 16);
       
  4667 
       
  4668     glMatrixMode(GL_MODELVIEW);
       
  4669     glLoadIdentity();
       
  4670 
       
  4671     glActiveTexture(GL_TEXTURE0);
       
  4672     glEnable(GL_TEXTURE_2D);
       
  4673 
       
  4674     // generate texture name if not already generated
       
  4675     if (glIsTexture(iPbufferTexture) == GL_FALSE)
       
  4676     {
       
  4677         glGenTextures(1, &iPbufferTexture);
       
  4678     }
       
  4679 
       
  4680     glBindTexture(GL_TEXTURE_2D, iPbufferTexture);
       
  4681     if (eglBindTexImage(iEglDisplay, iEglPbufferSurface, EGL_BACK_BUFFER) == EGL_FALSE)
       
  4682     {
       
  4683         ELOG1(EJavaUI, "eglBindTexImage() failed, eglError=%d", eglGetError());
       
  4684         ASSERT(EFalse);
       
  4685     }
       
  4686 
       
  4687     glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
       
  4688     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
       
  4689     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
       
  4690 
       
  4691     // calculate texture coordinates, i.e. the area in pbuffer
       
  4692     // that has the actual frame content
       
  4693     GLfloat contentWidth = iContentSize.iWidth;
       
  4694     GLfloat contentHeight = iContentSize.iHeight;
       
  4695     TSize bufferSize = GetEglSurfaceSize(iEglPbufferSurface);
       
  4696     GLfloat horRatio = contentWidth / bufferSize.iWidth;
       
  4697     GLfloat yoffset = (bufferSize.iHeight - contentHeight) / bufferSize.iHeight;
       
  4698     GLfloat tc[8] = { 0.0f, 1.0f, 0.0f, yoffset, horRatio, 1.0f, horRatio, yoffset};
       
  4699 
       
  4700     GLshort pos[8];
       
  4701 
       
  4702     ASSERT_GL();
       
  4703 
       
  4704     glClientActiveTexture(GL_TEXTURE0);
       
  4705     glTexCoordPointer(2, GL_FLOAT, 0, tc);
       
  4706     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
       
  4707     glVertexPointer(2, GL_SHORT, 0, pos);
       
  4708     glEnableClientState(GL_VERTEX_ARRAY);
       
  4709     glMatrixMode(GL_TEXTURE);
       
  4710     glLoadIdentity();
       
  4711 
       
  4712     // position texture screen coordinates
       
  4713     pos[0] = (GLshort)iViewRect.iTl.iX;
       
  4714     pos[1] = (GLshort)iViewRect.Height() + (height - iViewRect.iBr.iY);
       
  4715     pos[2] = pos[0];
       
  4716     pos[3] = (GLshort)height - iViewRect.iBr.iY;
       
  4717     pos[4] = (GLshort)iViewRect.iBr.iX;
       
  4718     pos[5] = pos[1];
       
  4719     pos[6] = pos[4];
       
  4720     pos[7] = pos[3];
       
  4721 
       
  4722     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
       
  4723 
       
  4724     // release pbuffer from texture
       
  4725     eglReleaseTexImage(iEglDisplay, iEglPbufferSurface, EGL_BACK_BUFFER);
       
  4726 
       
  4727     DEBUG("CMIDCanvas::BlitPBufferScaledToWindowSurface() --");
       
  4728 }
       
  4729 
       
  4730 
       
  4731 // ---------------------------------------------------------------------------
       
  4732 // CMIDCanvas::ClearFrameBuffer
       
  4733 // Clears the frame buffer with fully transparent color. Rendering canvas 2D
       
  4734 // content as an OpenGL texture requires that texture is transparent in
       
  4735 // the areas where no 2D content has been drawn.
       
  4736 // ---------------------------------------------------------------------------
       
  4737 //
       
  4738 void CMIDCanvas::ClearFrameBuffer()
       
  4739 {
       
  4740     if (!iM3GStart && iUpperUpdateRect.IsEmpty() && iLowerUpdateRect.IsEmpty())
       
  4741     {
       
  4742         return;
       
  4743     }
       
  4744     // Clear the frame buffer
       
  4745     iFrameContext->SetBrushColor(KTransparentClearColor);
       
  4746     iFrameContext->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
       
  4747 
       
  4748     iFrameContext->Clear(iUpperUpdateRect);
       
  4749     iFrameContext->Clear(iLowerUpdateRect);
       
  4750 
       
  4751     // Reset members
       
  4752     iUpperUpdateRect.SetRect(0,0,0,0);
       
  4753     iLowerUpdateRect.SetRect(0,0,0,0);
       
  4754 }
       
  4755 
       
  4756 
       
  4757 // ---------------------------------------------------------------------------
       
  4758 // CMIDCanvas::AssertGL
       
  4759 // Check for OpenGL ES errors. Only for debug builds.
       
  4760 // ---------------------------------------------------------------------------
       
  4761 //
       
  4762 void CMIDCanvas::AssertGL()
       
  4763 {
       
  4764     GLint err = glGetError();
       
  4765     if (err == GL_NO_ERROR)
       
  4766     {
       
  4767         return;
       
  4768     }
       
  4769     else
       
  4770     {
       
  4771         ELOG1(EJavaUI, "OpenGL ES error=%d", err);
       
  4772         ASSERT(EFalse);
       
  4773     }
       
  4774 }
       
  4775 
       
  4776 // ---------------------------------------------------------------------------
       
  4777 // CMIDCanvas::AssertGL
       
  4778 // Check for OpenGL ES errors. Only for debug builds.
       
  4779 // ---------------------------------------------------------------------------
       
  4780 //
       
  4781 const TDesC8& CMIDCanvas::GetEglError(EGLint aErr)
       
  4782 {
       
  4783     _LIT8(KEglSuccess, "EGL_SUCCESS");
       
  4784     _LIT8(KEglNotInitialized, "EGL_NOT_INITIALIZED");
       
  4785     _LIT8(KEglBadAccess, "EGL_BAD_ACCESS");
       
  4786     _LIT8(KEglBadAlloc, "EGL_BAD_ALLOC");
       
  4787     _LIT8(KEglBadAttribute, "EGL_BAD_ATTRIBUTE");
       
  4788     _LIT8(KEglBadContext, "EGL_BAD_CONTEXT");
       
  4789     _LIT8(KEglBadConfig, "EGL_BAD_CONFIG");
       
  4790     _LIT8(KEglBadCurrentSurface, "EGL_BAD_CURRENT_SURFACE");
       
  4791     _LIT8(KEglBadDisplay, "EGL_BAD_DISPLAY");
       
  4792     _LIT8(KEglBadSurface, "EGL_BAD_SURFACE");
       
  4793     _LIT8(KEglBadMatch, "EGL_BAD_MATCH");
       
  4794     _LIT8(KEglBadParameter, "EGL_BAD_PARAMETER");
       
  4795     _LIT8(KEglBadNativePixmap, "EGL_BAD_NATIVE_PIXMAP");
       
  4796     _LIT8(KEglBadNativeWindow, "EGL_BAD_NATIVE_WINDOW");
       
  4797     switch (aErr)
       
  4798     {
       
  4799     case EGL_NOT_INITIALIZED:
       
  4800         return KEglNotInitialized;
       
  4801     case EGL_BAD_ACCESS:
       
  4802         return KEglBadAccess;
       
  4803     case EGL_BAD_ALLOC:
       
  4804         return KEglBadAlloc;
       
  4805     case EGL_BAD_ATTRIBUTE:
       
  4806         return KEglBadAttribute;
       
  4807     case EGL_BAD_CONTEXT:
       
  4808         return KEglBadContext;
       
  4809     case EGL_BAD_CONFIG:
       
  4810         return KEglBadConfig;
       
  4811     case EGL_BAD_CURRENT_SURFACE:
       
  4812         return KEglBadCurrentSurface;
       
  4813     case EGL_BAD_DISPLAY:
       
  4814         return KEglBadDisplay;
       
  4815     case EGL_BAD_SURFACE:
       
  4816         return KEglBadSurface;
       
  4817     case EGL_BAD_MATCH:
       
  4818         return KEglBadMatch;
       
  4819     case EGL_BAD_PARAMETER:
       
  4820         return KEglBadParameter;
       
  4821     case EGL_BAD_NATIVE_PIXMAP:
       
  4822         return KEglBadNativePixmap;
       
  4823     case EGL_BAD_NATIVE_WINDOW:
       
  4824         return KEglBadNativeWindow;
       
  4825     }
       
  4826     return KEglSuccess;
       
  4827 }
       
  4828 
       
  4829 
       
  4830 #endif // RD_JAVA_NGA_ENABLED        
       
  4831 // End of File.