--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/tredir/redirector.cpp Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,374 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Symbian test code
+*/
+
+#include "redirector.h"
+#include <fbs.h>
+#include <bitdev.h>
+#include <bitstd.h>
+#include <gdi.h>
+#ifdef __WINS__
+#include "../debuglog/osbwin.h"
+#endif
+
+const TInt KDefaultScreen = 0;
+
+const TUint8 KCmdQuery = 0;
+const TUint8 KCmdSetGcFront = 1;
+const TUint8 KCmdSetGcBack = 2;
+const TUint8 KCmdResetGcFront = 3;
+const TUint8 KCmdResetGcBack = 4;
+const TUint8 KCmdSetBackObject = 5;
+const TUint8 KCmdResetBackObject= 6;
+
+const TUint8 KRedirectorInfoSig = 0x7e;
+
+NONSHARABLE_STRUCT(TRedirectorInfo)
+ {
+ TUint8 iSignature;
+ TAny* iFrontBufferInterface;
+ TAny* iBackBufferInterface;
+ TAny* iScreenConfigInterface;
+ TInt iScreenBitmapHandle;
+ TInt iFlickerBitmapHandle;
+ TInt iUpdateCounter;
+ };
+
+NONSHARABLE_STRUCT(TWsBackBuffer): public MWsBackBuffer
+ {
+public:
+ TWsBackBuffer(CFbsBitmap* aBit,CFbsBitGc* aGc): iBit(aBit), iGc(aGc)
+ {}
+ virtual CFbsBitmap* GetBitmap()
+ {return iBit;}
+ virtual CFbsBitGc* GetBitGc()
+ {return iGc;}
+ virtual TInt SetBitGc(CFbsBitGc*)
+ {return KErrNotSupported;}
+ virtual TInt RedirectTo(MWsBackBuffer*)
+ {return KErrNotSupported;}
+ virtual void SetObserver(MWsFlickerFreeBufferObserver* /*aObserver*/)
+ {ASSERT(0);}
+ virtual MWsFlickerFreeBufferObserver* Observer()
+ {
+ ASSERT(0);
+ return NULL;
+ }
+ virtual CFbsBitGc* GetBitGcCurrent()
+ {
+ ASSERT(0);
+ return NULL;
+ }
+
+private:
+ CFbsBitmap* iBit;
+ CFbsBitGc* iGc;
+ };
+
+//
+CWsGcRedirector* CWsGcRedirector::NewL()
+ {
+ return new(ELeave) CWsGcRedirector;
+ }
+
+CWsGcRedirector::~CWsGcRedirector()
+ {
+#ifdef __WINS__
+ delete iFrontWin;
+ delete iBackWin;
+ delete iUpdateDebugWinsTimer;
+#endif
+
+ if (iFrontBuf)
+ iFrontBuf->SetBitGc(NULL);
+ if (iBackBuf)
+ iBackBuf->SetBitGc(NULL);
+
+ delete iFrontGc;
+ delete iFrontDev;
+ delete iFrontBit;
+ delete iBackGc;
+ delete iBackDev;
+ delete iBackBit;
+ delete iBadGc;
+ delete iBackObj;
+ }
+
+void CWsGcRedirector::ConstructL(MWsGraphicDrawerEnvironment& aEnv, const TGraphicDrawerId& aId, MWsClient& aOwner, const TDesC8& aData)
+ {
+ BaseConstructL(aEnv, aId, aOwner);
+
+#ifdef __WINS__
+ if (aData.Length()>1)
+ iDisableWin = aData[1]==1;
+#endif
+ iScreenId = KDefaultScreen;
+ if (aData.Length()>0)
+ iScreenId = aData[0];
+ MWsScreen* scr = aEnv.Screen(iScreenId);
+ User::LeaveIfNull(scr);
+
+ MWsScreenConfig* cfg = scr->ObjectInterface<MWsScreenConfig>();
+ User::LeaveIfNull(cfg);
+
+ iFrontBuf = scr->ObjectInterface<MWsFrontBuffer>();
+ User::LeaveIfNull(iFrontBuf);
+ iBackBuf = scr->ObjectInterface<MWsBackBuffer>();
+
+ iFrontBit = new(ELeave) CFbsBitmap;
+ iDefaultSize=cfg->SizeInPixels();
+ User::LeaveIfError(iFrontBit->Create(iDefaultSize,EColor64K));
+ iFrontDev = CFbsBitmapDevice::NewL(iFrontBit);
+ User::LeaveIfNull(iFrontDev);
+ User::LeaveIfError(iFrontDev->CreateContext(iFrontGc));
+
+ User::LeaveIfError(iFrontDev->CreateContext(iBadGc));
+ iBadGc->ChangeDevice(NULL);
+
+#ifdef __WINS__
+ if (!iDisableWin)
+ {
+ iUpdateDebugWinsTimer = CPeriodic::NewL(0);
+ iUpdateDebugWinsTimer->Start(0, 300 * 1000, TCallBack(UpdateDebugWindowsCallback, this));
+
+ _LIT(KRedFront, "RedFront");
+ iFrontWin = CDebugOsbWin::NewL(KRedFront, iFrontBit->SizeInPixels());
+ }
+#endif
+
+ if (iBackBuf)
+ {
+ CFbsBitmap* bit = iBackBuf->GetBitmap();
+ User::LeaveIfNull(bit);
+ iBackBit = new(ELeave) CFbsBitmap;
+ User::LeaveIfError(iBackBit->Create(bit->SizeInPixels(),EColor64K));
+ iBackDev = CFbsBitmapDevice::NewL(iBackBit);
+ User::LeaveIfNull(iBackDev);
+ User::LeaveIfError(iBackDev->CreateContext(iBackGc));
+
+ iBackObj = new(ELeave) TWsBackBuffer(iBackBit,iBackGc);
+#ifdef __WINS__
+ if (!iDisableWin)
+ {
+ _LIT(KRedBack, "RedBack");
+ iBackWin = CDebugOsbWin::NewL(KRedBack, iBackBit->SizeInPixels());
+ }
+#endif
+ }
+
+ // compile check, non-const interface access
+ MWsGraphicDrawerEnvironment& ee = Env();
+ MWsScreen* ss = ee.Screen(iScreenId);
+ MWsScreenConfig* cc = ss->ObjectInterface<MWsScreenConfig>();
+ }
+
+void CWsGcRedirector::HandleMessage(const TDesC8& aData)
+ {
+ // wserv already check data size, and won't invoke this handler if it's empty
+ TBuf8<1> ack;
+ ack.Append(KRedirectorInfoSig);
+
+ switch (aData[0])
+ {
+ case KCmdQuery:
+ SendInfo();
+ break;
+
+ case KCmdSetGcFront:
+ Env().RegisterEventHandler(this,this,TWservCrEvent::EScreenUpdated|TWservCrEvent::EScreenOrientationChanged|TWservCrEvent::EDeviceOrientationChanged);
+
+ // -test bad gc
+ __ASSERT_ALWAYS(iFrontBuf->SetBitGc(iBadGc)==KErrArgument, User::Invariant());
+ // -test bad gc
+ __ASSERT_ALWAYS(iFrontBuf->SetBitGc(iBadGc,ETrue)==KErrArgument, User::Invariant());
+ // +test
+ __ASSERT_ALWAYS(iFrontBuf->SetBitGc(iFrontGc,EFalse)==KErrNone, User::Invariant());
+ // -test duplicate calls
+ __ASSERT_ALWAYS(iFrontBuf->SetBitGc(iFrontGc)==KErrAlreadyExists, User::Invariant());
+
+ SendMessage(ack);
+ break;
+
+ case KCmdSetGcBack:
+ if (iBackBuf)
+ {
+ // -test bad gc
+ __ASSERT_ALWAYS(iBackBuf->SetBitGc(iBadGc)==KErrArgument, User::Invariant());
+ // +test
+ __ASSERT_ALWAYS(iBackBuf->SetBitGc(iBackGc)==KErrNone, User::Invariant());
+ // -test duplicate calls
+ __ASSERT_ALWAYS(iBackBuf->SetBitGc(iBackGc)==KErrAlreadyExists, User::Invariant());
+ // -test double redirection
+ __ASSERT_ALWAYS(iBackBuf->RedirectTo(iBackObj)==KErrInUse, User::Invariant());
+ }
+ SendMessage(ack);
+ break;
+
+ case KCmdResetGcFront:
+ Env().UnregisterEventHandler(this);
+ iUpdateCounter = 0;
+
+ __ASSERT_ALWAYS(iFrontBuf->SetBitGc(NULL,EFalse)==KErrNone, User::Invariant());
+ // -test duplicate calls
+ __ASSERT_ALWAYS(iFrontBuf->SetBitGc(NULL,EFalse)==KErrNone, User::Invariant());
+ SendMessage(ack);
+ break;
+
+ case KCmdResetGcBack:
+ if (iBackBuf)
+ {
+ // +test
+ __ASSERT_ALWAYS(iBackBuf->SetBitGc(NULL)==KErrNone, User::Invariant());
+ // -test duplicate calls
+ __ASSERT_ALWAYS(iBackBuf->SetBitGc(NULL)==KErrNone, User::Invariant());
+ }
+ SendMessage(ack);
+ break;
+
+ case KCmdSetBackObject:
+ if (iBackBuf)
+ {
+ TWsBackBuffer badObj1(NULL,iBackGc);
+ // -test bad obj (null bitmap)
+ __ASSERT_ALWAYS(iBackBuf->RedirectTo(&badObj1)==KErrArgument, User::Invariant());
+ // -test bad obj (null gc)
+ TWsBackBuffer badObj2(iBackBit,NULL);
+ __ASSERT_ALWAYS(iBackBuf->RedirectTo(&badObj2)==KErrArgument, User::Invariant());
+ // -test bad obj (null device)
+ TWsBackBuffer badObj3(iBackBit,iBadGc);
+ __ASSERT_ALWAYS(iBackBuf->RedirectTo(&badObj3)==KErrArgument, User::Invariant());
+ // +test
+ __ASSERT_ALWAYS(iBackBuf->RedirectTo(iBackObj)==KErrNone, User::Invariant());
+ // -test duplicate calls
+ __ASSERT_ALWAYS(iBackBuf->RedirectTo(iBackObj)==KErrAlreadyExists, User::Invariant());
+ // -test double redirection
+ __ASSERT_ALWAYS(iBackBuf->SetBitGc(iBackGc)==KErrInUse, User::Invariant());
+ }
+ SendMessage(ack);
+ break;
+
+ case KCmdResetBackObject:
+ if (iBackBuf)
+ {
+ // +test
+ __ASSERT_ALWAYS(iBackBuf->RedirectTo(NULL)==KErrNone, User::Invariant());
+ // -test duplicate calls
+ __ASSERT_ALWAYS(iBackBuf->RedirectTo(NULL)==KErrNone, User::Invariant());
+ }
+ SendMessage(ack);
+ break;
+ }
+ }
+
+void CWsGcRedirector::DoDraw(MWsGc& aGc, const TRect& aRect, const TDesC8& aData) const
+ {
+ aGc.PushBitGcSettings();
+ CFbsBitGc& bc = aGc.BitGc();
+ bc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ bc.SetBrushColor(TRgb(255,0,0,128));
+ bc.DrawRect(aRect);
+ TGraphicDrawerId id;
+ id.iId = 0x10281fb6;
+ id.iIsUid = ETrue;
+ const CWsGraphicDrawer* listener = Env().ResolveGraphic(id);
+ if (listener)
+ listener->Draw(aGc, aRect, aData);
+ aGc.PopBitGcSettings();
+
+ // compile check, const interface access
+ const MWsGraphicDrawerEnvironment& env = Env(); // Env() const
+ const MWsScreen* scr = env.Screen(iScreenId); // Screen(TInt) const
+ const MWsScreenConfig* cfg = scr->ObjectInterface<MWsScreenConfig>(); // ObjectInterface() const
+ }
+
+void CWsGcRedirector::SendInfo()
+ {
+ TPckgBuf<TRedirectorInfo> buf;
+ MWsScreen* scr = Env().Screen(iScreenId);
+ if (scr)
+ {
+ buf().iSignature = KRedirectorInfoSig;
+ buf().iFrontBufferInterface = scr->ObjectInterface<MWsFrontBuffer>();
+ buf().iBackBufferInterface = scr->ObjectInterface<MWsBackBuffer>();
+ buf().iScreenConfigInterface = scr->ObjectInterface<MWsScreenConfig>();
+ buf().iScreenBitmapHandle = iFrontBit->Handle();
+ buf().iFlickerBitmapHandle = iBackBit? iBackBit->Handle() : 0;
+ buf().iUpdateCounter = iUpdateCounter;
+ }
+ TInt err = SendMessage(buf);
+ __ASSERT_ALWAYS(err>=KErrNone, User::Invariant());
+ }
+
+void CWsGcRedirector::DoHandleEvent(const TWservCrEvent& aEvent)
+ {
+ if (aEvent.ScreenNumber()==iScreenId)
+ {
+ switch(aEvent.Type())
+ {
+ case TWservCrEvent::EScreenUpdated:
+ ++iUpdateCounter;
+ break;
+ case TWservCrEvent::EDeviceOrientationChanged:
+ case TWservCrEvent::EScreenOrientationChanged:
+ {
+ CFbsBitGc::TGraphicsOrientation orientation=aEvent.Orientation();
+ TSize bmpSize;
+ if (orientation==CFbsBitGc::EGraphicsOrientationNormal || orientation==CFbsBitGc::EGraphicsOrientationRotated180)
+ bmpSize=iDefaultSize;
+ else
+ bmpSize.SetSize(iDefaultSize.iHeight,iDefaultSize.iWidth);
+ const TSize fBufSize(iFrontBit->SizeInPixels());
+ if (fBufSize!=bmpSize)
+ {
+ __ASSERT_DEBUG(fBufSize.iWidth==bmpSize.iHeight && fBufSize.iHeight==bmpSize.iWidth, User::Invariant());
+ iFrontDev->SwapWidthAndHeight();
+ iFrontGc->Activate(iFrontDev);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+#ifdef __WINS__
+TInt CWsGcRedirector::UpdateDebugWindowsCallback(TAny* aSelf)
+ {
+ CWsGcRedirector* self = static_cast<CWsGcRedirector*>(aSelf);
+ if(!self)
+ return KErrArgument;
+
+ if(self->iFrontWin && self->iFrontBit)
+ {
+ CFbsBitmap* bitmap = self->iFrontBit;
+ bitmap->LockHeap();
+ self->iFrontWin->Refresh(bitmap->SizeInPixels(), bitmap->DisplayMode(), bitmap->DataAddress());
+ bitmap->UnlockHeap();
+ }
+
+ if(self->iBackWin && self->iBackBit)
+ {
+ CFbsBitmap* bitmap = self->iBackBit;
+ bitmap->LockHeap();
+ self->iBackWin->Refresh(bitmap->SizeInPixels(), bitmap->DisplayMode(), bitmap->DataAddress());
+ bitmap->UnlockHeap();
+ }
+ return KErrNone;
+ }
+#endif