javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swtdisplaybase.cpp
branchRCL_3
changeset 19 04becd199f91
child 23 98ccebc37403
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swtdisplaybase.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,1201 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Nokia Corporation - S60 implementation
+ *******************************************************************************/
+
+
+#include <eikbtgpc.h>
+#include <fbs.h>
+#include <gulutil.h>
+#include <eikon.hrh>
+#include <AknUtils.h>
+#include <bautils.h>
+#include <swtlaffacade.h>
+#include "s60commonutils.h"
+#include "swtfactory.h"
+#include "swtdisplaybase.h"
+#include "eswtwidgetsexpanded.h"
+#include "eswtmobileextensions.h"
+#include "swtevents.h"
+#include "swtkeymapper.h"
+#include "swttimer.h"
+#include "swtimage.h"
+#include "swtmidremconobserver.h"
+#include "swtjavabufferdrawer.h"
+#include "swtfont.h"
+#include "swtuiutils.h"
+
+
+#define ASSERT_JAVAUITHREAD() ASSERT(IsCurrentThreadJavaUi())
+#define ASSERT_NATIVEUITHREAD() ASSERT(IsCurrentThreadNativeUi())
+
+
+// Assuming ResourceLanguageFileNameL inserts DRIVE:/KDC_RESOURCE_FILES_DIR/java/
+// Assuming KDC_RESOURCE_FILES_DIR = /resource/java/
+_LIT(KSwtResFile, "eswtcore.rsc");
+
+
+// ======== MEMBER FUNCTIONS ========
+
+
+/**
+ * 2nd phase constructor
+ */
+void ASwtDisplayBase::ConstructInJavaUiThreadL()
+{
+    iEventQueue = CSwtEventQueue::NewL(*this);
+}
+
+/**
+ * UI thread's side constructor
+ */
+void ASwtDisplayBase::ConstructInNativeUiThreadL()
+{
+    ASSERT_NATIVEUITHREAD();
+
+    iCoeEnv = CEikonEnv::Static(); // codescanner::eikonenvstatic
+    ASSERT(iCoeEnv);
+    iFactory = CSwtFactory::NewL();
+    iResId = LoadResourceFileL();
+    iUiUtils = iFactory->NewUiUtilsL(*this);
+    iMenuArranger = iFactory->NewMenuArrangerL(*this);
+    iCommandArranger = iFactory->NewCommandArrangerL(*this);
+    iKeyMapper = CSwtKeyMapper::NewL();
+    iRemConObserver = CSwtMIDRemConObserver::NewL();
+    if (iRemConObserver)
+    {
+        iRemConObserver->AddMediaKeysListenerL(this);
+    }
+    iJavaBufferDrawer = new(ELeave) CSwtJavaBufferDrawer(*this);
+#ifdef RD_SCALABLE_UI_V2
+    iLongTapDetector = CAknLongTapDetector::NewL(this);
+#endif
+}
+
+
+/**
+ * Destructor
+ */
+ASwtDisplayBase::~ASwtDisplayBase()
+{
+}
+
+
+/**
+ * Destroys the Display part that runs in the UI thread
+ */
+void ASwtDisplayBase::DestroyInNativeUiThread()
+{
+    ASSERT_NATIVEUITHREAD();
+
+    if (iRemConObserver)
+    {
+        iRemConObserver->RemoveMediaKeysListener(this);
+    }
+    delete iRemConObserver;
+    iRemConObserver = NULL;
+
+    if (iSystemFont)
+    {
+        iSystemFont->RemoveRef();
+        iSystemFont = NULL;
+    }
+
+    delete iKeyMapper;
+    iKeyMapper = NULL;
+
+    delete iCommandArranger;  // Mobile Extensions
+    iCommandArranger = NULL;
+
+    delete iMenuArranger;
+    iMenuArranger = NULL;
+
+    delete iUiUtils;          // Core
+    iUiUtils = NULL;
+
+    delete iFactory;
+    iFactory = NULL;
+
+    iTimers.ResetAndDestroy();
+
+    if (iEventQueue)
+        iEventQueue->Flush();
+
+    iResourceChangeObservers.Close();
+    iAppFocusObservers.Close();
+
+    delete iJavaBufferDrawer;
+    iJavaBufferDrawer = NULL;
+
+#ifdef RD_SCALABLE_UI_V2
+    delete iLongTapDetector;
+    iLongTapDetector = NULL;
+#endif //RD_SCALABLE_UI_V2   
+
+    if (iResId != KErrNotFound)
+    {
+        iCoeEnv->DeleteResourceFile(iResId);
+        iResId = KErrNotFound;
+    }
+
+    iCoeEnv = NULL;
+}
+
+
+/**
+ * Sleeps until an event is received
+ *
+ * Must be executed in the main thread.
+ *
+ * @return <code>ETrue</code> if the reason for awakening is reception of an
+ *         event; <code>EFalse</code> otherwise.
+ */
+TBool ASwtDisplayBase::Sleep()
+{
+    ASSERT_JAVAUITHREAD();
+
+    // Must be set before checking if the queue is empty so that if an event
+    // arrives between the moment we checked the queue and when we call
+    // WaitForRequest(), we won't go to sleep.
+    iRequestStatus = KRequestPending;
+
+    if (!iEventQueue->IsEmpty()) //lint !e613
+        return ETrue;
+
+    User::WaitForRequest(iRequestStatus);
+    return ETrue;
+}
+
+/**
+ * Creates a new timer that will auto-destruct. It will also register with
+ * <code>RegisterTimerL()</code>, in case we need to exit and the timer is
+ * still running.
+ */
+void ASwtDisplayBase::AddTimerL(TInt aDelayInMilliSeconds, TInt aTimerHandle)
+{
+    CSwtTimer* timer = CSwtTimer::NewL(*this);
+    timer->ExecuteAfterLD(aDelayInMilliSeconds, aTimerHandle);
+}
+
+
+/**
+ * Adds a new timer to the java side timer list
+ */
+void ASwtDisplayBase::RegisterTimerL(const CSwtTimer* aTimer)
+{
+    UnRegisterTimer(aTimer); //prevents duplicating timers
+    User::LeaveIfError(iTimers.Append(aTimer));
+}
+
+
+/**
+ * Removes the timer from the java side timer list
+ */
+void ASwtDisplayBase::UnRegisterTimer(const CSwtTimer* aTimer)
+{
+    TInt pos = iTimers.Find(aTimer);
+    if (pos >= 0)
+    {
+        iTimers.Remove(pos);
+    }
+}
+
+
+/**
+ * Awakens the display because of reception of a new event.
+ *
+ * Must be executed from within the App UI's thread.
+ */
+void ASwtDisplayBase::HandleNewEvent()
+{
+    ASSERT_NATIVEUITHREAD();
+    DoWake(ETrue);
+}
+
+
+/**
+ * Awakens the display (i.e. the main thread)
+ */
+void ASwtDisplayBase::DoWake(TBool aBecauseOfEvent)
+{
+    if (iRequestStatus == KRequestPending)
+    {
+        TRequestStatus* statusPtr = &iRequestStatus;
+        iJavaUiThread.RequestComplete(statusPtr, aBecauseOfEvent);
+    }
+}
+
+
+/**
+ * Returns the maximum allowed depth of icons
+ *
+ * Must be executed from within the App UI's thread.
+ */
+TInt ASwtDisplayBase::GetIconDepth() const
+{
+    ASSERT_NATIVEUITHREAD();
+    return TDisplayModeUtils::NumDisplayModeBitsPerPixel(iCoeEnv->ScreenDevice()->DisplayMode());
+}
+
+
+/**
+ * Returns the double click time
+ *
+ * Must be executed from within the App UI's thread.
+ */
+TInt ASwtDisplayBase::GetDoubleClickTime() const
+{
+    ASSERT_NATIVEUITHREAD();
+    TTimeIntervalMicroSeconds32 interval(0);
+    TInt distance(0);
+    iCoeEnv->WsSession().GetDoubleClickSettings(interval, distance);
+    return interval.Int();
+}
+
+
+/**
+ * Emits a beep
+ *
+ * Must be executed from within the App UI's thread.
+ */
+void ASwtDisplayBase::Beep() const
+{
+    ASSERT_NATIVEUITHREAD();
+    iCoeEnv->Beep();
+}
+
+
+/**
+ * Posts an asynchronous event.
+ *
+ * @param aData  SWT data of the key event.
+ *
+ * This method should be able to post events of type KeyDown or KeyUp.
+ */
+void ASwtDisplayBase::PostL(const TSwtKeyEventData& aData)
+{
+    ASSERT_NATIVEUITHREAD();
+
+    if ((aData.iType == ESwtEventKeyDown) || (aData.iType == ESwtEventKeyUp))
+    {
+        MSwtShell* shell = iUiUtils->GetActiveShell();
+        if (shell == NULL)
+        {
+            return;
+        }
+        MSwtControl* control = shell->FocusControl();
+        if (control == NULL)
+        {
+            return;
+        }
+
+        TKeyEvent keyEvent;
+        keyEvent.iCode      = 0;
+        keyEvent.iRepeats   = 0;
+        keyEvent.iModifiers = iKeyMapper->GetSymbianModifier(aData);
+
+        if (aData.iType == ESwtEventKeyUp)
+        {
+            // Key up event: keyEvent.iCode is set to 0
+            keyEvent.iScanCode  = iKeyMapper->GetSymbianScanCode(aData.iKeyCode);
+            control->CoeControl().OfferKeyEventL(keyEvent, EEventKeyUp);
+        }
+        else
+        {
+            // Key down event in SWT = key down event follows with key event in Symbian
+            // If several SWT ESwtEventKeyDown are following,
+            // we should post first one Symbian EEventKeyDown
+            // and then as many Symbian EEventKey as SWT ESwtEventKeyDown.
+            // But posting EEventKeyDown and EEventKey at each time should not cause any problem.
+
+            // Key down event: keyEvent.iCode is set to 0
+            TUint code = aData.iCharacter;
+            iKeyMapper->GetSymbianCodes(aData.iKeyCode, keyEvent.iScanCode, &code);
+            control->CoeControl().OfferKeyEventL(keyEvent, EEventKeyDown);
+
+            // Key event: keyEvent.iCode is not 0.
+            keyEvent.iCode = code;
+            control->CoeControl().OfferKeyEventL(keyEvent, EEventKey);
+        }
+    }
+}
+
+/**
+ * Posts an asynchronous event.
+ * @param aData  SWT data of the mouse event.
+ * This method should be able to post events of type MouseDown, MouseUp, MouseMove.
+ */
+TBool ASwtDisplayBase::MousePostL(const TSwtKeyEventData& aData, TPoint point)
+{
+    ASSERT_NATIVEUITHREAD();
+
+    if (AknLayoutUtils::PenEnabled())
+    {
+        TRawEvent event;
+        if (aData.iType == ESwtEventMouseDown)
+        {
+            event.Set(TRawEvent::EButton1Down, point.iX, point.iY);
+            iCoeEnv->WsSession().SimulateRawEvent(event);
+        }
+        else if (aData.iType == ESwtEventMouseUp)
+        {
+            event.Set(TRawEvent::EButton1Up, point.iX, point.iY);
+            iCoeEnv->WsSession().SimulateRawEvent(event);
+        }
+        else if (aData.iType == ESwtEventMouseMove)
+        {
+            event.Set(TRawEvent::EPointerMove, point.iX, point.iY);
+            iCoeEnv->WsSession().SimulateRawEvent(event);
+        }
+        return ETrue;
+    }
+    else
+    {
+        return EFalse;
+    }
+}
+
+/**
+ * Constructs an uninitialised Image
+ *
+ * @param aSize  The new image's size
+ */
+MSwtImage* ASwtDisplayBase::NewImageL(const TSize& aSize)
+{
+    return CSwtImage::NewL(*this, aSize, *this);
+}
+
+
+/**
+ * Constructs an Image with initial data
+ *
+ * @param aData  The data to construct the image from
+ */
+MSwtImage* ASwtDisplayBase::NewImageFromDataL(const MSwtImageData& aData)
+{
+    return CSwtImage::NewL(this, aData, this);
+}
+
+
+//
+// Own internal event methods
+//
+
+void ASwtDisplayBase::PostForegroundEventL(TSwtPeer aPeer, const TBool& aForeground)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtForegroundEvent(aPeer, aForeground)); //lint !e613
+}
+
+
+//
+// Virtual methods from MSwtDisplay
+//
+
+MSwtDevice& ASwtDisplayBase::Device()
+{
+    return *this;
+}
+
+const MSwtFactory& ASwtDisplayBase::Factory() const
+{
+    ASSERT(iFactory);
+    return *iFactory;
+}
+
+MSwtUiUtils& ASwtDisplayBase::UiUtils()
+{
+    ASSERT(iUiUtils!=NULL);
+    return *iUiUtils;         //lint !e613
+}
+
+MSwtMenuArranger& ASwtDisplayBase::MenuArranger()
+{
+    ASSERT(iMenuArranger!=NULL);
+    return *iMenuArranger;
+}
+
+MSwtCommandArranger* ASwtDisplayBase::CommandArranger()
+{
+    return iCommandArranger;
+}
+
+void ASwtDisplayBase::AddResourceChangeObserverL(MSwtResourceChangeObserver* aObserver)
+{
+    User::LeaveIfError(iResourceChangeObservers.Append(aObserver));
+}
+
+void ASwtDisplayBase::RemoveResourceChangeObserver(MSwtResourceChangeObserver* aObserver)
+{
+    TInt pos = iResourceChangeObservers.Find(aObserver);
+    if (pos != KErrNotFound)
+    {
+        iResourceChangeObservers.Remove(pos);
+    }
+}
+
+void ASwtDisplayBase::AddAppFocusObserverL(MSwtAppFocusObserver* aObserver)
+{
+    User::LeaveIfError(iAppFocusObservers.Append(aObserver));
+}
+
+void ASwtDisplayBase::RemoveAppFocusObserver(MSwtAppFocusObserver* aObserver)
+{
+    TInt pos = iAppFocusObservers.Find(aObserver);
+    if (pos != KErrNotFound)
+    {
+        iAppFocusObservers.Remove(pos);
+    }
+}
+
+TInt ASwtDisplayBase::GetSymbianScanCode(const TInt aSwtKeyCode) const
+{
+    return CSwtKeyMapper::GetSymbianScanCode(aSwtKeyCode);
+}
+
+TUint ASwtDisplayBase::GetSymbianKeyCode(const TInt aSwtKeyCode) const
+{
+    TUint keyCode = aSwtKeyCode;
+    TInt scanCodeNotNeeded;
+    CSwtKeyMapper::GetSymbianCodes(aSwtKeyCode, scanCodeNotNeeded, &keyCode);
+    return keyCode;
+}
+
+void ASwtDisplayBase::ForceTraverseEventL(MSwtControl& aControl, TSwtTraversal aDetail, TBool aDoIt)
+{
+    ASSERT_NATIVEUITHREAD();
+
+    TSwtKeyEventData data;
+    data.iType      = ESwtEventTraverse;
+    data.iCharacter = 0;
+    data.iKeyCode   = 0;
+    data.iStateMask = 0;
+
+    TKeyEvent keyEvent;
+    keyEvent.iCode      = 0;
+    keyEvent.iModifiers = 0;
+    keyEvent.iRepeats   = 0;
+    keyEvent.iScanCode  = 0;
+
+    iEventQueue->PushL(new(ELeave) CSwtTraverseEvent(aControl, aDetail, aDoIt, data, keyEvent, EEventKey)); //lint !e613
+}
+
+
+void ASwtDisplayBase::PostTraverseEventL(MSwtControl& aControl, TSwtTraversal aDetail, const TKeyEvent& aKeyEvent,
+        TEventCode aType, TBool aDoIt)
+{
+    ASSERT_NATIVEUITHREAD();
+    ASSERT(iKeyMapper!=NULL);
+
+    TSwtKeyEventData data(iKeyMapper->MapKeyEventL(aKeyEvent, aType)); //lint !e613
+    if (data.iType != ESwtEventNone)
+        iEventQueue->PushL(new(ELeave) CSwtTraverseEvent(aControl, aDetail, aDoIt, data, aKeyEvent, aType)); //lint !e613
+}
+
+
+void ASwtDisplayBase::PostKeyEventL(MSwtControl& aControl, const TKeyEvent& aKeyEvent, TEventCode aType)
+{
+    ASSERT_NATIVEUITHREAD();
+    ASSERT(iKeyMapper!=NULL);
+    ASSERT(aType!=EEventNull);
+
+    // EEventKeyDown can be posted only if the key does not generate EEventKey!
+    TSwtKeyEventData data(iKeyMapper->MapKeyEventL(aKeyEvent, aType)); //lint !e613
+    if (data.iType != ESwtEventNone)
+        iEventQueue->PushL(new(ELeave) CSwtKeyEvent(aControl, data, aKeyEvent, aType)); //lint !e613
+}
+
+
+void ASwtDisplayBase::PostPaintEventL(TSwtPeer aSenderPeer, TSwtPeer aShellPeer, const TRect& aRect, TBool aMergeable)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtPaintEvent(aSenderPeer, aShellPeer, aRect, aMergeable)); //lint !e613
+}
+
+
+void ASwtDisplayBase::PostMouseEventL(TSwtPeer aPeer, TSwtEventType aType, TInt aButton, const TPoint& aPos, TInt aStateMask)
+{
+    ASSERT_NATIVEUITHREAD();
+    ASSERT(aType>=ESwtEventMouseDown && aType<=ESwtEventMouseDoubleClick);
+    ASSERT(aButton==0 || (aType==ESwtEventMouseDown || aType==ESwtEventMouseUp));
+
+#ifdef RD_SCALABLE_UI_V2
+    // After the long tap we send mouse up event for button2, see also HandleLongTapEventL().
+    if (iLongTapDetected && aType == ESwtEventMouseUp && aButton == KSwtMouseButton1)
+    {
+        aButton = KSwtMouseButton2;
+    }
+#endif //RD_SCALABLE_UI_V2        
+
+    iEventQueue->PushL(new(ELeave) CSwtMouseEvent(aPeer, aType, aButton, aPos, aStateMask)); //lint !e613
+}
+
+void ASwtDisplayBase::PostMoveEventL(TSwtPeer aPeer)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtPlainEvent(aPeer, ESwtEventMove)); //lint !e613
+}
+
+void ASwtDisplayBase::PostResizeEventL(TSwtPeer aPeer)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtResizeEvent(aPeer)); //lint !e613
+}
+
+void ASwtDisplayBase::PostScrollEventL(TSwtPeer aPeer, TInt aDetail)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtScrollEvent(aPeer, aDetail)); //lint !e613
+}
+
+void ASwtDisplayBase::PostSelectionEventL(TSwtPeer aPeer)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtPlainEvent(aPeer, ESwtEventSelection)); //lint !e613
+}
+
+void ASwtDisplayBase::PostSelectionEventL(TSwtPeer aPeer, const TDesC& aText)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(CSwtTextSelectionEvent::NewL(aPeer, aText));  //lint !e613
+}
+
+void ASwtDisplayBase::PostSelectionEventL(TSwtPeer aPeer, TInt aDetail, TSwtPeer aItemPeer)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtPlainEvent(aPeer, ESwtEventSelection, aDetail, aItemPeer)); //lint !e613
+}
+
+void ASwtDisplayBase::PostDefaultSelectionEventL(TSwtPeer aPeer)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtPlainEvent(aPeer, ESwtEventDefaultSelection,KSwtNone,NULL)); //lint !e613
+}
+
+void ASwtDisplayBase::PostDefaultSelectionEventL(TSwtPeer aPeer, TInt aDetail, TSwtPeer aItemPeer)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtPlainEvent(aPeer, ESwtEventDefaultSelection, aDetail, aItemPeer)); //lint !e613
+}
+
+void ASwtDisplayBase::PostFocusEventL(TSwtPeer aPeer, TSwtEventType aType)
+{
+    ASSERT_NATIVEUITHREAD();
+    ASSERT(aType==ESwtEventFocusIn || aType==ESwtEventFocusOut);
+    iEventQueue->PushL(new(ELeave) CSwtPlainEvent(aPeer, aType)); //lint !e613
+}
+
+void ASwtDisplayBase::PostShellEventL(TSwtPeer aPeer, TSwtEventType aType)
+{
+    ASSERT_NATIVEUITHREAD();
+    ASSERT(aType==ESwtEventActivate || aType==ESwtEventDeactivate);
+    iEventQueue->PushL(new(ELeave) CSwtPlainEvent(aPeer, aType)); //lint !e613
+}
+
+void ASwtDisplayBase::PostModifyEventL(TSwtPeer aPeer)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtPlainEvent(aPeer, ESwtEventModify, KSwtNone, NULL)); //lint !e613
+}
+
+void ASwtDisplayBase::PostVerifyEventL(MSwtVerifyEventObserver& aWidget, TSwtPeer aPeer, TInt aStart, TInt aEnd, const TDesC& aText)
+{
+    ASSERT_NATIVEUITHREAD();
+    ASSERT(aStart>=0 && aStart<=aEnd);
+    iEventQueue->PushL(CSwtVerifyEvent::NewL(aWidget, aPeer, aStart, aEnd, aText)); //lint !e613
+}
+
+void ASwtDisplayBase::PostShowEventL(TSwtPeer aPeer)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtPlainEvent(aPeer, ESwtEventShow)); //lint !e613
+}
+
+void ASwtDisplayBase::PostHideEventL(TSwtPeer aPeer)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtPlainEvent(aPeer, ESwtEventHide)); //lint !e613
+}
+
+void ASwtDisplayBase::PostScreenEventL(TSwtPeer aPeer, TInt aType)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtScreenEvent(aPeer, aType)); //lint !e613
+}
+
+void ASwtDisplayBase::PostMobileDeviceEventL(TSwtPeer aPeer, TInt aEventType)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtMobileDeviceEvent(aPeer, aEventType)); //lint !e613
+}
+
+void ASwtDisplayBase::PostTreeEventL(TSwtPeer aPeer, TSwtEventType aType, TInt aItemHandle)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtTreeEvent(aPeer, aType, aItemHandle)); //lint !e613
+}
+
+void ASwtDisplayBase::PostLocationChangingEventL(TSwtPeer aPeer
+        , MSwtBrowser& aBrowser, TBool aDoIt, TBool aTop
+        , const TDesC& aLocation, TSwtBrCallBackOperationType aCallBackOperationType)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(CSwtLocationChangingEvent::NewL(aPeer, aBrowser, aDoIt, aTop
+                       , aLocation, aCallBackOperationType));
+}
+
+void ASwtDisplayBase::PostLocationChangedEventL(TSwtPeer aPeer,
+        TBool aDoIt, TBool aTop, const TDesC& aLocation)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(CSwtLocationChangedEvent::NewL(aPeer, aDoIt, aTop, aLocation));
+}
+
+void ASwtDisplayBase::PostProgressEventL(TSwtPeer aPeer, TInt aCurrent, TInt aTotal)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtProgressEvent(aPeer, aCurrent, aTotal));
+}
+
+void ASwtDisplayBase::PostProgressCompletedEventL(TSwtPeer aPeer, TInt aCurrent, TInt aTotal)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtProgressCompletedEvent(aPeer, aCurrent, aTotal));
+}
+
+void ASwtDisplayBase::PostStatusTextEventL(TSwtPeer aPeer, const TDesC& aStatusText)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(CSwtStatusTextEvent::NewL(aPeer, aStatusText));
+}
+
+void ASwtDisplayBase::PostTitleEventL(TSwtPeer aPeer, const TDesC& aTitle)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(CSwtTitleEvent::NewL(aPeer, aTitle));
+}
+
+void ASwtDisplayBase::PostDialogResultEventL(CSwtDialogBroker* aBroker, TSwtPeer aPeer, const TDesC& aDialogResult)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(CSwtDialogStringResultEvent::NewL(aBroker, aPeer, aDialogResult));
+}
+
+void ASwtDisplayBase::PostDialogResultEventL(CSwtDialogBroker* aBroker, TSwtPeer aPeer, TInt aDialogResult)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtDialogIntegerResultEvent(aBroker, aPeer, aDialogResult));
+}
+
+void ASwtDisplayBase::PostDialogResultEventL(CSwtDialogBroker* aBroker, TSwtPeer aPeer,  TInt aDialogResult1, TInt aDialogResult2, TInt aDialogResult3)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtDialogRgbResultEvent(aBroker, aPeer, aDialogResult1, aDialogResult2, aDialogResult3));
+}
+
+void ASwtDisplayBase::PostCloseEventL(TSwtPeer aPeer, TBool& aDispatched)
+{
+    ASSERT_NATIVEUITHREAD();
+    iEventQueue->PushL(new(ELeave) CSwtCloseEvent(aPeer, aDispatched));
+}
+
+TInt ASwtDisplayBase::ApplicationUid()
+{
+    return iApplicationUid;
+}
+
+CEikonEnv* ASwtDisplayBase::CoeEnv() const
+{
+    ASSERT(iCoeEnv);
+    return iCoeEnv;
+}
+
+CDesC16ArrayFlat* ASwtDisplayBase::GetFontNamesL(TBool aScalable) const
+{
+    ASSERT_NATIVEUITHREAD();
+
+    CEikonEnv* eikEnv = iCoeEnv;
+    CWsScreenDevice* screenDevice = NULL;
+    if (eikEnv)
+    {
+        screenDevice = eikEnv->ScreenDevice();
+    }
+    if (!eikEnv || !screenDevice)
+    {
+        return NULL;
+    }
+
+    // Look for available fonts
+    const TInt KArrayGranularity = 4;
+    //Caller method is responsible for deleting the fontNameList
+    CDesC16ArrayFlat* fontNameList = new(ELeave) CDesC16ArrayFlat(KArrayGranularity);
+    CleanupStack::PushL(fontNameList);
+    FontUtils::GetAvailableFontsL(*screenDevice, *fontNameList, EGulAllFonts);
+
+    TFontSpec fontSpec;
+    CFont* font = NULL;
+    TInt  fontNameListCount = fontNameList->Count();
+    for (TInt nameIndex=0; nameIndex<fontNameListCount; ++nameIndex)
+    {
+        // Look for the nearest font from the current typeface name.
+        // This is needed only to check if the font correspond to the
+        // aScalable parameter
+        fontSpec.iTypeface.iName = (*fontNameList)[nameIndex];
+        fontSpec.iHeight = 0;
+        fontSpec.iFontStyle = TFontStyle(EPostureUpright, EStrokeWeightNormal, EPrintPosNormal);
+        User::LeaveIfError(screenDevice->GetNearestFontInTwips(font, fontSpec) == KErrNone);
+
+        // Manage scalable attribute
+        // CFont::TypeUid() returns the UId of the type of the font:
+        //  - KCFbsFontUid for a CFbsFont
+        //  - KCBitmapFontUid or KCBitmapFontUidVal for a CBitmapFont
+        // On Series60 SDK, no Uid  is available for CBitmapFont.
+        // So scalable management is processed only for CFbsFont.
+        // For the other font types, the font is always added to the list.
+        if (font->TypeUid() == KCFbsFontUid)
+        {
+            if (aScalable !=(static_cast<CFbsFont*>(font))->IsOpenFont())
+            {
+                // Delete the font because its scalable attribute
+                // doesn't correspond to aScalable parameter.
+                fontNameList->Delete(nameIndex);
+                fontNameList->Compress();
+                fontNameListCount--;
+                nameIndex--;
+            }
+        }
+#ifdef _DEBUG
+        else
+        {
+            // Non-recognized font type Uid.
+            __DEBUGGER();
+        }
+#endif
+        screenDevice->ReleaseFont(font);
+        font = NULL;
+    }
+
+    CleanupStack::Pop(fontNameList);
+    return fontNameList;
+}
+
+TBool ASwtDisplayBase::RevertPointerEvent() const
+{
+    return iRevertPointerEvent || iLongTapDetected;
+}
+
+void ASwtDisplayBase::SetRevertPointerEvent(TBool aStatus) 
+{
+    iRevertPointerEvent = aStatus;
+}
+
+//
+// Virtual methods from MSwtDevice
+//
+
+MSwtColor* ASwtDisplayBase::CreateColorL(const TRgb& aRgbValue) const
+{
+    return iFactory->NewColorL(*this, aRgbValue); //lint !e613
+}
+
+TRect ASwtDisplayBase::Bounds() const
+{
+    ASSERT_NATIVEUITHREAD();
+    return TRect(iCoeEnv->EikAppUi()->ApplicationRect());
+}
+
+TRect ASwtDisplayBase::ClientArea() const
+{
+    ASSERT_NATIVEUITHREAD();
+    TRect appUiCltRect(iCoeEnv->EikAppUi()->ApplicationRect());
+    iUiUtils->Cba().ReduceRect(appUiCltRect);
+    return appUiCltRect;
+}
+
+TInt ASwtDisplayBase::Depth() const
+{
+    ASSERT_NATIVEUITHREAD();
+    switch (iCoeEnv->ScreenDevice()->DisplayMode())
+    {
+    case EGray2:
+        return 1;
+    case EGray4:
+        return 2;
+    case EGray16:
+        return 4;
+    case EGray256:
+        return 8;
+    case EColor16:
+        return 4;
+    case EColor256:
+        return 8;
+    case EColor64K:
+        return 16;
+    case EColor16M:
+        return 24;
+    case EColor16MU:
+        return 32;
+    case EColor16MA:
+        return 32;
+    case EColor16MAP:
+        return 32;
+    case EColor4K:
+        return 12;
+    default:
+        ASSERT(EFalse);
+        return 0;
+    }
+}
+
+TSize ASwtDisplayBase::Dpi() const
+{
+    ASSERT_NATIVEUITHREAD();
+
+    // Convert a 1440x1440 twips (i.e. 1x1 inch) square to pixels, this yelds the
+    // DPI resolution.
+    return iCoeEnv->ScreenDevice()->TwipsToPixels(TPoint(KTwipsPerInch,KTwipsPerInch)).AsSize();
+}
+
+static TInt getTheHeightInTWipsL(CEikonEnv* aEnv, const MSwtDevice& aDevice,
+                                 const TFontSpec& aFontSpec, TInt aIndexInArray, CArrayFixFlat<TInt>* aArrayHeight)
+{
+    TFontSpec fontSpec(aFontSpec);
+    CFont*    iFont                = NULL;
+    TInt      heightInTWips        = aArrayHeight->At(aIndexInArray);
+    TInt      heightOfObtainFontPt = 0;
+    TInt      heightOfAskedFontPt  = FontUtils::PointsFromTwips(heightInTWips);
+    TInt      maxHeightPt          = FontUtils::PointsFromTwips(aArrayHeight->At(aArrayHeight->Count()-1));
+
+    CBitmapDevice& bmpDevice = *(aEnv->ScreenDevice());
+
+    // Look for available heights for the current font.
+    fontSpec.iHeight = FontUtils::TwipsFromPoints(heightOfAskedFontPt);
+    User::LeaveIfError(bmpDevice.GetNearestFontInTwips(iFont, fontSpec));
+    heightOfObtainFontPt = FontUtils::PointsFromTwips(iFont->FontSpecInTwips().iHeight);
+
+    while (((heightInTWips != iFont->FontSpecInTwips().iHeight)
+            && (heightOfAskedFontPt < maxHeightPt))
+            && (heightOfAskedFontPt >  heightOfObtainFontPt))
+    {
+        heightOfAskedFontPt++;
+        fontSpec.iHeight = FontUtils::TwipsFromPoints(heightOfAskedFontPt);
+
+        const_cast<MSwtDevice&>(aDevice).GraphicsDevice().ReleaseFont(iFont);
+        heightOfObtainFontPt = FontUtils::PointsFromTwips(iFont->FontSpecInTwips().iHeight);
+        User::LeaveIfError(bmpDevice.GetNearestFontInTwips(iFont, fontSpec));
+    }
+
+    const_cast<MSwtDevice&>(aDevice).GraphicsDevice().ReleaseFont(iFont);
+    return fontSpec.iHeight;
+}
+
+CArrayFixFlat<TSwtFontData>* ASwtDisplayBase::GetFontListL(const TDesC& aFaceName, TBool aScalable) const
+{
+    ASSERT_NATIVEUITHREAD();
+
+    CEikonEnv& eikEnv = *iCoeEnv;
+
+    // Look for available fonts
+    const TInt        KArrayGranularity = 4;
+    CDesC16ArrayFlat* fontNameList = new(ELeave) CDesC16ArrayFlat(KArrayGranularity);
+    CleanupStack::PushL(fontNameList);
+    if (aFaceName.Length() == 0)
+    {
+        FontUtils::GetAvailableFontsL(*(eikEnv.ScreenDevice()), *fontNameList, EGulAllFonts);
+    }
+    else
+    {
+        fontNameList->AppendL(aFaceName);
+    }
+
+    CArrayFixFlat<TSwtFontData>* arrayFontData = new(ELeave) CArrayFixFlat<TSwtFontData>(KArrayGranularity);
+    CleanupStack::PushL(arrayFontData);
+
+    CArrayFixFlat<TInt>* heightList = new(ELeave)CArrayFixFlat<TInt>(KArrayGranularity);
+    CleanupStack::PushL(heightList);
+
+    TFontSpec    fontSpec;
+    TSwtFontData fontData;
+    CFont*       font = NULL;
+    TInt  heightIndex;
+    TInt  fontNameListCount = fontNameList->Count();
+    TInt  heightListCount;
+    for (TInt nameIndex=0; nameIndex<fontNameListCount; ++nameIndex)
+    {
+        // Look for the nearest font from the current typeface name.
+        fontSpec.iTypeface.iName = (*fontNameList)[nameIndex];
+        fontSpec.iHeight = 0;
+        fontSpec.iFontStyle = TFontStyle(EPostureUpright, EStrokeWeightNormal, EPrintPosNormal);
+        User::LeaveIfError(eikEnv.ScreenDevice()->GetNearestFontInTwips(font, fontSpec) == KErrNone);
+
+        // Manage scalable attribute
+        // CFont::TypeUid() returns the UId of the type of the font:
+        //  - KCFbsFontUid for a CFbsFont
+        //  - KCBitmapFontUid or KCBitmapFontUidVal for a CBitmapFont
+        // On Series60 SDK, no Uid  is available for CBitmapFont.
+        // So scalable management is processed only for CFbsFont.
+        // For the other font types, the font is always added to the list.
+        if (font->TypeUid() == KCFbsFontUid)
+        {
+            if (aScalable != (static_cast<CFbsFont*>(font))->IsOpenFont())
+            {
+                // Ignore the font because its scalable attribute
+                // doesn't correspond to aScalable parameter.
+                continue;
+            }
+        }
+#ifdef _DEBUG
+        else
+        {
+            // Non-recognized font type Uid.
+            __DEBUGGER();
+        }
+#endif
+
+
+        fontSpec = font->FontSpecInTwips();
+
+        // Look for available heights for the current font
+        if (FontUtils::GetAvailableHeightsInTwipsL(*(eikEnv.ScreenDevice()),
+                fontSpec.iTypeface.iName, *heightList) == KErrNone)
+        {
+            fontData.iFontSpec  = font->FontSpecInTwips();
+            heightListCount     = heightList->Count();
+            for (heightIndex = 0; heightIndex<heightListCount; heightIndex++)
+            {
+                fontData.iFontSpec.iHeight = getTheHeightInTWipsL(iCoeEnv, *this,
+                                             fontData.iFontSpec, heightIndex, heightList);
+                arrayFontData->AppendL(fontData);
+            }
+        }
+        heightList->Reset();
+        eikEnv.ScreenDevice()->ReleaseFont(font);
+        font = NULL;
+    }
+
+    CleanupStack::PopAndDestroy(heightList);
+    CleanupStack::Pop(arrayFontData);
+    CleanupStack::PopAndDestroy(fontNameList);
+    return arrayFontData;
+}
+
+TRgb ASwtDisplayBase::GetSystemColor(TSwtColorId aId) const
+{
+    ASSERT_NATIVEUITHREAD();
+    return iUiUtils->GetSystemColor(aId); //lint !e613
+}
+
+const MSwtFont* ASwtDisplayBase::GetSystemFont() const
+{
+    ASSERT_NATIVEUITHREAD();
+    if (!iSystemFont)
+    {
+        ASwtDisplayBase* self = const_cast<ASwtDisplayBase*>(this);
+        TRAP_IGNORE(self->iSystemFont = CSwtFont::NewL(*self, *AknLayoutUtils::FontFromId(
+                                            CSwtLafFacade::GetFontId(CSwtLafFacade::EForm2MidpLabelPaneT1Font, 0))));
+    }
+    return iSystemFont;
+}
+
+TInt ASwtDisplayBase::GetDefaultFontHeightL()
+{
+    TFontSpec fontSpec(KNullDesC, 0);
+    CFont* font = NULL;
+    CBitmapDevice& device = GraphicsDevice();
+    User::LeaveIfError(device.GetNearestFontInTwips(font, fontSpec));
+
+    TInt result = 0;
+    if (font!=NULL)
+    {
+        fontSpec = font->FontSpecInTwips();
+        result = FontUtils::PointsFromTwips(fontSpec.iHeight);
+        device.ReleaseFont(font);
+        font = NULL;
+    }
+
+    return result;
+}
+
+
+//
+// Virtual methods from MSwtDrawable
+//
+
+MSwtGc* ASwtDisplayBase::NewGcL()
+{
+    _LIT(KLibName, "scdv");
+
+    ASSERT_NATIVEUITHREAD();
+
+    CFbsScreenDevice* device = CFbsScreenDevice::NewL(KLibName, iCoeEnv->ScreenDevice()->DisplayMode());
+    device->SetAutoUpdate(ETrue);
+    CleanupStack::PushL(device);
+    CFbsBitGc* nativeGc;
+    User::LeaveIfError(device->CreateContext(nativeGc));
+    CleanupStack::Pop(device);
+
+    return iFactory->NewBitmapGcL(*this, nativeGc, DestroyNativeGc, KRgbBlack, KRgbWhite, *iSystemFont); //lint !e613
+}
+
+void ASwtDisplayBase::DestroyNativeGc(CBitmapContext* aGc)
+{
+    delete aGc->Device();
+    delete aGc;
+}
+
+CBitmapDevice& ASwtDisplayBase::GraphicsDevice()
+{
+    ASSERT_NATIVEUITHREAD();
+    return *(iCoeEnv->ScreenDevice());
+}
+
+void ASwtDisplayBase::HandleUpdate()
+{
+    // Nothing to do
+}
+
+void ASwtDisplayBase::SetMobileDevice(MSwtMobileDevice* aMobileDevice)
+{
+    // Not to be called by anyone except CSwtMobileDevice and only once
+    ASSERT(!iMobileDevice);
+    iMobileDevice = aMobileDevice;
+}
+
+MSwtMobileDevice* ASwtDisplayBase::MobileDevice()
+{
+    return iMobileDevice;
+}
+
+#ifdef RD_SCALABLE_UI_V2
+void ASwtDisplayBase::TryDetectLongTapL(const TPointerEvent& aPointerEvent)
+{
+    ASSERT_NATIVEUITHREAD();
+    ASSERT(iCommandArranger);
+
+    if (aPointerEvent.iType == TPointerEvent::EButton1Down)
+    {
+        iLongTapControl = NULL;
+        iLongTapDetected = EFalse;
+        MSwtControl* ctrl = iUiUtils->GetPointerGrabbingControl();
+
+        // No long tap animation on scrollbars or trimings.
+        // Long tap animation only if there is a popup menu.
+        if (ctrl && ctrl->IsLongTapAnimationCandidate(aPointerEvent))
+        {
+            iLongTapControl = ctrl;
+        }
+    }
+    
+    iLongTapPointerEvent = aPointerEvent;
+
+    if (iLongTapControl)
+    {
+        iLongTapDetector->PointerEventL(aPointerEvent);
+    }
+}
+
+MSwtControl* ASwtDisplayBase::LongTapAnimationControl() const
+{
+    ASSERT_NATIVEUITHREAD();
+    return iLongTapControl;
+}
+
+void ASwtDisplayBase::CancelLongTapAnimation()
+{
+    ASSERT_NATIVEUITHREAD();
+    // IAD WARNING: Do not call CAknLongTapDetector::CancelAnimationL()
+    iLongTapControl = NULL;
+    iLongTapDetected = EFalse;
+}
+
+void ASwtDisplayBase::HandleLongTapEventL(const TPoint& /*aPenEventLocation*/,
+        const TPoint& aPenEventScreenLocation)
+{
+    ASSERT_NATIVEUITHREAD();
+    ASSERT(iMenuArranger);
+
+    MSwtControl* ctrl = iLongTapControl;
+    if (!ctrl)
+    {
+        // Control disposed or pen lifted just before menu was about to open.
+        iLongTapDetected = EFalse;
+        return;
+    }
+
+    // Will be switched back after the popup menu closes 
+    // and the late pointer up event was delivered.
+    iLongTapDetected = ETrue;
+
+    // Open menu on the longTap cursor position
+    iMenuArranger->OpenStylusPopupMenuL(*ctrl, aPenEventScreenLocation, this);
+}
+#endif //RD_SCALABLE_UI_V2    
+
+// From MSwtPopupMenuCallBack
+// Native Ui Thread
+void ASwtDisplayBase::HandlePopupMenuClosedL()
+{
+    if (iLongTapControl)
+    {
+        // Forward delayed pointer event
+        TPointerEvent event(iLongTapPointerEvent);
+        event.iType = TPointerEvent::EButton1Up;
+        iLongTapControl->HandlePointerEventL(event); // revert
+    }
+    
+    // Just to clear the flags.
+    CancelLongTapAnimation();
+}
+
+// From MSwtMediaKeysListener
+// Native Ui Thread
+void ASwtDisplayBase::HandleMediaKeyEvent(TKeyEvent& aKeyEvent, TInt aEventType)
+{
+    ASSERT(iUiUtils);
+
+    MSwtControl* focusControl = 0;
+    MSwtShell* activeShell = NULL;
+
+    if (iUiUtils->IsAppFocused())
+    {
+        activeShell = iUiUtils->GetActiveShell();
+
+        if (activeShell)
+        {
+            focusControl = activeShell->FocusControl();
+        }
+    }
+    else
+    {
+        CSwtUiUtils* uiUtils = static_cast<CSwtUiUtils*>(iUiUtils);
+        focusControl = uiUtils->NextFocusedControl();
+    }
+
+    if (focusControl)
+    {
+        TRAP_IGNORE(focusControl->CoeControl().OfferKeyEventL(aKeyEvent, (TEventCode)aEventType));
+    }
+    else
+    {
+        if (activeShell)
+        {
+            TRAP_IGNORE(activeShell->Control()->CoeControl().OfferKeyEventL(aKeyEvent, (TEventCode)aEventType));
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtUiUtils::LoadResourceFileL
+// ---------------------------------------------------------------------------
+//
+TInt ASwtDisplayBase::LoadResourceFileL()
+{
+    TFileName langFile = java::util::S60CommonUtils::ResourceLanguageFileNameL(KSwtResFile);
+    return iCoeEnv->AddResourceFileL(langFile);
+}