windowing/windowserver/tredir/redirector.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @test
       
    19  @internalComponent - Internal Symbian test code
       
    20 */
       
    21 
       
    22 #include "redirector.h"
       
    23 #include <fbs.h>
       
    24 #include <bitdev.h>
       
    25 #include <bitstd.h>
       
    26 #include <gdi.h>
       
    27 #ifdef __WINS__
       
    28 #include "../debuglog/osbwin.h"
       
    29 #endif
       
    30 
       
    31 const TInt KDefaultScreen = 0;
       
    32 
       
    33 const TUint8 KCmdQuery			= 0;
       
    34 const TUint8 KCmdSetGcFront 	= 1;
       
    35 const TUint8 KCmdSetGcBack  	= 2;
       
    36 const TUint8 KCmdResetGcFront	= 3;
       
    37 const TUint8 KCmdResetGcBack 	= 4;
       
    38 const TUint8 KCmdSetBackObject 	= 5;
       
    39 const TUint8 KCmdResetBackObject= 6;
       
    40 
       
    41 const TUint8 KRedirectorInfoSig = 0x7e;
       
    42 
       
    43 NONSHARABLE_STRUCT(TRedirectorInfo)
       
    44 	{
       
    45 	TUint8 iSignature;
       
    46 	TAny* iFrontBufferInterface;
       
    47 	TAny* iBackBufferInterface;
       
    48 	TAny* iScreenConfigInterface;
       
    49 	TInt iScreenBitmapHandle;
       
    50 	TInt iFlickerBitmapHandle; 
       
    51 	TInt iUpdateCounter;
       
    52 	};
       
    53 
       
    54 NONSHARABLE_STRUCT(TWsBackBuffer): public MWsBackBuffer
       
    55 	{
       
    56 public:
       
    57 	TWsBackBuffer(CFbsBitmap* aBit,CFbsBitGc* aGc): iBit(aBit), iGc(aGc)
       
    58 		{}
       
    59 	virtual CFbsBitmap* GetBitmap() 
       
    60 		{return iBit;}
       
    61 	virtual CFbsBitGc* GetBitGc() 
       
    62 		{return iGc;}
       
    63 	virtual TInt SetBitGc(CFbsBitGc*)
       
    64 		{return KErrNotSupported;}
       
    65 	virtual TInt RedirectTo(MWsBackBuffer*)
       
    66 		{return KErrNotSupported;}
       
    67 	virtual void SetObserver(MWsFlickerFreeBufferObserver* /*aObserver*/)
       
    68 		{ASSERT(0);}
       
    69 	virtual MWsFlickerFreeBufferObserver* Observer()
       
    70 		{
       
    71 		 ASSERT(0);
       
    72 		 return NULL;
       
    73 		}
       
    74 	virtual CFbsBitGc* GetBitGcCurrent()
       
    75 		{
       
    76 		ASSERT(0);
       
    77 		return NULL;
       
    78 		}
       
    79 
       
    80 private:
       
    81 	CFbsBitmap* iBit;
       
    82 	CFbsBitGc* iGc;	
       
    83 	};
       
    84 
       
    85 //
       
    86 CWsGcRedirector* CWsGcRedirector::NewL()
       
    87 	{
       
    88 	return new(ELeave) CWsGcRedirector;	
       
    89 	}
       
    90 	
       
    91 CWsGcRedirector::~CWsGcRedirector()
       
    92 	{
       
    93 #ifdef __WINS__
       
    94 	delete iFrontWin;
       
    95 	delete iBackWin;
       
    96 	delete iUpdateDebugWinsTimer;
       
    97 #endif
       
    98 
       
    99 	if (iFrontBuf)
       
   100 		iFrontBuf->SetBitGc(NULL);
       
   101 	if (iBackBuf)
       
   102 		iBackBuf->SetBitGc(NULL);
       
   103 	
       
   104 	delete iFrontGc;
       
   105 	delete iFrontDev;
       
   106 	delete iFrontBit;
       
   107 	delete iBackGc;
       
   108 	delete iBackDev;
       
   109 	delete iBackBit;
       
   110 	delete iBadGc;
       
   111 	delete iBackObj;
       
   112 	}
       
   113 	
       
   114 void CWsGcRedirector::ConstructL(MWsGraphicDrawerEnvironment& aEnv, const TGraphicDrawerId& aId, MWsClient& aOwner, const TDesC8& aData)
       
   115 	{
       
   116 	BaseConstructL(aEnv, aId, aOwner);
       
   117 
       
   118 #ifdef __WINS__
       
   119 	if (aData.Length()>1)
       
   120 		iDisableWin = aData[1]==1;
       
   121 #endif
       
   122 	iScreenId = KDefaultScreen;
       
   123 	if (aData.Length()>0)
       
   124 		iScreenId = aData[0];
       
   125 	MWsScreen* scr = aEnv.Screen(iScreenId);
       
   126 	User::LeaveIfNull(scr);
       
   127 
       
   128 	MWsScreenConfig* cfg = scr->ObjectInterface<MWsScreenConfig>();
       
   129 	User::LeaveIfNull(cfg);
       
   130 
       
   131 	iFrontBuf = scr->ObjectInterface<MWsFrontBuffer>();
       
   132 	User::LeaveIfNull(iFrontBuf);
       
   133 	iBackBuf = scr->ObjectInterface<MWsBackBuffer>();
       
   134 	
       
   135 	iFrontBit = new(ELeave) CFbsBitmap;
       
   136 	iDefaultSize=cfg->SizeInPixels();
       
   137 	User::LeaveIfError(iFrontBit->Create(iDefaultSize,EColor64K));
       
   138 	iFrontDev = CFbsBitmapDevice::NewL(iFrontBit);
       
   139 	User::LeaveIfNull(iFrontDev);
       
   140 	User::LeaveIfError(iFrontDev->CreateContext(iFrontGc));
       
   141 	
       
   142 	User::LeaveIfError(iFrontDev->CreateContext(iBadGc));
       
   143 	iBadGc->ChangeDevice(NULL);
       
   144 
       
   145 #ifdef __WINS__
       
   146 	if (!iDisableWin)
       
   147 		{
       
   148 		iUpdateDebugWinsTimer = CPeriodic::NewL(0);
       
   149 		iUpdateDebugWinsTimer->Start(0, 300 * 1000, TCallBack(UpdateDebugWindowsCallback, this));
       
   150 
       
   151 		_LIT(KRedFront, "RedFront");
       
   152 		iFrontWin = CDebugOsbWin::NewL(KRedFront, iFrontBit->SizeInPixels());
       
   153 		}
       
   154 #endif	
       
   155 
       
   156 	if (iBackBuf)
       
   157 		{
       
   158 		CFbsBitmap* bit = iBackBuf->GetBitmap();
       
   159 		User::LeaveIfNull(bit);
       
   160 		iBackBit = new(ELeave) CFbsBitmap;
       
   161 		User::LeaveIfError(iBackBit->Create(bit->SizeInPixels(),EColor64K));
       
   162 		iBackDev = CFbsBitmapDevice::NewL(iBackBit);
       
   163 		User::LeaveIfNull(iBackDev);
       
   164 		User::LeaveIfError(iBackDev->CreateContext(iBackGc));
       
   165 		
       
   166 		iBackObj = new(ELeave) TWsBackBuffer(iBackBit,iBackGc);
       
   167 #ifdef __WINS__		
       
   168 		if (!iDisableWin)
       
   169 			{
       
   170 			_LIT(KRedBack, "RedBack");
       
   171 			iBackWin = CDebugOsbWin::NewL(KRedBack, iBackBit->SizeInPixels());
       
   172 			}
       
   173 #endif		
       
   174 		}
       
   175 		
       
   176 	// compile check, non-const interface access
       
   177 	MWsGraphicDrawerEnvironment& ee = Env();
       
   178 	MWsScreen* ss = ee.Screen(iScreenId);
       
   179 	MWsScreenConfig* cc = ss->ObjectInterface<MWsScreenConfig>();
       
   180 	}
       
   181 
       
   182 void CWsGcRedirector::HandleMessage(const TDesC8& aData)
       
   183 	{
       
   184 	// wserv already check data size, and won't invoke this handler if it's empty
       
   185 	TBuf8<1> ack;
       
   186 	ack.Append(KRedirectorInfoSig);
       
   187 	
       
   188 	switch (aData[0])
       
   189 		{
       
   190 		case KCmdQuery:
       
   191 		SendInfo();
       
   192 		break;
       
   193 		
       
   194 		case KCmdSetGcFront:
       
   195 		Env().RegisterEventHandler(this,this,TWservCrEvent::EScreenUpdated|TWservCrEvent::EScreenOrientationChanged|TWservCrEvent::EDeviceOrientationChanged);
       
   196 
       
   197 		// -test bad gc
       
   198 		__ASSERT_ALWAYS(iFrontBuf->SetBitGc(iBadGc)==KErrArgument, User::Invariant());	
       
   199 		// -test bad gc
       
   200 		__ASSERT_ALWAYS(iFrontBuf->SetBitGc(iBadGc,ETrue)==KErrArgument, User::Invariant());
       
   201 		// +test
       
   202 		__ASSERT_ALWAYS(iFrontBuf->SetBitGc(iFrontGc,EFalse)==KErrNone, User::Invariant());
       
   203 		// -test duplicate calls
       
   204 		__ASSERT_ALWAYS(iFrontBuf->SetBitGc(iFrontGc)==KErrAlreadyExists, User::Invariant());
       
   205 		
       
   206 		SendMessage(ack);
       
   207 		break;
       
   208 		
       
   209 		case KCmdSetGcBack:
       
   210 		if (iBackBuf)
       
   211 			{
       
   212 			// -test bad gc
       
   213 			__ASSERT_ALWAYS(iBackBuf->SetBitGc(iBadGc)==KErrArgument, User::Invariant());
       
   214 			// +test
       
   215 			__ASSERT_ALWAYS(iBackBuf->SetBitGc(iBackGc)==KErrNone, User::Invariant());
       
   216 			// -test duplicate calls
       
   217 			__ASSERT_ALWAYS(iBackBuf->SetBitGc(iBackGc)==KErrAlreadyExists, User::Invariant());
       
   218 			// -test double redirection
       
   219 			__ASSERT_ALWAYS(iBackBuf->RedirectTo(iBackObj)==KErrInUse, User::Invariant());
       
   220 			}
       
   221 		SendMessage(ack);
       
   222 		break;
       
   223 		
       
   224 		case KCmdResetGcFront:
       
   225 		Env().UnregisterEventHandler(this);
       
   226 		iUpdateCounter = 0;
       
   227 
       
   228 		__ASSERT_ALWAYS(iFrontBuf->SetBitGc(NULL,EFalse)==KErrNone, User::Invariant());
       
   229 		// -test duplicate calls
       
   230 		__ASSERT_ALWAYS(iFrontBuf->SetBitGc(NULL,EFalse)==KErrNone, User::Invariant());
       
   231 		SendMessage(ack);
       
   232 		break;
       
   233 		
       
   234 		case KCmdResetGcBack:
       
   235 		if (iBackBuf)
       
   236 			{
       
   237 			// +test
       
   238 			__ASSERT_ALWAYS(iBackBuf->SetBitGc(NULL)==KErrNone, User::Invariant());
       
   239 			// -test duplicate calls
       
   240 			__ASSERT_ALWAYS(iBackBuf->SetBitGc(NULL)==KErrNone, User::Invariant());
       
   241 			}
       
   242 		SendMessage(ack);
       
   243 		break;
       
   244 
       
   245 		case KCmdSetBackObject:
       
   246 		if (iBackBuf)
       
   247 			{
       
   248 			TWsBackBuffer badObj1(NULL,iBackGc);
       
   249 			// -test bad obj (null bitmap)
       
   250 			__ASSERT_ALWAYS(iBackBuf->RedirectTo(&badObj1)==KErrArgument, User::Invariant());
       
   251 			// -test bad obj (null gc)
       
   252 			TWsBackBuffer badObj2(iBackBit,NULL);
       
   253 			__ASSERT_ALWAYS(iBackBuf->RedirectTo(&badObj2)==KErrArgument, User::Invariant());			
       
   254 			// -test bad obj (null device)
       
   255 			TWsBackBuffer badObj3(iBackBit,iBadGc);			
       
   256 			__ASSERT_ALWAYS(iBackBuf->RedirectTo(&badObj3)==KErrArgument, User::Invariant());
       
   257 			// +test
       
   258 			__ASSERT_ALWAYS(iBackBuf->RedirectTo(iBackObj)==KErrNone, User::Invariant());
       
   259 			// -test duplicate calls
       
   260 			__ASSERT_ALWAYS(iBackBuf->RedirectTo(iBackObj)==KErrAlreadyExists, User::Invariant());
       
   261 			// -test double redirection
       
   262 			__ASSERT_ALWAYS(iBackBuf->SetBitGc(iBackGc)==KErrInUse, User::Invariant());
       
   263 			}
       
   264 		SendMessage(ack);
       
   265 		break;
       
   266 
       
   267 		case KCmdResetBackObject:
       
   268 		if (iBackBuf)
       
   269 			{
       
   270 			// +test
       
   271 			__ASSERT_ALWAYS(iBackBuf->RedirectTo(NULL)==KErrNone, User::Invariant());
       
   272 			// -test duplicate calls
       
   273 			__ASSERT_ALWAYS(iBackBuf->RedirectTo(NULL)==KErrNone, User::Invariant());
       
   274 			}
       
   275 		SendMessage(ack);
       
   276 		break;
       
   277 		}
       
   278 	}
       
   279 	
       
   280 void CWsGcRedirector::DoDraw(MWsGc& aGc, const TRect& aRect, const TDesC8& aData) const
       
   281 	{
       
   282 	aGc.PushBitGcSettings();
       
   283 	CFbsBitGc& bc = aGc.BitGc();	
       
   284 	bc.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   285 	bc.SetBrushColor(TRgb(255,0,0,128));
       
   286 	bc.DrawRect(aRect);
       
   287 	TGraphicDrawerId id;
       
   288 	id.iId = 0x10281fb6;
       
   289 	id.iIsUid = ETrue;
       
   290 	const CWsGraphicDrawer* listener = Env().ResolveGraphic(id);
       
   291 	if (listener)
       
   292 		listener->Draw(aGc, aRect, aData);
       
   293 	aGc.PopBitGcSettings();
       
   294 	
       
   295 	// compile check, const interface access
       
   296 	const MWsGraphicDrawerEnvironment& env = Env(); // Env() const
       
   297 	const MWsScreen* scr = env.Screen(iScreenId); // Screen(TInt) const
       
   298 	const MWsScreenConfig* cfg = scr->ObjectInterface<MWsScreenConfig>(); // ObjectInterface() const
       
   299 	}
       
   300 
       
   301 void CWsGcRedirector::SendInfo()
       
   302 	{
       
   303 	TPckgBuf<TRedirectorInfo> buf;
       
   304 	MWsScreen* scr = Env().Screen(iScreenId);
       
   305 	if (scr)
       
   306 		{
       
   307 		buf().iSignature = KRedirectorInfoSig;
       
   308 		buf().iFrontBufferInterface = scr->ObjectInterface<MWsFrontBuffer>();
       
   309 		buf().iBackBufferInterface = scr->ObjectInterface<MWsBackBuffer>();
       
   310 		buf().iScreenConfigInterface = scr->ObjectInterface<MWsScreenConfig>();
       
   311 		buf().iScreenBitmapHandle = iFrontBit->Handle();
       
   312 		buf().iFlickerBitmapHandle = iBackBit? iBackBit->Handle() : 0;
       
   313 		buf().iUpdateCounter = iUpdateCounter;
       
   314 		}
       
   315 	TInt err = SendMessage(buf);
       
   316 	__ASSERT_ALWAYS(err>=KErrNone, User::Invariant());
       
   317 	}
       
   318 
       
   319 void CWsGcRedirector::DoHandleEvent(const TWservCrEvent& aEvent)
       
   320 	{
       
   321 	if (aEvent.ScreenNumber()==iScreenId)
       
   322 		{
       
   323 		switch(aEvent.Type())
       
   324 			{
       
   325 		case TWservCrEvent::EScreenUpdated:
       
   326 			++iUpdateCounter;
       
   327 			break;
       
   328 		case TWservCrEvent::EDeviceOrientationChanged:
       
   329 		case TWservCrEvent::EScreenOrientationChanged:
       
   330 			{
       
   331 			CFbsBitGc::TGraphicsOrientation orientation=aEvent.Orientation();
       
   332 			TSize bmpSize;
       
   333 			if (orientation==CFbsBitGc::EGraphicsOrientationNormal || orientation==CFbsBitGc::EGraphicsOrientationRotated180)
       
   334 				bmpSize=iDefaultSize;
       
   335 			else
       
   336 				bmpSize.SetSize(iDefaultSize.iHeight,iDefaultSize.iWidth);
       
   337 			const TSize fBufSize(iFrontBit->SizeInPixels());
       
   338 			if (fBufSize!=bmpSize)
       
   339 				{
       
   340 				__ASSERT_DEBUG(fBufSize.iWidth==bmpSize.iHeight && fBufSize.iHeight==bmpSize.iWidth, User::Invariant());
       
   341 				iFrontDev->SwapWidthAndHeight();
       
   342 				iFrontGc->Activate(iFrontDev);
       
   343 				}
       
   344 			}
       
   345 			break;
       
   346 			}
       
   347 		}
       
   348 	}
       
   349 
       
   350 #ifdef __WINS__
       
   351 TInt CWsGcRedirector::UpdateDebugWindowsCallback(TAny* aSelf)
       
   352 	{
       
   353 	CWsGcRedirector* self = static_cast<CWsGcRedirector*>(aSelf);
       
   354 	if(!self)
       
   355 		return KErrArgument;
       
   356 
       
   357 	if(self->iFrontWin && self->iFrontBit)
       
   358 		{
       
   359 		CFbsBitmap* bitmap = self->iFrontBit;
       
   360 		bitmap->LockHeap();
       
   361 		self->iFrontWin->Refresh(bitmap->SizeInPixels(), bitmap->DisplayMode(), bitmap->DataAddress());
       
   362 		bitmap->UnlockHeap();
       
   363 		}
       
   364 
       
   365 	if(self->iBackWin && self->iBackBit)
       
   366 		{
       
   367 		CFbsBitmap* bitmap = self->iBackBit;
       
   368 		bitmap->LockHeap();
       
   369 		self->iBackWin->Refresh(bitmap->SizeInPixels(), bitmap->DisplayMode(), bitmap->DataAddress());
       
   370 		bitmap->UnlockHeap();
       
   371 		}
       
   372 	return KErrNone;
       
   373 	}
       
   374 #endif