javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swtcontrolbase.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 13 Oct 2010 14:23:59 +0300
branchRCL_3
changeset 83 26b2b12093af
parent 77 7cee158cb8cd
permissions -rw-r--r--
Revision: v2.2.17 Kit: 201041

/*******************************************************************************
 * 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 <biditext.h>
#include <aknappui.h>
#include <aknnavi.h>
#include <aknnavide.h>
#include <akntabgrp.h>
#include <coecntrl.h>
#include <eikon.hrh>
#include <AknsDrawUtils.h>
#include <swtlaffacade.h>
#include <coreuiavkoneswt.h>
#include "eswtmobileextensions.h"
#include "swtcontrolbase.h"
#include "swtuiutils.h"
#include "swtjavabufferdrawer.h"


// ======== MEMBER FUNCTIONS ========


EXPORT_C ASwtControlBase::ASwtControlBase(MSwtDisplay& aDisplay, TSwtPeer aPeer,
        MSwtComposite* aParent, TInt aStyle)
        : iDisplay(aDisplay)
        , iPeer(aPeer)
        , iParent(aParent)
        , iCtrlFlags(0)
        , iStyle(aStyle)
        , iFont(NULL)
        , iPopupMenu(NULL)
        , iIsOnControlStack(EFalse)
        , iStackedSetRedrawFalseNb(0)
        , iBackgrdDefaultUsed(ETrue)
        , iFocusFrame(NULL)
        , iFocusChanged(EFalse)
{
    ASSERT(iPeer!=NULL);

    // Orientation not specified, find default
    TInt orientation = iStyle & KSwtOrientationMask;
    if (orientation!=KSwtStyleLeftToRight && orientation!=KSwtStyleRightToLeft)
    {
        if (iParent != NULL) // Inherit from parent
            orientation = iParent->Control()->Style() & KSwtOrientationMask;
        else                 // Based on user's locale
            orientation = (TBidiText::ScriptDirectionality(User::Language())==TBidiText::ELeftToRight) ?
                          KSwtStyleLeftToRight : KSwtStyleRightToLeft;

        iStyle &= ~KSwtOrientationMask;
        iStyle |= orientation;
    }
}

void ASwtControlBase::CreateFocusBackgroundL()
{
    ASSERT(!iFocusFrame);

    TRect rect(CoeControl().Rect());
    TRect innerRect;
    innerRect.iTl = CSwtLafFacade::GetLayoutRect(
                        CSwtLafFacade::EInputFieldSkinPlacingGeneralLine2, rect, 0).Rect().iBr;
    innerRect.iBr = CSwtLafFacade::GetLayoutRect(
                        CSwtLafFacade::EInputFieldSkinPlacingGeneralLine5, rect, 0).Rect().iTl;

    iFocusFrame = CAknsFrameBackgroundControlContext::NewL(
                      KAknsIIDQsnFrInput, rect, innerRect, EFalse /*parent absolute*/);

    if (iBackgrdDefaultUsed)
    {
        iFocusFrame->SetParentContext(SwtMopSupplyCtrlContext(EFalse));
    }
}

CAknsBasicBackgroundControlContext* ASwtControlBase::FocusBackgroundNow() const
{
    if (HasHighlight(EFalse)) // not checking parents
    {
        return iFocusFrame;
    }
    else
    {
        return NULL;
    }
}

void ASwtControlBase::RedrawFocusBackground()
{
    MSwtCaptionedControl* captCtrl = GetNearestCaptionedControl();
    if (captCtrl)
    {
        captCtrl->Composite()->Control()->Redraw();
    }
    else
    {
        Redraw();
    }
}

void ASwtControlBase::InitControlBaseL()
{
    RegisterWithParentL();
}

EXPORT_C ASwtControlBase::~ASwtControlBase()
{
    delete iFocusFrame;

    // RemoveRef here in case it goes through destruction before being
    // registered (and Dispose() is not called)
    if (iFont != NULL)
        iFont->RemoveRef();

#ifdef _lint
    //lint -esym(1740, ASwtControlBase::iPeer)
    //lint -esym(1740, ASwtControlBase::iParent)
    iFont      = NULL;
    iPopupMenu = NULL;
#endif
}

// From class MCoeControlBackground.
// Draw the Background. This method was called by the eSWT and Symbian drawing framework.
// If the control is a Composite then make sure not to draw the background to
// the areas that will be painted by the children. This is to avoid painting
// over them as this would cause flickering.
//
EXPORT_C void ASwtControlBase::Draw(CWindowGc& aGc, const CCoeControl& aControl,
                                    const TRect& aRect) const
{
    RRegion* clippingRegion = NULL;
    const MSwtComposite* composite = CompositeInterface();
    if (composite)
    {
        clippingRegion = SetupChildClippingRegion(composite, aGc, aRect);
    }

    TBool isDialogShell = IsShell() && iParent;
    TBool isTaskTip = isDialogShell && ShellInterface()->IsTaskTip();

    // Draw the background.
    if (!IsDefaultBackgroundUse()
#ifdef RD_JAVA_S60_RELEASE_9_2
            // Fill the round corners
            || (isDialogShell && !isTaskTip)
#endif // RD_JAVA_S60_RELEASE_9_2
       )
    {
        aGc.SetBrushColor(GetBackground());
        aGc.Clear(aRect);
    }

    // Hopefully the highlight back is always semi transparent,
    // otherwise the back color is lost.
    MAknsControlContext* cc = SwtMopSupplyCtrlContext();
    AknsDrawUtils::Background(AknsUtils::SkinInstance(), cc, &aControl, aGc, aRect);

    // Cancel & destroy the clipping region
    CancelChildClippingRegion(clippingRegion, aGc);
}

EXPORT_C void ASwtControlBase::DrawBorder(const TRect& /*aRect*/) const
{
    TInt borderWidth = GetBorderWidth();
    if (borderWidth > 0)
    {
        CWindowGc& gc = CoeControl().SystemGc();
        gc.SetBrushStyle(CGraphicsContext::ENullBrush);
        gc.SetPenColor(UiUtils().GetSystemColor(ESwtColorWidgetBorder));
        gc.SetPenStyle(CGraphicsContext::ESolidPen);
        gc.SetPenSize(TSize(borderWidth, borderWidth));
        gc.DrawRect(CoeControl().Rect());
    }
}

// In eSWT all border should have the same width/height.
EXPORT_C TInt ASwtControlBase::GetBorderWidth() const
{
    if (HasBorderStyle())
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

// Window coords
EXPORT_C TRect ASwtControlBase::ClientRect() const
{
    return BorderInnerRect();
}

TBool ASwtControlBase::HasBorderStyle() const
{
    TBool res = (iStyle & KSwtStyleBorder);
    const MSwtShell* shell = ShellInterface();
    if (shell)
    {
        // TaskTip shells have the border.
        res = shell->IsTaskTip() || (res && !(iStyle & KSwtStyleNoTrim) && iParent);
    }
    return res;
}

TSize ASwtControlBase::BorderSizeDelta() const
{
    return TSize(GetBorderWidth()*2, GetBorderWidth()*2) ;
}

// Window coords
EXPORT_C TRect ASwtControlBase::BorderInnerRect() const
{
    TRect borderInnerRect = CoeControl().Rect();

    if (borderInnerRect.Height() != 0 && borderInnerRect.Width() != 0)
    {
        TInt w(GetBorderWidth());
        borderInnerRect.Shrink(w, w);
    }

    return borderInnerRect;
}

EXPORT_C TRect ASwtControlBase::BorderOuterRect(const TRect& aRect) const
{
    TRect borderOuterRect(aRect);
    borderOuterRect.Grow(GetBorderWidth(), GetBorderWidth());

    return borderOuterRect;
}

TKeyResponse ASwtControlBase::HandleDiagonalKeysL(const TKeyEvent& aKeyEvent, TEventCode aType,
        TBool aTraversalDoIt, const TUint key1, const TStdScanCode scanCode1,
        const TUint key2, const TStdScanCode scanCode2)
{
    TKeyEvent keyTemp;
    // send first event
    keyTemp.iRepeats = 0;
    keyTemp.iScanCode = scanCode1;
    keyTemp.iModifiers = 32768;
    keyTemp.iCode = 0;
    HandleKeyL(keyTemp, EEventKeyDown, aTraversalDoIt);     //DOWN
    keyTemp = aKeyEvent;
    keyTemp.iCode = key1;
    keyTemp.iScanCode = scanCode1;
    TKeyResponse firstResponse = HandleKeyL(keyTemp, aType, aTraversalDoIt);     // KEYCODE
    keyTemp.iRepeats = 0;
    keyTemp.iScanCode = scanCode1;
    keyTemp.iModifiers = 32768;
    keyTemp.iCode = 0;
    HandleKeyL(keyTemp, EEventKeyUp, aTraversalDoIt);      // UP

    // send second event
    keyTemp.iRepeats = 0;
    keyTemp.iScanCode = scanCode2;
    keyTemp.iModifiers = 32768;
    keyTemp.iCode = 0;
    HandleKeyL(keyTemp, EEventKeyDown, aTraversalDoIt);     // DOWN
    keyTemp = aKeyEvent;
    keyTemp.iCode = key2;
    keyTemp.iScanCode = scanCode2;
    TKeyResponse secondResponse = HandleKeyL(keyTemp, aType, aTraversalDoIt);     // KEYCODE
    keyTemp.iRepeats = 0;
    keyTemp.iScanCode = scanCode2;
    keyTemp.iModifiers = 32768;
    keyTemp.iCode = 0;
    HandleKeyL(keyTemp, EEventKeyUp, aTraversalDoIt);       // UP

    TKeyResponse response = EKeyWasNotConsumed;
    if (EKeyWasConsumed == firstResponse && EKeyWasConsumed == secondResponse)
    {
        response = EKeyWasConsumed;
    }

    return response;
}

void ASwtControlBase::DrawComponentControls(const CCoeControl& aControl,
        const TRect& aRect, CWindowGc& aGc, TBool aCanDrawOutsideRect)
{
    const TInt count = aControl.CountComponentControls();
    for (TInt i=0; i<count; ++i)
    {
        CCoeControl& compCtrl = *aControl.ComponentControl(i);
        if (compCtrl.IsVisible())
        {
            if (compCtrl.OwnsWindow())
            {
            }
            else
            {
                TRect drawRect(compCtrl.Rect());
                drawRect.Intersection(aRect);
                if (!drawRect.IsEmpty())
                {
                    aGc.Reset();
                    aGc.SetClippingRect(drawRect);
                    compCtrl.DrawBackground(drawRect);
                    compCtrl.DrawForeground(drawRect);
                }

                if (aCanDrawOutsideRect)
                {
                    DrawComponentControls(compCtrl, aRect, aGc, aCanDrawOutsideRect);
                }
                else if (!drawRect.IsEmpty())
                {
                    DrawComponentControls(compCtrl, drawRect, aGc, aCanDrawOutsideRect);
                }
            }
        }
    }
}

TBool ASwtControlBase::RectContainsRect(const TRect& aContainer, const TRect& aContainee)
{
    return (aContainer.iTl.iX <= aContainee.iTl.iX
            && aContainer.iTl.iY <= aContainee.iTl.iY
            && aContainer.iBr.iX >= aContainee.iBr.iX
            && aContainer.iBr.iY >= aContainee.iBr.iY);
}

void ASwtControlBase::FlushJavaBuffer(MSwtGc* aGc, TInt* aIntParams, TInt aIntCount, HBufC* aStrParams, RWindow* aWindow, const TRect& aDrawRect) const
{
    iDisplay.JavaBufferDrawer().Draw(aGc, aIntParams, aIntCount, aStrParams, aWindow, aDrawRect);
}

EXPORT_C void ASwtControlBase::PostMouseEventL(const TPointerEvent& aPointerEvent)
{
    TPoint eventPosition(aPointerEvent.iPosition);

    // Is is essential that the coordinates posted to the queue are in screen
    // coordinates to ensure the case where late mouse events are handled
    // after the control has moved away from the current position.
    TPoint pos(WindowToScreen(eventPosition));

    // Compute the state mask
    TInt stateMask = UiUtils().GetPointerEventStateMask(aPointerEvent.iModifiers);

    // Handle double click (must be issued between Down and Up)
    if (aPointerEvent.iModifiers & EModifierDoubleClick)
        iDisplay.PostMouseEventL(iPeer, ESwtEventMouseDoubleClick, 0, pos, stateMask);

    // Compute the event type and button number
    TSwtEventType type;
    TInt          button = 0;
    switch (aPointerEvent.iType)
    {
    case TPointerEvent::EButton1Down:
        type   = ESwtEventMouseDown;
        button = KSwtMouseButton1;
        break;
    case TPointerEvent::EButton1Up:
        type   = ESwtEventMouseUp;
        button = KSwtMouseButton1;
        break;
    case TPointerEvent::EButton2Down:
        type   = ESwtEventMouseDown;
        button = KSwtMouseButton2;
        break;
    case TPointerEvent::EButton2Up:
        type   = ESwtEventMouseUp;
        button = KSwtMouseButton2;
        break;
    case TPointerEvent::EButton3Down:
        type   = ESwtEventMouseDown;
        button = KSwtMouseButton3;
        break;
    case TPointerEvent::EButton3Up:
        type   = ESwtEventMouseUp;
        button = KSwtMouseButton3;
        break;
    case TPointerEvent::EDrag:
    case TPointerEvent::EMove:
        type = ESwtEventMouseMove;
        break;
    default:
        return;
    }

    iDisplay.PostMouseEventL(iPeer, type, button, pos, stateMask);
}

EXPORT_C void ASwtControlBase::EnableFocusHighlight(TBool /*aEnable*/)
{
    // Method is used only on 9.2 for list controls (Lists, ListView,
    // ListBox and Table)
}

TPoint ASwtControlBase::ComputeLocationToSet(const TPoint& aLocation)
{
    ASSERT(!IsShell());
    return aLocation + iParent->Scrollable()->Control()->ClientRect().iTl; //lint !e613
}

EXPORT_C MSwtShell& ASwtControlBase::GetShell() const
{
    if (!iShell)
    {
        MSwtShell* selfAsShell = const_cast<MSwtShell*>(ShellInterface());
        if (selfAsShell)
            iShell = selfAsShell;
        else
            iShell = &iParent->Control()->GetShell();
    }
    ASSERT(iShell);
    return *iShell;
}

void ASwtControlBase::Invalidate(const TRect& aRect)
{
    if (!aRect.IsEmpty() && CoeControl().IsVisible() && !(iCtrlFlags & MSwtControl::EFlagDoNotDraw))
        ForceInvalidate(aRect);
}

void ASwtControlBase::ForceInvalidate(const TRect& aRect)
{
    if (aRect.IsEmpty())
    {
        return;
    }

    MSwtShell& shell = GetShell();
    MSwtControl* urgentPaintControl = shell.UrgentPaintControl();
    if (urgentPaintControl)
    {
        // Redraw requests outside urgently painted controls are ignored.
        if (IsDescentOf(*urgentPaintControl))
        {
            urgentPaintControl->PaintUrgently(aRect);
        }
    }
    else
    {
        if (shell.AsyncPainting())
        {
            TRect dirtyRect(aRect);
            MSwtControl* controlShell = shell.Control();

            // Convert to Screen Coordinate
            dirtyRect.Move(controlShell->CoeControl().PositionRelativeToScreen());

            TBool mergeable = !(iStyle & KSwtStyleNoMergePaints);
            TRAP_IGNORE(iDisplay.PostPaintEventL(JavaPeer(), controlShell->JavaPeer(), dirtyRect, mergeable));
        }
        else
        {
            static_cast<RWindow*>(shell.Control()->CoeControl().DrawableWindow())->Invalidate(aRect);
        }
    }
}

EXPORT_C void ASwtControlBase::DoPaint(const TRect& aRect) const
{
    ASSERT(!IsShell());
    const CCoeControl& ctrl = CoeControl();
    ctrl.DrawBackground(aRect);
    ctrl.DrawForeground(aRect);
}

EXPORT_C void ASwtControlBase::SetColorL(TLogicalColor aLogicalColor, const MSwtColor* aColor)
{
    CCoeControl& coeCtrl = CoeControl();
    TRgb color((aColor!=NULL) ? aColor->RgbValue() : iDisplay.CoeEnv()->Color(aLogicalColor));
    coeCtrl.OverrideColorL(aLogicalColor, color);
}

EXPORT_C CSwtUiUtils& ASwtControlBase::UiUtils() const
{
    return static_cast<CSwtUiUtils&>(iDisplay.UiUtils());
}

EXPORT_C void ASwtControlBase::DoDelete()
{
    delete this;
}

EXPORT_C TRect ASwtControlBase::VisibleRect(TBool aVisibleBounds) const
{
    // WINDOW COORDINATES!
    if (!CoeControl().IsVisible())
        return TRect(); // This is (0,0,0,0)

    TRect rect((aVisibleBounds)? CoeControl().Rect() : ClientRect());

    if (!IsShell())
    {
        rect = ClipToVisibleRect(rect);
    }

    return rect;
}

EXPORT_C TBool ASwtControlBase::HasHighlight(TBool aIncludingParents /*= ETrue*/) const
{
    TBool res = iHighlightEnabled;
    if (!res && aIncludingParents)
    {
        res = res || (iParent && iParent->Control()->HasHighlight(ETrue));
    }
    return res;
}

EXPORT_C void ASwtControlBase::SetHighlight(TBool aEnabled)
{
    iHighlightEnabled = aEnabled;

    // Prepare the frame
    if (aEnabled && !iFocusFrame)
    {
        TRAP_IGNORE(const_cast<ASwtControlBase*>(this)->CreateFocusBackgroundL());
    }

    HandleHighlightChange();
}

EXPORT_C void ASwtControlBase::HandleHighlightChange()
{
    // Do nothing here. Inherit where needed.
}

TRect ASwtControlBase::ClipToVisibleRect(const TRect& aRect) const
{
    // WINDOW COORDINATES!
    TRect rect = aRect;
    MSwtComposite* composite = iParent;
    while (composite != NULL)
    {
        MSwtControl* ctrl = composite->Control();
        rect.Intersection(ctrl->ClientRect());
        composite = (!ctrl->IsShell()) ? ctrl->GetParent() : NULL;
    }
    return rect;
}

// Hurts the performance of non overlapping drawing when there are a lot
// of control sibblings and does not really work for overlapping drawing
#if 0
void ASwtControlBase::VisibleRegion(RRegion& aRegion, TBool aVisibleBounds) const
{
    // SCREEN COORDINATES!
    aRegion.AddRect(TRect(CoeControl().PositionRelativeToScreen(),
                          aVisibleBounds ? CoeControl().Size() : ClientRect().Size()));
    MSwtComposite* parent = iParent;
    const MSwtControl*  children = this;

    while (parent && !children->IsShell())
    {
        const RSwtControlArray* siblings = parent->Children();

        for (TInt i = siblings->Find(children)-1; i >= 0; i--)
        {
            MSwtControl* control = (*siblings)[i];

            if (!control->IsShell() && control->CoeControl().IsVisible())
            {
                aRegion.SubRect(TRect(control->CoeControl().PositionRelativeToScreen(), control->CoeControl().Size()));
            }
        }

        children = parent->Control();
        parent = parent->Control()->GetParent();
    }
}
#endif

TPoint ASwtControlBase::WindowToScreen(const TPoint& aPoint) const
{
    const CCoeControl& coeControl = CoeControl();
    const TPoint posInScreen(coeControl.PositionRelativeToScreen());
    const TPoint posInWindow((coeControl.OwnsWindow()) ? TPoint(0,0) : coeControl.Position());

    TInt x = (aPoint.iX - posInWindow.iX) + posInScreen.iX;
    TInt y = (aPoint.iY - posInWindow.iY) + posInScreen.iY;
    return TPoint(x,y);
}

void ASwtControlBase::FocusabilityChanged()
{
    CCoeControl& coeCtrl = CoeControl();
    MSwtShell& shell = GetShell();

    if (!IsFocusable(EFalse))
    {
        if (coeCtrl.IsFocused())
        {
            // Composite losing focusability can mean that it has received a new child.
            // Otherwise it means that the Composite itself has been disabled or hidden.
            // If a Control loses focusability, let the parent find a new focus target.
            // If a Composite loses focusability, find new target first in children then ancestors.
            MSwtControl* newFocus = NULL;
            MSwtComposite* comp = CompositeInterface();
            if (comp)
            {
                TRAP_IGNORE((newFocus = shell.FindTraversalTargetL(ESwtTraverseArrowNext, *this)));
            }
            if (!newFocus)
            {
                TRAP_IGNORE((newFocus = shell.FindTraversalTargetL(ESwtTraverseParent, *this)));
            }
            if (newFocus)
            {
                newFocus->CoeControl().SetFocus(ETrue);
            }
            else
            {
                // This control was focused but now there's nothing focusable anymore
                coeCtrl.SetFocus(EFalse);
                shell.SetControlGainingFocus(NULL);
                shell.SetControlGoingToStack(NULL);
                if (UiUtils().NextFocusedControl() == this)
                {
                    UiUtils().SetNextFocusedControl(NULL);
                }
            }
        }
        ASSERT(!coeCtrl.IsFocused());
    }
    else
    {
        if (UiUtils().GetActiveShell() == &shell && shell.FocusControl() == NULL)
            coeCtrl.SetFocus(ETrue);
    }
}

EXPORT_C void ASwtControlBase::HandleFocusChanged(TDrawNow /*aDrawNow*/)
{
    CCoeControl&  coeCtrl     = CoeControl();
    TBool         focused     = coeCtrl.IsFocused();
    CSwtUiUtils&  uiUtils     = UiUtils();
    MSwtShell*    activeShell = uiUtils.GetActiveShell();
    MSwtControl*  oldFocus    = (activeShell!=NULL) ? activeShell->FocusControl() : NULL;
    TBool         appFocus    = uiUtils.IsAppFocused();

    // Detect when SetFocus() has been called twice with the same parameter
    if (oldFocus && ((focused && oldFocus == this)
                     || (!focused && oldFocus != this)))
    {
        return;
    }

    MSwtShell& shell = GetShell();

    // Make sure that UiUtils' information of the control that most
    // recently had focus is up-to-date. This way the focus will be
    // returned to the correct control once we regain application
    // focus after losing it.
    if (oldFocus == this)
    {
        uiUtils.SetNextFocusedControl(oldFocus);
    }

    // if app fails on next line check this issue:
    // caller should call MSwtControl::SetFocus() or MSwtControl::ForceFocus()
    // or Overridden function if posssible,
    // instead of CCoeControl::SetFoucus directly
    ASSERT(!(focused && !appFocus));

    if (!focused)
    {
        // Remove current control from ControlStack since the control becomes unfocused
        RemoveFromControlStack();
    }

    // Update the focus control
    if (focused)
    {
        // Clear the urgent paint control if focus goes outside it.
        // There cannot be an urgently painted control that is not
        // focused or does not have a focused child.
        MSwtControl* urgentPaintControl = shell.UrgentPaintControl();
        if (urgentPaintControl && urgentPaintControl != this
                && !IsDescentOf(*urgentPaintControl))
        {
            shell.SetUrgentPaintControl(NULL);
        }

        // Activate our shell and remove focus from current owner
        if (activeShell != &shell)
        {
            // This removes focus from oldFocus
            uiUtils.SetActiveShell(shell, EFalse);
        }
        else
        {
            if (oldFocus)
            {
                // first add control before removing the control from controlstack
                // so that it stop calling focusChanged of shell.
                TRAP_IGNORE(AddToControlStackL(ECoeStackPriorityDefault));
                oldFocus->CoeControl().SetFocus(EFalse);
            }
        }

        ASSERT(!oldFocus || !oldFocus->CoeControl().IsFocused());

        // Set ourselves as the new focus control
        // Can't register a Shell with itself
        if (shell.Control() != this)
        {
            shell.SetFocusControl(this);
        }
    }
    else
    {
        shell.SetFocusControl(NULL);
    }

    // Notify parent of our new focus
    MSwtComposite* parent = GetParent();
    if (parent)
    {
        parent->ChildFocusChanged(*this);
    }


    // Notify Menu arranger
    if (focused)
    {
        iDisplay.MenuArranger().ControlFocusGained(*this);
    }
    else
    {
        iDisplay.MenuArranger().ControlFocusLost();
    }

    // Notify Command arranger
    MSwtCommandArranger* commandArranger = iDisplay.CommandArranger();
    if (commandArranger)   // commandArranger may be null as Mobile Extensions is optional
    {
        if (focused)
        {
            commandArranger->ControlFocusGained(*this);
        }
        else
        {
            commandArranger->ControlFocusLost();
        }
    }

    // Post the focus event
    TSwtEventType type((focused) ? ESwtEventFocusIn : ESwtEventFocusOut);
    TRAP_IGNORE(iDisplay.PostFocusEventL(JavaPeer(), type));

    if (focused)
    {
        // Add to ControlStack since the control becomes focused
        TRAP_IGNORE(AddToControlStackL(ECoeStackPriorityDefault));
    }

    shell.UpdateHighlight();
}

TKeyResponse ASwtControlBase::OfferKeyEventToCommandAndMenuArrangersL(
    const TKeyEvent& aKeyEvent,
    TEventCode aType)
{
    if ((aType == EEventKeyDown) || (aType==EEventKeyUp))
    {
        return EKeyWasNotConsumed;
    }

    MSwtShell* activeTopShell = iDisplay.UiUtils().GetParentTopShellOfActiveShell();
    MSwtMenuArranger& menuArranger = iDisplay.MenuArranger();
    if (activeTopShell
            && activeTopShell->FullScreenMode()
            && menuArranger.IsOptionsCommandAdded())
    {
        if (aKeyEvent.iCode == EKeyCBA1 || aKeyEvent.iCode == EKeyCBA2)
        {
            menuArranger.TryDisplayMenuBarL(EFalse);
            return EKeyWasConsumed;
        }
    }

    // If the OK and backspace keys are not used by the control, HandleKeyL() returns EKeyWasNotConsumed.
    // Thus, this allows the command arranger calling the operations associated to these keys
    MSwtCommandArranger* commandArranger = iDisplay.CommandArranger();
    if (commandArranger != NULL)
    {
        // Clear command is called when backspace key is pressed
        if (aKeyEvent.iCode == EKeyBackspace &&
                !IsKeyUsed(EKeyBackspace) &&
                commandArranger->IsClearOperationSet())
        {
            if (commandArranger->DoClearOperationL())
            {
                return EKeyWasConsumed;
            }
        }
        else if (!AknLayoutUtils::MSKEnabled() ||
                 (activeTopShell && activeTopShell->FullScreenMode()))
        {
            // When the selection key is pressed, the default command is called otherwise
            // a menu with the OK and SELECT commands is displayed
            if (aKeyEvent.iCode == EKeyOK
                    && !IsKeyUsed(EKeyOK)
                    && commandArranger->IsContextSensitiveOperationSet())
            {
                if (commandArranger->DoContextSensitiveOperationL())
                {
                    return EKeyWasConsumed;
                }
            }
        }
        else if (aKeyEvent.iCode == EKeyEnter && !IsKeyUsed(EKeyEnter))
        {
            if (commandArranger->HandleEnterKeyL())
            {
                return EKeyWasConsumed;
            }
        }
    }

    return EKeyWasNotConsumed;
}

TKeyResponse ASwtControlBase::HandleKeyL(const TKeyEvent& aKeyEvent,
        TEventCode aType, TBool aTraversalDoIt)
{
    // Follows implementation of diagonal Keys. Native diagonal keys are in eSWT
    // replaced by two corresponding key events check if key is diagonal, if yes,
    // change the traversalDoIt state
    if (aKeyEvent.iCode == EKeyLeftUpArrow
            || aKeyEvent.iCode == EKeyRightUpArrow
            || aKeyEvent.iCode == EKeyLeftDownArrow
            || aKeyEvent.iCode == EKeyRightDownArrow)
    {
        aTraversalDoIt = EFalse;
    }

    switch (aKeyEvent.iCode)
    {
    case EKeyLeftUpArrow:
        return HandleDiagonalKeysL(aKeyEvent, aType, aTraversalDoIt, EKeyLeftArrow,
                                   EStdKeyLeftArrow, EKeyUpArrow, EStdKeyUpArrow);
    case EKeyLeftDownArrow:
        return HandleDiagonalKeysL(aKeyEvent, aType, aTraversalDoIt, EKeyLeftArrow,
                                   EStdKeyLeftArrow, EKeyDownArrow, EStdKeyDownArrow);
    case EKeyRightUpArrow:
        return HandleDiagonalKeysL(aKeyEvent, aType, aTraversalDoIt, EKeyRightArrow,
                                   EStdKeyRightArrow, EKeyUpArrow, EStdKeyUpArrow);
    case EKeyRightDownArrow:
        return HandleDiagonalKeysL(aKeyEvent, aType, aTraversalDoIt, EKeyRightArrow,
                                   EStdKeyRightArrow, EKeyDownArrow, EStdKeyDownArrow);
    }

    // Offer key event to command arranger first
    TKeyResponse keyResponse = OfferKeyEventToCommandAndMenuArrangersL(aKeyEvent, aType);
    if (keyResponse == EKeyWasConsumed)
    {
        iTraverse = EFalse;
        return EKeyWasConsumed;
    }

    // Traversal only on key event, not key down nor key up
    if (aType != EEventKey)
    {
        if (!iTraverse

#ifndef RD_JAVA_S60_RELEASE_9_2
                && !(AknLayoutUtils::MSKEnabled()
                     && aKeyEvent.iScanCode == EStdKeyDevice3
                     && iDisplay.CommandArranger()->IsDefaultCommandSet())
#endif
           )
        {
            iDisplay.PostKeyEventL(*this, aKeyEvent, aType);
        }
        iTraverse = EFalse;
        return EKeyWasConsumed;
    }

    // In any case cancel the traverse state
    iTraverse = EFalse;

    TSwtTraversal detail(ESwtTraverseNone);

    const TInt modifiers = aKeyEvent.iModifiers & ECtrlFuncShiftMask;

    // If we press left or right arrow key and if there is a TabGroup displayed,
    // we let the TabGroup manage the keys.
    if (aTraversalDoIt && modifiers == 0
            && (aKeyEvent.iCode == EKeyRightArrow || aKeyEvent.iCode == EKeyLeftArrow))
    {
        keyResponse = OfferKeyEventToTabGroupL(aKeyEvent, aType);
        if (keyResponse == EKeyWasConsumed)
        {
            return EKeyWasConsumed;
        }
    }

    // Tab
    if (aKeyEvent.iCode == EKeyTab)
    {
        switch (modifiers)
        {
        case 0:                                // Tab
        case EModifierCtrl:                    // Ctrl+Tab
            detail = ESwtTraverseTabNext;
            break;
        case EModifierShift:                   // Shift+Tab
        case EModifierCtrl|EModifierShift:     // Ctrl+Shift+Tab
            detail = ESwtTraverseTabPrevious;
            break;
        default:
            break;
        }
    }
    else if (aKeyEvent.iCode == EKeyRightArrow ||
             aKeyEvent.iCode == EKeyDownArrow)
    {
        detail = ESwtTraverseArrowNext;
    }
    else if (aKeyEvent.iCode == EKeyLeftArrow ||
             aKeyEvent.iCode == EKeyUpArrow)
    {
        detail = ESwtTraverseArrowPrevious;
    }

    /*
     * These two conditions are because workaround in Text. We simulate
     * EEventKey from EEventKeyDown, so in this moment we haven't
     * aKeyEvent.iCode value, only iScanCode.
     */
    if (aType == EEventKey && aKeyEvent.iCode == 0)
    {
        if (aKeyEvent.iScanCode == EStdKeyLeftArrow)
        {
            detail = ESwtTraverseArrowPrevious;
        }
        if (aKeyEvent.iScanCode == EStdKeyRightArrow)
        {
            detail = ESwtTraverseArrowNext;
        }
    }

    // Return (only if there is a default button or a default command)
    if ((aKeyEvent.iCode==EKeyEnter || aKeyEvent.iCode==EKeyOK) && modifiers==0)
    {
        const MSwtShell& shell = GetShell();
        if ((!ButtonInterface() || ((Style() & KSwtStylePush) == 0))
                && const_cast<MSwtShell&>(shell).Decorations()->DefaultButton())
        {
            detail = ESwtTraverseReturn;
        }

        if (shell.DefaultCommand())
        {
            detail = ESwtTraverseReturn;
        }
    }

    // Escape (only for non top-level Shells)
    if (aKeyEvent.iCode==EKeyEscape && modifiers==0)
    {
        if (GetShell().GetParentShell() != NULL)
            detail = ESwtTraverseEscape;
    }

    // Send event
    if (detail != ESwtTraverseNone)
    {
        iTraverse = aTraversalDoIt;
        MSwtComposite* parent = this->GetParent();
        if (parent)
        {
            // if the parent does not have a tablist.
            // it means the parent should not be used as a composite.
            // So don't post traverse event
            CSwtPeerArray* tabList = parent->GetTabListL();
            if (tabList)
            {
                delete tabList;
                tabList = NULL;
                iDisplay.PostTraverseEventL(*this, detail, aKeyEvent, aType, aTraversalDoIt);
            }
        }
        else
        {
            iDisplay.PostTraverseEventL(*this, detail, aKeyEvent, aType, aTraversalDoIt);
        }
    }
    else
    {
        iDisplay.PostKeyEventL(*this, aKeyEvent, aType);
    }

    return EKeyWasConsumed;
}

TKeyResponse ASwtControlBase::OfferKeyEventToTabGroupL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
    CEikStatusPane *sp = ((CAknAppUi*)iDisplay.CoeEnv()->EikAppUi())->StatusPane();
    ASSERT(sp != NULL);
    CAknNavigationControlContainer* naviCtrlCtnr = static_cast<CAknNavigationControlContainer*>
            (sp->ControlL(TUid::Uid(EEikStatusPaneUidNavi)));
    ASSERT(naviCtrlCtnr != NULL);
    CAknNavigationDecorator* navi = naviCtrlCtnr->Top();
    if (navi != NULL && navi->ControlType() == CAknNavigationDecorator::ETabGroup) // if there is a tab group
    {
        CAknTabGroup* tabGroup = static_cast<CAknTabGroup*>(navi->DecoratedControl());
        if (tabGroup != NULL && tabGroup->OfferKeyEventL(aKeyEvent, aType) == EKeyWasConsumed)
        {
            TSwtTraversal detail(ESwtTraverseNone);
            if (AknLayoutUtils::LayoutMirrored())
            {
                detail = (aKeyEvent.iCode == EKeyRightArrow ?
                          ESwtTraversePagePrevious : ESwtTraversePageNext);
            }
            else
            {
                detail = (aKeyEvent.iCode == EKeyRightArrow ?
                          ESwtTraversePageNext : ESwtTraversePagePrevious);
            }
            iDisplay.PostTraverseEventL(*this, detail, aKeyEvent, aType, ETrue);
            // The tab has consumed the key event.
            return EKeyWasConsumed;
        }
    }
    return EKeyWasNotConsumed;
}

EXPORT_C void ASwtControlBase::RegisterWithParentL()
{
    if (iParent != NULL)
    {
        // eSWT hierarchy controls.
        iParent->RegisterChildL(*this);
    }

    // Set our DoNotDraw flag according to our parent flag
    if (iParent != NULL)
    {
        UpdateDoNotDrawFlag();
    }
}

EXPORT_C TTypeUid::Ptr ASwtControlBase::SwtMopSupplyObject(TTypeUid aId)
{
    // MAknsControlContext is ask.
    if (aId.iUid == MAknsControlContext::ETypeId)
    {
        MAknsControlContext* bckgd = SwtMopSupplyCtrlContext();

        // If a parent have is own background context and the color background was not set on it.
        // Return the Control Context of his background.
        if (bckgd != NULL)
        {
            return MAknsControlContext::SupplyMopObject(aId, bckgd);
        }
    }

    // Else return Null
    return TTypeUid::Null();
}

MAknsControlContext* ASwtControlBase::SwtMopSupplyCtrlContext(TBool aBeginSearchToThis) const
{
    MAknsControlContext* background = NULL;
    if (aBeginSearchToThis)
    {
        background = FocusBackgroundNow();
        if (background)
        {
            return background;
        }
    }

    MSwtComposite* parent = GetParent();
    TInt policy = FocusBackgroundPolicy();
    if (IsDefaultBackgroundUse())
    {
        background = aBeginSearchToThis ? GetControlContext() : NULL;
        while (!background && parent)
        {
            // If policy is ENoFocusBackgroundInCaptionedControl, bypass the caption highlight.
            if (policy == ENoFocusBackgroundInCaptionedControl
                    && parent->Control()->CaptionedControlInterface())
            {
                parent = parent->Control()->GetParent();
                ASSERT(parent);
            }

            background = parent->Control()->GetControlContext();

            // If the parent is a Shell we stop on it.
            if (parent->Control()->IsShell())
            {
                parent = NULL;
            }
            else
            {
                parent = parent->Control()->GetParent();
            }
        }
    }

    return background;
}

RRegion* ASwtControlBase::SetupChildClippingRegion(const MSwtComposite* aComposite,
        CWindowGc& aGc,
        const TRect& aDrawRect,
        const TPoint& aOffset /*= TPoint( 0, 0 )*/) const
{
    ASSERT(aComposite);

    TBool clippingRegionSet(EFalse);
    RRegion* clippingRegion = NULL;
    if (aComposite)
    {
        TInt childCount(0);
        const RSwtControlArray* children = aComposite->Children();
        if (children)
        {
            childCount = children->Count();
        }
        // If this control has children then proceed with setting
        // a clipping region to exclude them.
        if (childCount > 0)
        {
            clippingRegion = new RRegion(aDrawRect, childCount + 1);
            if (clippingRegion)
            {
                for (TInt i = 0; i < childCount; ++i)
                {
                    MSwtControl* child = (*children)[ i ];
                    // Shells are window owning so they will get clipped anyway.
                    // No point in adding overhead by handling them manually here.
                    // Also controls that are not visible should not be clipped.
                    if (child && !child->IsShell() && child->CoeControl().IsVisible()
                            && !child->HasDoNotDrawFlag())
                    {
                        clippingRegion->SubRect(child->CoeControl().Rect());
                    }
                }
                if (!clippingRegion->CheckError())
                {
                    if (aOffset != TPoint(0, 0))
                    {
                        clippingRegion->Offset(aOffset);
                    }
                    if (aGc.SetClippingRegion(*clippingRegion) == KErrNone)
                    {
                        clippingRegionSet = ETrue;
                    }
                }
                if (!clippingRegionSet)
                {
                    if (clippingRegion)
                    {
                        clippingRegion->Destroy();
                    }
                    clippingRegion = NULL;
                }
            }
        }
    }
    return clippingRegion;
}

void ASwtControlBase::CancelChildClippingRegion(RRegion* aClippingRegion,
        CWindowGc& aGc) const
{
    // Cancel & destroy the clipping region
    if (aClippingRegion)
    {
        aGc.CancelClippingRegion();
        aClippingRegion->Destroy();
    }
}

TPoint ASwtControlBase::ClientToWindow(const TPoint& aPoint) const
{
    return aPoint + ClientRect().iTl;
}

TRect ASwtControlBase::ClientToWindow(const TRect& aRect)  const
{
    const TRect clientRect(ClientRect());
    return TRect(aRect.iTl+clientRect.iTl, aRect.iBr+clientRect.iTl);
}

TPoint ASwtControlBase::WindowToClient(const TPoint& aPoint) const
{
    return aPoint - ClientRect().iTl;
}

EXPORT_C const MSwtFont& ASwtControlBase::DefaultFont() const
{
    return *(iDisplay.Device().GetSystemFont());
}

void ASwtControlBase::HandleRectChanged()
{
    // Rebound the focus highlight
    if (iFocusFrame)
    {
        TRect rect(CoeControl().Rect());
        TRect innerRect;
        innerRect.iTl = CSwtLafFacade::GetLayoutRect(
                            CSwtLafFacade::EInputFieldSkinPlacingGeneralLine2, rect, 0).Rect().iBr;
        innerRect.iBr = CSwtLafFacade::GetLayoutRect(
                            CSwtLafFacade::EInputFieldSkinPlacingGeneralLine5, rect, 0).Rect().iTl;
        iFocusFrame->SetFrameRects(rect, innerRect);
    }
}

EXPORT_C void ASwtControlBase::HandleSizeChanged()
{
    if (iPrevCoeSize == CoeControl().Size())
    {
        return;
    }

    if (iPrevCoeSize != CoeControl().Size())
    {
        iPrevCoeSize = CoeControl().Size();
        TRAP_IGNORE(iDisplay.PostResizeEventL(iPeer));
        HandleRectChanged();
    }
}

EXPORT_C void ASwtControlBase::HandlePositionChanged()
{
    if (iPrevSwtPos == GetLocation() && iPrevCoePos == CoeControl().Position())
    {
        return;
    }

    if (iPrevSwtPos != GetLocation())
    {
        iPrevSwtPos = GetLocation();
        TRAP_IGNORE(iDisplay.PostMoveEventL(iPeer));
    }

    if (iPrevCoePos != CoeControl().Position())
    {
        iPrevCoePos = CoeControl().Position();
        HandleRectChanged();
    }
}

//
// Virtual methods from MSwtDrawable
//
EXPORT_C MSwtGc* ASwtControlBase::NewGcL()
{
    CCoeControl& coeCtrl = CoeControl();

    // Create the native GC
    CWsScreenDevice& device = static_cast<CWsScreenDevice&>(GraphicsDevice());
    CWindowGc* nativeGc = new(ELeave) CWindowGc(&device);
    TInt error = nativeGc->Construct();
    if (error)
    {
        delete nativeGc;
        User::Leave(error);
    }
    nativeGc->Activate(*coeCtrl.DrawableWindow());

    // Set the GC's origin to the top-left of the client area
    const TRect clientRect(ClientRect()); // in window coords
    nativeGc->SetOrigin(clientRect.iTl);

    // Compute the boundary rect (in GC coords)
    TRect boundaryRect(clientRect);
    if (!IsShell())
    {
        MSwtComposite* parent = GetParent();
        if (parent != NULL)
            boundaryRect.Intersection(static_cast<ASwtControlBase*>(parent->Control())->VisibleRect());
    }
    boundaryRect.Move(-clientRect.iTl);

    // Compute the GC rect in screen coords
    const TRect gcScreenRect(WindowToScreen(clientRect.iTl), clientRect.Size());

    // Get the colours & the font
    CEikonEnv* eikenv = iDisplay.CoeEnv();
    TRgb penCol(eikenv->ControlColor(EColorControlText,       coeCtrl));
    TRgb brushCol(eikenv->ControlColor(EColorControlBackground, coeCtrl));
    const MSwtFont* font = GetFont();
    ASSERT(font!=NULL);

    return iDisplay.Factory().NewWindowGcL(*this, nativeGc, DestroyNativeGc,
                                           penCol, brushCol, *font, boundaryRect, gcScreenRect);
}

EXPORT_C CBitmapDevice& ASwtControlBase::GraphicsDevice()
{
    return *static_cast<CWsScreenDevice*>(iDisplay.CoeEnv()->SystemGc().Device());
}

EXPORT_C void ASwtControlBase::HandleUpdate()
{
    // Nothing to do for controls
}

void ASwtControlBase::DestroyNativeGc(CBitmapContext* aGc)
{
    static_cast<CWindowGc*>(aGc)->Deactivate();
    delete aGc;
}

//
// Virtual methods from MSwtControl
//
EXPORT_C TSwtPeer ASwtControlBase::Dispose()
{
    // Note that unregistration is done here rather than in the destructor.
    // The reason for it is that an object may go through destruction before
    // being registered.
    if (iParent)   // This may be NULL because of top-level Shells
    {
        iParent->UnregisterChild(*this);
    }
    // If the control has a bad parent, such as combo, table or caption control
    // UnregisterChild does not kill the focus
    if (CoeControl().IsFocused())
    {
        CoeControl().SetFocus(EFalse);
        ASSERT(!CoeControl().IsFocused());
    }

    // RemoveRef here in case iFont would be pointing to an MSwtFont
    // that is disposed in destructor of the object (e.g. iDefaultFont)
    if (iFont)
    {
        iFont->RemoveRef();
        iFont = NULL;
    }

    Invalidate(CoeControl().Rect());

    if (UiUtils().PointerCaptureControl() == this)
    {
        UiUtils().SetPointerCaptureControl(NULL);
    }
    if (UiUtils().NextFocusedControl() == this)
    {
        UiUtils().SetNextFocusedControl(NULL);
    }
    if (iDisplay.LongTapAnimationControl() == this)
    {
        iDisplay.CancelLongTapAnimation();
    }

    RemoveFromControlStack();

    GetShell().ControlDisposing(*this);

    TSwtPeer peer(iPeer);
    DoDelete();
    return peer;
}

EXPORT_C TSwtPeer ASwtControlBase::JavaPeer() const
{
    return iPeer;
}

EXPORT_C TUint ASwtControlBase::Flags() const
{
    return iCtrlFlags;
}

EXPORT_C void ASwtControlBase::Paint(const TRect& aRect,
                                     TBool aPaintNatively /*= ETrue*/,
                                     MSwtGc* aGc /*= NULL*/,
                                     TInt* aIntParams /*= NULL*/,
                                     TInt aIntCount /*= 0*/,
                                     HBufC* aStrParams /*= NULL*/) const
{
    // While emergency paints are required, painting is done by PaintUrgently
    // It is essential that paint events coming from Java are not served as
    // they can slow down considerably the kinetic scrolling.
    // The only reason for letting non-urgent paint controls still paint is
    // that there might be late paint event arriving after the urgent paint
    // has started as in the case of focus changes.
    MSwtShell& shell = GetShell();
    if (shell.UrgentPaintControl() == this)
    {
        return;
    }

    if (iCtrlFlags & MSwtControl::EFlagDoNotDraw)
    {
        return;
    }

    // Except Shells, Controls cannot draw over invisible parents.
    if (!GetVisibleRecursively())
    {
        return;
    }

    const CCoeControl& coeCtrl = CoeControl();
    RWindow* window = static_cast<RWindow*>(coeCtrl.DrawableWindow());
    ASSERT(window);

    TRect dirtyRect(aRect);                     // screen coordinates
    dirtyRect.Move(-window->Position());        // window coordinates
    dirtyRect.Intersection(VisibleRect(ETrue));
    if (dirtyRect.IsEmpty())
    {
        return;
    }

    CWindowGc& systemGc = coeCtrl.SystemGc();
    MSwtComposite* comp = CompositeInterface();

    window->Invalidate(dirtyRect);
    window->BeginRedraw(dirtyRect);

    // Native controls draw here
    if (aPaintNatively)
    {
        systemGc.Activate(*window);
        systemGc.Reset();
        systemGc.SetClippingRect(dirtyRect);
        DoPaint(dirtyRect);

        TBool isChildShell(EFalse);
        if (comp)
        {
            // GC intentionally reset only once for both scrollbar back and border.
            systemGc.Reset();
            systemGc.SetClippingRect(dirtyRect);
            comp->DrawScrollBarBackground(dirtyRect);

            // For child Shells, the border is drawn right after the background.
            isChildShell = IsShell() && iParent;
            if (isChildShell)
            {
                if (HasBorderStyle())
                {
                    DrawBorder(dirtyRect);
                }
            }
        }

        // GC is reset inside DrawComponentControls
        DrawComponentControls(coeCtrl, dirtyRect, systemGc, CanDrawOutsideRect());

        if (!isChildShell)
        {
            if (HasBorderStyle())
            {
                systemGc.Reset();
                systemGc.SetClippingRect(dirtyRect);
                DrawBorder(dirtyRect);
            }
        }
    }

    // Java paint listener draws here
    if (aGc)
    {
        // Workaround, corrects the clipping region. Currently without this workaround
        // if we do a BitBlt from the command buffer and the GCs origin has been set to > (0, 0)
        // then clipping region will be wrong. Origin is applied to it twice. Adding some
        // operation here, before the potential BitBlt, will correct the problem. This is
        // a platform issue in 3.2 with pre-activated graphics contexts.
#ifndef RD_SCALABLE_UI_V2
        aGc->BitmapContext().Plot(TPoint(-1,-1));
#endif //RD_SCALABLE_UI_V2

        // Clip Java GC so that it does not need to draw under children of the composite.
        CWindowGc& javaGc= static_cast<CWindowGc&>(aGc->BitmapContext());
        RRegion* javaGcClipRegion = NULL;
        TRect javaGcRect(dirtyRect);             // window coordinates
        javaGcRect.Intersection(ClientRect());   // window coordinates
        if (comp)
        {
            javaGcClipRegion = SetupChildClippingRegion(
                                   comp,
                                   javaGc,
                                   javaGcRect,
                                   -ClientRect().iTl);              // Java GC coordinates (relative to client area)
        }

        // Flush Java GC
        FlushJavaBuffer(aGc, aIntParams, aIntCount, aStrParams, window, javaGcRect);
        CancelChildClippingRegion(javaGcClipRegion, javaGc);
    }

    window->EndRedraw();

    if (aPaintNatively)
    {
        systemGc.Deactivate();
    }

#ifdef RD_JAVA_S60_RELEASE_9_2
    iDisplay.CoeEnv()->WsSession().Finish();
#endif
}

EXPORT_C void ASwtControlBase::PaintUrgently(const TRect& aRect, TBool aInitDraw /*= ETrue*/) const
{
    if (iCtrlFlags & MSwtControl::EFlagDoNotDraw)
    {
        return;
    }

    // Except Shells, Controls cannot draw over invisible parents.
    if (!GetVisibleRecursively())
    {
        return;
    }

    TRect dirtyRect(aRect);   // window coordinates
    dirtyRect.Intersection(VisibleRect(ETrue));
    if (dirtyRect.IsEmpty())
    {
        return;
    }

    const CCoeControl& coeCtrl = CoeControl();
    RWindow* window = static_cast<RWindow*>(coeCtrl.DrawableWindow());
    ASSERT(window);
    CWindowGc& systemGc = coeCtrl.SystemGc();

    if (aInitDraw)
    {
        systemGc.Activate(*window);
        window->Invalidate(dirtyRect);
        window->BeginRedraw(dirtyRect);
    }

    systemGc.Reset();
    systemGc.SetClippingRect(dirtyRect);
    DoPaint(dirtyRect);

    TBool isChildShell(EFalse);
    MSwtComposite* comp = CompositeInterface();
    if (comp)
    {
        // GC intentionally reset only once for both scrollbar back and border.
        systemGc.Reset();
        systemGc.SetClippingRect(dirtyRect);
        comp->DrawScrollBarBackground(dirtyRect);

        // For child Shells, the border is drawn right after the background.
        isChildShell = IsShell() && iParent;
        if (isChildShell)
        {
            if (HasBorderStyle())
            {
                DrawBorder(dirtyRect);
            }
        }
    }

    // GC is reset inside DrawComponentControls
    DrawComponentControls(coeCtrl, dirtyRect, systemGc, CanDrawOutsideRect());

    if (!isChildShell)
    {
        if (HasBorderStyle())
        {
            systemGc.Reset();
            systemGc.SetClippingRect(dirtyRect);
            DrawBorder(dirtyRect);
        }
    }

    if (comp)
    {
        const RSwtControlArray* children = comp->Children();
        const TInt count = children->Count();
        for (TInt i = 0; i < count; i++)
        {
            MSwtControl* child = (*children)[i];
            if (!child->IsShell())
                child->PaintUrgently(dirtyRect, EFalse);
        }
    }

    if (aInitDraw)
    {
        window->EndRedraw();
        systemGc.Deactivate();
#ifdef RD_JAVA_S60_RELEASE_9_2
        iDisplay.CoeEnv()->WsSession().Finish();
#endif
    }
}

EXPORT_C TBool ASwtControlBase::IsPaintingUrgently() const
{
    MSwtControl* urgentPaintControl = GetShell().UrgentPaintControl();
    return urgentPaintControl
           && (urgentPaintControl == this || IsDescentOf(*urgentPaintControl));
}

EXPORT_C TBool ASwtControlBase::IsFocusable(TInt aReason /*=KSwtFocusByApi*/) const
{
    const CCoeControl& coeCtrl = CoeControl();

    // Invisible or disabled control can never get the focus (not even forced)
    if (!coeCtrl.IsVisible() || coeCtrl.IsDimmed())
        return EFalse;

    MSwtComposite* parent = GetParent();

    // Go through the whole ancestor chain, if any of the ancestors is
    // disabled or invisible, return EFalse.
    while (parent)
    {
        MSwtControl* parentCtrl = parent->Control();

        if (!parentCtrl->GetEnabled() || !parentCtrl->GetVisible())
        {
            return EFalse;
        }

        if (!parentCtrl->IsShell())
        {
            parent = parentCtrl->GetParent();
        }
        else
        {
            parent = NULL;
        }
    }

    return ((aReason == KSwtFocusByForce) || !coeCtrl.IsNonFocusing());
}

EXPORT_C TBool ASwtControlBase::SetSwtFocus(TInt aReason /*=KSwtFocusByApi*/)
{
    ASSERT(!IsShell());

    CCoeControl& coeCtrl = CoeControl();
    if (coeCtrl.IsFocused())
    {
        return ETrue;
    }

    MSwtShell& shell = GetShell();
    if (!IsFocusable(aReason))
    {
        // remember the control which is not focusible because its parent shell is invisible currently
        // the control can get the focus later whenever the shell becomes visible.

        if (shell.Control()->GetVisible())
        {
            // don't need to remember the control when the control itself is a shell
            // or its parent shell is visible.
            return EFalse;
        }

        const CCoeControl& coeCtrl = CoeControl();
        if ((aReason != KSwtFocusByForce) && coeCtrl.IsNonFocusing())
        {
            // don't remember non-focusing control
            return EFalse;
        }

        // Go through the whole ancestor chain, if any of the ancestors is
        // disabled, don't remember the control.
        TBool rememberIt(ETrue);
        MSwtComposite* parent = GetParent();
        while (parent)
        {
            MSwtControl* parentCtrl = parent->Control();
            if (!parentCtrl->GetEnabled())
            {
                rememberIt = EFalse;
                break;
            }

            if (!parentCtrl->IsShell())
            {
                parent = parentCtrl->GetParent();
            }
            else
            {
                break;
            }
        }

        if (rememberIt)
        {
            shell.SetToBeFocusedControl(this);
        }

        return EFalse;
    }


    CSwtUiUtils& uiUtils = UiUtils();

    if (uiUtils.GetActiveShell()==&shell || uiUtils.CanBeActive(shell))
    {
        if (uiUtils.IsAppFocused())
        {
            // Focus if we can (Shell must be able to be active)
            coeCtrl.SetFocus(ETrue);
        }
        else
        {
            // Set next focused control
            uiUtils.SetNextFocusedControl(this);
        }
    }

    return coeCtrl.IsFocused();
}

EXPORT_C TInt ASwtControlBase::FocusBackgroundPolicy() const
{
    return EDefaultFocusBackground;
};

EXPORT_C TInt ASwtControlBase::PressBackgroundPolicy() const
{
    return ENoPressBackground;
};

EXPORT_C TBool ASwtControlBase::GetEnabled() const
{
    return (CoeControl().IsDimmed()) ? EFalse : ETrue;
}

EXPORT_C TBool ASwtControlBase::GetVisible() const
{
    return !(iCtrlFlags & MSwtControl::EFlagInvisible);
}

EXPORT_C TBool ASwtControlBase::GetVisibleRecursively() const
{
    if (!IsShell() && iParent && !iParent->Control()->GetVisibleRecursively())
    {
        return EFalse;
    }
    return GetVisible();
}

EXPORT_C TBool ASwtControlBase::IsDefaultBackgroundUse() const
{
    return iBackgrdDefaultUsed;
}

EXPORT_C MAknsControlContext* ASwtControlBase::GetControlContext() const
{
    if (CaptionedControlInterface())
    {
        return FocusBackgroundNow();
    }
    else
    {
        return NULL;
    }
}

EXPORT_C TRgb ASwtControlBase::GetBackground() const
{
    return iDisplay.CoeEnv()->ControlColor(EColorControlBackground, CoeControl());
}

EXPORT_C TRgb ASwtControlBase::GetForeground() const
{
    return iDisplay.CoeEnv()->ControlColor(EColorControlText, CoeControl());
}

EXPORT_C void ASwtControlBase::SetBackgroundL(const MSwtColor* aColor)
{
    DoSetBackgroundL(aColor);
    Redraw();
}

void ASwtControlBase::DoSetBackgroundL(const MSwtColor* aColor)
{
    SetColorL(EColorControlBackground, aColor);
    if (aColor)
    {
        iBackgrdDefaultUsed = EFalse;
        // Not using FocusBackgroundNow() intentionally
        if (iFocusFrame)
        {
            iFocusFrame->SetParentContext(NULL);
        }
    }
    else
    {
        iBackgrdDefaultUsed = ETrue;
        // Not using FocusBackgroundNow() intentionally
        if (iFocusFrame)
        {
            iFocusFrame->SetParentContext(SwtMopSupplyCtrlContext(EFalse));
        }
    }
}

EXPORT_C void ASwtControlBase::SetForegroundL(const MSwtColor* aColor)
{
    DoSetForegroundL(aColor);
    Redraw();
}

void ASwtControlBase::DoSetForegroundL(const MSwtColor* aColor)
{
    SetColorL(EColorControlText, aColor);
}

EXPORT_C const MSwtFont* ASwtControlBase::GetFont() const
{
    return (iFont!=NULL) ? iFont : &DefaultFont();
}

EXPORT_C TRect ASwtControlBase::GetBounds() const
{
    return TRect(GetLocation(), CoeControl().Size());
}

EXPORT_C TPoint ASwtControlBase::GetLocation() const
{
    TRect parentClientRect(iParent->Scrollable()->Control()->ClientRect()); //lint !e613
    return CoeControl().Position() - parentClientRect.iTl;
}

EXPORT_C const MSwtMenu* ASwtControlBase::GetPopupMenu() const
{
    return iPopupMenu;
}

EXPORT_C const MSwtMenu* ASwtControlBase::GetControlMenu() const
{
    return NULL;
}

EXPORT_C MSwtComposite* ASwtControlBase::GetParent() const
{
    return iParent;
}

EXPORT_C TBool ASwtControlBase::IsDescentOf(const MSwtControl& aControl) const
{
    MSwtComposite* aParent = aControl.CompositeInterface();
    if (!aParent)
    {
        return EFalse;
    }

    MSwtComposite* parent = GetParent();
    while (parent)
    {
        if (parent == aParent)
        {
            return ETrue;
        }
        parent = parent->Control()->GetParent();
    }

    return EFalse;
}

EXPORT_C MSwtShell& ASwtControlBase::GetTopShell() const
{
    const MSwtControl* ctrl = this;
    while (ctrl && ctrl->GetParent())
    {
        ctrl = ctrl->GetParent()->Control();
    }
    MSwtShell* shell = const_cast<MSwtShell*>(ctrl->ShellInterface());
    ASSERT(shell);
    return *shell;
}

EXPORT_C MSwtCaptionedControl* ASwtControlBase::GetNearestCaptionedControl(TBool aIncludeSelf /*= ETrue*/) const
{
    MSwtCaptionedControl* res = NULL;
    const MSwtControl* ctrl = aIncludeSelf ? this : (GetParent() ? GetParent()->Control() : NULL);
    while (ctrl)
    {
        if (ctrl->CaptionedControlInterface())
        {
            return ctrl->CaptionedControlInterface();
        }
        ctrl = ctrl->GetParent() ? ctrl->GetParent()->Control() : NULL;
    }
    return res;
}

EXPORT_C TSize ASwtControlBase::GetWidgetSize() const
{
    return CoeControl().Size();
}

EXPORT_C void ASwtControlBase::SetWidgetSize(const TSize& aSize)
{
    ASSERT(!IsShell());

    CCoeControl& coeCtrl = CoeControl();
    TRect oldRect(coeCtrl.Rect());
    TRect newRect(coeCtrl.Position(), aSize);

    if (newRect == oldRect)
    {
        return;
    }

    MSwtShell& shell = GetShell();
    if (shell.UrgentPaintControl() == this)
    {
        shell.SetUrgentPaintControl(NULL);
    }

    TBool urgent = EFalse;
    if (iParent->ScrolledCompositeContent() == this
            && shell.UrgentPaintControl() == iParent->Control())
    {
        if (iParent->ScrolledCompositePysicsAction() != KSwtPhysicsNoAction)
        {
            // Cannot change the bounds of the content while flicking or panning
            return;
        }
        urgent = ETrue;
    }

    if (!urgent)
    {
        // Do not invalidate outside parent's visible client area.
        if (iParent)
        {
            TRect parentVisibleRect(static_cast<ASwtControlBase*>(
                                        iParent->Control())->VisibleRect());
            oldRect.Intersection(parentVisibleRect);
            newRect.Intersection(parentVisibleRect);
        }

        // Invalidate uncovered regions.
        RRegion invalidRegion;
        invalidRegion.Clear();
        invalidRegion.AddRect(oldRect);
        invalidRegion.SubRect(newRect);
        if (!invalidRegion.IsEmpty())
        {
            ASSERT(invalidRegion.Count() <= 2);
            for (TInt i = 0; i < invalidRegion.Count(); i++)
            {
                Invalidate(invalidRegion[i]);
            }
        }
        invalidRegion.Close();
    }

    // Set and redraw new rect
    coeCtrl.SetSize(aSize);
    if (!(iStyle & KSwtStyleNoRedrawResize))
    {
        if (urgent)
        {
            iParent->Control()->PaintUrgently(iParent->Control()->CoeControl().Rect());
        }
        else
        {
            Redraw();
        }
    }
}

EXPORT_C TBool ASwtControlBase::IsFocusControl()
{
    ASSERT(!IsShell());
    return CoeControl().IsFocused();
}

EXPORT_C void ASwtControlBase::MoveAbove(const MSwtControl* aControl)
{
    ASSERT(!IsShell());
    ASSERT(iParent!=NULL);
    iParent->MoveChildAbove(*this, aControl);
}

EXPORT_C void ASwtControlBase::MoveBelow(const MSwtControl* aControl)
{
    ASSERT(!IsShell());
    ASSERT(iParent!=NULL);
    iParent->MoveChildBelow(*this, aControl);
}

EXPORT_C void ASwtControlBase::Redraw()
{
    RedrawRegion(TRect(TPoint(0, 0), CoeControl().Size()));
}

// aRect is in Control coords / relative to itself!
EXPORT_C void ASwtControlBase::RedrawRegion(const TRect& aRect)
{
    if (!GetVisibleRecursively() || (iCtrlFlags & MSwtControl::EFlagDoNotDraw))
    {
        return;
    }

    CCoeControl& coeCtrl = CoeControl();
    TRect rectInWindow(aRect);
    if (!coeCtrl.OwnsWindow())
    {
        rectInWindow.Move(coeCtrl.Position());   // In window coords
    }
    TRect dirtyRect(VisibleRect(ETrue));     // In window coords
    dirtyRect.Intersection(rectInWindow);    // In window coords
    if (dirtyRect.IsEmpty())
    {
        return;
    }

    MSwtShell& shell = GetShell();
    MSwtControl* urgentPaintControl = shell.UrgentPaintControl();
    if (urgentPaintControl)
    {
        // Redraw requests outside urgently painted controls are ignored.
        if (urgentPaintControl == this || IsDescentOf(*urgentPaintControl))
        {
            PaintUrgently(dirtyRect);
        }
    }
    else
    {
        if (shell.AsyncPainting())
        {
            TRect ctrlRect(coeCtrl.Rect());
            MSwtControl* controlShell = shell.Control();
            TSwtPeer peerOfTheTargetControl(controlShell->JavaPeer());
            if (RectContainsRect(ctrlRect, dirtyRect))
            {
                peerOfTheTargetControl = JavaPeer();
            }

            dirtyRect.Move(controlShell->CoeControl().PositionRelativeToScreen());   // Screen coords
            TBool mergeable = !(iStyle & KSwtStyleNoMergePaints);
            TRAP_IGNORE(iDisplay.PostPaintEventL(JavaPeer(), peerOfTheTargetControl, dirtyRect, mergeable));
        }
        else
        {
            PaintUrgently(dirtyRect);
        }
    }
}

EXPORT_C void ASwtControlBase::SetRedraw(TBool aRedraw)
{
    if (aRedraw)
    {
        if (iStackedSetRedrawFalseNb > 0)
        {
            --iStackedSetRedrawFalseNb;
        }
    }
    else
    {
        ++iStackedSetRedrawFalseNb;
    }

    UpdateDoNotDrawFlag();

    if (!(iCtrlFlags & MSwtControl::EFlagDoNotDraw))
    {

        //For Shell the drawing are doing in Java Side.
        if (!IsShell())
        {
            // We mark this Control as needed to be redraw.
            // Redraw() is prefered instead DrawDeferred() because it directly post a
            // PaintEvent on this Control whereas DrawDeferred
            // notify the Windows server that the windows container need to be redraw.
            Redraw();
        }
    }
}

TBool ASwtControlBase::ParentHasDoNotDrawFlag()
{
    MSwtControl* parent = NULL;

    if (iParent!=NULL)
        parent = iParent->Control();

    while (parent != NULL)
    {
        if (parent->Flags() & MSwtControl::EFlagDoNotDraw)
        {
            return ETrue;
        }
        else if (!parent->GetParent() || parent->IsShell())
        {
            return EFalse;
        }
        else
        {
            parent = parent->GetParent()->Control();
        }
    }

    return EFalse;
}

EXPORT_C TBool ASwtControlBase::HasDoNotDrawFlag() const
{
    return (iCtrlFlags & MSwtControl::EFlagDoNotDraw);
}

EXPORT_C void ASwtControlBase::UpdateDoNotDrawFlag()
{
    if (iStackedSetRedrawFalseNb == 0 && !ParentHasDoNotDrawFlag())
    {
        iCtrlFlags &= ~MSwtControl::EFlagDoNotDraw;
    }
    else
    {
        iCtrlFlags |= MSwtControl::EFlagDoNotDraw;
    }
}

EXPORT_C void ASwtControlBase::SetFontL(const MSwtFont* aFont)
{
    DoSetFontL(aFont);
    Redraw();
}

void ASwtControlBase::DoSetFontL(const MSwtFont* aFont)
{
    if (iFont != NULL)
        iFont->RemoveRef();
    iFont = aFont;
    if (iFont != NULL)
        iFont->AddRef();
}

EXPORT_C void ASwtControlBase::SetVisible(TBool aVisible)
{
    CCoeControl& coeCtrl = CoeControl();
    MSwtShell& shell = GetShell();
    TBool redrawFocusedCtrl = (&shell == UiUtils().GetActiveShell())
                              && (shell.FocusControl() != this);
    TInt oldCount = 0;
    TInt newCount = 0;

    if (redrawFocusedCtrl)
    {
        oldCount = shell.Composite()->CountFocusableChildren(2);
    }

    if (aVisible)
    {
        iCtrlFlags &= ~MSwtControl::EFlagInvisible;
    }
    else
    {
        if (shell.UrgentPaintControl() == this)
        {
            shell.SetUrgentPaintControl(NULL);
        }
    }

    coeCtrl.MakeVisible(aVisible);

    if (!aVisible)
        iCtrlFlags |= MSwtControl::EFlagInvisible;

    if (aVisible)
    {
        Redraw();
    }
    else
    {
        Invalidate(coeCtrl.Rect());
    }

    if (!IsShell())
    {
        FocusabilityChanged();
    }

    if (redrawFocusedCtrl)
    {
        newCount = shell.Composite()->CountFocusableChildren(2);
    }

    if (redrawFocusedCtrl
            && ((oldCount >= 2 && newCount == 1)
                || (oldCount == 1 && newCount >= 2)))
    {
        MSwtControl* focusedCtrl = GetShell().FocusControl();
        if (focusedCtrl)
        {
            static_cast<ASwtControlBase*>(focusedCtrl)->RedrawFocusBackground();
        }
    }
}

EXPORT_C void ASwtControlBase::SetLocation(const TPoint& aPoint)
{
    ASSERT(!IsShell());

    TPoint oldLocation(GetLocation());
    TPoint newLocation = ComputeLocationToSet(aPoint);
    CCoeControl& coeCtrl = CoeControl();
    TRect oldRect(coeCtrl.Rect());
    TRect newRect(newLocation, coeCtrl.Size());

    if (oldLocation == newLocation)
    {
        return;
    }

    MSwtShell& shell = GetShell();
    if (shell.UrgentPaintControl() == this)
    {
        shell.SetUrgentPaintControl(NULL);
    }

    TBool urgent = EFalse;
    if (iParent->ScrolledCompositeContent() == this
            && shell.UrgentPaintControl() == iParent->Control())
    {
        if (iParent->ScrolledCompositePysicsAction() != KSwtPhysicsNoAction)
        {
            // Cannot change the bounds of the content while flicking or panning
            return;
        }
        urgent = ETrue;
    }

    if (!urgent)
    {
        // Do not invalidate outside parent's visible client area.
        if (iParent)
        {
            TRect parentVisibleRect(static_cast<ASwtControlBase*>(
                                        iParent->Control())->VisibleRect());
            oldRect.Intersection(parentVisibleRect);
            newRect.Intersection(parentVisibleRect);
        }

        // Invalidate uncovered regions.
        if (newRect.Intersects(oldRect))
        {
            RRegion invalidRegion;
            invalidRegion.Clear();
            invalidRegion.AddRect(oldRect);
            invalidRegion.SubRect(newRect);
            ASSERT(invalidRegion.Count() <= 2);
            for (TInt i = 0; i < invalidRegion.Count(); i++)
            {
                Invalidate(invalidRegion[i]);
            }
            invalidRegion.Close();
        }
        else
        {
            Invalidate(oldRect);
        }
    }

    // Set and redraw new rect
    coeCtrl.SetPosition(newLocation);
    if (!(iStyle & KSwtStyleNoRedrawResize))
    {
        if (urgent)
        {
            iParent->Control()->PaintUrgently(iParent->Control()->CoeControl().Rect());
        }
        else
        {
            Redraw();
        }
    }
}

EXPORT_C void ASwtControlBase::SetEnabled(TBool aEnabled)
{
    CCoeControl& coeCtrl = CoeControl();
    MSwtShell& shell = GetShell();
    TBool redrawFocusedCtrl = (&shell == UiUtils().GetActiveShell())
                              && (shell.FocusControl() != this);
    TInt oldCount = 0;
    TInt newCount = 0;

    if (redrawFocusedCtrl)
    {
        oldCount = shell.Composite()->CountFocusableChildren(2);
    }

    if (aEnabled)
    {
        iCtrlFlags &= ~MSwtControl::EFlagDisabled;
    }

    coeCtrl.SetFocusing(aEnabled);
    coeCtrl.SetDimmed(!aEnabled);

    if (!aEnabled)
        iCtrlFlags |= MSwtControl::EFlagDisabled;

    if (!IsShell())
    {
        // If we got disabled this will find a new focused item.
        FocusabilityChanged();
    }

    Redraw();

    if (redrawFocusedCtrl)
    {
        newCount = shell.Composite()->CountFocusableChildren(2);
    }

    if (redrawFocusedCtrl
            && ((oldCount >= 2 && newCount == 1)
                || (oldCount == 1 && newCount >= 2)))
    {
        MSwtControl* focusedCtrl = GetShell().FocusControl();
        if (focusedCtrl)
        {
            static_cast<ASwtControlBase*>(focusedCtrl)->RedrawFocusBackground();
        }
    }
}

EXPORT_C void ASwtControlBase::SetBounds(const TRect& aRect)
{
    // Must NOT call SetExtent if we want component controls to be relocated.
    ASSERT(!IsShell());

    CCoeControl& coeCtrl = CoeControl();
    TSize oldSize(coeCtrl.Size());
    TSize newSize(aRect.Size());
    TPoint oldLocation(GetLocation());
    TPoint newLocation(ComputeLocationToSet(aRect.iTl));
    TRect oldRect(coeCtrl.Rect());
    TRect newRect(newLocation, newSize);

    if (oldLocation == newLocation && oldSize == newSize)
    {
        return;
    }

    MSwtShell& shell = GetShell();
    if (shell.UrgentPaintControl() == this)
    {
        shell.SetUrgentPaintControl(NULL);
    }

    TBool urgent = EFalse;
    if (iParent->ScrolledCompositeContent() == this
            && shell.UrgentPaintControl() == iParent->Control())
    {
        if (iParent->ScrolledCompositePysicsAction() != KSwtPhysicsNoAction)
        {
            // Cannot change the bounds of the content while flicking or panning
            return;
        }
        urgent = ETrue;
    }

    if (!urgent)
    {
        // Do not invalidate outside parent's visible client area.
        if (iParent)
        {
            TRect parentVisibleRect(static_cast<ASwtControlBase*>(
                                        iParent->Control())->VisibleRect());
            oldRect.Intersection(parentVisibleRect);
            newRect.Intersection(parentVisibleRect);
        }

        // Invalidate uncovered regions.
        if (newRect.Intersects(oldRect))
        {
            RRegion invalidRegion;
            invalidRegion.Clear();
            invalidRegion.AddRect(oldRect);
            invalidRegion.SubRect(newRect);
            ASSERT(invalidRegion.Count() <= 4);
            for (TInt i = 0; i < invalidRegion.Count(); i++)
            {
                Invalidate(invalidRegion[i]);
            }
            invalidRegion.Close();
        }
        else
        {
            Invalidate(oldRect);
        }
    }

    // Set and invalidate new rect
    if (oldLocation != newLocation)
    {
        coeCtrl.SetPosition(newLocation);
    }
    if (oldSize != newSize)
    {
        coeCtrl.SetSize(newSize);
    }

    if (!(iStyle & KSwtStyleNoRedrawResize))
    {
        if (urgent)
        {
            iParent->Control()->PaintUrgently(iParent->Control()->CoeControl().Rect());
        }
        else
        {
            Redraw();
        }
    }
}

EXPORT_C void ASwtControlBase::SetPopupMenuL(const MSwtMenu* aMenu)
{
    if (aMenu)
    {
        GetShell().InstallCba();
    }

    const MSwtMenu* oldMenu = iPopupMenu;
    iPopupMenu = aMenu;

    if (iPopupMenu == NULL && oldMenu != NULL)
    {
        iDisplay.MenuArranger().HandleMenuChangedL(*oldMenu, MSwtMenuArranger::ESwtMenuRemoved);
    }
    else if (iPopupMenu != NULL)
    {
        iDisplay.MenuArranger().HandleMenuChangedL(*iPopupMenu, MSwtMenuArranger::ESwtMenuAdded);
    }
}

EXPORT_C void ASwtControlBase::SetCapture(TBool aCapture)
{
    if (aCapture)
    {
        UiUtils().SetPointerCaptureControl(this);
    }
    else
    {
        if (UiUtils().PointerCaptureControl() == this)
        {
            UiUtils().SetPointerCaptureControl(NULL);
        }
    }
}

EXPORT_C TInt ASwtControlBase::Style() const
{
    return iStyle;
}

EXPORT_C void ASwtControlBase::Update() const
{
    if (iCtrlFlags & MSwtControl::EFlagDoNotDraw)
        return;
}

EXPORT_C void ASwtControlBase::ComputeTabListL(RSwtControlArray& aList)
{
    User::LeaveIfError(aList.Append(this));
}

EXPORT_C TPoint ASwtControlBase::ToControl(const TPoint& aPoint) const
{
    const TPoint clientOriginInScreen(WindowToScreen(ClientRect().iTl));
    return aPoint - clientOriginInScreen;
}

EXPORT_C TPoint ASwtControlBase::ToDisplay(const TPoint& aPoint) const
{
    const TPoint clientOriginInScreen(WindowToScreen(ClientRect().iTl));
    return aPoint + clientOriginInScreen;
}

EXPORT_C TBool ASwtControlBase::CbaButtonIsUsed(TInt /*aCbaButtonIndex*/) const
{
    return EFalse;
}

EXPORT_C TBool ASwtControlBase::IsKeyUsed(TUint /*aKeyCode*/) const
{
    // By default, we assume that the control doesn't use key
    return EFalse;
}

EXPORT_C TBool ASwtControlBase::MSKSelCmdEnabled() const
{
    return EFalse;
}

EXPORT_C TBool ASwtControlBase::ForceTraverseEvent(TSwtTraversal aDetail, TBool aDoIt)
{
    TRAPD(ignore, iDisplay.ForceTraverseEventL(*this, aDetail, aDoIt));
    return (ignore == KErrNone);
}

EXPORT_C void ASwtControlBase::AddToControlStackL(TInt aPriority)
{
    if (!iIsOnControlStack)
    {
        iIsOnControlStack = ETrue;
        TRAPD(error, iDisplay.CoeEnv()->EikAppUi()->AddToStackL(&CoeControl(), aPriority));
        if (error!=KErrNone)
        {
            iIsOnControlStack = EFalse;
            User::Leave(error);
        }
        if (!IsShell())
        {
            GetShell().SetControlGoingToStack(this);
            GetShell().SetControlGainingFocus(NULL);
        }
    }
}
EXPORT_C HBufC* ASwtControlBase::MSKLabelL() const
{
    return KNullDesC().Alloc();
}

EXPORT_C void ASwtControlBase::RemoveFromControlStack()
{
    if (iIsOnControlStack)
    {
        iDisplay.CoeEnv()->EikAppUi()->RemoveFromStack(&CoeControl());
        iIsOnControlStack = EFalse;
        if (!IsShell())
        {
            if (
                iDisplay.MenuArranger().EikMenuBar()->IsDisplayed() ||
                iDisplay.CoeEnv()->EikAppUi()->IsDisplayingControlBetweenPriorities(
                    ECoeStackPriorityMenu, ECoeStackPriorityCba))
            {
                GetShell().SetControlGainingFocus(this);
            }
        }
    }
}

EXPORT_C TBool ASwtControlBase::IsOnControlStack() const
{
    return iIsOnControlStack;
}

#ifdef RD_SCALABLE_UI_V2
EXPORT_C void ASwtControlBase::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{
    CoeControl().HandlePointerEventL(aPointerEvent);
    PostMouseEventL(aPointerEvent);
}
#else
EXPORT_C void ASwtControlBase::HandlePointerEventL(const TPointerEvent& /*aPointerEvent*/)
{
    ASSERT(EFalse);
}
#endif

#ifdef RD_SCALABLE_UI_V2
EXPORT_C TBool ASwtControlBase::IsLongTapAnimationCandidate(const TPointerEvent& aPointerEvent) const
{
    return (ClientRect().Contains(aPointerEvent.iPosition)
            && iDisplay.CommandArranger()->ControlHasStylusPopupMenu(*this));
}
#else
EXPORT_C TBool ASwtControlBase::IsLongTapAnimationCandidate(const TPointerEvent& /*aPointerEvent*/) const
{
    return EFalse;
}
#endif

TBool ASwtControlBase::IsFocusedOrChildIsFocused() const
{
    return (GetShell().FocusControl() == this) || ChildIsFocused();
}

TBool ASwtControlBase::ChildIsFocused() const
{
    MSwtControl* focusedControl = GetShell().FocusControl();
    return focusedControl && focusedControl->IsDescentOf(*this);
}

EXPORT_C void ASwtControlBase::DoControlSpecificFeedback(
    const TBool& /*aFirstTap*/, const TBool& /*aTappedToChildRect*/,
    const TPointerEvent& /*aPointerEvent*/) const
{
    //Do nothing here. Each child class will implement
    //this function according to its needs.
    //Note that this function is not called by platform.
}