os/graphics/windowing/windowserver/test/tdynamicres/src/t_wsdynamicreswinbase.cpp
First public contribution.
1 // Copyright (c) 2008-2010 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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
25 #include "teflogextensions.h"
26 #include "t_wsdynamicreswinbase.h"
27 #include "globalsettings.h"
29 #include <bitdrawinterfaceid.h>
31 #include <dispchannel.h>
32 #include <graphics/displaycontrol.h>
34 #if (!defined(K_DISPLAY_CH_MAJOR_VERSION_NUMBER) && !defined(K_DISPLAY_CH_MINOR_VERSION_NUMBER))
35 #define MODE_CHANGE_BASE_FUNCTIONALITY_NOT_PRESENT_IN_HEADER
38 _LIT(KMonospaceTestFontTypefaceName,"Arial");
39 const TInt KMaxFontSize = 150;
40 TBool CWsDynamicResWinBase::iTransparencyEnabled=EFalse;
42 CWsDynamicResWinBase::CWsDynamicResWinBase():
44 iSession(TGlobalSettings::Instance().iScreen)
48 void CWsDynamicResWinBase::SetupL()
52 CActiveScheduler CWsDynamicResWinBase::iScheduler;
54 void CWsDynamicResWinBase::SetupL(TBool aUseOtherScreenForInfo)
56 if (CActiveScheduler::Current()!=&iScheduler)
58 new (&iScheduler) CActiveScheduler;
59 CActiveScheduler::Install(&iScheduler);
62 iRed.SetInternal(0xFFFF0000);
63 iGreen.SetInternal(0xFF00FF00);
64 iBlue.SetInternal(0xFF0000FF);
65 iCyan.SetInternal(0xFF00FFFF);
66 iMagenta.SetInternal(0xFFFF00FF);
67 iYellow.SetInternal(0xFFFFFF00);
68 iWhite.SetInternal(0xFFFFFFFF);
69 iLastGceHoleColor.SetInternal(0);
70 TITLE_BACKGROUND=iCyan;
71 COMPARE_BACKGROUND=iBlue;
73 ASSERT_EQUALS_X(iSession.Connect(), KErrNone);
75 {//Stolen from TAuto CloseAllPanicWindows()
76 TInt idFocus = iSession.GetFocusWindowGroup();
78 event.SetType(EEventKey); //EEventKeyDown
79 TKeyEvent *keyEvent = event.Key();
80 keyEvent->iCode = EKeyEscape;
81 keyEvent->iScanCode = EStdKeyEscape;
82 keyEvent->iModifiers = 0;
84 while(idFocus != NULL && (theLimit-- > 0))
86 iSession.SendEventToAllWindowGroups(event);
87 TInt idNewFocus = iSession.GetFocusWindowGroup();
88 if (idNewFocus!=idFocus)
90 INFO_PRINTF1(_L("A window was closed [probably a panic box from the previous test]."));
97 TRAP(err, iScreenDevice = new (ELeave) CWsScreenDevice(iSession));
98 PRINT_ON_ERROR2_L(err, _L("Failed to create screen device: %d"), err);
99 ASSERT_EQUALS_X(iScreenDevice->Construct(TGlobalSettings::Instance().iScreen), KErrNone);
100 iDisplayMode = iScreenDevice->DisplayMode(); // Get default display mode
102 CheckAndConnectScreen();
104 TRAP(err, iGc = new (ELeave) CWindowGc(iScreenDevice));
105 PRINT_ON_ERROR2_L(err, _L("Failed to create graphics context: %d"), err);
106 ASSERT_EQUALS_X(iGc->Construct(), KErrNone);
108 iGroup = RWindowGroup(iSession);
109 ASSERT_EQUALS_X(iGroup.Construct(++iWindowHandle,iScreenDevice), KErrNone);
110 iGroup.SetOrdinalPositionErr(0, KPasswordWindowGroupPriority - 1); // Added code ---- Fastpath
113 if (aUseOtherScreenForInfo)
115 if (iSession.NumberOfScreens()>1)
116 { //Create server objects for info windows to appear on alternate screen
117 TInt alternateScreenNum=iSession.NumberOfScreens()-1;
118 if (TGlobalSettings::Instance().iScreen==alternateScreenNum)
119 { //Alternate screen is last screen, or first screen if that is being tested.
120 alternateScreenNum=0;
123 TRAP(err, iInfoScreenDevice = new (ELeave) CWsScreenDevice(iSession));
124 PRINT_ON_ERROR2_L(err, _L("Failed to create second screen device: %d"), err);
125 ASSERT_EQUALS_X(iInfoScreenDevice->Construct(alternateScreenNum), KErrNone);
127 TRAP(err, iInfoGc = new (ELeave) CWindowGc(iInfoScreenDevice));
128 PRINT_ON_ERROR2_L(err, _L("Failed to create second graphics context: %d"), err);
129 ASSERT_EQUALS_X(iInfoGc->Construct(), KErrNone);
131 iInfoGroupInstance = RWindowGroup(iSession);
132 ASSERT_EQUALS_X(iInfoGroupInstance.Construct(++iWindowHandle,iInfoScreenDevice), KErrNone);
133 iInfoGroup=&iInfoGroupInstance;
136 { //If alternate screen is not available then no text or compare windows should be created!
137 iInfoScreenDevice=iScreenDevice; //it is "convenient" for the device to still be good.
144 iInfoScreenDevice=iScreenDevice;
149 if (iInfoGroup && iInfoGc)
151 // Add a plain background window to obscure anything else that
152 // happens to be behind the test. Setting this window's display mode is also
153 // used to set the screen device display mode, and hence the composition
154 // mode: alpha or chroma key.
155 iBackground = RBlankWindow(iSession);
156 ASSERT_EQUALS_X(iBackground.Construct(*iInfoGroup, ++iWindowHandle), KErrNone);
158 iBackground.SetOrdinalPosition(100); // Behind anything else in this group.
159 iBackground.SetColor(TRgb(iWhite));
160 //iBackground.SetExtent(TPoint(-1000,-1000),TSize(3000,3000));
161 iBackground.Activate();
162 iBackground.SetVisible(ETrue);
166 RWindow testTrans(iSession);
167 ASSERT_EQUALS_X(testTrans.Construct(iGroup, ++iWindowHandle), KErrNone);
168 iTransparencyEnabled=(testTrans.SetTransparencyFactor(iWhite)==KErrNone);
169 if (iTransparencyEnabled)
172 testName.Format(_L("Screen %i, depth %i: Found Trans Man"),
173 TGlobalSettings::Instance().iScreen
175 UpdateTitleWindowL(testName,KMaxInfoLines-1);
180 testName.Format(_L("Screen %i, depth %i: No Trans Man"),
181 TGlobalSettings::Instance().iScreen
183 UpdateTitleWindowL(testName,KMaxInfoLines-1);
189 void CWsDynamicResWinBase::CheckAndConnectScreen()
191 if (TGlobalSettings::Instance().iDisconnected) //set from script file to match wsini keyword SIMULATE_STARTUP_DISCONNECTED
193 //Verify that the display really is disconnected
194 ASSERT_TRUE_X(iScreenDevice != NULL);
195 MDisplayControl* interface = static_cast<MDisplayControl*>(iScreenDevice->GetInterface(MDisplayControl::ETypeId));
196 ASSERT_TRUE_X(interface != NULL);
197 RArray<MDisplayControl::TResolution> resolutions;
198 const TInt err = interface->GetResolutions(resolutions);
199 ASSERT_EQUALS_X(err, KErrDisconnected);
203 #ifndef MODE_CHANGE_BASE_FUNCTIONALITY_NOT_PRESENT_IN_HEADER
204 //make sure display is attached to screen (only if I/F is available at compile time...)
205 TInt displayState = ENormalResolution;
206 UserSvr::HalFunction(EHalGroupDisplay | (TGlobalSettings::Instance().iScreen<<16), EDisplayHalSetDisplayState, &displayState, NULL);
210 if (TGlobalSettings::Instance().iDisconnected)
212 //Verify that the display now is connected
213 MDisplayControl* interface = static_cast<MDisplayControl*>(iScreenDevice->GetInterface(MDisplayControl::ETypeId));
214 RArray<MDisplayControl::TResolution> resolutions;
215 const TInt err = interface->GetResolutions(resolutions);
216 ASSERT_EQUALS_X(err, KErrNone);
217 const_cast<TGlobalSettings&>(TGlobalSettings::Instance()).iDisconnected = EFalse;
223 Common tear down code for all tests.
225 Windows, group and session created are closed. Screen device is destroyed.
226 Surfaces, manager and update session are closed.
228 void CWsDynamicResWinBase::TearDownL()
234 if (iInfoScreenDevice!=iScreenDevice)
235 delete iInfoScreenDevice;
236 delete iScreenDevice;
239 if (iInfoGroupInstance.WsHandle())
240 iInfoGroupInstance.Close();
245 * Note that this is not the ideal mechanism.
246 * 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
248 void CWsDynamicResWinBase::TearDownFromDeleteL()
250 CWsDynamicResWinBase::TearDownL(); //Explicitly call the non-derived implementation.
253 CWsDynamicResWinBase::~CWsDynamicResWinBase()
256 TearDownFromDeleteL(); //This mechanism is not entirely clean to use.
259 Pause for the given number of milliseconds.
261 @param aMilliseconds Time to wait in milliseconds.
263 void CWsDynamicResWinBase::Pause(TInt aMilliseconds)
265 User::After(TTimeIntervalMicroSeconds32(aMilliseconds * 1000));
267 // This handles any non-member uses of the extended ASSERT_XXX macros
268 void TefUnitFailLeaveL()
271 User::Leave(KErrTEFUnitFail);
274 * side-effect: log the state info just before I leave!
275 * Note that this only logs intentional assertion failures.
276 * Fails due to panics or throws won't log this info.
278 void CWsDynamicResWinBase::TefUnitFailLeaveL()
280 for (TInt line=0;line<KMaxInfoLines;line++)
281 if (iTestInfo[line].Length())
282 Logger().LogExtra((TText8*)"Test state at fail - line",line, ESevrAll, iTestInfo[line]);
284 User::Leave(KErrTEFUnitFail);
287 /** Creates the LHS info window, annd a middle window to display a representation of the expected result.
288 * Also sets up a rectangle representing the space on the right to be used for the test
289 * @param aTitle The title to display on the info window
290 * @param aDetail Optional text to display on the first line under the title
292 void CWsDynamicResWinBase::MakeTitleAndCompareWindowsL(TRefByValue<const TDesC16> aTitle,TRefByValue<const TDesC16> aDetail)
295 iTestInfo[0]=aDetail;
297 TRect screenSize(iInfoScreenDevice->SizeInPixels());
298 TPoint oneThird(screenSize.iBr.iX/3,screenSize.iBr.iY/3);
299 TRect winSize(0,0,oneThird.iX,oneThird.iY);
301 if (oneThird.iX>oneThird.iY)
304 winSize.iBr.iY=screenSize.iBr.iY;
309 winSize.iBr.iX=screenSize.iBr.iX;
315 iTitle=RWindow(iSession);
316 ASSERT_EQUALS_X(iTitle.Construct(*iInfoGroup, ++iWindowHandle), KErrNone);
317 iTitle.SetBackgroundColor(iCyan);
318 iTitle.SetExtent(winSize.iTl,winSize.Size());
321 RepaintTitleWindowL();
322 iTitle.SetVisible(ETrue);
324 winSize.Move(oneThird);
325 iCompare=RWindow(iSession);
326 ASSERT_EQUALS_X(iCompare.Construct(*iInfoGroup, ++iWindowHandle), KErrNone);
327 iCompare.SetBackgroundColor(COMPARE_BACKGROUND);
328 iCompare.SetExtent(winSize.iTl,winSize.Size());
330 iCompare.BeginRedraw();
331 ActivateWithWipe(iInfoGc,iCompare,COMPARE_BACKGROUND);
333 TFontSpec fspec(KMonospaceTestFontTypefaceName,KMaxFontSize);
335 ASSERT_EQUALS(iScreenDevice->GetNearestFontToDesignHeightInTwips(font,fspec),KErrNone);
336 iInfoGc->UseFont(font);
337 iInfoGc->DrawText(_L("Simulation"),winSize.Size(),winSize.Size().iHeight-5,iGc->ECenter);
339 iInfoGc->Deactivate();
340 iCompare.EndRedraw();
341 iCompare.SetVisible(ETrue);
342 if (iScreenDevice!=iInfoScreenDevice)
344 winSize.Move(-oneThird);
348 winSize.Move(oneThird);
353 winSize=iScreenDevice->SizeInPixels();
357 iTestPointCentre=winSize.Center();
358 iCenteredFrontWinRect=winSize;
359 iCenteredFrontWinRect.Shrink(winSize.Size().iWidth/3,winSize.Size().iHeight/3);
362 /** Makes the compare window larger by covering the test window area as well.
363 * Copes with vertically aligned screens, but will be naughty if called multiple times!!!
364 * @param aGoLarger If set false, resets the size back.
366 void CWsDynamicResWinBase::LargerCompareWindow(TBool aGoLarger)
368 TPoint currPos=iCompare.AbsPosition();
369 TSize currSize=iCompare.Size();
370 if (currPos.iX<currPos.iY)
373 currSize.iHeight<<=1;
375 currSize.iHeight>>=1;
384 iCompare.SetSize(currSize);
388 /** Puts a line of text on the LHS window.
389 * Repaints the window. The line of text will also be shown in the log if the test fails.
390 * @param aDetail The text to display
391 * @param aIndex The row number to display at
393 void CWsDynamicResWinBase::UpdateTitleWindowL(TRefByValue<const TDesC16> aDetail,TInt aIndex)
395 ASSERT(aIndex>=0 && aIndex<KMaxInfoLines);
396 iTestInfo[aIndex]=aDetail;
398 RepaintTitleWindowL();
401 /** Activate the GC onto the Window.
402 * In non-transparent mode it also performs a wipe background as the WServ system does not necessarily do this.
403 * @param aGc The GC to associate
404 * @param aWin The window to associate
405 * @param aColor The color to use as the wipe. Default is transparent, which means no wipe.
407 TBool CWsDynamicResWinBase::ActivateWithWipe(CWindowGc* aGc,RWindow& aWin,TRgb aColor)
410 aGc->SetBrushColor(aColor);
411 aGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
412 if (aColor!=TRgb(0,0) && !iTransparencyEnabled) //presume that all redraw-stored windows will draw background
415 return ETrue; //window was cleared
420 CWindowGc* CWsDynamicResWinBase::GcForWindow(RWindow& aWin)
422 if (aWin.WsHandle()==NULL)
423 return NULL; //can't activate uninitialised window.
426 if (&aWin==&iCompare || &aWin==&iTitle)
428 else if (iInfoGroup && aWin.WindowGroupId()==iInfoGroup->WindowGroupId())
432 /** Activates an appropriate predefined GC on the specified window and wipes the background if necessary.
433 * @param aWin The window to wipe
434 * @param aColor The colour to wipe with (if necessary)
435 * @return the GC to use for drawing and deactivate at end. This may be NULL if the window is not "live"
437 CWindowGc* CWsDynamicResWinBase::BeginActivateWithWipe(TBool aInvalidate,RWindow& aWin,TRgb aColor)
439 CWindowGc* gc=GcForWindow(aWin);
442 return gc; //can't activate uninitialised window.
448 ActivateWithWipe(gc,aWin,aColor);
452 /** Activates an appropriate predefined GC on the specified window and wipes the background if necessary.
453 * @param aWin The window to wipe
454 * @param aColor The colour to wipe with (if necessary)
455 * @return the GC to use for drawing and deactivate at end. This may be NULL if the window is not "live"
457 CWindowGc* CWsDynamicResWinBase::BeginActivateWithWipe(TBool aInvalidate,TRect aRect,RWindow& aWin,TRgb aColor)
459 if (aWin.WsHandle()==NULL)
460 return NULL; //can't activate uninitialised window.
462 aWin.Invalidate(aRect);
463 aWin.BeginRedraw(aRect);
466 if (&aWin==&iCompare || &aWin==&iTitle)
468 else if (aWin.WindowGroupId()==iInfoGroup->WindowGroupId())
470 ActivateWithWipe(gc,aWin,aColor);
474 TBool CWsDynamicResWinBase::InvalidateRegion(const TRegion& aRegion,RWindow& aWin)
476 if (aWin.WsHandle()==NULL)
477 return false; //can't activate uninitialised window.
478 for (TInt ii = 0; ii < aRegion.Count(); ii++)
480 aWin.Invalidate(aRegion[ii]);
485 CWindowGc* CWsDynamicResWinBase::BeginActivateWithWipe(const TRegion& aRegion,RWindow& aWin,TRgb aColor)
487 if (!InvalidateRegion(aRegion,aWin))
488 return NULL; //can't activate uninitialised window.
493 if (&aWin==&iCompare || &aWin==&iTitle)
495 else if (aWin.WindowGroupId()==iInfoGroup->WindowGroupId())
497 ActivateWithWipe(gc,aWin,aColor);
502 /** Paints the LHS window with rows of text.
505 void CWsDynamicResWinBase::RepaintTitleWindowL()
507 if (iTitle.WsHandle())
511 iTitle.BeginRedraw();
512 ActivateWithWipe(iInfoGc,iTitle,TITLE_BACKGROUND);
513 iInfoGc->SetUnderlineStyle(EUnderlineOn);
514 TSize winSize=iTitle.Size();
515 TRect textRect(winSize);
517 TFontSpec fspec(KMonospaceTestFontTypefaceName,KMaxFontSize);
519 ASSERT_EQUALS(iInfoScreenDevice->GetNearestFontToDesignHeightInTwips(font,fspec),KErrNone);
520 iInfoGc->UseFont(font);
521 iInfoGc->DrawText(iTestName,textRect,textRect.iBr.iY/2,iGc->ECenter);
522 iInfoGc->SetUnderlineStyle(EUnderlineOff);
523 textRect.iTl.iY=textRect.iBr.iY;
524 TInt rowHeight=winSize.iHeight*3/(4*(KMaxInfoLines+1));
525 textRect.iBr.iY+=rowHeight;
526 for (TInt index=0;index<KMaxInfoLines;index++)
528 if (iTestInfo[index].Length())
530 iInfoGc->DrawText(iTestInfo[index],textRect,textRect.Size().iHeight*3/4,iInfoGc->ECenter);
532 textRect.Move(0,rowHeight);
534 iInfoGc->DiscardFont();
535 iInfoGc->Deactivate();
537 iInfoScreenDevice->ReleaseFont(font);
544 /** Useful test culled from other GCE test classes.
549 TBool CWsDynamicResWinBase::DisplayHasAlpha() const
551 return (iDisplayMode == EColor16MA || iDisplayMode == EColor16MAP);
553 /** Test using an indipendent method that GCE version of WServ is running
554 * This method can only be called after the testcase is started
556 * @return true if WServ version is GCE technology, false if legacy technology
558 TBool CWsDynamicResWinBase::GCEIsSupported() const
560 CFbsDrawDevice* screenDevice=NULL;
561 TDisplayMode displayMode=iScreenDevice->DisplayMode();
562 TRAPD(err, screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode));
567 rv=(screenDevice->GetInterface(KSurfaceInterfaceID, p)==KErrNone);
572 /** Test using an indipendent method that GCE version of WServ is running
573 * This method can be called at any time, even by external code, but creates temporary window session objects
575 * @return true if WServ version is GCE technology, false if legacy technology
577 TBool CWsDynamicResWinBase::GCEIsSupportedStatic()
579 CFbsDrawDevice* screenDevice=NULL;
581 if (session.Connect()!=KErrNone)
585 TDisplayMode displayMode=ENone;
586 {CWsScreenDevice screen(session);
587 if (screen.Construct(TGlobalSettings::Instance().iScreen)!=KErrNone)
591 displayMode=screen.DisplayMode();
593 TRAPD(err, screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode));
598 rv=(screenDevice->GetInterface(KSurfaceInterfaceID, p)==KErrNone);
604 Use the full-screen background window to select a display mode that doesn't use
605 alpha (anything other than EColor16MA or EColor16MAP). Record the mode for use
606 in setting all other windows.
607 @return ETrue if an appropriate mode was selected, EFalse otherwise.
609 TBool CWsDynamicResWinBase::SelectChromaCompositionMode()
611 // Request EColor64K, but as long as the actual mode doesn't use alpha, it
612 // doesn't matter too much which one is used.
615 iDisplayMode = (TDisplayMode)iBackground.SetRequiredDisplayMode(EColor64K);
616 iSession.Flush(); // Force switching to the display mode.
618 return !DisplayHasAlpha();
620 /** Returns the colour used by WServ to paint holes in UI layer to reveal the GCE behind.
621 * The window should have a surface attached.
622 * If the method is called after the surface has been detached or the window was removed then
623 * the previous recorded hole color is returned.
625 TRgb CWsDynamicResWinBase::GceHoleColor( RWindowBase& aWin)const
627 if (aWin.WsHandle()==NULL)
629 return iLastGceHoleColor;
631 TRgb retVal=aWin.KeyColor();
632 if (retVal==TRgb(0,0))
634 return iLastGceHoleColor;
638 iLastGceHoleColor=retVal;
645 Use the full-screen background window to select a display mode that can use
646 alpha (either EColor16MA or EColor16MAP). Record the mode for use in setting all
648 @return ETrue if an appropriate mode was selected, EFalse otherwise.
650 TBool CWsDynamicResWinBase::SelectAlphaCompositionMode(TDisplayMode aMode)
652 // Request EColor16MA, but as long as the actual mode can use alpha, it
653 // doesn't matter too much which one is used.
656 iDisplayMode = (TDisplayMode)iBackground.SetRequiredDisplayMode(aMode);
657 iSession.Flush(); // Force switching to the display mode.
659 return DisplayHasAlpha();
663 * Interesting UI pattern used by other GCE tests.
667 void CWsDynamicResWinBase::DrawUIContent(RWindow& aWindow)
669 aWindow.BeginRedraw();
670 CWindowGc* gc=(&aWindow==&iCompare)?iInfoGc:iGc;
672 gc->Activate(aWindow);
674 TBool hasAlpha = DisplayHasAlpha();
676 // Draw a red-green graduated box in the central portion of the window,
677 // with alpha if available.
680 TInt halfW = KSurfaceWidth / 2;
681 TInt quarterW = halfW / 2;
682 TInt halfH = KSurfaceHeight / 2;
683 TInt quarterH = halfH / 2;
685 // Set constant ordinals for non-alpha case.
687 end.iX = quarterW + halfW;
689 for (TInt yy = 0; yy < halfH; yy++)
691 TInt yval = yy * 255 / (halfH - 1);
692 start.iY = yy + quarterH;
697 for (TInt xx = 0; xx < halfW; xx++)
699 TInt xval = xx * 255 / (halfW - 1);
700 start.iX = xx + quarterW;
701 end.iX = start.iX + 1;
702 gc->SetPenColor(TRgb(yval, 255 - yval, 0, xval));
703 gc->DrawLine(start, end);
708 gc->SetPenColor(TRgb(yval, 255 - yval, 0));
709 gc->DrawLine(start, end);
718 * Causes the given window to be redrawn.
719 * Doesn't draw anything except the background wipe, when the transparency manager hasn't
722 void CWsDynamicResWinBase::DrawPlainUI(RWindow& aWindow,TBool aInvalidate,TRgb aWipeColor)
724 if (CWindowGc* gc=BeginActivateWithWipe(aInvalidate,aWindow,aWipeColor))
726 //actually does nothing!
732 * Interesting UI pattern used by other GCE tests.
736 void CWsDynamicResWinBase::DrawCross(RWindow& aWindow, TRgb aColor, TInt aThickness)
738 aWindow.BeginRedraw();
739 CWindowGc* gc=(&aWindow==&iCompare)?iInfoGc:iGc;
740 gc->Activate(aWindow);
742 // Draw a red diagonal cross in the window.
743 gc->SetPenColor(aColor);
744 gc->SetPenSize(TSize(aThickness, aThickness));
745 gc->DrawLine(TPoint(0, 0), TPoint(KSurfaceWidth, KSurfaceHeight));
746 gc->DrawLine(TPoint(KSurfaceWidth, 0), TPoint(0, KSurfaceHeight));
753 * Checks the RGB value
757 void CWsDynamicResWinBase::TestPixelL(TPoint aPt, TRgb aColor, TBool aMatch)
759 TRect screenArea(iScreenDevice->SizeInPixels());
760 if (aPt.iX < screenArea.iTl.iX)
762 aPt.iX = screenArea.iTl.iX;
764 else if (aPt.iX >= screenArea.iBr.iX)
766 aPt.iX = screenArea.iBr.iX - 1;
768 if (aPt.iY < screenArea.iTl.iY)
770 aPt.iY = screenArea.iTl.iY;
772 else if (aPt.iY >= screenArea.iBr.iY)
774 aPt.iY = screenArea.iBr.iY - 1;
778 iScreenDevice->GetPixel(pixel, aPt);
781 ASSERT_EQUALS_X(pixel.Internal(), aColor.Internal());
785 ASSERT_NOT_EQUALS_X(pixel.Internal(), aColor.Internal());
793 TBool operator < (const CountColour& aRhs)const
794 { return iColor.Value()<aRhs.iColor.Value(); }
796 CountColour(TRgb aColor,TInt aCount=0):
797 iColor(aColor),iCount(aCount) {}
799 CountColour(const CountColour& aRhs):
800 iColor(aRhs.iColor),iCount(aRhs.iCount) {}
803 void LogColorL(TRgb aPixel,RArray<CountColour>& aColors)
805 //I am sure one of the find methods would do this, but life is too short!
807 for (existingIndex=0;existingIndex<aColors.Count();existingIndex++)
808 if (aColors[existingIndex].iColor==aPixel)
810 if (existingIndex==aColors.Count())
811 aColors.AppendL(CountColour(aPixel,1));
813 aColors[existingIndex].iCount++;
817 * Tests the outline of the given rectangle to verify that it has the expected inner and outer colors
818 * There may be a limited number of other colors present.
819 * If the given count of other colors is exceeded then false is returned
820 * If the majority of inner and outer edge pixels are not the given colors then returns false
821 * If the colors are repeated on inside and outside then returns false
822 * If there are corners then the insides of the corners are also check for outside color
823 * Note that the right and bottom edge coordinates are outside the rectangle.
824 * Note that I am not performing any safety clipping at present. The rectangle must be on-screen!
825 * A negative value for corner size indicates that the window may or may not have corners that size.
826 * Only leaves if fatal memory condition!
828 TBool CWsDynamicResWinBase::TestRectL(TRect aRect,TRgb aInnerColor,TInt aOtherInnerColors,TRgb aOuterColor,TInt aOtherOuterColors,TInt aExpectedCornerSize)
830 if (aRect.iTl.iX<=0 || aRect.iTl.iY<=0)
831 return ETrue; //can't perform the test against the outside of the screen
832 //quantise the expectation based on the current mode.
833 TDisplayMode displayMode=iScreenDevice->DisplayMode();
837 aInnerColor=aInnerColor.Color4K(aInnerColor.Color4K());
838 aOuterColor=aOuterColor.Color4K(aOuterColor.Color4K());
841 aInnerColor=aInnerColor.Color64K(aInnerColor.Color64K());
842 aOuterColor=aOuterColor.Color64K(aOuterColor.Color64K());
850 ASSERT_EQUALS(EColor16MA,displayMode); //Can't quantise color for this display mode!
853 RArray<CountColour> innerColors;
854 innerColors.AppendL(aInnerColor);
855 RArray<CountColour> outerColors;
856 outerColors.AppendL(aOuterColor);
857 TInt cornerSize=aExpectedCornerSize>=0?aExpectedCornerSize:-aExpectedCornerSize;
858 //Check outside first!
860 for(TPoint pixelPos(aRect.iTl.iX-1,aRect.iTl.iY-1);pixelPos.iX<aRect.iBr.iX;pixelPos.iX++)
862 iScreenDevice->GetPixel(pixelVal, pixelPos);
863 LogColorL(pixelVal,outerColors);
865 for(TPoint pixelPos(aRect.iTl.iX,aRect.iBr.iY);pixelPos.iX<=aRect.iBr.iX;pixelPos.iX++)
867 iScreenDevice->GetPixel(pixelVal, pixelPos);
868 LogColorL(pixelVal,outerColors);
870 for(TPoint pixelPos(aRect.iTl.iX-1,aRect.iTl.iY);pixelPos.iY<=aRect.iBr.iY;pixelPos.iY++)
872 iScreenDevice->GetPixel(pixelVal, pixelPos);
873 LogColorL(pixelVal,outerColors);
875 for(TPoint pixelPos(aRect.iBr.iX,aRect.iTl.iY-1);pixelPos.iY<aRect.iBr.iY;pixelPos.iY++)
877 iScreenDevice->GetPixel(pixelVal, pixelPos);
878 LogColorL(pixelVal,outerColors);
883 cornerStart=cornerSize;
884 if (aExpectedCornerSize>0)
886 iScreenDevice->GetPixel(pixelVal, aRect.iTl);
887 LogColorL(pixelVal,outerColors);
888 iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX,aRect.iBr.iY-1));
889 LogColorL(pixelVal,outerColors);
890 iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1,aRect.iTl.iY));
891 LogColorL(pixelVal,outerColors);
892 iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1,aRect.iBr.iY-1));
893 LogColorL(pixelVal,outerColors);
897 //test inside edges (excluding 4 corner pixels - do them seperately)
898 for(TPoint pixelPos(aRect.iTl.iX+cornerStart,aRect.iTl.iY);pixelPos.iX<aRect.iBr.iX-cornerStart;pixelPos.iX++)
900 iScreenDevice->GetPixel(pixelVal, pixelPos);
901 LogColorL(pixelVal,innerColors);
903 for(TPoint pixelPos(aRect.iTl.iX+cornerStart,aRect.iBr.iY-1);pixelPos.iX<aRect.iBr.iX-cornerStart;pixelPos.iX++)
905 iScreenDevice->GetPixel(pixelVal, pixelPos);
906 LogColorL(pixelVal,innerColors);
908 for(TPoint pixelPos(aRect.iTl.iX,aRect.iTl.iY+cornerStart);pixelPos.iY<aRect.iBr.iY-cornerStart;pixelPos.iY++)
910 iScreenDevice->GetPixel(pixelVal, pixelPos);
911 LogColorL(pixelVal,innerColors);
913 for(TPoint pixelPos(aRect.iBr.iX-1,aRect.iTl.iY+cornerStart);pixelPos.iY<aRect.iBr.iY-cornerStart;pixelPos.iY++)
915 iScreenDevice->GetPixel(pixelVal, pixelPos);
916 LogColorL(pixelVal,innerColors);
918 //the 4 corner cells - not checking the whole corner area...
919 if (aExpectedCornerSize>=0)
921 iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX+cornerSize,aRect.iTl.iY+cornerSize));
922 LogColorL(pixelVal,innerColors);
923 iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iTl.iX+cornerSize,aRect.iBr.iY-1-cornerSize));
924 LogColorL(pixelVal,innerColors);
925 iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1-cornerSize,aRect.iBr.iY-1-cornerSize));
926 LogColorL(pixelVal,innerColors);
927 iScreenDevice->GetPixel(pixelVal, TPoint(aRect.iBr.iX-1-cornerSize,aRect.iTl.iY+cornerSize));
928 LogColorL(pixelVal,innerColors);
930 //OK... that has tested all the pixels, now check the result
931 if (innerColors.Count()>aOtherInnerColors+1)
933 if (outerColors.Count()>aOtherOuterColors+1)
935 for (TInt index=1;index<innerColors.Count();index++)
936 if (innerColors[0].iCount<innerColors[index].iCount)
940 for (TInt index=1;index<outerColors.Count();index++)
941 if (outerColors[0].iCount<outerColors[index].iCount)
945 for (TInt indexIn=1;indexIn<innerColors.Count();indexIn++)
946 for (TInt indexOut=0;indexOut<outerColors.Count();indexOut++)
947 if (innerColors[indexIn].iColor.Value()==outerColors[indexOut].iColor.Value())
954 TRect CWsDynamicResWinBase::PentCellRect(const TRect& aFullRect,char aStartLetter,char aEndLetter)
957 aEndLetter=aStartLetter;
960 TInt startx=(aStartLetter-1)%5;
961 TInt starty=(aStartLetter-1)/5;
962 TInt endx=(aEndLetter-1)%5;
963 TInt endy=(aEndLetter-1)/5;
968 starty=endy-starty; // e
974 startx=endx-startx; // e
976 TSize fullSize=aFullRect.Size();
977 return TRect( aFullRect.iTl.iX+fullSize.iWidth*startx/5,
978 aFullRect.iTl.iY+fullSize.iHeight*starty/5,
979 aFullRect.iTl.iX+fullSize.iWidth*(endx+1)/5,
980 aFullRect.iTl.iY+fullSize.iHeight*(endy+1)/5