fep/frontendprocessor/test/feps/TFEP2.CPP
changeset 0 eb1f2e154e89
equal deleted inserted replaced
-1:000000000000 0:eb1f2e154e89
       
     1 // Copyright (c) 2005-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  @internalComponent
       
    19 */
       
    20 
       
    21 #include <e32std.h>
       
    22 #include <e32base.h>
       
    23 #include <e32math.h>
       
    24 #include <e32keys.h>
       
    25 #include <s32strm.h>
       
    26 #include <gdi.h>
       
    27 #include <fbs.h>
       
    28 #include <w32std.h>
       
    29 #include <coemain.h>
       
    30 #include <coeaui.h>
       
    31 #include <coecntrl.h>
       
    32 #include <coefepff.h>
       
    33 #include <fepbase.h>
       
    34 #include <bautils.h>
       
    35 #include <techview/eikon.hrh>
       
    36 #include <techview/eikdialg.h>
       
    37 #include <techview/eikchkbx.h>
       
    38 #include <techview/eikbutb.h>
       
    39 
       
    40 #include "tfep2.hrh"
       
    41 #include "TFEP2.H"
       
    42 #include "tfep2com.h"
       
    43 
       
    44 #define DEBUGGING_MESSAGES
       
    45 #if defined(DEBUGGING_MESSAGES)
       
    46 #include <e32svr.h>
       
    47 #endif
       
    48 
       
    49 // constants
       
    50 
       
    51 enum TPanic
       
    52 	{
       
    53 	EPanicTimerActive1=1,
       
    54 	EPanicTimerActive2,
       
    55 	EPanicUnexpectedError1,
       
    56 	EPanicUnexpectedError2,
       
    57 	EPanicUnexpectedError3,
       
    58 	EPanicUnexpectedError4,
       
    59 	EPanicUnexpectedError5,
       
    60 	EPanicUnexpectedError6,
       
    61 	EPanicBadIndex1,
       
    62 	EPanicBadIndex2,
       
    63 	EPanicBadAttributeUid1,
       
    64 	EPanicBadAttributeUid2,
       
    65 	EPanicBadAttributeUid3,
       
    66 	EPanicBadAttributeUid4,
       
    67 	EPanicLowLevelFlagsDoNotReflectStateOfRemoteObjects,
       
    68 	EPanicArithmeticConfusion,
       
    69 	EPanicBadLengthOfTextBeforeSelection,
       
    70 	EPanicSelectionExtendsPastEndOfDocument,
       
    71 	EPanicBadLengthOfTextAfterSelection,
       
    72 	EPanicBadLengthOfSelection,
       
    73 	EPanicBadKeyCode1,
       
    74 	EPanicBadKeyCode2,
       
    75 	EPanicBadHeight,
       
    76 	EPanicIsAlreadyActive,
       
    77 	EPanicInconsistentUpperCaseSetting,
       
    78 	EPanicBadFlagAffectingWhetherActive,
       
    79 	EPanicBadKeyResponse,
       
    80 	EPanicBadCheckBoxState,
       
    81 	EPanicUnexpectedButtonId,
       
    82 	EPanicBadNumberOfAttributes
       
    83 	};
       
    84 
       
    85 #if defined(_UNICODE)
       
    86 const TUint KEllipsisCharacter=0x2026;
       
    87 #else
       
    88 const TUint KEllipsisCharacter=0x85;
       
    89 #endif
       
    90 _LIT(KLitTFEP2, "TFEP2");
       
    91 _LIT(KLitBitmapHandleSynchronizationMutexName, "0x10003eaa-Mutex"); // using the same UID here as in the MMP file
       
    92 _LIT(KLitDllNameOfWindowServerPlugIn, "\\system\\fep\\TFEP2BE.ANI");
       
    93 _LIT(KLitStatusFontTypefaceName, "arial");
       
    94 _LIT(KLitNotAvailable, "[not available]");
       
    95 //_LIT(KLitTooLong, "[too long]");
       
    96 _LIT(KLitQuotationMark, "\"");
       
    97 _LIT(KLitTextBeforeSelectionColonSpace, "Text before selection: ");
       
    98 _LIT(KLitTextAfterSelectionColonSpace, "Text after selection: ");
       
    99 _LIT(KLitSelectionColonSpace, "Selection: ");
       
   100 _LIT(KLitUpperCaseColonSpace, "Upper case: ");
       
   101 _LIT(KLitOn, "on");
       
   102 _LIT(KLitOff, "off");
       
   103 _LIT(KLitScribbleAreaColonSpace, "Scribble area: ");
       
   104 _LIT(KLitWholeScreen, "whole screen");
       
   105 _LIT(KLitWindow, "window");
       
   106 _LIT(KLitPointerBufferColonSpace, "Pointer buffer: ");
       
   107 _LIT(KLitEnabled, "enabled");
       
   108 _LIT(KLitDisabled, "disabled");
       
   109 _LIT(KLitOpeningSquareBracket, "[");
       
   110 _LIT(KLitCaptionColonSpace, "Caption: ");
       
   111 _LIT(KLitInputCapabilitiesColonSpace, "Input-capabilities: ");
       
   112 _LIT(KLitNone, "none");
       
   113 _LIT(KLitWesternNumericIntegerPositive, "Western numeric integer positive");
       
   114 _LIT(KLitWesternNumericIntegerNegative, "Western numeric integer negative");
       
   115 _LIT(KLitWesternNumericReal, "Western numeric real");
       
   116 _LIT(KLitWesternAlphabetic, "Western alphabetic");
       
   117 _LIT(KLitJapaneseHiragana, "Japanese hiragana");
       
   118 _LIT(KLitJapaneseKatakanaHalfWidth, "Japanese katakana half-width");
       
   119 _LIT(KLitJapaneseKatakanaFullWidth, "Japanese katakana full-width");
       
   120 _LIT(KLitDialableCharacters, "dialable characters");
       
   121 _LIT(KLitSecretText, "secret text");
       
   122 _LIT(KLitAllText, "all text");
       
   123 _LIT(KLitNavigation, "navigation");
       
   124 _LIT(KLitCommaSpace, ", ");
       
   125 _LIT(KLitClosingSquareBracket, "]");
       
   126 
       
   127 // local and global functions
       
   128 
       
   129 LOCAL_C void Panic(TPanic aPanic)
       
   130 	{
       
   131 	User::Panic(KLitTFEP2, aPanic);
       
   132 	}
       
   133 
       
   134 GLDEF_C TInt E32Dll(
       
   135 					)
       
   136 	{
       
   137 	return KErrNone;
       
   138 	}
       
   139 
       
   140 // CTstScribbleWindow
       
   141 
       
   142 CTstScribbleWindow* CTstScribbleWindow::NewL(CTstFep& aFep, RWindowTreeNode& aParent)
       
   143 	{
       
   144 	CTstScribbleWindow* const scribbleWindow=new(ELeave) CTstScribbleWindow(aFep);
       
   145 	CleanupStack::PushL(scribbleWindow);
       
   146 	scribbleWindow->ConstructL(aParent);
       
   147 	CleanupStack::Pop(); // scribbleWindow
       
   148 	return scribbleWindow;
       
   149 	}
       
   150 
       
   151 CTstScribbleWindow::~CTstScribbleWindow()
       
   152 	{
       
   153 	// there is no need here to call FreePointerMoveBuffer on the window, as the buffer gets freed when the window gets destroyed
       
   154 	iArrayOfPolyLines.ResetAndDestroy();
       
   155 	iArrayOfPolyLines.Close();
       
   156 	delete iTimeOutTimer;
       
   157 	}
       
   158 
       
   159 void CTstScribbleWindow::SetPointerBufferEnabled(TBool aPointerBufferEnabled)
       
   160 	{
       
   161 	RDrawableWindow& window=*DrawableWindow();
       
   162 	if (!aPointerBufferEnabled!=!(iFlags&EFlagPointerBufferActuallyEnabled)) // fold non-zero values on both sides before comparing for inequality
       
   163 		{
       
   164 		if (aPointerBufferEnabled)
       
   165 			{
       
   166 			window.EnablePointerMoveBuffer();
       
   167 			iFlags|=EFlagPointerBufferActuallyEnabled;
       
   168 			}
       
   169 		else
       
   170 			{
       
   171 			window.DisablePointerMoveBuffer();
       
   172 			iFlags&=~EFlagPointerBufferActuallyEnabled;
       
   173 			}
       
   174 		}
       
   175 	}
       
   176 
       
   177 void CTstScribbleWindow::HandleTimeOutL()
       
   178 	{
       
   179 	TInt i;
       
   180 	TInt minimumX=KMaxTInt;
       
   181 	TInt maximumX=KMinTInt;
       
   182 	for (i=iArrayOfPolyLines.Count()-1; i>=0; --i)
       
   183 		{
       
   184 		const CArrayFix<TPoint>& polyLine=*iArrayOfPolyLines[i];
       
   185 		for (TInt j=polyLine.Count()-1; j>=0; --j)
       
   186 			{
       
   187 			const TInt x=polyLine[j].iX;
       
   188 			if (minimumX>x)
       
   189 				{
       
   190 				minimumX=x;
       
   191 				}
       
   192 			if (maximumX<x)
       
   193 				{
       
   194 				maximumX=x;
       
   195 				}
       
   196 			}
       
   197 		}
       
   198 	const TInt numberOfCharacters=((maximumX-minimumX)/80)+1;
       
   199 	CArrayFix<TUint>* arrayOfCharacters=new(ELeave) CArrayFixFlat<TUint>(numberOfCharacters); // a RArray would be better than a CArrayFix, but unfortunately RArray doesn't (yet) have a TArray interface
       
   200 	CleanupStack::PushL(arrayOfCharacters);
       
   201 	const TUint baseCharacter=iFep.UpperCase()? 'A': 'a';
       
   202 	TTime homeTime;
       
   203 	homeTime.HomeTime();
       
   204 	TInt64 seedForRandomNumber=homeTime.Int64();
       
   205 	for (i=0; i<numberOfCharacters; ++i)
       
   206 		{
       
   207 		arrayOfCharacters->AppendL(baseCharacter+(Math::Rand(seedForRandomNumber)%26));
       
   208 		}
       
   209 	iFep.SimulateKeyEventsL(arrayOfCharacters->Array());
       
   210 	CancelTransactionAndDrawNow();
       
   211 	CleanupStack::PopAndDestroy(); // arrayOfCharacters
       
   212 	}
       
   213 
       
   214 void CTstScribbleWindow::CancelTransactionAndDrawNow()
       
   215 	{
       
   216 	TBool changeWasMade;
       
   217 	CancelTransaction(changeWasMade);
       
   218 	if (changeWasMade)
       
   219 		{
       
   220 		DrawNow();
       
   221 		}
       
   222 	}
       
   223 
       
   224 void CTstScribbleWindow::CancelTransaction(TBool& aChangeWasMade)
       
   225 	{
       
   226 	aChangeWasMade=EFalse;
       
   227 	iTimeOutTimer->Cancel();
       
   228 	if (iArrayOfPolyLines.Count()>0)
       
   229 		{
       
   230 		iArrayOfPolyLines.ResetAndDestroy();
       
   231 		aChangeWasMade=ETrue;
       
   232 		}
       
   233 	}
       
   234 
       
   235 void CTstScribbleWindow::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
   236 	{
       
   237 	switch (aPointerEvent.iType)
       
   238 		{
       
   239 	case TPointerEvent::EDrag:
       
   240 		{
       
   241 		if (iFlags&EFlagPointerIsDown) // this test is needed in the case where there was a "leave" when handling the TRawEvent::EButton1Down event
       
   242 			{
       
   243 			__ASSERT_DEBUG(!iTimeOutTimer->IsActive(), Panic(EPanicTimerActive1));
       
   244 			CArrayFix<TPoint>& polyLine=*iArrayOfPolyLines[iArrayOfPolyLines.Count()-1];
       
   245 			polyLine.AppendL(aPointerEvent.iPosition);
       
   246 			ActivateGc();
       
   247 			CWindowGc& graphicsContext=SystemGc();
       
   248 			graphicsContext.SetPenStyle(CGraphicsContext::ESolidPen);
       
   249 			graphicsContext.SetPenColor(KRgbBlack);
       
   250 			graphicsContext.DrawLine(polyLine[polyLine.Count()-2], aPointerEvent.iPosition);
       
   251 			graphicsContext.Plot(aPointerEvent.iPosition);
       
   252 			DeactivateGc();
       
   253 			}
       
   254 		}
       
   255 		break;
       
   256 	case TPointerEvent::EButton1Down:
       
   257 		{
       
   258 		iTimeOutTimer->Cancel();
       
   259 		CArrayFix<TPoint>* const polyLine=new(ELeave) CArrayFixSeg<TPoint>(50);
       
   260 		CleanupStack::PushL(polyLine);
       
   261 		polyLine->AppendL(aPointerEvent.iPosition);
       
   262 		User::LeaveIfError(iArrayOfPolyLines.Append(polyLine));
       
   263 		CleanupStack::Pop(); // polyLine
       
   264 		ActivateGc();
       
   265 		CWindowGc& graphicsContext=SystemGc();
       
   266 		graphicsContext.SetPenStyle(CGraphicsContext::ESolidPen);
       
   267 		graphicsContext.SetPenColor(KRgbBlack);
       
   268 		graphicsContext.Plot(aPointerEvent.iPosition);
       
   269 		DeactivateGc();
       
   270 		iFlags|=EFlagPointerIsDown;
       
   271 		if (iArrayOfPolyLines.Count()==1)
       
   272 			{
       
   273 			iCoeEnv->ForEachFepObserverCall(FepObserverHandleStartOfTransactionL); // called at the end of handling this event as it may launch a waiting dialog
       
   274 			}
       
   275 		}
       
   276 		break;
       
   277 	case TPointerEvent::EButton1Up:
       
   278 		if (iFlags&EFlagPointerIsDown) // this test is needed in the cases where (i) there was a "leave" when handling the TRawEvent::EButton1Down event, and (ii) the window server sends a TPointerEvent::EButton1Up event if ClaimPointerGrab is called when the pointer is not down (this behaviour is the window-server's spec, it is not a bug)
       
   279 			{
       
   280 			__ASSERT_DEBUG(!iTimeOutTimer->IsActive(), Panic(EPanicTimerActive2));
       
   281 			iTimeOutTimer->After(ETimeOutInMicroSeconds);
       
   282 			iFlags&=~EFlagPointerIsDown;
       
   283 			}
       
   284 		break;
       
   285 #if defined(__GCC32__)
       
   286 	default:
       
   287 		break;
       
   288 #endif
       
   289 		}
       
   290 	}
       
   291 
       
   292 void CTstScribbleWindow::HandlePointerBufferReadyL()
       
   293 	{
       
   294 	TPoint arrayOfPoints[ENumberOfPointsInBuffer];
       
   295 	TPtr8 bufferOfPoints(REINTERPRET_CAST(TUint8*, arrayOfPoints), 0, ENumberOfPointsInBuffer*sizeof(TPoint));
       
   296 	User::LeaveIfError(DrawableWindow()->RetrievePointerMoveBuffer(bufferOfPoints));
       
   297 	if (iFlags&EFlagPointerIsDown) // this test is needed in the case where there was a "leave" when handling the TRawEvent::EButton1Down event
       
   298 		{
       
   299 		const TInt numberOfPointsInBuffer=bufferOfPoints.Length()/sizeof(TPoint);
       
   300 		if (numberOfPointsInBuffer>0)
       
   301 			{
       
   302 			CArrayFix<TPoint>& polyLine=*iArrayOfPolyLines[iArrayOfPolyLines.Count()-1];
       
   303 			for (TInt i=0; i<numberOfPointsInBuffer; ++i)
       
   304 				{
       
   305 				polyLine.AppendL(arrayOfPoints[i]);
       
   306 				}
       
   307 			ActivateGc();
       
   308 			CWindowGc& graphicsContext=SystemGc();
       
   309 			graphicsContext.SetPenStyle(CGraphicsContext::ESolidPen);
       
   310 			graphicsContext.SetPenColor(KRgbBlack);
       
   311 			graphicsContext.DrawLine(polyLine[polyLine.Count()-(numberOfPointsInBuffer+1)], arrayOfPoints[0]);
       
   312 			graphicsContext.DrawPolyLine(arrayOfPoints, numberOfPointsInBuffer); // draws the end-point of the last line segment of the poly-line
       
   313 			DeactivateGc();
       
   314 			}
       
   315 		}
       
   316 	}
       
   317 
       
   318 CTstScribbleWindow::CTstScribbleWindow(CTstFep& aFep)
       
   319 	:iFep(aFep),
       
   320 	 iFlags(0),
       
   321 	 iArrayOfPolyLines(12),
       
   322 	 iTimeOutTimer(NULL)
       
   323 	{
       
   324 	}
       
   325 
       
   326 void CTstScribbleWindow::ConstructL(RWindowTreeNode& aParent)
       
   327 	{
       
   328 	CreateWindowL(aParent);
       
   329 	EnableDragEvents();
       
   330 	ClaimPointerGrab();
       
   331 	SetNonFocusing();
       
   332 	RDrawableWindow& window=*DrawableWindow();
       
   333 	User::LeaveIfError(window.AllocPointerMoveBuffer(ENumberOfPointsInBuffer, 0));
       
   334 	iFlags|=EFlagPointerBufferActuallyEnabled;
       
   335 	iTimeOutTimer=CTimeOutTimer::NewL(*this);
       
   336 	}
       
   337 
       
   338 void CTstScribbleWindow::Draw(const TRect&) const
       
   339 	{
       
   340 	CWindowGc& graphicsContext=SystemGc();
       
   341 	graphicsContext.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   342 	graphicsContext.SetBrushColor(KRgbWhite);
       
   343 	graphicsContext.SetPenStyle(CGraphicsContext::ESolidPen);
       
   344 	graphicsContext.SetPenColor(KRgbWhite);
       
   345 	graphicsContext.DrawRect(Rect());
       
   346 	graphicsContext.SetPenColor(KRgbBlack);
       
   347 	for (TInt i=iArrayOfPolyLines.Count()-1; i>=0; --i)
       
   348 		{
       
   349 		graphicsContext.DrawPolyLine(iArrayOfPolyLines[i]); // draws the end-point of the last line segment of the poly-line
       
   350 		}
       
   351 	}
       
   352 
       
   353 // CTstScribbleWindow::CTimeOutTimer
       
   354 
       
   355 CTstScribbleWindow::CTimeOutTimer* CTstScribbleWindow::CTimeOutTimer::NewL(CTstScribbleWindow& aScribbleWindow)
       
   356 	{
       
   357 	CTimeOutTimer* const timeOutTimer=new(ELeave) CTimeOutTimer(aScribbleWindow);
       
   358 	CleanupStack::PushL(timeOutTimer);
       
   359 	CActiveScheduler::Add(timeOutTimer);
       
   360 	timeOutTimer->ConstructL();
       
   361 	CleanupStack::Pop(); // timeOutTimer
       
   362 	return timeOutTimer;
       
   363 	}
       
   364 
       
   365 CTstScribbleWindow::CTimeOutTimer::~CTimeOutTimer()
       
   366 	{
       
   367 	Cancel();
       
   368 	}
       
   369 
       
   370 CTstScribbleWindow::CTimeOutTimer::CTimeOutTimer(CTstScribbleWindow& aScribbleWindow)
       
   371 	:CTimer(EPriorityLow),
       
   372 	 iScribbleWindow(aScribbleWindow)
       
   373 	{
       
   374 	}
       
   375 
       
   376 void CTstScribbleWindow::CTimeOutTimer::RunL()
       
   377 	{
       
   378 	iScribbleWindow.HandleTimeOutL();
       
   379 	}
       
   380 
       
   381 // CTstWholeScreenScribbleArea
       
   382 
       
   383 CTstWholeScreenScribbleArea* CTstWholeScreenScribbleArea::NewL(RWsSession& aWindowServerSession, RWindowGroup& aWindowGroup, const TSize& aScreenSize, TDisplayMode aDisplayMode, const TDesC& aDllName)
       
   384 	{
       
   385 	CTstWholeScreenScribbleArea* const wholeScreenScribbleArea=new(ELeave) CTstWholeScreenScribbleArea(aWindowServerSession);
       
   386 	CleanupStack::PushL(wholeScreenScribbleArea);
       
   387 	wholeScreenScribbleArea->ConstructL(aWindowGroup, aScreenSize, aDisplayMode, aDllName);
       
   388 	CleanupStack::Pop(); // wholeScreenScribbleArea
       
   389 	return wholeScreenScribbleArea;
       
   390 	}
       
   391 
       
   392 CTstWholeScreenScribbleArea::~CTstWholeScreenScribbleArea()
       
   393 	{
       
   394 	if (iFlags&EFlagMutexIsConstructed)
       
   395 		{
       
   396 		iMutex.Wait();
       
   397 		iHandWritingRecognizer.Close();
       
   398 		iSprite.Close();
       
   399 		iDll.Close();
       
   400 		delete iSpriteMember.iBitmap;
       
   401 		delete iSpriteMember.iMaskBitmap;
       
   402 		iMutex.Signal();
       
   403 		}
       
   404 	}
       
   405 
       
   406 CTstWholeScreenScribbleArea::CTstWholeScreenScribbleArea(RWsSession& aWindowServerSession)
       
   407 	:iFlags(0),
       
   408 	 iDll(aWindowServerSession),
       
   409 	 iSprite(aWindowServerSession)
       
   410 	{
       
   411 	iSpriteMember.iBitmap=NULL;
       
   412 	iSpriteMember.iMaskBitmap=NULL;
       
   413 	}
       
   414 
       
   415 void CTstWholeScreenScribbleArea::ConstructL(RWindowGroup& aWindowGroup, const TSize& aScreenSize, TDisplayMode aDisplayMode, const TDesC& aDllName)
       
   416 	{
       
   417 	// the mutex *must* be created first as it is used in the construction and destruction routines of this class
       
   418 	TInt error=iMutex.CreateGlobal(KLitBitmapHandleSynchronizationMutexName);
       
   419 	if (error==KErrAlreadyExists)
       
   420 		{
       
   421 		error=iMutex.OpenGlobal(KLitBitmapHandleSynchronizationMutexName);
       
   422 		}
       
   423 	User::LeaveIfError(error);
       
   424 	iFlags|=EFlagMutexIsConstructed;
       
   425 	iMutex.Wait();
       
   426 	CleanupStack::PushL(TCleanupItem(SignalMutex, &iMutex));
       
   427 	User::LeaveIfError(iDll.Load(aDllName));
       
   428 	User::LeaveIfError(iSprite.Construct(aWindowGroup, TPoint(0, 0), ESpriteNoChildClip|ESpriteNoShadows));
       
   429 	STstBitmapHandles bitmapHandles;
       
   430 	iHandWritingRecognizer=RHandWritingRecognizer(iDll);
       
   431 	iHandWritingRecognizer.ConstructL(iSprite, bitmapHandles);
       
   432 	iSpriteMember.iBitmap=CreateBitmapL(bitmapHandles.iMain, aScreenSize, aDisplayMode);
       
   433 	iSpriteMember.iMaskBitmap=CreateBitmapL(bitmapHandles.iMask, aScreenSize, aDisplayMode);
       
   434 	iSpriteMember.iInvertMask=ETrue;
       
   435 	iSpriteMember.iDrawMode=CGraphicsContext::EDrawModePEN;
       
   436 	iSpriteMember.iOffset.iX=0;
       
   437 	iSpriteMember.iOffset.iY=0;
       
   438 	iSpriteMember.iInterval=0;
       
   439 	User::LeaveIfError(iSprite.AppendMember(iSpriteMember));
       
   440 	iHandWritingRecognizer.FinishConstructionL();
       
   441 	CleanupStack::PopAndDestroy(); // TCleanupItem(SignalMutex, &iMutex)
       
   442 	}
       
   443 
       
   444 CFbsBitmap* CTstWholeScreenScribbleArea::CreateBitmapL(TInt aHandleOfBitmapToUse, const TSize& aScreenSize, TDisplayMode aDisplayMode)
       
   445 	{
       
   446 	CFbsBitmap* const bitmap=new(ELeave) CFbsBitmap;
       
   447 	CleanupStack::PushL(bitmap);
       
   448 	if (aHandleOfBitmapToUse!=0)
       
   449 		{
       
   450 		User::LeaveIfError(bitmap->Duplicate(aHandleOfBitmapToUse));
       
   451 		}
       
   452 	else
       
   453 		{
       
   454 		User::LeaveIfError(bitmap->Create(aScreenSize, aDisplayMode)); // bitmaps are automatically cleared to white when first created
       
   455 		}
       
   456 	CleanupStack::Pop(); // bitmap
       
   457 	return bitmap;
       
   458 	}
       
   459 
       
   460 void CTstWholeScreenScribbleArea::SignalMutex(TAny* aMutex)
       
   461 	{
       
   462 	STATIC_CAST(RMutex*, aMutex)->Signal();
       
   463 	}
       
   464 
       
   465 // CTstWholeScreenScribbleArea::RHandWritingRecognizer
       
   466 
       
   467 void CTstWholeScreenScribbleArea::RHandWritingRecognizer::ConstructL(const RWsSprite& aSprite, STstBitmapHandles& aBitmapHandles)
       
   468 	{
       
   469 	TPckg<STstBitmapHandles> bitmapHandles(aBitmapHandles);
       
   470 	TIpcArgs ipcArgs;
       
   471 	ipcArgs.Set(EIpcSlot, &bitmapHandles);
       
   472 	User::LeaveIfError(RAnim::Construct(aSprite, EAnimTypeHandWritingRecognizer, KNullDesC8, ipcArgs));
       
   473 	}
       
   474 
       
   475 void CTstWholeScreenScribbleArea::RHandWritingRecognizer::FinishConstructionL()
       
   476 	{
       
   477 	const TInt error=CommandReply(EHandWritingRecognizerCommandFinishConstructionL, KNullDesC8());
       
   478 	__ASSERT_ALWAYS(error==KErrNone, Panic(EPanicUnexpectedError1));
       
   479 	}
       
   480 
       
   481 void CTstWholeScreenScribbleArea::RHandWritingRecognizer::RequestNotificationOfStartOfTransaction(TRequestStatus& aRequestStatus)
       
   482 	{
       
   483 	AsyncCommandReply(aRequestStatus, EHandWritingRecognizerCommandRequestNotificationOfStartOfTransaction, TIpcArgs());
       
   484 	}
       
   485 
       
   486 void CTstWholeScreenScribbleArea::RHandWritingRecognizer::CancelRequestForNotificationOfStartOfTransaction()
       
   487 	{
       
   488 	const TInt error=CommandReply(EHandWritingRecognizerCommandCancelRequestForNotificationOfStartOfTransaction);
       
   489 	__ASSERT_ALWAYS(error==KErrNone, Panic(EPanicUnexpectedError3));
       
   490 	}
       
   491 
       
   492 void CTstWholeScreenScribbleArea::RHandWritingRecognizer::RequestCharacters(TRequestStatus& aRequestStatus, TDes8& aCharacterBuffer, TBool /*aUpperCase*/)
       
   493 	{
       
   494 	TIpcArgs ipcArgs;
       
   495 	ipcArgs.Set(EAsyncIpcSlot, &aCharacterBuffer);
       
   496 	AsyncCommandReply(aRequestStatus, EHandWritingRecognizerCommandRequestCharacters, ipcArgs);
       
   497 	}
       
   498 
       
   499 void CTstWholeScreenScribbleArea::RHandWritingRecognizer::CancelRequestForCharacters()
       
   500 	{
       
   501 	const TInt error=CommandReply(EHandWritingRecognizerCommandCancelRequestForCharacters);
       
   502 	__ASSERT_ALWAYS(error==KErrNone, Panic(EPanicUnexpectedError5));
       
   503 	}
       
   504 
       
   505 void CTstWholeScreenScribbleArea::RHandWritingRecognizer::SetUpperCase(TBool aUpperCase)
       
   506 	{
       
   507 	TPckgBuf<STstParametersForHandWritingRecognizerCommandSetUpperCase> parameters;
       
   508 	parameters().iUpperCase=aUpperCase;
       
   509 	const TInt error=CommandReply(EHandWritingRecognizerCommandSetUpperCase, parameters);
       
   510 	__ASSERT_ALWAYS(error==KErrNone, Panic(EPanicUnexpectedError6));
       
   511 	}
       
   512 
       
   513 // CTstControl
       
   514 
       
   515 CTstControl* CTstControl::NewL(CTstFep& aFep)
       
   516 	{
       
   517 	CTstControl* const control=new(ELeave) CTstControl(aFep);
       
   518 	CleanupStack::PushL(control);
       
   519 	control->ConstructL();
       
   520 	CleanupStack::Pop(); // control
       
   521 	return control;
       
   522 	}
       
   523 
       
   524 CTstControl::~CTstControl()
       
   525 	{
       
   526 	delete iScribbleWindow;
       
   527 	delete iHandlerForStartOfTransaction;
       
   528 	delete iHandlerForCharacters;
       
   529 	delete iWholeScreenScribbleArea; // must be deleted after iHandlerForStartOfTransaction and iHandlerForCharacters as they both have a reference to it
       
   530 	iCoeEnv->ReleaseScreenFont(iStatusFont);
       
   531 	STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi())->RemoveFromStack(this);
       
   532 	}
       
   533 
       
   534 void CTstControl::CancelTransaction()
       
   535 	{
       
   536 	iScribbleWindow->CancelTransactionAndDrawNow();
       
   537 	}
       
   538 
       
   539 void CTstControl::IsOnHasChangedState()
       
   540 	{
       
   541 	ChangeSetupAndDrawNow(NULL);
       
   542 	}
       
   543 
       
   544 void CTstControl::OfferPointerEventL(CCoeFep::TEventResponse& aEventResponse, const TPointerEvent& aPointerEvent, const CCoeControl* aWindowOwningControl)
       
   545 	{
       
   546 	// this function must correctly set aEventResponse *before* calling anything that can leave
       
   547 	if (aWindowOwningControl==this)
       
   548 		{
       
   549 		aEventResponse=CCoeFep::EEventWasConsumed;
       
   550 		HandlePointerEventL(aPointerEvent);
       
   551 		}
       
   552 	else if (aWindowOwningControl==iScribbleWindow)
       
   553 		{
       
   554 		aEventResponse=CCoeFep::EEventWasConsumed;
       
   555 		iScribbleWindow->HandlePointerEventL(aPointerEvent);
       
   556 		}
       
   557 	else
       
   558 		{
       
   559 		aEventResponse=CCoeFep::EEventWasNotConsumed;
       
   560 		}
       
   561 	}
       
   562 
       
   563 void CTstControl::OfferPointerBufferReadyEventL(CCoeFep::TEventResponse& aEventResponse, const CCoeControl* aWindowOwningControl)
       
   564 	{
       
   565 	// this function must correctly set aEventResponse *before* calling anything that can leave
       
   566 	if (aWindowOwningControl==iScribbleWindow)
       
   567 		{
       
   568 		aEventResponse=CCoeFep::EEventWasConsumed;
       
   569 		iScribbleWindow->HandlePointerBufferReadyL();
       
   570 		}
       
   571 	else
       
   572 		{
       
   573 		aEventResponse=CCoeFep::EEventWasNotConsumed;
       
   574 		}
       
   575 	}
       
   576 
       
   577 TInt CTstControl::NumberOfAttributes()
       
   578 	{
       
   579 	return 3;
       
   580 	}
       
   581 
       
   582 TUid CTstControl::AttributeAtIndex(TInt aIndex)
       
   583 	{
       
   584 	switch (aIndex)
       
   585 		{
       
   586 	case 0:
       
   587 		return TUid::Uid(ETstUpperCaseUid);
       
   588 	case 1:
       
   589 		return TUid::Uid(ETstWholeScreenUid);
       
   590 	case 2:
       
   591 		return TUid::Uid(ETstPointerBufferEnabledUid);
       
   592 #if defined(_DEBUG)
       
   593 	default:
       
   594 		Panic(EPanicBadIndex1);
       
   595 		break;
       
   596 #endif
       
   597 		}
       
   598 	return KNullUid;
       
   599 	}
       
   600 
       
   601 void CTstControl::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream) const
       
   602 	{
       
   603 	switch (aAttributeUid.iUid)
       
   604 		{
       
   605 	case ETstUpperCaseUid:
       
   606 		aStream.WriteUint8L((iFlags&EFlagUpperCase)!=0);
       
   607 		break;
       
   608 	case ETstWholeScreenUid:
       
   609 		aStream.WriteUint8L((iFlags&EFlagWholeScreen)!=0);
       
   610 		break;
       
   611 	case ETstPointerBufferEnabledUid:
       
   612 		aStream.WriteUint8L((iFlags&EFlagPointerBufferEnabled)!=0);
       
   613 		break;
       
   614 #if defined(_DEBUG)
       
   615 	default:
       
   616 		Panic(EPanicBadAttributeUid1);
       
   617 		break;
       
   618 #endif
       
   619 		}
       
   620 	}
       
   621 
       
   622 void CTstControl::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)
       
   623 	{
       
   624 	switch (aAttributeUid.iUid)
       
   625 		{
       
   626 	case ETstUpperCaseUid:
       
   627 		ChangeSetupAndDrawNow(SetUpperCase, aStream.ReadUint8L());
       
   628 		break;
       
   629 	case ETstWholeScreenUid:
       
   630 		ChangeSetupAndDrawNow(SetWholeScreen, aStream.ReadUint8L());
       
   631 		break;
       
   632 	case ETstPointerBufferEnabledUid:
       
   633 		ChangeSetupAndDrawNow(SetPointerBufferEnabled, aStream.ReadUint8L());
       
   634 		break;
       
   635 #if defined(_DEBUG)
       
   636 	default:
       
   637 		Panic(EPanicBadAttributeUid2);
       
   638 		break;
       
   639 #endif
       
   640 		}
       
   641 	}
       
   642 
       
   643 void CTstControl::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream, TBool aUpperCase, TBool aWholeScreen, TBool aPointerBufferEnabled)
       
   644 	{
       
   645 	switch (aAttributeUid.iUid)
       
   646 		{
       
   647 	case ETstUpperCaseUid:
       
   648 		aStream.WriteUint8L(aUpperCase!=EFalse);
       
   649 		break;
       
   650 	case ETstWholeScreenUid:
       
   651 		aStream.WriteUint8L(aWholeScreen!=EFalse);
       
   652 		break;
       
   653 	case ETstPointerBufferEnabledUid:
       
   654 		aStream.WriteUint8L(aPointerBufferEnabled!=EFalse);
       
   655 		break;
       
   656 #if defined(_DEBUG)
       
   657 	default:
       
   658 		Panic(EPanicBadAttributeUid3);
       
   659 		break;
       
   660 #endif
       
   661 		}
       
   662 	}
       
   663 
       
   664 void CTstControl::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream, TBool& aUpperCase, TBool& aWholeScreen, TBool& aPointerBufferEnabled)
       
   665 	{
       
   666 	switch (aAttributeUid.iUid)
       
   667 		{
       
   668 	case ETstUpperCaseUid:
       
   669 		aUpperCase=aStream.ReadUint8L();
       
   670 		break;
       
   671 	case ETstWholeScreenUid:
       
   672 		aWholeScreen=aStream.ReadUint8L();
       
   673 		break;
       
   674 	case ETstPointerBufferEnabledUid:
       
   675 		aPointerBufferEnabled=aStream.ReadUint8L();
       
   676 		break;
       
   677 #if defined(_DEBUG)
       
   678 	default:
       
   679 		Panic(EPanicBadAttributeUid4);
       
   680 		break;
       
   681 #endif
       
   682 		}
       
   683 	}
       
   684 
       
   685 void CTstControl::HandleGainingForeground()
       
   686 	{
       
   687 	DrawableWindow()->MoveToGroup(iCoeEnv->WsSession().GetFocusWindowGroup()); // ignore the error returned
       
   688 	ChangeSetupAndDrawNow(SetForeground, ETrue);
       
   689 	}
       
   690 
       
   691 void CTstControl::HandleLosingForeground()
       
   692 	{
       
   693 	ChangeSetupAndDrawNow(SetForeground, EFalse);
       
   694 	}
       
   695 
       
   696 void CTstControl::HandleChangeInFocus()
       
   697 	{
       
   698 	ChangeSetupAndDrawNow(SetInputCapabilities);
       
   699 	}
       
   700 
       
   701 void CTstControl::HandleDestructionOfFocusedItem()
       
   702 	{
       
   703 	if (!IsBeingDestroyed())
       
   704 		{
       
   705 		ChangeSetupAndDrawNow(SetInputCapabilities);
       
   706 		}
       
   707 	}
       
   708 
       
   709 CTstControl::CTstControl(CTstFep& aFep)
       
   710 	:iFep(aFep),
       
   711 	 iFlags(0),
       
   712 	 iInputCapabilities(TCoeInputCapabilities::ENone),
       
   713 	 iScribbleWindow(NULL),
       
   714 	 iWholeScreenScribbleArea(NULL),
       
   715 	 iHandlerForStartOfTransaction(NULL),
       
   716 	 iHandlerForCharacters(NULL),
       
   717 	 iStatusFont(NULL),
       
   718 	 iPositionOnWindowBeingDragged(0, 0)
       
   719 	{
       
   720 	}
       
   721 
       
   722 void CTstControl::ConstructL()
       
   723 	{
       
   724 	RWindowGroup& windowGroup=iCoeEnv->RootWin();
       
   725 	CreateWindowL();
       
   726 	EnableDragEvents();
       
   727 	ClaimPointerGrab();
       
   728 	SetNonFocusing();
       
   729 	RDrawableWindow& window=*DrawableWindow();
       
   730 	window.SetOrdinalPosition(0, ECoeWinPriorityFep);
       
   731 	window.SetShadowHeight(3);
       
   732 	iScribbleWindow=CTstScribbleWindow::NewL(iFep, window);
       
   733 	RWsSession& windowServerSession=iCoeEnv->WsSession();
       
   734 	CWsScreenDevice& screenDevice=*iCoeEnv->ScreenDevice();
       
   735 	const TSize screenSize=screenDevice.SizeInPixels();
       
   736 	iWholeScreenScribbleArea=CTstWholeScreenScribbleArea::NewL(windowServerSession, windowGroup, screenSize, screenDevice.DisplayMode(), KLitDllNameOfWindowServerPlugIn);
       
   737 	iHandlerForStartOfTransaction=CHandlerForStartOfTransaction::NewL(*iWholeScreenScribbleArea, *iCoeEnv);
       
   738 	const TBool foreground=(windowGroup.Identifier()==windowServerSession.GetFocusWindowGroup());
       
   739 	iHandlerForCharacters=CHandlerForCharacters::NewL(*iWholeScreenScribbleArea, iFep, foreground);
       
   740 	iStatusFont=iCoeEnv->CreateScreenFontL(TFontSpec(KLitStatusFontTypefaceName, 120));
       
   741 	const TInt statusFontHeightInPixels=iStatusFont->HeightInPixels();
       
   742 	const TSize size(320, 1+EHeightOfScribbleWindow+EGapAboveTopLine+statusFontHeightInPixels+(4*(EGapBetweenEachLine+statusFontHeightInPixels))+EGapBelowBottomLine+1);
       
   743 	SetExtent(TPoint(screenSize.iWidth-(size.iWidth+10), screenSize.iHeight-(size.iHeight+10)), size);
       
   744 	iScribbleWindow->SetExtent(TPoint(1, 1), TSize(size.iWidth-2, EHeightOfScribbleWindow));
       
   745 	STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi())->AddToStackL(this, ECoeStackPriorityFep, ECoeStackFlagRefusesFocus|ECoeStackFlagSharable);
       
   746 	__ASSERT_DEBUG((iFlags&EFlagActuallyWholeScreen)==0, Panic(EPanicLowLevelFlagsDoNotReflectStateOfRemoteObjects));
       
   747 	ChangeSetupAndDrawNow(SetForeground, foreground);
       
   748 	ChangeSetupAndDrawNow(SetFocus, EFalse);
       
   749 	ChangeSetupAndDrawNow(SetUpperCase, EFalse);
       
   750 	ChangeSetupAndDrawNow(SetWholeScreen, ETrue);
       
   751 	ChangeSetupAndDrawNow(SetPointerBufferEnabled, ETrue);
       
   752 	ChangeSetupAndDrawNow(SetInputCapabilities);
       
   753 	}
       
   754 
       
   755 void CTstControl::SetForeground(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
       
   756 	{
       
   757 	SetFlag(aControl, aChangeWasMade, aParameter, EFlagForeground);
       
   758 	if (aChangeWasMade)
       
   759 		{
       
   760 		aControl.iHandlerForCharacters->SetForeground(aParameter); // background TFEP2 instances must not have a request for characters outstanding, as the corresponding server-side object may intercept raw events from the rightful TFEP2 instance in the foreground, hence the need for this function
       
   761 		if (aParameter)
       
   762 			{
       
   763 			aControl.iHandlerForCharacters->SetUpperCase(aControl.iFlags&EFlagUpperCase);
       
   764 			aControl.DoSetWholeScreen(aControl.iFlags&EFlagWholeScreen);
       
   765 			aControl.iScribbleWindow->SetPointerBufferEnabled(aControl.iFlags&EFlagPointerBufferEnabled);
       
   766 			}
       
   767 		}
       
   768 	}
       
   769 
       
   770 void CTstControl::SetFocus(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
       
   771 	{
       
   772 	aChangeWasMade=EFalse;
       
   773 	if (!aParameter!=!aControl.IsFocused()) // fold non-zero values on both sides before comparing for inequality
       
   774 		{
       
   775 		CCoeAppUi& appUi=*STATIC_CAST(CCoeAppUi*, aControl.iCoeEnv->AppUi());
       
   776 		appUi.UpdateStackedControlFlags(&aControl, (aParameter? 0: ECoeStackFlagRefusesFocus), ECoeStackFlagRefusesFocus);
       
   777 		appUi.HandleStackChanged();
       
   778 		aControl.iScribbleWindow->MakeVisible(!aParameter);
       
   779 		aChangeWasMade=ETrue;
       
   780 		}
       
   781 	}
       
   782 
       
   783 void CTstControl::SetUpperCase(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
       
   784 	{
       
   785 	SetFlag(aControl, aChangeWasMade, aParameter, EFlagUpperCase);
       
   786 	if (aChangeWasMade && (aControl.iFlags&EFlagForeground))
       
   787 		{
       
   788 		aControl.iHandlerForCharacters->SetUpperCase(aParameter);
       
   789 		}
       
   790 	}
       
   791 
       
   792 void CTstControl::SetWholeScreen(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
       
   793 	{
       
   794 	SetFlag(aControl, aChangeWasMade, aParameter, EFlagWholeScreen);
       
   795 	if (aChangeWasMade && (aControl.iFlags&EFlagForeground))
       
   796 		{
       
   797 		aControl.DoSetWholeScreen(aParameter);
       
   798 		}
       
   799 	}
       
   800 
       
   801 void CTstControl::SetPointerBufferEnabled(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter)
       
   802 	{
       
   803 	SetFlag(aControl, aChangeWasMade, aParameter, EFlagPointerBufferEnabled);
       
   804 	if (aChangeWasMade && (aControl.iFlags&EFlagForeground))
       
   805 		{
       
   806 		aControl.iScribbleWindow->SetPointerBufferEnabled(aParameter);
       
   807 		}
       
   808 	}
       
   809 
       
   810 void CTstControl::SetInputCapabilities(CTstControl& aControl, TBool& aChangeWasMade, TInt)
       
   811 	{
       
   812 	aChangeWasMade=EFalse;
       
   813 	if (!aControl.IsFocused())
       
   814 		{
       
   815 		const TCoeInputCapabilities inputCapabilities(STATIC_CAST(const CCoeAppUi*, aControl.iCoeEnv->AppUi())->InputCapabilities());
       
   816 		if (aControl.iInputCapabilities!=inputCapabilities)
       
   817 			{
       
   818 			aControl.iInputCapabilities=inputCapabilities;
       
   819 			aChangeWasMade=ETrue;
       
   820 			}
       
   821 		}
       
   822 	}
       
   823 
       
   824 void CTstControl::SetFlag(CTstControl& aControl, TBool& aChangeWasMade, TInt aParameter, TUint aFlag)
       
   825 	{
       
   826 	aChangeWasMade=EFalse;
       
   827 	if (!aParameter!=!(aControl.iFlags&aFlag)) // fold non-zero values on both sides before comparing for inequality
       
   828 		{
       
   829 		aControl.iFlags^=aFlag;
       
   830 		aChangeWasMade=ETrue;
       
   831 		}
       
   832 	}
       
   833 
       
   834 void CTstControl::DoSetWholeScreen(TBool aWholeScreen)
       
   835 	{
       
   836 	if (!aWholeScreen!=!(iFlags&EFlagActuallyWholeScreen)) // fold non-zero values on both sides before comparing for inequality
       
   837 		{
       
   838 		TInt windowAdjustmentY;
       
   839 		TInt scribbleWindowPositionY;
       
   840 		if (aWholeScreen)
       
   841 			{
       
   842 			windowAdjustmentY=EHeightOfScribbleWindow;
       
   843 			scribbleWindowPositionY=-EHeightOfScribbleWindow;
       
   844 			iFlags|=EFlagActuallyWholeScreen;
       
   845 			}
       
   846 		else 
       
   847 			{
       
   848 			windowAdjustmentY=-EHeightOfScribbleWindow;
       
   849 			scribbleWindowPositionY=1;
       
   850 			iFlags&=~EFlagActuallyWholeScreen;
       
   851 			}
       
   852 		iHandlerForCharacters->SetWholeScreen(aWholeScreen);
       
   853 		iScribbleWindow->SetPosition(TPoint(1, scribbleWindowPositionY));
       
   854 		TRect rectangle(Position(), Size()); // creating rectangle from Rect() will give the wrong result as this control owns a window (its top left position would come out as TPoint(0, 0) rather than what Position() returns)
       
   855 		rectangle.iTl.iY+=windowAdjustmentY;
       
   856 		SetRect(rectangle);
       
   857 		}
       
   858 	}
       
   859 
       
   860 void CTstControl::ChangeSetupAndDrawNow(FChangeFunction aChangeFunction, TInt aParameter)
       
   861 	{
       
   862 	TBool needToDraw=EFalse;
       
   863 	{
       
   864 	TBool changeWasMade;
       
   865 	iScribbleWindow->CancelTransaction(changeWasMade);
       
   866 	if (changeWasMade)
       
   867 		{
       
   868 		needToDraw=ETrue;
       
   869 		}
       
   870 	}
       
   871 	if (aChangeFunction!=NULL)
       
   872 		{
       
   873 		TBool changeWasMade;
       
   874 		(*aChangeFunction)(*this, changeWasMade, aParameter);
       
   875 		if (changeWasMade)
       
   876 			{
       
   877 			needToDraw=ETrue;
       
   878 			}
       
   879 		}
       
   880 	const TBool isOn=iFep.IsOn();
       
   881 	iHandlerForCharacters->SetIsOn(isOn);
       
   882 	const TBool shouldBeVisible=(isOn && (iFlags&EFlagForeground));
       
   883 	if (!IsVisible()!=!shouldBeVisible) // fold non-zero values on both sides before comparing for inequality
       
   884 		{
       
   885 		MakeVisible(shouldBeVisible);
       
   886 		needToDraw=EFalse;
       
   887 		}
       
   888 	if (needToDraw)
       
   889 		{
       
   890 		DrawNow();
       
   891 		}
       
   892 	}
       
   893 
       
   894 TKeyResponse CTstControl::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aEventCode)
       
   895 	{
       
   896 	// CTstFep::OfferKeyEventL assumes that this will not leave if it returns EKeyWasNotConsumed
       
   897 	FEP_START_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, aEventCode);
       
   898 	const TBool isFocused=IsFocused();
       
   899 	const TCharUC keyCodeInUpperCase=aKeyEvent.iCode;
       
   900 	if ((aKeyEvent.iModifiers&EModifierRightShift) && !isFocused)
       
   901 		{
       
   902 		switch (keyCodeInUpperCase)
       
   903 			{
       
   904 		case 'F':
       
   905 			ChangeSetupAndDrawNow(SetFocus, ETrue);
       
   906 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
       
   907 		case 'C':
       
   908 			ChangeSetupAndDrawNow(SetUpperCase, !(iFlags&EFlagUpperCase));
       
   909 			iFep.WriteAttributeDataAndBroadcastL(TUid::Uid(ETstUpperCaseUid));
       
   910 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
       
   911 		case 'W':
       
   912 			ChangeSetupAndDrawNow(SetWholeScreen, !(iFlags&EFlagWholeScreen));
       
   913 			iFep.WriteAttributeDataAndBroadcastL(TUid::Uid(ETstWholeScreenUid));
       
   914 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
       
   915 		case 'P':
       
   916 			ChangeSetupAndDrawNow(SetPointerBufferEnabled, !(iFlags&EFlagPointerBufferEnabled));
       
   917 			iFep.WriteAttributeDataAndBroadcastL(TUid::Uid(ETstPointerBufferEnabledUid));
       
   918 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
       
   919 		case 'N':
       
   920 			{
       
   921 			const MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
       
   922 			if (fepAwareTextEditor==NULL)
       
   923 				{
       
   924 				User::InfoPrint(KLitNotAvailable);
       
   925 				}
       
   926 			else
       
   927 				{
       
   928 				TCursorSelection cursorSelection;
       
   929 				fepAwareTextEditor->GetCursorSelectionForFep(cursorSelection);
       
   930 				TPoint position;
       
   931 				TInt height;
       
   932 				TInt ascent;
       
   933 				fepAwareTextEditor->GetScreenCoordinatesForFepL(position,height,ascent,cursorSelection.LowerPos());
       
   934 				position.iY+=height-ascent;
       
   935 				const TSize screenSize(iCoeEnv->ScreenDevice()->SizeInPixels());
       
   936 				const TInt xMaximum=screenSize.iWidth-iSize.iWidth;
       
   937 				if ((position.iX<0) || (xMaximum<0))
       
   938 					{
       
   939 					position.iX=0;
       
   940 					}
       
   941 				else if (position.iX>xMaximum)
       
   942 					{
       
   943 					position.iX=xMaximum;
       
   944 					}
       
   945 				const TInt yMaximum=screenSize.iHeight-iSize.iHeight;
       
   946 				if ((position.iY<0) || (yMaximum<0))
       
   947 					{
       
   948 					position.iY=0;
       
   949 					}
       
   950 				else
       
   951 					{
       
   952 					const TInt yOverlapIfFepIsBelow=position.iY-yMaximum;
       
   953 					if (yOverlapIfFepIsBelow>0)
       
   954 						{
       
   955 						const TInt yPositionIfFepIsAbove=Max(0, position.iY-(height+iSize.iHeight));
       
   956 						const TInt yOverlapIfFepIsAbove=(yPositionIfFepIsAbove+iSize.iHeight)-(position.iY-height);
       
   957 						if (yOverlapIfFepIsAbove<yOverlapIfFepIsBelow)
       
   958 							{
       
   959 							position.iY=yPositionIfFepIsAbove;
       
   960 							}
       
   961 						}
       
   962 					}
       
   963 				SetPosition(position);
       
   964 				}
       
   965 			}
       
   966 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
       
   967 		case 'B':
       
   968 		case 'A':
       
   969 		case 'S':
       
   970 			{
       
   971 			const MCoeFepAwareTextEditor* const fepAwareTextEditor=iInputCapabilities.FepAwareTextEditor();
       
   972 			TBuf<40+EMaximumLengthOfDisplayOfContextInformation> textToDisplay;
       
   973 			if (fepAwareTextEditor==NULL)
       
   974 				{
       
   975 				textToDisplay=KLitNotAvailable;
       
   976 				}
       
   977 			else
       
   978 				{
       
   979 				TCursorSelection cursorSelection;
       
   980 				fepAwareTextEditor->GetCursorSelectionForFep(cursorSelection);
       
   981 				switch (keyCodeInUpperCase)
       
   982 					{
       
   983 				case 'B':
       
   984 					{
       
   985 					TInt lengthToRetrieve=EMaximumLengthOfDisplayOfContextInformation+1;
       
   986 					TInt documentPositionBeforeSelection=cursorSelection.LowerPos()-lengthToRetrieve;
       
   987 					if (documentPositionBeforeSelection<0)
       
   988 						{
       
   989 						lengthToRetrieve+=documentPositionBeforeSelection; // same as doing "lengthToRetrieve=cursorSelection.LowerPos()", hence the assert below
       
   990 						__ASSERT_DEBUG(lengthToRetrieve==cursorSelection.LowerPos(), Panic(EPanicArithmeticConfusion));
       
   991 						documentPositionBeforeSelection=0;
       
   992 						}
       
   993 					fepAwareTextEditor->GetEditorContentForFep(textToDisplay, documentPositionBeforeSelection, lengthToRetrieve);
       
   994 					const TInt lengthOfTextBeforeSelection=textToDisplay.Length();
       
   995 					if (lengthOfTextBeforeSelection>EMaximumLengthOfDisplayOfContextInformation)
       
   996 						{
       
   997 						textToDisplay.Delete(0, (lengthOfTextBeforeSelection-EMaximumLengthOfDisplayOfContextInformation)-1);
       
   998 						__ASSERT_DEBUG(textToDisplay.Length()==EMaximumLengthOfDisplayOfContextInformation+1, Panic(EPanicBadLengthOfTextBeforeSelection));
       
   999 						textToDisplay[0]=KEllipsisCharacter;
       
  1000 						}
       
  1001 					}
       
  1002 					textToDisplay.Insert(0, KLitQuotationMark);
       
  1003 					textToDisplay.Append(KLitQuotationMark);
       
  1004 					textToDisplay.Insert(0, KLitTextBeforeSelectionColonSpace);
       
  1005 					break;
       
  1006 				case 'A':
       
  1007 					{
       
  1008 					const TInt documentLength=fepAwareTextEditor->DocumentLengthForFep();
       
  1009 					const TInt documentPositionAfterSelection=cursorSelection.HigherPos()+1;
       
  1010 					if (documentPositionAfterSelection>documentLength)
       
  1011 						{
       
  1012 						__ASSERT_DEBUG(documentPositionAfterSelection==documentLength+1, Panic(EPanicSelectionExtendsPastEndOfDocument));
       
  1013 						}
       
  1014 					else
       
  1015 						{
       
  1016 						fepAwareTextEditor->GetEditorContentForFep(textToDisplay, documentPositionAfterSelection, EMaximumLengthOfDisplayOfContextInformation+1);
       
  1017 						const TInt lengthOfTextAfterSelection=textToDisplay.Length();
       
  1018 						if (lengthOfTextAfterSelection>EMaximumLengthOfDisplayOfContextInformation)
       
  1019 							{
       
  1020 							textToDisplay.Delete(EMaximumLengthOfDisplayOfContextInformation, (lengthOfTextAfterSelection-EMaximumLengthOfDisplayOfContextInformation)-1);
       
  1021 							__ASSERT_DEBUG(textToDisplay.Length()==EMaximumLengthOfDisplayOfContextInformation+1, Panic(EPanicBadLengthOfTextAfterSelection));
       
  1022 							textToDisplay[EMaximumLengthOfDisplayOfContextInformation]=KEllipsisCharacter;
       
  1023 							}
       
  1024 						}
       
  1025 					}
       
  1026 					textToDisplay.Insert(0, KLitQuotationMark);
       
  1027 					textToDisplay.Append(KLitQuotationMark);
       
  1028 					textToDisplay.Insert(0, KLitTextAfterSelectionColonSpace);
       
  1029 					break;
       
  1030 				case 'S':
       
  1031 					fepAwareTextEditor->GetEditorContentForFep(textToDisplay, cursorSelection.LowerPos(), EMaximumLengthOfDisplayOfContextInformation+1);
       
  1032 					{
       
  1033 					const TInt lengthOfSelection=textToDisplay.Length();
       
  1034 					if (lengthOfSelection>EMaximumLengthOfDisplayOfContextInformation)
       
  1035 						{
       
  1036 						textToDisplay.Delete(EMaximumLengthOfDisplayOfContextInformation, (lengthOfSelection-EMaximumLengthOfDisplayOfContextInformation)-1);
       
  1037 						__ASSERT_DEBUG(textToDisplay.Length()==EMaximumLengthOfDisplayOfContextInformation+1, Panic(EPanicBadLengthOfSelection));
       
  1038 						textToDisplay[EMaximumLengthOfDisplayOfContextInformation]=KEllipsisCharacter;
       
  1039 						}
       
  1040 					}
       
  1041 					textToDisplay.Insert(0, KLitQuotationMark);
       
  1042 					textToDisplay.Append(KLitQuotationMark);
       
  1043 					textToDisplay.Insert(0, KLitSelectionColonSpace);
       
  1044 					break;
       
  1045 #if defined(_DEBUG)
       
  1046 				default:
       
  1047 					Panic(EPanicBadKeyCode1);
       
  1048 					break;
       
  1049 #endif
       
  1050 					}
       
  1051 				}
       
  1052 			User::InfoPrint(textToDisplay);
       
  1053 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
       
  1054 			}
       
  1055 			}
       
  1056 		}
       
  1057 	switch (keyCodeInUpperCase)
       
  1058 		{
       
  1059 	case EKeyEnter:
       
  1060 	case EKeyEscape:
       
  1061 		if (isFocused)
       
  1062 			{
       
  1063 			ChangeSetupAndDrawNow(SetFocus, EFalse);
       
  1064 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
       
  1065 			}
       
  1066 		break;
       
  1067 	case EKeyHome:
       
  1068 	case EKeyEnd:
       
  1069 	case EKeyPageUp:
       
  1070 	case EKeyPageDown:
       
  1071 	case EKeyLeftArrow:
       
  1072 	case EKeyRightArrow:
       
  1073 	case EKeyUpArrow:
       
  1074 	case EKeyDownArrow:
       
  1075 		if (isFocused)
       
  1076 			{
       
  1077 			TPoint offset(0, 0);
       
  1078 			TInt magnification=10;
       
  1079 			switch (keyCodeInUpperCase)
       
  1080 				{
       
  1081 			case EKeyLeftArrow:
       
  1082 				offset.iX=-1;
       
  1083 				break;
       
  1084 			case EKeyRightArrow:
       
  1085 				offset.iX=1;
       
  1086 				break;
       
  1087 			case EKeyUpArrow:
       
  1088 				offset.iY=-1;
       
  1089 				break;
       
  1090 			case EKeyDownArrow:
       
  1091 				offset.iY=1;
       
  1092 				break;
       
  1093 			case EKeyHome:
       
  1094 				offset.iX=-iPosition.iX;
       
  1095 				offset.iY=-iPosition.iY;
       
  1096 				magnification=1;
       
  1097 				break;
       
  1098 			case EKeyEnd:
       
  1099 				{
       
  1100 				const TSize screenWidth(iCoeEnv->ScreenDevice()->SizeInPixels());
       
  1101 				offset.iX=(screenWidth.iWidth-iSize.iWidth)-iPosition.iX;
       
  1102 				offset.iY=(screenWidth.iHeight-iSize.iHeight)-iPosition.iY;
       
  1103 				}
       
  1104 				magnification=1;
       
  1105 				break;
       
  1106 			case EKeyPageUp:
       
  1107 				offset.iY=-iSize.iHeight;
       
  1108 				magnification=1;
       
  1109 				break;
       
  1110 			case EKeyPageDown:
       
  1111 				offset.iY=iSize.iHeight;
       
  1112 				magnification=1;
       
  1113 				break;
       
  1114 #if defined(_DEBUG)
       
  1115 			default:
       
  1116 				Panic(EPanicBadKeyCode2);
       
  1117 				break;
       
  1118 #endif
       
  1119 				}
       
  1120 			if (aKeyEvent.iModifiers&EModifierCtrl)
       
  1121 				{
       
  1122 				offset.iX*=magnification;
       
  1123 				offset.iY*=magnification;
       
  1124 				}
       
  1125 			SetPosition(TPoint(iPosition.iX+offset.iX, iPosition.iY+offset.iY));
       
  1126 			if (iFlags&EFlagWindowIsBeingDragged)
       
  1127 				{
       
  1128 				iPositionOnWindowBeingDragged.iX-=offset.iX;
       
  1129 				iPositionOnWindowBeingDragged.iY-=offset.iY;
       
  1130 				}
       
  1131 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
       
  1132 			}
       
  1133 		break;
       
  1134 	default:
       
  1135 		if (isFocused)
       
  1136 			{
       
  1137 			FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasConsumed); // returns from this function
       
  1138 			}
       
  1139 		break;
       
  1140 		}
       
  1141 	FEP_END_KEY_EVENT_HANDLER_L(iFep, aKeyEvent, EKeyWasNotConsumed); // returns from this function
       
  1142 	}
       
  1143 
       
  1144 void CTstControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  1145 	{
       
  1146 	switch (aPointerEvent.iType)
       
  1147 		{
       
  1148 	case TPointerEvent::EButton1Down:
       
  1149 	case TPointerEvent::EDrag:
       
  1150 		if (iFlags&EFlagWindowIsBeingDragged)
       
  1151 			{
       
  1152 			SetPosition(aPointerEvent.iParentPosition-iPositionOnWindowBeingDragged);
       
  1153 			}
       
  1154 		else
       
  1155 			{
       
  1156 			iFlags|=EFlagWindowIsBeingDragged;
       
  1157 			iPositionOnWindowBeingDragged=aPointerEvent.iPosition;
       
  1158 			}
       
  1159 		break;
       
  1160 	case TPointerEvent::EButton1Up:
       
  1161 		iFlags&=~EFlagWindowIsBeingDragged;
       
  1162 		break;
       
  1163 #if defined(__GCC32__)
       
  1164 	default:
       
  1165 		break;
       
  1166 #endif
       
  1167 		}
       
  1168 	}
       
  1169 
       
  1170 TInt CTstControl::CountComponentControls() const
       
  1171 	{
       
  1172 	return 1;
       
  1173 	}
       
  1174 
       
  1175 CCoeControl* CTstControl::ComponentControl(TInt aIndex) const
       
  1176 	{
       
  1177 	switch (aIndex)
       
  1178 		{
       
  1179 	case 0:
       
  1180 		return iScribbleWindow;
       
  1181 	default:
       
  1182 #if defined(_DEBUG)
       
  1183 		Panic(EPanicBadIndex2);
       
  1184 #endif
       
  1185 		return NULL;
       
  1186 		}
       
  1187 	}
       
  1188 
       
  1189 void CTstControl::Draw(const TRect&) const
       
  1190 	{
       
  1191 	CWindowGc& graphicsContext=SystemGc();
       
  1192 	graphicsContext.SetPenStyle(CGraphicsContext::ESolidPen);
       
  1193 	graphicsContext.SetPenColor(KRgbBlack);
       
  1194 	graphicsContext.SetBrushStyle(CGraphicsContext::ENullBrush);
       
  1195 	TRect rectangle(Rect());
       
  1196 	graphicsContext.DrawRect(rectangle);
       
  1197 	rectangle.Shrink(1, 1);
       
  1198 	graphicsContext.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1199 	if (IsFocused())
       
  1200 		{
       
  1201 		// the pen color is still black here
       
  1202 		graphicsContext.SetBrushColor(KRgbBlack);
       
  1203 		graphicsContext.DrawRect(rectangle);
       
  1204 		const TPoint center=rectangle.Center();
       
  1205 		graphicsContext.SetPenColor(KRgbWhite);
       
  1206 		const TPoint leftArrowHead((rectangle.iTl.iX+center.iX)/2, center.iY);
       
  1207 		const TPoint rightArrowHead((center.iX+rectangle.iBr.iX)/2, center.iY);
       
  1208 		const TPoint topArrowHead(center.iX, (rectangle.iTl.iY+center.iY)/2);
       
  1209 		const TPoint bottomArrowHead(center.iX, (center.iY+rectangle.iBr.iY)/2);
       
  1210 		graphicsContext.DrawLine(leftArrowHead, rightArrowHead);
       
  1211 		graphicsContext.Plot(rightArrowHead);
       
  1212 		graphicsContext.DrawLine(topArrowHead, bottomArrowHead);
       
  1213 		graphicsContext.Plot(bottomArrowHead);
       
  1214 		graphicsContext.DrawLine(TPoint(leftArrowHead.iX+EArrowHeadSize, leftArrowHead.iY+EArrowHeadSize), leftArrowHead);
       
  1215 		graphicsContext.DrawLine(TPoint(leftArrowHead.iX+EArrowHeadSize, leftArrowHead.iY-EArrowHeadSize), leftArrowHead);
       
  1216 		graphicsContext.DrawLine(TPoint(rightArrowHead.iX-EArrowHeadSize, rightArrowHead.iY-EArrowHeadSize), rightArrowHead);
       
  1217 		graphicsContext.DrawLine(TPoint(rightArrowHead.iX-EArrowHeadSize, rightArrowHead.iY+EArrowHeadSize), rightArrowHead);
       
  1218 		graphicsContext.DrawLine(TPoint(topArrowHead.iX-EArrowHeadSize, topArrowHead.iY+EArrowHeadSize), topArrowHead);
       
  1219 		graphicsContext.DrawLine(TPoint(topArrowHead.iX+EArrowHeadSize, topArrowHead.iY+EArrowHeadSize), topArrowHead);
       
  1220 		graphicsContext.DrawLine(TPoint(bottomArrowHead.iX+EArrowHeadSize, bottomArrowHead.iY-EArrowHeadSize), bottomArrowHead);
       
  1221 		graphicsContext.DrawLine(TPoint(bottomArrowHead.iX-EArrowHeadSize, bottomArrowHead.iY-EArrowHeadSize), bottomArrowHead);
       
  1222 		}
       
  1223 	else
       
  1224 		{
       
  1225 		TRect temp(rectangle);
       
  1226 		if (~iFlags&EFlagWholeScreen)
       
  1227 			{
       
  1228 			temp.iTl.iY+=EHeightOfScribbleWindow;
       
  1229 			}
       
  1230 		temp.iBr.iY=temp.iTl.iY;
       
  1231 		graphicsContext.SetBrushColor(KRgbGray);
       
  1232 		graphicsContext.UseFont(iStatusFont);
       
  1233 		TBuf<200> textToDisplay;
       
  1234 		const TInt statusFontHeightInPixels=iStatusFont->HeightInPixels();
       
  1235 		const TInt statusFontAscentInPixels=iStatusFont->AscentInPixels();
       
  1236 		textToDisplay=KLitUpperCaseColonSpace;
       
  1237 		textToDisplay.Append((iFlags&EFlagUpperCase)? KLitOn(): KLitOff());
       
  1238 		temp.iBr.iY+=EGapAboveTopLine+statusFontHeightInPixels+EGapBetweenEachLine;
       
  1239 		graphicsContext.DrawText(textToDisplay, temp, EGapAboveTopLine+statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
       
  1240 		textToDisplay=KLitScribbleAreaColonSpace;
       
  1241 		textToDisplay.Append((iFlags&EFlagWholeScreen)? KLitWholeScreen(): KLitWindow());
       
  1242 		temp.iTl.iY=temp.iBr.iY;
       
  1243 		temp.iBr.iY+=statusFontHeightInPixels+EGapBetweenEachLine;
       
  1244 		graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
       
  1245 		textToDisplay=KLitPointerBufferColonSpace;
       
  1246 		textToDisplay.Append((iFlags&EFlagPointerBufferEnabled)? KLitEnabled(): KLitDisabled());
       
  1247 		temp.iTl.iY=temp.iBr.iY;
       
  1248 		temp.iBr.iY+=statusFontHeightInPixels+EGapBetweenEachLine;
       
  1249 		graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
       
  1250 		textToDisplay=KLitOpeningSquareBracket;
       
  1251 		textToDisplay.Append(KLitCaptionColonSpace);
       
  1252 		textToDisplay.Append(KLitQuotationMark);
       
  1253 		const MCoeCaptionRetrieverForFep* captionRetrieverForFep=iInputCapabilities.CaptionRetrieverForFep();
       
  1254 		if (captionRetrieverForFep!=NULL)
       
  1255 			{
       
  1256 			TBuf<51> caption;
       
  1257 			captionRetrieverForFep->GetCaptionForFep(caption);
       
  1258 			const TInt captionLength=caption.Length();
       
  1259 			if (captionLength==caption.MaxLength())
       
  1260 				{
       
  1261 				caption[captionLength-1]=KEllipsisCharacter;
       
  1262 				}
       
  1263 			textToDisplay.Append(caption);
       
  1264 			}
       
  1265 		textToDisplay.Append(KLitQuotationMark);
       
  1266 		textToDisplay.Append(KLitClosingSquareBracket);
       
  1267 		temp.iTl.iY=temp.iBr.iY;
       
  1268 		temp.iBr.iY+=statusFontHeightInPixels+EGapBetweenEachLine;
       
  1269 		graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
       
  1270 		textToDisplay=KLitOpeningSquareBracket;
       
  1271 		textToDisplay.Append(KLitInputCapabilitiesColonSpace);
       
  1272 		if (iInputCapabilities.IsNone())
       
  1273 			{
       
  1274 			textToDisplay.Append(KLitNone);
       
  1275 			}
       
  1276 		else
       
  1277 			{
       
  1278 			TBool deleteLastSeparator=EFalse;
       
  1279 			if (iInputCapabilities.SupportsWesternNumericIntegerPositive())
       
  1280 				{
       
  1281 				textToDisplay.Append(KLitWesternNumericIntegerPositive);
       
  1282 				textToDisplay.Append(KLitCommaSpace);
       
  1283 				deleteLastSeparator=ETrue;
       
  1284 				}
       
  1285 			if (iInputCapabilities.SupportsWesternNumericIntegerNegative())
       
  1286 				{
       
  1287 				textToDisplay.Append(KLitWesternNumericIntegerNegative);
       
  1288 				textToDisplay.Append(KLitCommaSpace);
       
  1289 				deleteLastSeparator=ETrue;
       
  1290 				}
       
  1291 			if (iInputCapabilities.SupportsWesternNumericReal())
       
  1292 				{
       
  1293 				textToDisplay.Append(KLitWesternNumericReal);
       
  1294 				textToDisplay.Append(KLitCommaSpace);
       
  1295 				deleteLastSeparator=ETrue;
       
  1296 				}
       
  1297 			if (iInputCapabilities.SupportsWesternAlphabetic())
       
  1298 				{
       
  1299 				textToDisplay.Append(KLitWesternAlphabetic);
       
  1300 				textToDisplay.Append(KLitCommaSpace);
       
  1301 				deleteLastSeparator=ETrue;
       
  1302 				}
       
  1303 			if (iInputCapabilities.SupportsJapaneseHiragana())
       
  1304 				{
       
  1305 				textToDisplay.Append(KLitJapaneseHiragana);
       
  1306 				textToDisplay.Append(KLitCommaSpace);
       
  1307 				deleteLastSeparator=ETrue;
       
  1308 				}
       
  1309 			if (iInputCapabilities.SupportsJapaneseKatakanaHalfWidth())
       
  1310 				{
       
  1311 				textToDisplay.Append(KLitJapaneseKatakanaHalfWidth);
       
  1312 				textToDisplay.Append(KLitCommaSpace);
       
  1313 				deleteLastSeparator=ETrue;
       
  1314 				}
       
  1315 			if (iInputCapabilities.SupportsJapaneseKatakanaFullWidth())
       
  1316 				{
       
  1317 				textToDisplay.Append(KLitJapaneseKatakanaFullWidth);
       
  1318 				textToDisplay.Append(KLitCommaSpace);
       
  1319 				deleteLastSeparator=ETrue;
       
  1320 				}
       
  1321 			if (iInputCapabilities.SupportsDialableCharacters())
       
  1322 				{
       
  1323 				textToDisplay.Append(KLitDialableCharacters);
       
  1324 				textToDisplay.Append(KLitCommaSpace);
       
  1325 				deleteLastSeparator=ETrue;
       
  1326 				}
       
  1327 			if (iInputCapabilities.SupportsSecretText())
       
  1328 				{
       
  1329 				textToDisplay.Append(KLitSecretText);
       
  1330 				textToDisplay.Append(KLitCommaSpace);
       
  1331 				deleteLastSeparator=ETrue;
       
  1332 				}
       
  1333 			if (iInputCapabilities.SupportsAllText())
       
  1334 				{
       
  1335 				textToDisplay.Append(KLitAllText);
       
  1336 				textToDisplay.Append(KLitCommaSpace);
       
  1337 				deleteLastSeparator=ETrue;
       
  1338 				}
       
  1339 			if (iInputCapabilities.SupportsNavigation())
       
  1340 				{
       
  1341 				textToDisplay.Append(KLitNavigation);
       
  1342 				textToDisplay.Append(KLitCommaSpace);
       
  1343 				deleteLastSeparator=ETrue;
       
  1344 				}
       
  1345 			if (deleteLastSeparator)
       
  1346 				{
       
  1347 				const TInt lengthToDelete=KLitCommaSpace().Length();
       
  1348 				textToDisplay.Delete(textToDisplay.Length()-lengthToDelete, lengthToDelete);
       
  1349 				}
       
  1350 			}
       
  1351 		textToDisplay.Append(KLitClosingSquareBracket);
       
  1352 		temp.iTl.iY=temp.iBr.iY;
       
  1353 		temp.iBr.iY=rectangle.iBr.iY;
       
  1354 		__ASSERT_DEBUG(temp.iBr.iY==temp.iTl.iY+statusFontHeightInPixels+EGapBelowBottomLine, Panic(EPanicBadHeight));
       
  1355 		graphicsContext.DrawText(textToDisplay, temp, statusFontAscentInPixels, CGraphicsContext::ELeft, EGapLeftOfEachLine);
       
  1356 		graphicsContext.DiscardFont();
       
  1357 		}
       
  1358 	}
       
  1359 
       
  1360 // CTstControl::CHandlerForStartOfTransaction
       
  1361 
       
  1362 CTstControl::CHandlerForStartOfTransaction* CTstControl::CHandlerForStartOfTransaction::NewL(CTstWholeScreenScribbleArea& aWholeScreenScribbleArea, CCoeEnv& aConeEnvironment)
       
  1363 	{
       
  1364 	return new(ELeave) CHandlerForStartOfTransaction(aWholeScreenScribbleArea, aConeEnvironment);
       
  1365 	}
       
  1366 
       
  1367 CTstControl::CHandlerForStartOfTransaction::~CHandlerForStartOfTransaction()
       
  1368 	{
       
  1369 	Cancel();
       
  1370 	}
       
  1371 
       
  1372 CTstControl::CHandlerForStartOfTransaction::CHandlerForStartOfTransaction(CTstWholeScreenScribbleArea& aWholeScreenScribbleArea, CCoeEnv& aConeEnvironment)
       
  1373 	:CActive(EActivePriorityWsEvents),
       
  1374 	 iWholeScreenScribbleArea(aWholeScreenScribbleArea),
       
  1375 	 iConeEnvironment(aConeEnvironment)
       
  1376 	{
       
  1377 	CActiveScheduler::Add(this);
       
  1378 	RequestNotificationOfStartOfTransaction();
       
  1379 	}
       
  1380 
       
  1381 void CTstControl::CHandlerForStartOfTransaction::RequestNotificationOfStartOfTransaction()
       
  1382 	{
       
  1383 	iWholeScreenScribbleArea.RequestNotificationOfStartOfTransaction(iStatus);
       
  1384 	SetActive();
       
  1385 	}
       
  1386 
       
  1387 void CTstControl::CHandlerForStartOfTransaction::DoCancel()
       
  1388 	{
       
  1389 	iWholeScreenScribbleArea.CancelRequestForNotificationOfStartOfTransaction();
       
  1390 	}
       
  1391 
       
  1392 void CTstControl::CHandlerForStartOfTransaction::RunL()
       
  1393 	{
       
  1394 	RequestNotificationOfStartOfTransaction();
       
  1395 	iConeEnvironment.ForEachFepObserverCall(FepObserverHandleStartOfTransactionL); // called at the end of handling this event as it may launch a waiting dialog
       
  1396 	}
       
  1397 
       
  1398 // CTstControl::CHandlerForCharacters
       
  1399 
       
  1400 CTstControl::CHandlerForCharacters* CTstControl::CHandlerForCharacters::NewL(CTstWholeScreenScribbleArea& aWholeScreenScribbleArea, CTstFep& aFep, TBool aForeground)
       
  1401 	{
       
  1402 	return new(ELeave) CHandlerForCharacters(aWholeScreenScribbleArea, aFep, aForeground);
       
  1403 	}
       
  1404 
       
  1405 CTstControl::CHandlerForCharacters::~CHandlerForCharacters()
       
  1406 	{
       
  1407 	Cancel();
       
  1408 	}
       
  1409 
       
  1410 void CTstControl::CHandlerForCharacters::SetUpperCase(TBool aUpperCase)
       
  1411 	{
       
  1412 	if (!aUpperCase!=!(iFlags&EFlagUpperCase)) // fold non-zero values on both sides before comparing for inequality
       
  1413 		{
       
  1414 		iFlags^=EFlagUpperCase;
       
  1415 		if (IsActive())
       
  1416 			{
       
  1417 			iWholeScreenScribbleArea.SetUpperCase(aUpperCase);
       
  1418 			}
       
  1419 		}
       
  1420 	__ASSERT_DEBUG(!(iFlags&EFlagUpperCase)==!aUpperCase, Panic(EPanicInconsistentUpperCaseSetting)); // fold non-zero values on both sides before comparing for equality
       
  1421 	}
       
  1422 
       
  1423 CTstControl::CHandlerForCharacters::CHandlerForCharacters(CTstWholeScreenScribbleArea& aWholeScreenScribbleArea, CTstFep& aFep, TBool aForeground)
       
  1424 	:CActive(EActivePriorityWsEvents),
       
  1425 	 iWholeScreenScribbleArea(aWholeScreenScribbleArea),
       
  1426 	 iFep(aFep),
       
  1427 	 iFlags(aForeground? EFlagForeground: 0)
       
  1428 	{
       
  1429 	CActiveScheduler::Add(this);
       
  1430 	}
       
  1431 
       
  1432 void CTstControl::CHandlerForCharacters::SetFlagAffectingWhetherActive(TUint aFlagAffectingWhetherActive, TBool aSetting)
       
  1433 	{
       
  1434 	const TUint flagsAffectingWhetherActive=(EFlagWholeScreen|EFlagIsOn|EFlagForeground);
       
  1435 	__ASSERT_DEBUG(aFlagAffectingWhetherActive&flagsAffectingWhetherActive, Panic(EPanicBadFlagAffectingWhetherActive));
       
  1436 	const TUint oldFlags=iFlags;
       
  1437 	if (aSetting)
       
  1438 		{
       
  1439 		iFlags|=aFlagAffectingWhetherActive;
       
  1440 		}
       
  1441 	else
       
  1442 		{
       
  1443 		iFlags&=~aFlagAffectingWhetherActive;
       
  1444 		}
       
  1445 	if ((iFlags^oldFlags)&flagsAffectingWhetherActive)
       
  1446 		{
       
  1447 		if ((iFlags&flagsAffectingWhetherActive)==flagsAffectingWhetherActive)
       
  1448 			{
       
  1449 			RequestCharacters();
       
  1450 			}
       
  1451 		else if ((oldFlags&flagsAffectingWhetherActive)==flagsAffectingWhetherActive)
       
  1452 			{
       
  1453 			Cancel();
       
  1454 			}
       
  1455 		}
       
  1456 	}
       
  1457 
       
  1458 void CTstControl::CHandlerForCharacters::RequestCharacters()
       
  1459 	{
       
  1460 	iWholeScreenScribbleArea.RequestCharacters(iStatus, iCharacterBuffer, iFlags&EFlagUpperCase);
       
  1461 	SetActive();
       
  1462 	}
       
  1463 
       
  1464 TInt CTstControl::CHandlerForCharacters::NumberOfCharactersInBuffer(const CBase* aCharacterBuffer)
       
  1465 	{
       
  1466 	const TDesC8& characterBuffer=*REINTERPRET_CAST(const TDesC8*, aCharacterBuffer);
       
  1467 	return characterBuffer.Length()/sizeof(TUint);
       
  1468 	}
       
  1469 
       
  1470 const TAny* CTstControl::CHandlerForCharacters::CharacterInBuffer(const CBase* aCharacterBuffer, TInt aIndex)
       
  1471 	{
       
  1472 	const TDesC8& characterBuffer=*REINTERPRET_CAST(const TDesC8*, aCharacterBuffer);
       
  1473 	return characterBuffer.Ptr()+(aIndex*sizeof(TUint));
       
  1474 	}
       
  1475 
       
  1476 void CTstControl::CHandlerForCharacters::DoCancel()
       
  1477 	{
       
  1478 	iWholeScreenScribbleArea.CancelRequestForCharacters();
       
  1479 	}
       
  1480 
       
  1481 void CTstControl::CHandlerForCharacters::RunL()
       
  1482 	{
       
  1483 	TBuf8<EMaximumLengthOfCharacterBuffer> characterBuffer=iCharacterBuffer;
       
  1484 	RequestCharacters(); // calling RequestCharacters may complete immediately (thus trashing iCharacterBuffer), hence why iCharacterBuffer was copied to a temporary buffer first
       
  1485 	iFep.SimulateKeyEventsL(TArray<TUint>(NumberOfCharactersInBuffer, CharacterInBuffer, REINTERPRET_CAST(const CBase*, &characterBuffer)));
       
  1486 	}
       
  1487 
       
  1488 // CTstFep
       
  1489 
       
  1490 CTstFep::CTstFep(CCoeEnv& aConeEnvironment)
       
  1491 	:CCoeFep(aConeEnvironment)
       
  1492 	{
       
  1493 	}
       
  1494 
       
  1495 void CTstFep::ConstructL(const CCoeFepParameters& aFepParameters)
       
  1496 	{
       
  1497 	BaseConstructL(aFepParameters);
       
  1498 	iControl=CTstControl::NewL(*this);
       
  1499 	ReadAllAttributesL();
       
  1500 	iControl->ActivateL();
       
  1501 	}
       
  1502 
       
  1503 CTstFep::~CTstFep()
       
  1504 	{
       
  1505 	delete iControl;
       
  1506 	}
       
  1507 
       
  1508 void CTstFep::CancelTransaction()
       
  1509 	{
       
  1510 	iControl->CancelTransaction();
       
  1511 	}
       
  1512 
       
  1513 void CTstFep::IsOnHasChangedState()
       
  1514 	{
       
  1515 	iControl->IsOnHasChangedState();
       
  1516 	}
       
  1517 
       
  1518 void CTstFep::OfferKeyEventL(TEventResponse& aEventResponse, const TKeyEvent& aKeyEvent, TEventCode aEventCode)
       
  1519 	{
       
  1520 	// this function must correctly set aEventResponse *before* calling anything that can leave
       
  1521 	aEventResponse=EEventWasConsumed; // this assumes that CTstControl::OfferKeyEventL will not leave if it returns EKeyWasNotConsumed
       
  1522 	switch (iControl->OfferKeyEventL(aKeyEvent, aEventCode))
       
  1523 		{
       
  1524 	case EKeyWasNotConsumed:
       
  1525 		aEventResponse=EEventWasNotConsumed;
       
  1526 		break;
       
  1527 	case EKeyWasConsumed:
       
  1528 		aEventResponse=EEventWasConsumed;
       
  1529 		break;
       
  1530 #if defined(_DEBUG)
       
  1531 	default:
       
  1532 		Panic(EPanicBadKeyResponse);
       
  1533 		break;
       
  1534 #endif
       
  1535 		}
       
  1536 	}
       
  1537 
       
  1538 void CTstFep::OfferPointerEventL(TEventResponse& aEventResponse, const TPointerEvent& aPointerEvent, const CCoeControl* aWindowOwningControl)
       
  1539 	{
       
  1540 	iControl->OfferPointerEventL(aEventResponse, aPointerEvent, aWindowOwningControl);
       
  1541 	}
       
  1542 
       
  1543 void CTstFep::OfferPointerBufferReadyEventL(TEventResponse& aEventResponse, const CCoeControl* aWindowOwningControl)
       
  1544 	{
       
  1545 	iControl->OfferPointerBufferReadyEventL(aEventResponse, aWindowOwningControl);
       
  1546 	}
       
  1547 
       
  1548 TInt CTstFep::NumberOfAttributes() const
       
  1549 	{
       
  1550 	return CTstControl::NumberOfAttributes();
       
  1551 	}
       
  1552 
       
  1553 TUid CTstFep::AttributeAtIndex(TInt aIndex) const
       
  1554 	{
       
  1555 	return CTstControl::AttributeAtIndex(aIndex);
       
  1556 	}
       
  1557 
       
  1558 void CTstFep::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream) const
       
  1559 	{
       
  1560 	iControl->WriteAttributeDataToStreamL(aAttributeUid, aStream);
       
  1561 	}
       
  1562 
       
  1563 void CTstFep::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)
       
  1564 	{
       
  1565 	iControl->ReadAttributeDataFromStreamL(aAttributeUid, aStream);
       
  1566 	}
       
  1567 
       
  1568 void CTstFep::HandleGainingForeground()
       
  1569 	{
       
  1570 	iControl->HandleGainingForeground();
       
  1571 	}
       
  1572 
       
  1573 void CTstFep::HandleLosingForeground()
       
  1574 	{
       
  1575 	iControl->HandleLosingForeground();
       
  1576 	}
       
  1577 
       
  1578 void CTstFep::HandleChangeInFocus()
       
  1579 	{
       
  1580 	iControl->HandleChangeInFocus();
       
  1581 	}
       
  1582 
       
  1583 void CTstFep::HandleDestructionOfFocusedItem()
       
  1584 	{
       
  1585 	iControl->HandleDestructionOfFocusedItem();
       
  1586 	}
       
  1587 
       
  1588 // TTstResourceFileId
       
  1589 
       
  1590 #pragma warning(disable: 4355) // "'this' : used in base member initializer list"
       
  1591 
       
  1592 TTstResourceFileId::TTstResourceFileId(CCoeEnv& aConeEnvironment, TInt aResourceFileId)
       
  1593 	:TCleanupItem(UnloadResourceFile, this),
       
  1594 	 iConeEnvironment(aConeEnvironment),
       
  1595 	 iResourceFileId(aResourceFileId)
       
  1596 	{
       
  1597 	}
       
  1598 
       
  1599 #pragma warning(default: 4355)
       
  1600 
       
  1601 void TTstResourceFileId::UnloadResourceFile(TAny* aThis)
       
  1602 	{
       
  1603 	TTstResourceFileId& resourceFileId=*STATIC_CAST(TTstResourceFileId*, aThis);
       
  1604 	resourceFileId.iConeEnvironment.DeleteResourceFile(resourceFileId.iResourceFileId);
       
  1605 	}
       
  1606 
       
  1607 // CTstSettingsDialog
       
  1608 
       
  1609 CTstSettingsDialog::CTstSettingsDialog()
       
  1610 	:iFlags(0)
       
  1611 	{
       
  1612 	}
       
  1613 
       
  1614 TUint CTstSettingsDialog::CheckBoxStateAsFlag(TInt aControlId, TUint aFlag) const
       
  1615 	{
       
  1616 	switch (STATIC_CAST(CEikCheckBox*, Control(aControlId))->State())
       
  1617 		{
       
  1618 	case CEikButtonBase::EClear:
       
  1619 		return 0;
       
  1620 	case CEikButtonBase::ESet:
       
  1621 		return aFlag;
       
  1622 	case CEikButtonBase::EIndeterminate:
       
  1623 	default:
       
  1624 #if defined(_DEBUG)
       
  1625 		Panic(EPanicBadCheckBoxState);
       
  1626 #endif
       
  1627 		return 0;
       
  1628 		}
       
  1629 	}
       
  1630 
       
  1631 void CTstSettingsDialog::SetCheckBoxState(TInt aControlId, TUint aFlag)
       
  1632 	{
       
  1633 	STATIC_CAST(CEikCheckBox*, Control(aControlId))->SetState(iFlags&aFlag? CEikButtonBase::ESet: CEikButtonBase::EClear);
       
  1634 	}
       
  1635 
       
  1636 TBool CTstSettingsDialog::OkToExitL(TInt aButtonId)
       
  1637 	{
       
  1638 	__ASSERT_ALWAYS(aButtonId==EEikBidOk, Panic(EPanicUnexpectedButtonId));
       
  1639 	iFlags=CheckBoxStateAsFlag(EControlIdUpperCase, EFlagUpperCase)|
       
  1640 		   CheckBoxStateAsFlag(EControlIdWholeScreen, EFlagWholeScreen)|
       
  1641 		   CheckBoxStateAsFlag(EControlIdPointerBufferEnabled, EFlagPointerBufferEnabled);
       
  1642 	TFixedArray<TUid, 3> attributeUids;
       
  1643 	__ASSERT_DEBUG(NumberOfAttributes()==3, Panic(EPanicBadNumberOfAttributes));
       
  1644 	attributeUids[0].iUid=AttributeAtIndex(0).iUid;
       
  1645 	attributeUids[1].iUid=AttributeAtIndex(1).iUid;
       
  1646 	attributeUids[2].iUid=AttributeAtIndex(2).iUid;
       
  1647 	WriteAttributeDataAndBroadcastL(*iCoeEnv, attributeUids.Array());
       
  1648 	return ETrue;
       
  1649 	}
       
  1650 
       
  1651 void CTstSettingsDialog::PreLayoutDynInitL()
       
  1652 	{
       
  1653 	ReadAllAttributesL(*iCoeEnv);
       
  1654 	SetCheckBoxState(EControlIdUpperCase, EFlagUpperCase);
       
  1655 	SetCheckBoxState(EControlIdWholeScreen, EFlagWholeScreen);
       
  1656 	SetCheckBoxState(EControlIdPointerBufferEnabled, EFlagPointerBufferEnabled);
       
  1657 	}
       
  1658 
       
  1659 TInt CTstSettingsDialog::NumberOfAttributes() const
       
  1660 	{
       
  1661 	return CTstControl::NumberOfAttributes();
       
  1662 	}
       
  1663 
       
  1664 TUid CTstSettingsDialog::AttributeAtIndex(TInt aIndex) const
       
  1665 	{
       
  1666 	return CTstControl::AttributeAtIndex(aIndex);
       
  1667 	}
       
  1668 
       
  1669 void CTstSettingsDialog::WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream) const
       
  1670 	{
       
  1671 	CTstControl::WriteAttributeDataToStreamL(aAttributeUid, aStream, iFlags&EFlagUpperCase, iFlags&EFlagWholeScreen, iFlags&EFlagPointerBufferEnabled);
       
  1672 	}
       
  1673 
       
  1674 void CTstSettingsDialog::ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)
       
  1675 	{
       
  1676 	TBool upperCase;
       
  1677 	TBool wholeScreen;
       
  1678 	TBool pointerBufferEnabled;
       
  1679 	CTstControl::ReadAttributeDataFromStreamL(aAttributeUid, aStream, upperCase, wholeScreen, pointerBufferEnabled);
       
  1680 	iFlags=0;
       
  1681 	if (upperCase)
       
  1682 		{
       
  1683 		iFlags|=EFlagUpperCase;
       
  1684 		}
       
  1685 	if (wholeScreen)
       
  1686 		{
       
  1687 		iFlags|=EFlagWholeScreen;
       
  1688 		}
       
  1689 	if (pointerBufferEnabled)
       
  1690 		{
       
  1691 		iFlags|=EFlagPointerBufferEnabled;
       
  1692 		}
       
  1693 	}
       
  1694