// COECNTRL.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <coecntrl.h>
#include <coeccntx.h>
#include <coemain.h>
#include "coetls.h"
#include <coepanic.h>

//
// class CCoeControlExtension
//

class CCoeControlExtension : public CBase
	{
	friend class RCoeExtensionStorage;
public:
	static CCoeControlExtension* NewL();
	~CCoeControlExtension();
	void OverrideColorL(TInt aLogicalColor,TRgb aColor);
	TBool GetColor(TInt aLogicalColor,TRgb& aColor) const;
private:
	CCoeControlExtension();
	TInt FindColor(TInt aLogicalColor) const;
private:
	struct SColorOverride
		{
		TRgb iColor;
		TInt iLogicalColor;
		};
	CArrayFix<SColorOverride>* iColorOverrides;
	TInt iFlags;
	};

CCoeControlExtension* CCoeControlExtension::NewL()
	{ // static
	CCoeControlExtension* self=new(ELeave) CCoeControlExtension;
	return self;
	}

CCoeControlExtension::CCoeControlExtension()
	{}

CCoeControlExtension::~CCoeControlExtension()
	{
	delete iColorOverrides;
	}

void CCoeControlExtension::OverrideColorL(TInt aLogicalColor,TRgb aColor)
	{
	if (!iColorOverrides)
		iColorOverrides=new(ELeave) CArrayFixFlat<SColorOverride>(2);
	SColorOverride override;
	override.iLogicalColor=aLogicalColor;
	override.iColor=aColor;
	const TInt index=FindColor(aLogicalColor);
	if (index==KErrNotFound)
		iColorOverrides->AppendL(override);
	else
		(*iColorOverrides)[index]=override;
	}

TBool CCoeControlExtension::GetColor(TInt aLogicalColor,TRgb& aColor) const
	{
	TInt index=FindColor(aLogicalColor);
	if (index==KErrNotFound)
		return EFalse;
	aColor=(*iColorOverrides)[index].iColor;
	return ETrue;
	}

TInt CCoeControlExtension::FindColor(TInt aLogicalColor) const
	{
	TInt pos;
	TKeyArrayFix key(4,ECmpTInt);
	SColorOverride override;
	override.iLogicalColor=aLogicalColor;
	override.iColor=TRgb(); // ignore the actual color
	if (iColorOverrides->Find(override,key,pos)==KErrNone)
		return pos;
	return KErrNotFound;
	}

//
// class RCoeExtensionStorage
//

enum { EStorageAsFlags=0x3 };

RCoeExtensionStorage::RCoeExtensionStorage()
	{
	iFlags=EStorageAsFlags;
	}

void RCoeExtensionStorage::Close()
	{
	if (!IsFlags())
		delete iExtension;
	}

TInt& RCoeExtensionStorage::Flags()
	{
	if (IsFlags())
		return iFlags;
	return iExtension->iFlags;
	}

TInt RCoeExtensionStorage::Flags() const
	{
	if (IsFlags())
		return iFlags;
	return iExtension->iFlags;
	}

void RCoeExtensionStorage::SetExtension(CCoeControlExtension* aExtension)
	{
	__ASSERT_DEBUG(IsFlags(),Panic(ECoePanicExtensionAlreadyExists));
	TInt flags=iFlags;
	flags&=~EStorageAsFlags; // probably unecessary
	aExtension->iFlags=flags;
	iExtension=aExtension;
	}

CCoeControlExtension* RCoeExtensionStorage::Extension() const
	{
	if (IsFlags())
		return NULL;
	return iExtension;
	}

inline TBool RCoeExtensionStorage::IsFlags() const
	{return iFlags&EStorageAsFlags;}

//
// class CCoeControl
//

// the enums below must not set the bottom two bits as they're stored in a long-void* union
// ...and identifying which is currently in use relies on object pointers being word aligned
enum
	{
	EOwnsWindow						 	=0x000004,
	EFocused							=0x000008,
	EActivated						  	=0x000010,
	EInvisible						  	=0x000020,
	EDimmed								=0x000040,
	EGrabbed							=0x000080,
	EBackedUpWindow					 	=0x000100,
	ENonFocusing						=0x000200,
	EAllowStrayPointers					=0x000400,
	ECanDrawOutsideRect					=0x000800,
	EBlank								=0x001000,
	ECapturesPointer					=0x002000,
	EIgnoresFirstExternalPointerUp		=0x004000,
	EIgnoresEventsUntilNextPointerUp	=0x008000,
	EComponentsInheritVisibility		=0x010000,
	EGloballyCapturing					=0x020000
	};

EXPORT_C CCoeControl::CCoeControl()
	{
	iCoeEnv=TheCoe();
	}

EXPORT_C CCoeControl::~CCoeControl()
	{
	if (OwnsWindow())
		CloseWindow();
	iExt.Close();
	}

EXPORT_C TBool CCoeControl::IsFocused() const
	{
	return(Flags()&EFocused);
	}

EXPORT_C TBool CCoeControl::IsVisible() const
	{
	return(!(Flags()&EInvisible));
	}

EXPORT_C TBool CCoeControl::IsDimmed() const
	{
	return(Flags()&EDimmed);
	}

EXPORT_C TSize CCoeControl::Size() const
	{
	return(iSize);
	}

EXPORT_C TPoint CCoeControl::Position() const
	{
	return(iPosition);
	}

EXPORT_C TPoint CCoeControl::PositionRelativeToScreen() const
	{
	TPoint ret=iWin->InquireOffset(iCoeEnv->RootWin());
	if (!OwnsWindow())
		ret+=iPosition;
	return(ret);
	}

EXPORT_C void CCoeControl::SetObserver(MCoeControlObserver* aObserver)
	{
	iObserver=aObserver;
	}

EXPORT_C TBool CCoeControl::IsReadyToDraw() const
	{
	return((Flags()&(EInvisible|EActivated))==(EActivated));
	}

EXPORT_C TBool CCoeControl::OwnsWindow() const
	{
	return(Flags()&EOwnsWindow);
	}

EXPORT_C TBool CCoeControl::IsBackedUp() const
	{
	return(Flags()&EBackedUpWindow);
	}

EXPORT_C TBool CCoeControl::IsActivated() const
	{
	return(Flags()&EActivated);
	}

EXPORT_C TBool CCoeControl::IsBlank() const
	{
	return(Flags()&EBlank);
	}

TBool CCoeControl::IsGrabbed() const
	{
	return(Flags()&EGrabbed);
	}

EXPORT_C TKeyResponse CCoeControl::OfferKeyEventL(const TKeyEvent& /*aKeyEvent*/,TEventCode /*aType*/)
	{
	return(EKeyWasNotConsumed);
	}

void CCoeControl::ProcessPointerBufferReadyL()
	{
	CCoeControl* destination=NULL;
	for (TInt i=0; i<CountComponentControls(); i++)
		{
		CCoeControl* ctrl=ComponentControl(i);
		if (ctrl->IsGrabbed() && !(ctrl->OwnsWindow()))
			destination=ctrl;
		}
	if (destination)
		destination->ProcessPointerBufferReadyL();
	else
		HandlePointerBufferReadyL();
	}

EXPORT_C void CCoeControl::HandlePointerBufferReadyL()
	{
	}

EXPORT_C void CCoeControl::ClaimPointerGrab(TBool aSendUpEvent)
	{
	Flags()|=EAllowStrayPointers|EIgnoresFirstExternalPointerUp;
	iWin->SetPointerGrab(ETrue);
	iWin->ClaimPointerGrab(aSendUpEvent);
	}

EXPORT_C void CCoeControl::IgnoreEventsUntilNextPointerUp()
	{
	Flags()|=EIgnoresEventsUntilNextPointerUp;
	}

void CCoeControl::ProcessPointerEventL(const TPointerEvent& aPointerEvent)
	{
	TBool needsFocus=EFalse;
	if (aPointerEvent.iType==TPointerEvent::EButton1Down)
		{
		SetGrabbed(EFalse);
		if (!IsVisible())
			return;
		if (IsDimmed())
			{
			ReportEventL(MCoeControlObserver::EEventInteractionRefused);
			return;
			}
		if (!IsFocused() && !IsNonFocusing())
			{
			ReportEventL(MCoeControlObserver::EEventPrepareFocusTransition);
			needsFocus=ETrue;
			}
		SetGrabbed(ETrue);
		}
	else
		{
		if (IsGrabbed())
			{
			if (aPointerEvent.iType==TPointerEvent::EButton1Up)
				SetGrabbed(EFalse);
			}
		else
			{
			if (!(Flags()&EAllowStrayPointers))
				return;
			if (Flags()&EIgnoresFirstExternalPointerUp)
				{
				if (Rect().Contains(aPointerEvent.iPosition))
					Flags()&=(~EIgnoresFirstExternalPointerUp);
				else
					{
					if (aPointerEvent.iType==TPointerEvent::EButton1Up)
						Flags()&=(~EIgnoresFirstExternalPointerUp);
					return;
					}
				}
			}
		}
	if (Flags()&EIgnoresEventsUntilNextPointerUp)
		{
		if (aPointerEvent.iType==TPointerEvent::EButton1Up)
			Flags()&=(~EIgnoresEventsUntilNextPointerUp);
		return;
		}
	else
		HandlePointerEventL(aPointerEvent);
	if (needsFocus)
		ReportEventL(MCoeControlObserver::EEventRequestFocus);
	}

EXPORT_C void CCoeControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
	{
	const TInt count=CountComponentControls();
	if (!count)
		return;
	CCoeControl* pointerRecipient=NULL;
	if (aPointerEvent.iType!=TPointerEvent::EButton1Down)
		pointerRecipient=GrabbingComponent();
	else
		{
		for (TInt ii=0; ii<count; ii++)
			{
			CCoeControl* ctrl=ComponentControl(ii);
			if (ctrl->OwnsWindow() || !(ctrl->IsVisible()))
				continue;
			const TRect rect=ctrl->Rect();
			if (rect.Contains(aPointerEvent.iPosition))
				{
				pointerRecipient=ctrl;
				break;
				}
			}
		}
	if (pointerRecipient)
		pointerRecipient->ProcessPointerEventL(aPointerEvent);
	}

EXPORT_C void CCoeControl::ReportEventL(MCoeControlObserver::TCoeEvent aEvent)
	{
	if (iObserver)
		iObserver->HandleControlEventL(this,aEvent);
	}

EXPORT_C void CCoeControl::PrepareForFocusLossL()
	{
	}

EXPORT_C void CCoeControl::SetAdjacent(TInt /*aAdjacent*/)
	{
	}

EXPORT_C void CCoeControl::SetNeighbor(CCoeControl* /*aNeighbor*/)
	{
	}

EXPORT_C TBool CCoeControl::HasBorder() const
	{
	return EFalse;
	}

EXPORT_C TSize CCoeControl::MinimumSize()
	{ // designed to be overridden
	return(iSize);
	}

EXPORT_C void CCoeControl::ConstructFromResourceL(TResourceReader& /*aSource*/)
	{
	}

EXPORT_C void CCoeControl::CloseWindow()
	{
	__ASSERT_DEBUG(OwnsWindow(),Panic(ECoePanicNoWindow));
	if (iWin)
		{
		iWin->Close();
		delete(iWin);
		iWin=NULL;
		}
	Flags()&=(~(EOwnsWindow|EBackedUpWindow|EActivated));
	}

EXPORT_C void CCoeControl::CreateBackedUpWindowL(RWindowTreeNode& aParent)
	{
	TInt colors=0;
	TInt grays=0;
	TDisplayMode defaultMode=iCoeEnv->WsSession().GetDefModeMaxNumColors(colors,grays);
	CreateBackedUpWindowL(aParent,defaultMode);
	}

EXPORT_C void CCoeControl::CreateBackedUpWindowL(RWindowTreeNode& aParent,TDisplayMode aDisplayMode)
	{
	__ASSERT_DEBUG(!iWin,Panic(ECoePanicWindowAlreadyCreated));
	iWin=new(ELeave) RBackedUpWindow(iCoeEnv->WsSession());
	Flags()|=EOwnsWindow|EBackedUpWindow;
	User::LeaveIfError(((RBackedUpWindow*)iWin)->Construct(aParent,aDisplayMode,(TUint32)this));
	}

EXPORT_C void CCoeControl::CreateWindowL(RWindowTreeNode& aParent)
	{
	__ASSERT_DEBUG(!iWin,Panic(ECoePanicWindowAlreadyCreated));
	iWin=new(ELeave) RWindow(iCoeEnv->WsSession());
	Flags()|=EOwnsWindow;
	User::LeaveIfError(((RWindow*)iWin)->Construct(aParent,(TUint32)this));
	}

EXPORT_C void CCoeControl::CreateWindowL(const CCoeControl* aParent)
	{
	CreateWindowL(aParent? (RWindowTreeNode&)(*aParent->iWin): (RWindowTreeNode&)iCoeEnv->RootWin());
	}

EXPORT_C void CCoeControl::CreateWindowL(RWindowGroup* aParent)
	{
	CreateWindowL(aParent? (RWindowTreeNode&)(*aParent): (RWindowTreeNode&)iCoeEnv->RootWin());
	}

EXPORT_C void CCoeControl::CreateWindowL()
	{
	CreateWindowL(iCoeEnv->RootWin());
	}

EXPORT_C void CCoeControl::HandleRedrawEvent(const TRect& aRect) const
	{
	ActivateGc();
	Window().BeginRedraw(aRect);
	Draw(aRect);
	DrawComponents(aRect);
	Window().EndRedraw();
	DeactivateGc();
	}

void CCoeControl::DrawComponents(const TRect& aRect) const
	{
	const TInt count=CountComponentControls();
	for (TInt ii=0; ii<count; ii++)
		{
		const CCoeControl* ctrl=ComponentControl(ii);
		if (!(ctrl->OwnsWindow()) && ctrl->IsVisible())
			{
			TRect rect;
			const TRect* pRect=(&aRect);
			if (!((ctrl->Flags())&ECanDrawOutsideRect))
				{
				rect=ctrl->Rect();
				rect.Intersection(aRect);
				if (rect.IsEmpty())
					continue;
				pRect=(&rect);
				}
			ResetGc();
			ctrl->Draw(*pRect);
			ctrl->DrawComponents(*pRect);
			}
		}
	}

EXPORT_C void CCoeControl::Draw(const TRect& aRect) const
	{
	if (Flags()&EBlank)
		{ // else do nothing
		CGraphicsContext& gc=SystemGc();
		gc.SetPenStyle(CGraphicsContext::ENullPen);
		gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
    	gc.DrawRect(aRect);
		}
	}

EXPORT_C void CCoeControl::DrawNow() const
	{
	if (!IsReadyToDraw())
		return;
	const TRect rect=Rect();
	ActivateGc();
	TBool backedUp=IsBackedUp();
	if (!backedUp)
		{
		Window().Invalidate(rect);
		Window().BeginRedraw(rect);
		}
	Draw(rect);
	DrawComponents(rect);
	if (!backedUp)
		Window().EndRedraw();
	DeactivateGc();
	DrawWindowOwningComponentsNow();
	}

void CCoeControl::DrawWindowOwningComponentsNow() const
	{
	const TInt count=CountComponentControls();
	for (TInt ii=0; ii<count; ii++)
		{
		CCoeControl* ctrl=ComponentControl(ii);
		if (ctrl->OwnsWindow())
			ctrl->DrawNow();
		else
			ctrl->DrawWindowOwningComponentsNow();
		}
	}

EXPORT_C void CCoeControl::DrawDeferred() const
	{
	if (!IsReadyToDraw())
		return;
	if (IsBackedUp())
		DrawNow();
	else
		Window().Invalidate(Rect());
	const TInt count=CountComponentControls();
	for (TInt ii=0; ii<count; ii++)
		{
		const CCoeControl* ctrl=ComponentControl(ii);
		if (ctrl->OwnsWindow())
			ctrl->DrawDeferred();
		}
	}

EXPORT_C CWindowGc& CCoeControl::SystemGc() const
	{
	return(iCoeEnv->SystemGc());
	}

EXPORT_C void CCoeControl::ActivateGc() const
	{
	CWindowGc& gc=iCoeEnv->SystemGc();
	if (iContext)
		iContext->ActivateContext(gc,*iWin);
	else
		gc.Activate(*iWin);
	}

EXPORT_C void CCoeControl::ResetGc() const
	{
	CWindowGc& gc=iCoeEnv->SystemGc();
	if (iContext)
		iContext->ResetContext(gc);
	else
		gc.Reset();
	}

EXPORT_C void CCoeControl::DeactivateGc() const
	{ // no harm done if Gc other than system one used
	iCoeEnv->SystemGc().Deactivate();
	}

EXPORT_C void CCoeControl::SetFocus(TBool aFocus,TDrawNow aDrawNow)
	{
	iCoeEnv->IncrementNumberOfNestedSetFocusCalls();
	if (aFocus)
		Flags()|=EFocused;
	else
		Flags()&=(~EFocused);
	if (aDrawNow && !IsReadyToDraw())
		aDrawNow=ENoDrawNow;
	FocusChanged(aDrawNow);
	iCoeEnv->DecrementNumberOfNestedSetFocusCalls();
	const TInt numberOfNestedSetFocusCalls=iCoeEnv->NumberOfNestedSetFocusCalls();
	__ASSERT_DEBUG(numberOfNestedSetFocusCalls>=0,Panic(ECoePanicNegativeNumberOfNestedSetFocusCalls4));
	if (numberOfNestedSetFocusCalls==0)
		{
		MCoeFepAwareItem* focusedFepAwareItem=iCoeEnv->FocusedFepAwareItem();
		if ((focusedFepAwareItem!=NULL) && !(*iCoeEnv->FepAwareItemIsFocusedFunction())(*focusedFepAwareItem))
			{
			iCoeEnv->NoFocusedFepAwareItem();
			}
		iCoeEnv->NotifyFocusObserversOfChangeInFocus();
		}
	}

EXPORT_C void CCoeControl::FocusChanged(TDrawNow /*aDrawNow*/)
	{
	}

EXPORT_C void CCoeControl::SetDimmed(TBool aDimmed)
	{
	if (aDimmed)
		Flags()|=EDimmed;
	else
		Flags()&=(~EDimmed);
	}

void CCoeControl::SetGrabbed(TBool aGrabbed)
	{
	if (aGrabbed)
		Flags()|=EGrabbed;
	else
		Flags()&=(~EGrabbed);
	}

EXPORT_C void CCoeControl::MakeVisible(TBool aVisible)
	{
	DoMakeVisible(aVisible);
	if (Flags()&ECapturesPointer)
		CheckPointerEventPurge();
	}

void CCoeControl::DoMakeVisible(TBool aVisible)
	{
	TBool isVisible=IsVisible();
	if ((isVisible && aVisible) || (!isVisible && !aVisible))
		return;		// No change
	if (OwnsWindow())
		iWin->SetVisible(aVisible);
	else if (IsActivated())
		{
		if (IsBackedUp())
			DrawNow();
		else
			Window().Invalidate(Rect());
		}
	if (aVisible)
		Flags()&=(~EInvisible);
	else
		Flags()|=EInvisible;
	if (Flags()&EComponentsInheritVisibility)
		{
		const TInt count=CountComponentControls();
		for (TInt ii=0; ii<count; ii++)
			ComponentControl(ii)->DoMakeVisible(aVisible);
		}
	}

EXPORT_C void CCoeControl::SetComponentsToInheritVisibility(TBool aInherit)
	{
	if (aInherit)
		Flags()|=EComponentsInheritVisibility;
	else
		Flags()&=(~EComponentsInheritVisibility);
	}

EXPORT_C void CCoeControl::SetGloballyCapturing(TBool aGlobal)
	{
	if (aGlobal)
		Flags()|=EGloballyCapturing;
	else
		Flags()&=(~EGloballyCapturing);
	}

EXPORT_C void CCoeControl::SetNonFocusing()
	{
	Flags()|=ENonFocusing;
	}

EXPORT_C void CCoeControl::SetFocusing(TBool aFocusing)
	{
	if (aFocusing)
		Flags()|=ENonFocusing;
	else
		Flags()&=(~ENonFocusing);
	}

EXPORT_C TBool CCoeControl::IsNonFocusing() const
	{
	return(Flags()&ENonFocusing);
	}

EXPORT_C void CCoeControl::SetAllowStrayPointers()
	{
	Flags()|=EAllowStrayPointers;
	}

EXPORT_C void CCoeControl::SetCanDrawOutsideRect()
	{
	Flags()|=ECanDrawOutsideRect;
	}

EXPORT_C void CCoeControl::SetBlank()
	{
	Flags()|=EBlank;
	}

EXPORT_C void CCoeControl::SetRectL(const TRect& aRect)
	{
	SetExtentL(aRect.iTl,aRect.Size());
	}

EXPORT_C void CCoeControl::SetExtentToWholeScreenL()
	{
	SetExtentL(TPoint(0,0),iCoeEnv->ScreenDevice()->SizeInPixels());
	}

EXPORT_C void CCoeControl::SetExtentL(const TPoint& aPosition,const TSize& aSize)
	{
	if (OwnsWindow())
		{
		if (IsBackedUp())
			User::LeaveIfError(iWin->SetExtentErr(aPosition,aSize));
		else
			Window().SetExtent(aPosition,aSize);
		}
	iPosition=aPosition;
	iSize=aSize;
	SizeChangedL();
	}

EXPORT_C void CCoeControl::SizeChangedL()
	{
	}

EXPORT_C void CCoeControl::PositionChanged()
	{
	}

EXPORT_C void CCoeControl::SetSizeL(const TSize& aSize)
	{
	SetSizeWithoutNotificationL(aSize);
	SizeChangedL();
	}

EXPORT_C void CCoeControl::SetPosition(const TPoint& aPosition)
	{
	if (OwnsWindow())
		{
		iPosition=aPosition;
		iWin->SetPosition(aPosition);
		}
	else
		{
		const TPoint delta=aPosition-iPosition;
		iPosition=aPosition;
		const TInt count=CountComponentControls();
		for (TInt ii=0;ii<count;ii++)
			{
			CCoeControl* ctrl=ComponentControl(ii);
			const TPoint pos=ctrl->Position();
			ctrl->SetPosition(pos+delta);
			}
		}
	PositionChanged();
	}

EXPORT_C void CCoeControl::SetSizeWithoutNotificationL(const TSize& aSize)
	{
	if (OwnsWindow())
		{
		if (IsBackedUp())
			User::LeaveIfError(iWin->SetSizeErr(aSize));
		else
			Window().SetSize(aSize);
		}
	iSize=aSize;
	}

EXPORT_C void CCoeControl::ActivateL()
	{
	if (!(Flags()&EActivated))
		{
		Flags()|=EActivated;
		if (OwnsWindow())
			{
			iWin->Activate();
			if (Flags()&ECapturesPointer)
				CheckPointerEventPurge();
			if (IsBackedUp())
				DrawNow();
			}
		}
	const TInt count=CountComponentControls();
	for (TInt ii=0; ii<count; ii++)
		ComponentControl(ii)->ActivateL();
	}

EXPORT_C TRect CCoeControl::Rect() const
	{
	return(TRect(OwnsWindow()? TPoint(0,0): iPosition,iSize));
	}

EXPORT_C void CCoeControl::SetContainerWindowL(const CCoeControl& aContainer)
	{
	iWin=aContainer.iWin;
	if (!iContext)
		iContext=aContainer.iContext;
	if (aContainer.IsBackedUp())
		Flags()|=EBackedUpWindow;
	}

EXPORT_C void CCoeControl::SetContainerWindow(RWindow& aWindow)
	{
	iWin=&aWindow;
	}

EXPORT_C void CCoeControl::SetContainerWindow(RBackedUpWindow& aWindow)
	{
	iWin=&aWindow;
	Flags()|=EBackedUpWindow;
	}

EXPORT_C void CCoeControl::SetCornerAndSizeL(TCoeAlignment aCorner,const TSize& aSize)
	{ // the following assumes the window is being positioned wrt the screen
	TPoint pos=aCorner.InnerTopLeft(iCoeEnv->ScreenDevice()->SizeInPixels(),aSize);
	SetExtentL(pos,aSize);
	}

EXPORT_C TInt CCoeControl::CountComponentControls() const
	{
	return(0);
	}

EXPORT_C CCoeControl* CCoeControl::ComponentControl(TInt /*aIndex*/) const
	{
	Panic(ECoePanicControlIsNotContainer);
	return(NULL);
	}

EXPORT_C void CCoeControl::EnableDragEvents()
	{
	iWin->PointerFilter(EPointerFilterDrag,0);
	}

EXPORT_C void CCoeControl::SetPointerCapture(TBool aCapture)
	{
	TInt captureFlags=0;
	Flags()&=(~ECapturesPointer);
	if (aCapture)
		captureFlags=(Flags()&EGloballyCapturing? RWindowBase::TCaptureFlagAllGroups|RWindowBase::TCaptureFlagEnabled: RWindowBase::TCaptureFlagEnabled);
	iWin->SetPointerCapture(captureFlags);
	if (aCapture)
		{
		Flags()|=ECapturesPointer;
		CheckPointerEventPurge();
		}
	}

EXPORT_C TBool CCoeControl::CapturesPointer() const
	{
	return Flags()&ECapturesPointer;
	}

void CCoeControl::CheckPointerEventPurge() const
	{
	if (IsReadyToDraw())
		iCoeEnv->WsSession().PurgePointerEvents();
	}

EXPORT_C TInt CCoeControl::Index(const CCoeControl* aControl) const
	{
	TInt count=CountComponentControls();
	for (TInt ii=0; ii<count; ii++)
		{
		if (aControl==ComponentControl(ii))
			return(ii);
		}
	return(KErrNotFound);
	}

EXPORT_C void CCoeControl::SetControlContext(MCoeControlContext* aContext)
	{
	iContext=aContext;
	}

EXPORT_C void CCoeControl::CopyControlContextFrom(const CCoeControl* aControl)
	{
	iContext=aControl->iContext;
	}

EXPORT_C CCoeControl* CCoeControl::GrabbingComponent() const
	{
	const TInt count=CountComponentControls();
	for (TInt ii=0; ii<count; ii++)
		{
		CCoeControl* ctrl=ComponentControl(ii);
		if (ctrl->IsGrabbed())
			return(ctrl);
		}
	return(NULL);
	}

EXPORT_C void CCoeControl::OverrideColorL(TInt aLogicalColor,TRgb aColor)
	{
	CCoeControlExtension* extension=iExt.Extension();
	if (!extension)
		{
		extension=CCoeControlExtension::NewL();
		iExt.SetExtension(extension);
		}
	extension->OverrideColorL(aLogicalColor,aColor);
	}

EXPORT_C TBool CCoeControl::GetColor(TInt aLogicalColor,TRgb& aColor) const
	{
	CCoeControlExtension* extension=iExt.Extension();
	if (extension)
		return extension->GetColor(aLogicalColor,aColor);
	return EFalse;
	}

EXPORT_C void CCoeControl::Reserved_1()
	{
	}

EXPORT_C void CCoeControl::Reserved_2()
	{
	}

inline TInt CCoeControl::Flags() const
	{return iExt.Flags();}
inline TInt& CCoeControl::Flags()
	{return iExt.Flags();}
