os/graphics/windowing/windowserver/test/tdynamicres/src/t_wsdynamicreswinbase.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/windowing/windowserver/test/tdynamicres/src/t_wsdynamicreswinbase.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,982 @@
1.4 +// Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +/**
1.20 + @file
1.21 +*/
1.22 +
1.23 +
1.24 +#include <e32std.h>
1.25 +#include <e32math.h>
1.26 +#include <w32std.h>
1.27 +#include <w32debug.h>
1.28 +#include "teflogextensions.h"
1.29 +#include "t_wsdynamicreswinbase.h"
1.30 +#include "globalsettings.h"
1.31 +#include <bitdraw.h>
1.32 +#include <bitdrawinterfaceid.h>
1.33 +#include <u32hal.h>
1.34 +#include <dispchannel.h>
1.35 +#include <graphics/displaycontrol.h>
1.36 +
1.37 +#if (!defined(K_DISPLAY_CH_MAJOR_VERSION_NUMBER) && !defined(K_DISPLAY_CH_MINOR_VERSION_NUMBER))
1.38 +#define MODE_CHANGE_BASE_FUNCTIONALITY_NOT_PRESENT_IN_HEADER
1.39 +#endif
1.40 +
1.41 +_LIT(KMonospaceTestFontTypefaceName,"Arial");
1.42 +const TInt KMaxFontSize = 150;
1.43 +TBool CWsDynamicResWinBase::iTransparencyEnabled=EFalse;
1.44 +
1.45 +CWsDynamicResWinBase::CWsDynamicResWinBase():
1.46 + iDoTearDown(EFalse),
1.47 + iSession(TGlobalSettings::Instance().iScreen)
1.48 +{
1.49 +}
1.50 +
1.51 +void CWsDynamicResWinBase::SetupL()
1.52 + {
1.53 + SetupL(EFalse);
1.54 + }
1.55 +CActiveScheduler CWsDynamicResWinBase::iScheduler;
1.56 +
1.57 +void CWsDynamicResWinBase::SetupL(TBool aUseOtherScreenForInfo)
1.58 + {
1.59 + if (CActiveScheduler::Current()!=&iScheduler)
1.60 + {
1.61 + new (&iScheduler) CActiveScheduler;
1.62 + CActiveScheduler::Install(&iScheduler);
1.63 + }
1.64 + iDoTearDown=ETrue;
1.65 + iRed.SetInternal(0xFFFF0000);
1.66 + iGreen.SetInternal(0xFF00FF00);
1.67 + iBlue.SetInternal(0xFF0000FF);
1.68 + iCyan.SetInternal(0xFF00FFFF);
1.69 + iMagenta.SetInternal(0xFFFF00FF);
1.70 + iYellow.SetInternal(0xFFFFFF00);
1.71 + iWhite.SetInternal(0xFFFFFFFF);
1.72 + iLastGceHoleColor.SetInternal(0);
1.73 + TITLE_BACKGROUND=iCyan;
1.74 + COMPARE_BACKGROUND=iBlue;
1.75 +
1.76 + ASSERT_EQUALS_X(iSession.Connect(), KErrNone);
1.77 +
1.78 + {//Stolen from TAuto CloseAllPanicWindows()
1.79 + TInt idFocus = iSession.GetFocusWindowGroup();
1.80 + TWsEvent event;
1.81 + event.SetType(EEventKey); //EEventKeyDown
1.82 + TKeyEvent *keyEvent = event.Key();
1.83 + keyEvent->iCode = EKeyEscape;
1.84 + keyEvent->iScanCode = EStdKeyEscape;
1.85 + keyEvent->iModifiers = 0;
1.86 + TInt theLimit = 50;
1.87 + while(idFocus != NULL && (theLimit-- > 0))
1.88 + {
1.89 + iSession.SendEventToAllWindowGroups(event);
1.90 + TInt idNewFocus = iSession.GetFocusWindowGroup();
1.91 + if (idNewFocus!=idFocus)
1.92 + {
1.93 + INFO_PRINTF1(_L("A window was closed [probably a panic box from the previous test]."));
1.94 + }
1.95 + idFocus=idNewFocus;
1.96 + }
1.97 + }
1.98 + TInt err = KErrNone;
1.99 +
1.100 + TRAP(err, iScreenDevice = new (ELeave) CWsScreenDevice(iSession));
1.101 + PRINT_ON_ERROR2_L(err, _L("Failed to create screen device: %d"), err);
1.102 + ASSERT_EQUALS_X(iScreenDevice->Construct(TGlobalSettings::Instance().iScreen), KErrNone);
1.103 + iDisplayMode = iScreenDevice->DisplayMode(); // Get default display mode
1.104 +
1.105 + CheckAndConnectScreen();
1.106 +
1.107 + TRAP(err, iGc = new (ELeave) CWindowGc(iScreenDevice));
1.108 + PRINT_ON_ERROR2_L(err, _L("Failed to create graphics context: %d"), err);
1.109 + ASSERT_EQUALS_X(iGc->Construct(), KErrNone);
1.110 +
1.111 + iGroup = RWindowGroup(iSession);
1.112 + ASSERT_EQUALS_X(iGroup.Construct(++iWindowHandle,iScreenDevice), KErrNone);
1.113 + iGroup.SetOrdinalPositionErr(0, KPasswordWindowGroupPriority - 1); // Added code ---- Fastpath
1.114 + iSession.Flush();
1.115 +
1.116 + if (aUseOtherScreenForInfo)
1.117 + {
1.118 + if (iSession.NumberOfScreens()>1)
1.119 + { //Create server objects for info windows to appear on alternate screen
1.120 + TInt alternateScreenNum=iSession.NumberOfScreens()-1;
1.121 + if (TGlobalSettings::Instance().iScreen==alternateScreenNum)
1.122 + { //Alternate screen is last screen, or first screen if that is being tested.
1.123 + alternateScreenNum=0;
1.124 + }
1.125 +
1.126 + TRAP(err, iInfoScreenDevice = new (ELeave) CWsScreenDevice(iSession));
1.127 + PRINT_ON_ERROR2_L(err, _L("Failed to create second screen device: %d"), err);
1.128 + ASSERT_EQUALS_X(iInfoScreenDevice->Construct(alternateScreenNum), KErrNone);
1.129 +
1.130 + TRAP(err, iInfoGc = new (ELeave) CWindowGc(iInfoScreenDevice));
1.131 + PRINT_ON_ERROR2_L(err, _L("Failed to create second graphics context: %d"), err);
1.132 + ASSERT_EQUALS_X(iInfoGc->Construct(), KErrNone);
1.133 +
1.134 + iInfoGroupInstance = RWindowGroup(iSession);
1.135 + ASSERT_EQUALS_X(iInfoGroupInstance.Construct(++iWindowHandle,iInfoScreenDevice), KErrNone);
1.136 + iInfoGroup=&iInfoGroupInstance;
1.137 + }
1.138 + else
1.139 + { //If alternate screen is not available then no text or compare windows should be created!
1.140 + iInfoScreenDevice=iScreenDevice; //it is "convenient" for the device to still be good.
1.141 + iInfoGc=NULL;
1.142 + iInfoGroup=NULL;
1.143 + }
1.144 + }
1.145 + else
1.146 + { //
1.147 + iInfoScreenDevice=iScreenDevice;
1.148 + iInfoGc=iGc;
1.149 + iInfoGroup=&iGroup;
1.150 + }
1.151 +
1.152 + if (iInfoGroup && iInfoGc)
1.153 + {
1.154 + // Add a plain background window to obscure anything else that
1.155 + // happens to be behind the test. Setting this window's display mode is also
1.156 + // used to set the screen device display mode, and hence the composition
1.157 + // mode: alpha or chroma key.
1.158 + iBackground = RBlankWindow(iSession);
1.159 + ASSERT_EQUALS_X(iBackground.Construct(*iInfoGroup, ++iWindowHandle), KErrNone);
1.160 +
1.161 + iBackground.SetOrdinalPosition(100); // Behind anything else in this group.
1.162 + iBackground.SetColor(TRgb(iWhite));
1.163 + //iBackground.SetExtent(TPoint(-1000,-1000),TSize(3000,3000));
1.164 + iBackground.Activate();
1.165 + iBackground.SetVisible(ETrue);
1.166 + }
1.167 + iSession.Flush();
1.168 +
1.169 + RWindow testTrans(iSession);
1.170 + ASSERT_EQUALS_X(testTrans.Construct(iGroup, ++iWindowHandle), KErrNone);
1.171 + iTransparencyEnabled=(testTrans.SetTransparencyFactor(iWhite)==KErrNone);
1.172 + if (iTransparencyEnabled)
1.173 + {
1.174 + TTestName testName;
1.175 + testName.Format(_L("Screen %i, depth %i: Found Trans Man"),
1.176 + TGlobalSettings::Instance().iScreen
1.177 + );
1.178 + UpdateTitleWindowL(testName,KMaxInfoLines-1);
1.179 + }
1.180 + else
1.181 + {
1.182 + TTestName testName;
1.183 + testName.Format(_L("Screen %i, depth %i: No Trans Man"),
1.184 + TGlobalSettings::Instance().iScreen
1.185 + );
1.186 + UpdateTitleWindowL(testName,KMaxInfoLines-1);
1.187 + }
1.188 + testTrans.Close();
1.189 + }
1.190 +
1.191 +
1.192 +void CWsDynamicResWinBase::CheckAndConnectScreen()
1.193 + {
1.194 + if (TGlobalSettings::Instance().iDisconnected) //set from script file to match wsini keyword SIMULATE_STARTUP_DISCONNECTED
1.195 + {
1.196 + //Verify that the display really is disconnected
1.197 + ASSERT_TRUE_X(iScreenDevice != NULL);
1.198 + MDisplayControl* interface = static_cast<MDisplayControl*>(iScreenDevice->GetInterface(MDisplayControl::ETypeId));
1.199 + ASSERT_TRUE_X(interface != NULL);
1.200 + RArray<MDisplayControl::TResolution> resolutions;
1.201 + const TInt err = interface->GetResolutions(resolutions);
1.202 + ASSERT_EQUALS_X(err, KErrDisconnected);
1.203 + resolutions.Close();
1.204 + }
1.205 +
1.206 +#ifndef MODE_CHANGE_BASE_FUNCTIONALITY_NOT_PRESENT_IN_HEADER
1.207 + //make sure display is attached to screen (only if I/F is available at compile time...)
1.208 + TInt displayState = ENormalResolution;
1.209 + UserSvr::HalFunction(EHalGroupDisplay | (TGlobalSettings::Instance().iScreen<<16), EDisplayHalSetDisplayState, &displayState, NULL);
1.210 + Pause(200);
1.211 +#endif
1.212 +
1.213 + if (TGlobalSettings::Instance().iDisconnected)
1.214 + {
1.215 + //Verify that the display now is connected
1.216 + MDisplayControl* interface = static_cast<MDisplayControl*>(iScreenDevice->GetInterface(MDisplayControl::ETypeId));
1.217 + RArray<MDisplayControl::TResolution> resolutions;
1.218 + const TInt err = interface->GetResolutions(resolutions);
1.219 + ASSERT_EQUALS_X(err, KErrNone);
1.220 + const_cast<TGlobalSettings&>(TGlobalSettings::Instance()).iDisconnected = EFalse;
1.221 + resolutions.Close();
1.222 + }
1.223 + }
1.224 +
1.225 +/**
1.226 +Common tear down code for all tests.
1.227 +
1.228 +Windows, group and session created are closed. Screen device is destroyed.
1.229 +Surfaces, manager and update session are closed.
1.230 +*/
1.231 +void CWsDynamicResWinBase::TearDownL()
1.232 + {
1.233 + iDoTearDown=EFalse;
1.234 + if (iInfoGc!=iGc)
1.235 + delete iInfoGc;
1.236 + delete iGc;
1.237 + if (iInfoScreenDevice!=iScreenDevice)
1.238 + delete iInfoScreenDevice;
1.239 + delete iScreenDevice;
1.240 +
1.241 + iGroup.Close();
1.242 + if (iInfoGroupInstance.WsHandle())
1.243 + iInfoGroupInstance.Close();
1.244 + iSession.Flush();
1.245 + iSession.Close();
1.246 + }
1.247 +/**
1.248 + * Note that this is not the ideal mechanism.
1.249 + * A derived class may thinks its TearDown is safe to do from delete, but in the class it is derived from it may not be safe
1.250 + **/
1.251 +void CWsDynamicResWinBase::TearDownFromDeleteL()
1.252 + {
1.253 + CWsDynamicResWinBase::TearDownL(); //Explicitly call the non-derived implementation.
1.254 + }
1.255 +
1.256 +CWsDynamicResWinBase::~CWsDynamicResWinBase()
1.257 +{
1.258 + if (iDoTearDown)
1.259 + TearDownFromDeleteL(); //This mechanism is not entirely clean to use.
1.260 +}
1.261 +/**
1.262 +Pause for the given number of milliseconds.
1.263 +
1.264 +@param aMilliseconds Time to wait in milliseconds.
1.265 +*/
1.266 +void CWsDynamicResWinBase::Pause(TInt aMilliseconds)
1.267 + {
1.268 + User::After(TTimeIntervalMicroSeconds32(aMilliseconds * 1000));
1.269 + }
1.270 +// This handles any non-member uses of the extended ASSERT_XXX macros
1.271 +void TefUnitFailLeaveL()
1.272 + {
1.273 +
1.274 + User::Leave(KErrTEFUnitFail);
1.275 + }
1.276 +/**
1.277 + * side-effect: log the state info just before I leave!
1.278 + * Note that this only logs intentional assertion failures.
1.279 + * Fails due to panics or throws won't log this info.
1.280 + **/
1.281 +void CWsDynamicResWinBase::TefUnitFailLeaveL()
1.282 + {
1.283 + for (TInt line=0;line<KMaxInfoLines;line++)
1.284 + if (iTestInfo[line].Length())
1.285 + Logger().LogExtra((TText8*)"Test state at fail - line",line, ESevrAll, iTestInfo[line]);
1.286 +
1.287 + User::Leave(KErrTEFUnitFail);
1.288 + }
1.289 +
1.290 +/** Creates the LHS info window, annd a middle window to display a representation of the expected result.
1.291 + * Also sets up a rectangle representing the space on the right to be used for the test
1.292 + * @param aTitle The title to display on the info window
1.293 + * @param aDetail Optional text to display on the first line under the title
1.294 +**/
1.295 +void CWsDynamicResWinBase::MakeTitleAndCompareWindowsL(TRefByValue<const TDesC16> aTitle,TRefByValue<const TDesC16> aDetail)
1.296 + {
1.297 + iTestName=aTitle;
1.298 + iTestInfo[0]=aDetail;
1.299 +
1.300 + TRect screenSize(iInfoScreenDevice->SizeInPixels());
1.301 + TPoint oneThird(screenSize.iBr.iX/3,screenSize.iBr.iY/3);
1.302 + TRect winSize(0,0,oneThird.iX,oneThird.iY);
1.303 +
1.304 + if (oneThird.iX>oneThird.iY)
1.305 + {
1.306 + oneThird.iY=0;
1.307 + winSize.iBr.iY=screenSize.iBr.iY;
1.308 + }
1.309 + else
1.310 + {
1.311 + oneThird.iX=0;
1.312 + winSize.iBr.iX=screenSize.iBr.iX;
1.313 + }
1.314 + winSize.Shrink(5,5);
1.315 +
1.316 + if (iInfoGc)
1.317 + {
1.318 + iTitle=RWindow(iSession);
1.319 + ASSERT_EQUALS_X(iTitle.Construct(*iInfoGroup, ++iWindowHandle), KErrNone);
1.320 + iTitle.SetBackgroundColor(iCyan);
1.321 + iTitle.SetExtent(winSize.iTl,winSize.Size());
1.322 + iTitle.Activate();
1.323 +
1.324 + RepaintTitleWindowL();
1.325 + iTitle.SetVisible(ETrue);
1.326 +
1.327 + winSize.Move(oneThird);
1.328 + iCompare=RWindow(iSession);
1.329 + ASSERT_EQUALS_X(iCompare.Construct(*iInfoGroup, ++iWindowHandle), KErrNone);
1.330 + iCompare.SetBackgroundColor(COMPARE_BACKGROUND);
1.331 + iCompare.SetExtent(winSize.iTl,winSize.Size());
1.332 + iCompare.Activate();
1.333 + iCompare.BeginRedraw();
1.334 + ActivateWithWipe(iInfoGc,iCompare,COMPARE_BACKGROUND);
1.335 +
1.336 + TFontSpec fspec(KMonospaceTestFontTypefaceName,KMaxFontSize);
1.337 + CFont *font=NULL;
1.338 + ASSERT_EQUALS(iScreenDevice->GetNearestFontToDesignHeightInTwips(font,fspec),KErrNone);
1.339 + iInfoGc->UseFont(font);
1.340 + iInfoGc->DrawText(_L("Simulation"),winSize.Size(),winSize.Size().iHeight-5,iGc->ECenter);
1.341 +
1.342 + iInfoGc->Deactivate();
1.343 + iCompare.EndRedraw();
1.344 + iCompare.SetVisible(ETrue);
1.345 + if (iScreenDevice!=iInfoScreenDevice)
1.346 + {
1.347 + winSize.Move(-oneThird);
1.348 + }
1.349 + else
1.350 + {
1.351 + winSize.Move(oneThird);
1.352 + }
1.353 + }
1.354 + else
1.355 + {
1.356 + winSize=iScreenDevice->SizeInPixels();
1.357 + }
1.358 +
1.359 + iTestPos=winSize;
1.360 + iTestPointCentre=winSize.Center();
1.361 + iCenteredFrontWinRect=winSize;
1.362 + iCenteredFrontWinRect.Shrink(winSize.Size().iWidth/3,winSize.Size().iHeight/3);
1.363 +
1.364 + }
1.365 +/** Makes the compare window larger by covering the test window area as well.
1.366 + * Copes with vertically aligned screens, but will be naughty if called multiple times!!!
1.367 + * @param aGoLarger If set false, resets the size back.
1.368 + **/
1.369 +void CWsDynamicResWinBase::LargerCompareWindow(TBool aGoLarger)
1.370 + {
1.371 + TPoint currPos=iCompare.AbsPosition();
1.372 + TSize currSize=iCompare.Size();
1.373 + if (currPos.iX<currPos.iY)
1.374 + {
1.375 + if (aGoLarger)
1.376 + currSize.iHeight<<=1;
1.377 + else
1.378 + currSize.iHeight>>=1;
1.379 + }
1.380 + else
1.381 + {
1.382 + if (aGoLarger)
1.383 + currSize.iWidth<<=1;
1.384 + else
1.385 + currSize.iWidth>>=1;
1.386 + }
1.387 + iCompare.SetSize(currSize);
1.388 + }
1.389 +
1.390 +
1.391 +/** Puts a line of text on the LHS window.
1.392 + * Repaints the window. The line of text will also be shown in the log if the test fails.
1.393 + * @param aDetail The text to display
1.394 + * @param aIndex The row number to display at
1.395 + **/
1.396 +void CWsDynamicResWinBase::UpdateTitleWindowL(TRefByValue<const TDesC16> aDetail,TInt aIndex)
1.397 + {
1.398 + ASSERT(aIndex>=0 && aIndex<KMaxInfoLines);
1.399 + iTestInfo[aIndex]=aDetail;
1.400 +
1.401 + RepaintTitleWindowL();
1.402 +
1.403 + }
1.404 +/** Activate the GC onto the Window.
1.405 + * In non-transparent mode it also performs a wipe background as the WServ system does not necessarily do this.
1.406 + * @param aGc The GC to associate
1.407 + * @param aWin The window to associate
1.408 + * @param aColor The color to use as the wipe. Default is transparent, which means no wipe.
1.409 + **/
1.410 +TBool CWsDynamicResWinBase::ActivateWithWipe(CWindowGc* aGc,RWindow& aWin,TRgb aColor)
1.411 + {
1.412 + aGc->Activate(aWin);
1.413 + aGc->SetBrushColor(aColor);
1.414 + aGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
1.415 + if (aColor!=TRgb(0,0) && !iTransparencyEnabled) //presume that all redraw-stored windows will draw background
1.416 + {
1.417 + aGc->Clear();
1.418 + return ETrue; //window was cleared
1.419 + }
1.420 + return EFalse;
1.421 + }
1.422 +
1.423 +CWindowGc* CWsDynamicResWinBase::GcForWindow(RWindow& aWin)
1.424 + {
1.425 + if (aWin.WsHandle()==NULL)
1.426 + return NULL; //can't activate uninitialised window.
1.427 + CWindowGc* gc=iGc;
1.428 + if (iGc!=iInfoGc)
1.429 + if (&aWin==&iCompare || &aWin==&iTitle)
1.430 + gc=iInfoGc;
1.431 + else if (iInfoGroup && aWin.WindowGroupId()==iInfoGroup->WindowGroupId())
1.432 + gc=iInfoGc;
1.433 + return gc;
1.434 + }
1.435 +/** Activates an appropriate predefined GC on the specified window and wipes the background if necessary.
1.436 + * @param aWin The window to wipe
1.437 + * @param aColor The colour to wipe with (if necessary)
1.438 + * @return the GC to use for drawing and deactivate at end. This may be NULL if the window is not "live"
1.439 + **/
1.440 +CWindowGc* CWsDynamicResWinBase::BeginActivateWithWipe(TBool aInvalidate,RWindow& aWin,TRgb aColor)
1.441 + {
1.442 + CWindowGc* gc=GcForWindow(aWin);
1.443 + iSession.Flush();
1.444 + if (gc==NULL)
1.445 + return gc; //can't activate uninitialised window.
1.446 + if (aInvalidate)
1.447 + aWin.Invalidate();
1.448 + iSession.Flush();
1.449 + aWin.BeginRedraw();
1.450 + iSession.Flush();
1.451 + ActivateWithWipe(gc,aWin,aColor);
1.452 + return gc;
1.453 + }
1.454 +
1.455 +/** Activates an appropriate predefined GC on the specified window and wipes the background if necessary.
1.456 + * @param aWin The window to wipe
1.457 + * @param aColor The colour to wipe with (if necessary)
1.458 + * @return the GC to use for drawing and deactivate at end. This may be NULL if the window is not "live"
1.459 + **/
1.460 +CWindowGc* CWsDynamicResWinBase::BeginActivateWithWipe(TBool aInvalidate,TRect aRect,RWindow& aWin,TRgb aColor)
1.461 + {
1.462 + if (aWin.WsHandle()==NULL)
1.463 + return NULL; //can't activate uninitialised window.
1.464 + if (aInvalidate)
1.465 + aWin.Invalidate(aRect);
1.466 + aWin.BeginRedraw(aRect);
1.467 + CWindowGc* gc=iGc;
1.468 + if (iGc!=iInfoGc)
1.469 + if (&aWin==&iCompare || &aWin==&iTitle)
1.470 + gc=iInfoGc;
1.471 + else if (aWin.WindowGroupId()==iInfoGroup->WindowGroupId())
1.472 + gc=iInfoGc;
1.473 + ActivateWithWipe(gc,aWin,aColor);
1.474 + return gc;
1.475 + }
1.476 +
1.477 +TBool CWsDynamicResWinBase::InvalidateRegion(const TRegion& aRegion,RWindow& aWin)
1.478 + {
1.479 + if (aWin.WsHandle()==NULL)
1.480 + return false; //can't activate uninitialised window.
1.481 + for (TInt ii = 0; ii < aRegion.Count(); ii++)
1.482 + {
1.483 + aWin.Invalidate(aRegion[ii]);
1.484 + }
1.485 + return true;
1.486 + }
1.487 +
1.488 +CWindowGc* CWsDynamicResWinBase::BeginActivateWithWipe(const TRegion& aRegion,RWindow& aWin,TRgb aColor)
1.489 + {
1.490 + if (!InvalidateRegion(aRegion,aWin))
1.491 + return NULL; //can't activate uninitialised window.
1.492 +
1.493 + aWin.BeginRedraw();
1.494 + CWindowGc* gc=iGc;
1.495 + if (iGc!=iInfoGc)
1.496 + if (&aWin==&iCompare || &aWin==&iTitle)
1.497 + gc=iInfoGc;
1.498 + else if (aWin.WindowGroupId()==iInfoGroup->WindowGroupId())
1.499 + gc=iInfoGc;
1.500 + ActivateWithWipe(gc,aWin,aColor);
1.501 + return gc;
1.502 + }
1.503 +
1.504 +
1.505 +/** Paints the LHS window with rows of text.
1.506 + *
1.507 + **/
1.508 +void CWsDynamicResWinBase::RepaintTitleWindowL()
1.509 + {
1.510 + if (iTitle.WsHandle())
1.511 + {
1.512 + iTitle.Invalidate();
1.513 +
1.514 + iTitle.BeginRedraw();
1.515 + ActivateWithWipe(iInfoGc,iTitle,TITLE_BACKGROUND);
1.516 + iInfoGc->SetUnderlineStyle(EUnderlineOn);
1.517 + TSize winSize=iTitle.Size();
1.518 + TRect textRect(winSize);
1.519 + textRect.iBr.iY/=4;
1.520 + TFontSpec fspec(KMonospaceTestFontTypefaceName,KMaxFontSize);
1.521 + CFont *font=NULL;
1.522 + ASSERT_EQUALS(iInfoScreenDevice->GetNearestFontToDesignHeightInTwips(font,fspec),KErrNone);
1.523 + iInfoGc->UseFont(font);
1.524 + iInfoGc->DrawText(iTestName,textRect,textRect.iBr.iY/2,iGc->ECenter);
1.525 + iInfoGc->SetUnderlineStyle(EUnderlineOff);
1.526 + textRect.iTl.iY=textRect.iBr.iY;
1.527 + TInt rowHeight=winSize.iHeight*3/(4*(KMaxInfoLines+1));
1.528 + textRect.iBr.iY+=rowHeight;
1.529 + for (TInt index=0;index<KMaxInfoLines;index++)
1.530 + {
1.531 + if (iTestInfo[index].Length())
1.532 + {
1.533 + iInfoGc->DrawText(iTestInfo[index],textRect,textRect.Size().iHeight*3/4,iInfoGc->ECenter);
1.534 + }
1.535 + textRect.Move(0,rowHeight);
1.536 + }
1.537 + iInfoGc->DiscardFont();
1.538 + iInfoGc->Deactivate();
1.539 + iTitle.EndRedraw();
1.540 + iInfoScreenDevice->ReleaseFont(font);
1.541 +
1.542 + iSession.Flush();
1.543 + iSession.Finish();
1.544 + }
1.545 + }
1.546 +
1.547 +/** Useful test culled from other GCE test classes.
1.548 + *
1.549 + *
1.550 + *
1.551 + **/
1.552 +TBool CWsDynamicResWinBase::DisplayHasAlpha() const
1.553 + {
1.554 + return (iDisplayMode == EColor16MA || iDisplayMode == EColor16MAP);
1.555 + }
1.556 +/** Test using an indipendent method that GCE version of WServ is running
1.557 + * This method can only be called after the testcase is started
1.558 + *
1.559 + * @return true if WServ version is GCE technology, false if legacy technology
1.560 + **/
1.561 +TBool CWsDynamicResWinBase::GCEIsSupported() const
1.562 + {
1.563 + CFbsDrawDevice* screenDevice=NULL;
1.564 + TDisplayMode displayMode=iScreenDevice->DisplayMode();
1.565 + TRAPD(err, screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode));
1.566 + TBool rv=EFalse;
1.567 + if(err == KErrNone)
1.568 + {
1.569 + TAny* p=NULL;
1.570 + rv=(screenDevice->GetInterface(KSurfaceInterfaceID, p)==KErrNone);
1.571 + delete screenDevice;
1.572 + }
1.573 + return rv;
1.574 + }
1.575 +/** Test using an indipendent method that GCE version of WServ is running
1.576 + * This method can be called at any time, even by external code, but creates temporary window session objects
1.577 + *
1.578 + * @return true if WServ version is GCE technology, false if legacy technology
1.579 + **/
1.580 +TBool CWsDynamicResWinBase::GCEIsSupportedStatic()
1.581 + {
1.582 + CFbsDrawDevice* screenDevice=NULL;
1.583 + RWsSession session;
1.584 + if (session.Connect()!=KErrNone)
1.585 + {
1.586 + return EFalse;
1.587 + }
1.588 + TDisplayMode displayMode=ENone;
1.589 + {CWsScreenDevice screen(session);
1.590 + if (screen.Construct(TGlobalSettings::Instance().iScreen)!=KErrNone)
1.591 + {
1.592 + return EFalse;
1.593 + }
1.594 + displayMode=screen.DisplayMode();
1.595 + }//screen destroyed
1.596 + TRAPD(err, screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode));
1.597 + TBool rv=EFalse;
1.598 + if(err == KErrNone)
1.599 + {
1.600 + TAny* p=NULL;
1.601 + rv=(screenDevice->GetInterface(KSurfaceInterfaceID, p)==KErrNone);
1.602 + delete screenDevice;
1.603 + }
1.604 + return rv;
1.605 + }//session destroyed
1.606 +/**
1.607 +Use the full-screen background window to select a display mode that doesn't use
1.608 +alpha (anything other than EColor16MA or EColor16MAP). Record the mode for use
1.609 +in setting all other windows.
1.610 +@return ETrue if an appropriate mode was selected, EFalse otherwise.
1.611 +*/
1.612 +TBool CWsDynamicResWinBase::SelectChromaCompositionMode()
1.613 + {
1.614 + // Request EColor64K, but as long as the actual mode doesn't use alpha, it
1.615 + // doesn't matter too much which one is used.
1.616 + if (iInfoGc==iGc)
1.617 + {
1.618 + iDisplayMode = (TDisplayMode)iBackground.SetRequiredDisplayMode(EColor64K);
1.619 + iSession.Flush(); // Force switching to the display mode.
1.620 + }
1.621 + return !DisplayHasAlpha();
1.622 + }
1.623 +/** Returns the colour used by WServ to paint holes in UI layer to reveal the GCE behind.
1.624 + * The window should have a surface attached.
1.625 + * If the method is called after the surface has been detached or the window was removed then
1.626 + * the previous recorded hole color is returned.
1.627 + **/
1.628 +TRgb CWsDynamicResWinBase::GceHoleColor( RWindowBase& aWin)const
1.629 + {
1.630 + if (aWin.WsHandle()==NULL)
1.631 + {
1.632 + return iLastGceHoleColor;
1.633 + }
1.634 + TRgb retVal=aWin.KeyColor();
1.635 + if (retVal==TRgb(0,0))
1.636 + {
1.637 + return iLastGceHoleColor;
1.638 + }
1.639 + else
1.640 + {
1.641 + iLastGceHoleColor=retVal;
1.642 + return retVal;
1.643 + }
1.644 + }
1.645 +
1.646 +
1.647 +/**
1.648 +Use the full-screen background window to select a display mode that can use
1.649 +alpha (either EColor16MA or EColor16MAP). Record the mode for use in setting all
1.650 +other windows.
1.651 +@return ETrue if an appropriate mode was selected, EFalse otherwise.
1.652 +*/
1.653 +TBool CWsDynamicResWinBase::SelectAlphaCompositionMode(TDisplayMode aMode)
1.654 + {
1.655 + // Request EColor16MA, but as long as the actual mode can use alpha, it
1.656 + // doesn't matter too much which one is used.
1.657 + if (iInfoGc==iGc)
1.658 + {
1.659 + iDisplayMode = (TDisplayMode)iBackground.SetRequiredDisplayMode(aMode);
1.660 + iSession.Flush(); // Force switching to the display mode.
1.661 + }
1.662 + return DisplayHasAlpha();
1.663 + }
1.664 +
1.665 +/**
1.666 + * Interesting UI pattern used by other GCE tests.
1.667 + *
1.668 + *
1.669 + **/
1.670 +void CWsDynamicResWinBase::DrawUIContent(RWindow& aWindow)
1.671 + {
1.672 + aWindow.BeginRedraw();
1.673 + CWindowGc* gc=(&aWindow==&iCompare)?iInfoGc:iGc;
1.674 +
1.675 + gc->Activate(aWindow);
1.676 +
1.677 + TBool hasAlpha = DisplayHasAlpha();
1.678 +
1.679 + // Draw a red-green graduated box in the central portion of the window,
1.680 + // with alpha if available.
1.681 + TPoint start;
1.682 + TPoint end;
1.683 + TInt halfW = KSurfaceWidth / 2;
1.684 + TInt quarterW = halfW / 2;
1.685 + TInt halfH = KSurfaceHeight / 2;
1.686 + TInt quarterH = halfH / 2;
1.687 +
1.688 + // Set constant ordinals for non-alpha case.
1.689 + start.iX = quarterW;
1.690 + end.iX = quarterW + halfW;
1.691 +
1.692 + for (TInt yy = 0; yy < halfH; yy++)
1.693 + {
1.694 + TInt yval = yy * 255 / (halfH - 1);
1.695 + start.iY = yy + quarterH;
1.696 + end.iY = start.iY;
1.697 +
1.698 + if (hasAlpha)
1.699 + {
1.700 + for (TInt xx = 0; xx < halfW; xx++)
1.701 + {
1.702 + TInt xval = xx * 255 / (halfW - 1);
1.703 + start.iX = xx + quarterW;
1.704 + end.iX = start.iX + 1;
1.705 + gc->SetPenColor(TRgb(yval, 255 - yval, 0, xval));
1.706 + gc->DrawLine(start, end);
1.707 + }
1.708 + }
1.709 + else
1.710 + {
1.711 + gc->SetPenColor(TRgb(yval, 255 - yval, 0));
1.712 + gc->DrawLine(start, end);
1.713 + }
1.714 + }
1.715 +
1.716 + gc->Deactivate();
1.717 + aWindow.EndRedraw();
1.718 + }
1.719 +
1.720 +/**
1.721 + * Causes the given window to be redrawn.
1.722 + * Doesn't draw anything except the background wipe, when the transparency manager hasn't
1.723 + *
1.724 + **/
1.725 +void CWsDynamicResWinBase::DrawPlainUI(RWindow& aWindow,TBool aInvalidate,TRgb aWipeColor)
1.726 + {
1.727 + if (CWindowGc* gc=BeginActivateWithWipe(aInvalidate,aWindow,aWipeColor))
1.728 + {
1.729 + //actually does nothing!
1.730 + gc->Deactivate();
1.731 + aWindow.EndRedraw();
1.732 + }
1.733 + }
1.734 +/**
1.735 + * Interesting UI pattern used by other GCE tests.
1.736 + *
1.737 + *
1.738 + **/
1.739 +void CWsDynamicResWinBase::DrawCross(RWindow& aWindow, TRgb aColor, TInt aThickness)
1.740 + {
1.741 + aWindow.BeginRedraw();
1.742 + CWindowGc* gc=(&aWindow==&iCompare)?iInfoGc:iGc;
1.743 + gc->Activate(aWindow);
1.744 +
1.745 + // Draw a red diagonal cross in the window.
1.746 + gc->SetPenColor(aColor);
1.747 + gc->SetPenSize(TSize(aThickness, aThickness));
1.748 + gc->DrawLine(TPoint(0, 0), TPoint(KSurfaceWidth, KSurfaceHeight));
1.749 + gc->DrawLine(TPoint(KSurfaceWidth, 0), TPoint(0, KSurfaceHeight));
1.750 +
1.751 + gc->Deactivate();
1.752 + aWindow.EndRedraw();
1.753 + }
1.754 +
1.755 +/**
1.756 + * Checks the RGB value
1.757 + *
1.758 + *
1.759 + **/
1.760 +void CWsDynamicResWinBase::TestPixelL(TPoint aPt, TRgb aColor, TBool aMatch)
1.761 + {
1.762 + TRect screenArea(iScreenDevice->SizeInPixels());
1.763 + if (aPt.iX < screenArea.iTl.iX)
1.764 + {
1.765 + aPt.iX = screenArea.iTl.iX;
1.766 + }
1.767 + else if (aPt.iX >= screenArea.iBr.iX)
1.768 + {
1.769 + aPt.iX = screenArea.iBr.iX - 1;
1.770 + }
1.771 + if (aPt.iY < screenArea.iTl.iY)
1.772 + {
1.773 + aPt.iY = screenArea.iTl.iY;
1.774 + }
1.775 + else if (aPt.iY >= screenArea.iBr.iY)
1.776 + {
1.777 + aPt.iY = screenArea.iBr.iY - 1;
1.778 + }
1.779 +
1.780 + TRgb pixel;
1.781 + iScreenDevice->GetPixel(pixel, aPt);
1.782 + if (aMatch)
1.783 + {
1.784 + ASSERT_EQUALS_X(pixel.Internal(), aColor.Internal());
1.785 + }
1.786 + else
1.787 + {
1.788 + ASSERT_NOT_EQUALS_X(pixel.Internal(), aColor.Internal());
1.789 + }
1.790 + }
1.791 +
1.792 +struct CountColour
1.793 + {
1.794 + TRgb iColor;
1.795 + TInt iCount;
1.796 + TBool operator < (const CountColour& aRhs)const
1.797 + { return iColor.Value()<aRhs.iColor.Value(); }
1.798 +
1.799 + CountColour(TRgb aColor,TInt aCount=0):
1.800 + iColor(aColor),iCount(aCount) {}
1.801 +
1.802 + CountColour(const CountColour& aRhs):
1.803 + iColor(aRhs.iColor),iCount(aRhs.iCount) {}
1.804 + };
1.805 +
1.806 +void LogColorL(TRgb aPixel,RArray<CountColour>& aColors)
1.807 + {
1.808 + //I am sure one of the find methods would do this, but life is too short!
1.809 + TInt existingIndex;
1.810 + for (existingIndex=0;existingIndex<aColors.Count();existingIndex++)
1.811 + if (aColors[existingIndex].iColor==aPixel)
1.812 + break;
1.813 + if (existingIndex==aColors.Count())
1.814 + aColors.AppendL(CountColour(aPixel,1));
1.815 + else
1.816 + aColors[existingIndex].iCount++;
1.817 + }
1.818 +
1.819 +/**
1.820 + * Tests the outline of the given rectangle to verify that it has the expected inner and outer colors
1.821 + * There may be a limited number of other colors present.
1.822 + * If the given count of other colors is exceeded then false is returned
1.823 + * If the majority of inner and outer edge pixels are not the given colors then returns false
1.824 + * If the colors are repeated on inside and outside then returns false
1.825 + * If there are corners then the insides of the corners are also check for outside color
1.826 + * Note that the right and bottom edge coordinates are outside the rectangle.
1.827 + * Note that I am not performing any safety clipping at present. The rectangle must be on-screen!
1.828 + * A negative value for corner size indicates that the window may or may not have corners that size.
1.829 + * Only leaves if fatal memory condition!
1.830 +**/
1.831 +TBool CWsDynamicResWinBase::TestRectL(TRect aRect,TRgb aInnerColor,TInt aOtherInnerColors,TRgb aOuterColor,TInt aOtherOuterColors,TInt aExpectedCornerSize)
1.832 + {
1.833 + if (aRect.iTl.iX<=0 || aRect.iTl.iY<=0)
1.834 + return ETrue; //can't perform the test against the outside of the screen
1.835 + //quantise the expectation based on the current mode.
1.836 + TDisplayMode displayMode=iScreenDevice->DisplayMode();
1.837 + switch (displayMode)
1.838 + {
1.839 + case EColor4K:
1.840 + aInnerColor=aInnerColor.Color4K(aInnerColor.Color4K());
1.841 + aOuterColor=aOuterColor.Color4K(aOuterColor.Color4K());
1.842 + break;
1.843 + case EColor64K:
1.844 + aInnerColor=aInnerColor.Color64K(aInnerColor.Color64K());
1.845 + aOuterColor=aOuterColor.Color64K(aOuterColor.Color64K());
1.846 + break;
1.847 + case EColor16M:
1.848 + case EColor16MU:
1.849 + case EColor16MA:
1.850 + case EColor16MAP:
1.851 + break;
1.852 + default:
1.853 + ASSERT_EQUALS(EColor16MA,displayMode); //Can't quantise color for this display mode!
1.854 + }
1.855 +
1.856 + RArray<CountColour> innerColors;
1.857 + innerColors.AppendL(aInnerColor);
1.858 + RArray<CountColour> outerColors;
1.859 + outerColors.AppendL(aOuterColor);
1.860 + TInt cornerSize=aExpectedCornerSize>=0?aExpectedCornerSize:-aExpectedCornerSize;
1.861 + //Check outside first!
1.862 + TRgb pixelVal;
1.863 + for(TPoint pixelPos(aRect.iTl.iX-1,aRect.iTl.iY-1);pixelPos.iX<aRect.iBr.iX;pixelPos.iX++)
1.864 + {
1.865 + iScreenDevice->GetPixel(pixelVal, pixelPos);
1.866 + LogColorL(pixelVal,outerColors);
1.867 + }
1.868 + for(TPoint pixelPos(aRect.iTl.iX,aRect.iBr.iY);pixelPos.iX<=aRect.iBr.iX;pixelPos.iX++)
1.869 + {
1.870 + iScreenDevice->GetPixel(pixelVal, pixelPos);
1.871 + LogColorL(pixelVal,outerColors);
1.872 + }
1.873 + for(TPoint pixelPos(aRect.iTl.iX-1,aRect.iTl.iY);pixelPos.iY<=aRect.iBr.iY;pixelPos.iY++)
1.874 + {
1.875 + iScreenDevice->GetPixel(pixelVal, pixelPos);
1.876 + LogColorL(pixelVal,outerColors);
1.877 + }
1.878 + for(TPoint pixelPos(aRect.iBr.iX,aRect.iTl.iY-1);pixelPos.iY<aRect.iBr.iY;pixelPos.iY++)
1.879 + {
1.880 + iScreenDevice->GetPixel(pixelVal, pixelPos);
1.881 + LogColorL(pixelVal,outerColors);
1.882 + }
1.883 + TInt cornerStart=1;
1.884 + if (cornerSize)
1.885 + {
1.886 + cornerStart=cornerSize;
1.887 + if (aExpectedCornerSize>0)
1.888 + {
1.889 + iScreenDevice->GetPixel(pixelVal, aRect.iTl);
1.890 + LogColorL(pixelVal,outerColors);
1.891 + iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX,aRect.iBr.iY-1));
1.892 + LogColorL(pixelVal,outerColors);
1.893 + iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1,aRect.iTl.iY));
1.894 + LogColorL(pixelVal,outerColors);
1.895 + iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1,aRect.iBr.iY-1));
1.896 + LogColorL(pixelVal,outerColors);
1.897 + }
1.898 + }
1.899 +
1.900 + //test inside edges (excluding 4 corner pixels - do them seperately)
1.901 + for(TPoint pixelPos(aRect.iTl.iX+cornerStart,aRect.iTl.iY);pixelPos.iX<aRect.iBr.iX-cornerStart;pixelPos.iX++)
1.902 + {
1.903 + iScreenDevice->GetPixel(pixelVal, pixelPos);
1.904 + LogColorL(pixelVal,innerColors);
1.905 + }
1.906 + for(TPoint pixelPos(aRect.iTl.iX+cornerStart,aRect.iBr.iY-1);pixelPos.iX<aRect.iBr.iX-cornerStart;pixelPos.iX++)
1.907 + {
1.908 + iScreenDevice->GetPixel(pixelVal, pixelPos);
1.909 + LogColorL(pixelVal,innerColors);
1.910 + }
1.911 + for(TPoint pixelPos(aRect.iTl.iX,aRect.iTl.iY+cornerStart);pixelPos.iY<aRect.iBr.iY-cornerStart;pixelPos.iY++)
1.912 + {
1.913 + iScreenDevice->GetPixel(pixelVal, pixelPos);
1.914 + LogColorL(pixelVal,innerColors);
1.915 + }
1.916 + for(TPoint pixelPos(aRect.iBr.iX-1,aRect.iTl.iY+cornerStart);pixelPos.iY<aRect.iBr.iY-cornerStart;pixelPos.iY++)
1.917 + {
1.918 + iScreenDevice->GetPixel(pixelVal, pixelPos);
1.919 + LogColorL(pixelVal,innerColors);
1.920 + }
1.921 + //the 4 corner cells - not checking the whole corner area...
1.922 + if (aExpectedCornerSize>=0)
1.923 + {
1.924 + iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX+cornerSize,aRect.iTl.iY+cornerSize));
1.925 + LogColorL(pixelVal,innerColors);
1.926 + iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX+cornerSize,aRect.iBr.iY-1-cornerSize));
1.927 + LogColorL(pixelVal,innerColors);
1.928 + iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1-cornerSize,aRect.iBr.iY-1-cornerSize));
1.929 + LogColorL(pixelVal,innerColors);
1.930 + iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1-cornerSize,aRect.iTl.iY+cornerSize));
1.931 + LogColorL(pixelVal,innerColors);
1.932 + }
1.933 + //OK... that has tested all the pixels, now check the result
1.934 + if (innerColors.Count()>aOtherInnerColors+1)
1.935 + return EFalse;
1.936 + if (outerColors.Count()>aOtherOuterColors+1)
1.937 + return EFalse;
1.938 + for (TInt index=1;index<innerColors.Count();index++)
1.939 + if (innerColors[0].iCount<innerColors[index].iCount)
1.940 + {
1.941 + return EFalse;
1.942 + }
1.943 + for (TInt index=1;index<outerColors.Count();index++)
1.944 + if (outerColors[0].iCount<outerColors[index].iCount)
1.945 + {
1.946 + return EFalse;
1.947 + }
1.948 + for (TInt indexIn=1;indexIn<innerColors.Count();indexIn++)
1.949 + for (TInt indexOut=0;indexOut<outerColors.Count();indexOut++)
1.950 + if (innerColors[indexIn].iColor.Value()==outerColors[indexOut].iColor.Value())
1.951 + {
1.952 + return EFalse;
1.953 + }
1.954 + return ETrue;
1.955 + }
1.956 +
1.957 +TRect CWsDynamicResWinBase::PentCellRect(const TRect& aFullRect,char aStartLetter,char aEndLetter)
1.958 + {
1.959 + if (aEndLetter==0)
1.960 + aEndLetter=aStartLetter;
1.961 + aStartLetter&=0x1f;
1.962 + aEndLetter&=0x1f;
1.963 + TInt startx=(aStartLetter-1)%5;
1.964 + TInt starty=(aStartLetter-1)/5;
1.965 + TInt endx=(aEndLetter-1)%5;
1.966 + TInt endy=(aEndLetter-1)/5;
1.967 + if (starty>endy)
1.968 + { //swap // s e
1.969 + starty-=endy; // s-e
1.970 + endy+=starty; // s
1.971 + starty=endy-starty; // e
1.972 + }
1.973 + if (startx>endx)
1.974 + { //swap // s e
1.975 + startx-=endx; // s-e
1.976 + endx+=startx; // s
1.977 + startx=endx-startx; // e
1.978 + }
1.979 + TSize fullSize=aFullRect.Size();
1.980 + return TRect( aFullRect.iTl.iX+fullSize.iWidth*startx/5,
1.981 + aFullRect.iTl.iY+fullSize.iHeight*starty/5,
1.982 + aFullRect.iTl.iX+fullSize.iWidth*(endx+1)/5,
1.983 + aFullRect.iTl.iY+fullSize.iHeight*(endy+1)/5
1.984 + );
1.985 + }