201037_03
authorhgs
Thu, 14 Oct 2010 15:28:20 +0530
changeset 51 5aa1c6a27c95
parent 48 9b324b5dceff
child 52 164db16a7f09
201037_03
emulator/emulatorbsp/inc/gui.h
emulator/emulatorbsp/specific/gui.cpp
--- a/emulator/emulatorbsp/inc/gui.h	Thu Sep 23 17:42:45 2010 +0530
+++ b/emulator/emulatorbsp/inc/gui.h	Thu Oct 14 15:28:20 2010 +0530
@@ -286,6 +286,7 @@
 	TInt  iModeDepths[KEmulMaxNumModes];
 	TInt iCompositionBuffers;
 	TInt iRefreshRateHz;
+	DWORD* iRotateBuffer;
 	/**
 	The viewport owned by the screen
 	*/
--- a/emulator/emulatorbsp/specific/gui.cpp	Thu Sep 23 17:42:45 2010 +0530
+++ b/emulator/emulatorbsp/specific/gui.cpp	Thu Oct 14 15:28:20 2010 +0530
@@ -1,4942 +1,5069 @@
-// Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-// wins\specific\gui.cpp
-// 
-//
-#define WINVER 0x0500
-
-#include "gui.h"
-#include <emulator.h>
-#include <assp.h>
-#include <kernel/kern_priv.h>
-#include <kernel/kpower.h>
-#include "variant.h"
-#include "resource.h"
-#include "winsgui.h"
-#include "display_chan.h"
-#include "pixelformats.h"
-#include "multitouch.h"
-
-#include "monitors.h"
-
-//Define these so that emulator generates varying values for gce stride and offset.
-//By default in emulator, stride is exactly right for display resolution and offset is zero
-//Setting these will identify code which incorrectly calculates these factors instead of requesting them
-//Note that multiples of 4 bytes are preferred for various reasons.
-//[3/5/07 The Secure presentation burffer ignores stride extra because it uses a windows bitmap header to render.]
-// #define TEST_GCE_VARIABLE_STRIDE_EXTRA	16		 	//This constant is added to each mode's scanline length in bytes. It may cause a break if enabled because the iDisplayBufferOffset is not being set
-// #define TEST_GCE_VARIABLE_START_EXTRA	16			//A multiple of this is added to each mode's start address in bytes
-// #define ASSYMETRIC_SQUARE_STRIDE						//If this is defined and the width==height the the stride will not be the same!
-
-enum  
-	{
-		KMaskModeNum=0x0FFFFFFF,
-		KMaskModeFlag8=0x80000000,
-		KMaskModeFlag4=0x40000000,
-		KMaskModeFlag2=0x20000000,
-		KMaskModeFlag1=0x10000000,
-		
-		KModeFlagFlipped=KMaskModeFlag8,
-		
-	};
-enum  
-	{
-		KMaskScreenNum=0x0FFF,
-		KMaskScreenFlag8=0x8000,
-		KMaskScreenFlag4=0x4000,
-		KMaskScreenFlag2=0x2000,
-		KMaskScreenFlag1=0x1000,
-		
-		KScreenFlagSecure=KMaskScreenFlag8,
-		
-	};
-const TInt KMaxDisplayColors=16777216;
-const TInt KMaxDisplayContrast=1;
-
-static TEmulatorFlip* CurrentFlipState=NULL;
-static TInt CurrentConfiguration = 0;
-static TInt SavedFlipMessage = 0;
-
-DWinsUi *systemIni=NULL;
-DMasterIni* masterIni;
-
-DMultiTouch* TheMultiTouch;
-static HWND TheControlWin;
-static HWND* TheChildWin=NULL;
-static HWND* TheWin=NULL;
-static HWND hwndStatus; // To display the X,Y,Z information of each mouse
-static TInt VirtualKeyPressed = EStdKeyNull;
-static HBITMAP* TheScreenBitmap=NULL;
-static TUint LedMask;
-static TBool WsSwitchOnScreen;
-
-const char * DefaultWindowTitle = "Symbian OS Emulator";
-
-#ifdef __VC32__
-
-#ifdef _DEBUG
-const char * VersionText = " - wins udeb";
-#else
-const char * VersionText = " - wins urel";
-#endif
-
-#else
-#ifdef __CW32__
-
-#ifdef _DEBUG
-const char * VersionText = " - winscw udeb";
-#else
-const char * VersionText = " - winscw urel";
-#endif
-
-#else
-//not winscw or wins!
-#ifdef _DEBUG
-const char * VersionText = " - unknown udeb";
-#else
-const char * VersionText = " - unknown urel");
-#endif
-
-#endif
-#endif
-
-void Inactive();
-void Active();
-void DrawLeds();
-void UpdateModifiers(); 
-TInt DisplayHalFunction(TAny*, TInt aFunction, TAny* a1, TAny* a2);
-LOCAL_C TBool PaintWindowFromBuffer(HWND hWnd);
-
-GLDEF_C const char* skipws(const char* aPtr)
-	{
-	while (isspace(*aPtr))
-		++aPtr;
-	return aPtr;
-	}
-
-GLDEF_C const char* skiptok(const char* aPtr)
-	{
-	while (isalnum(*aPtr))
-		++aPtr;
-	return aPtr;
-	}
-
-GLDEF_C TInt CompareI(const TDesC8& aLhs, const TDesC8& aRhs)
-//
-// Case insensitive comparison of descriptors
-// (TDesC::CompareF not available to kernel side code)
-//
-	{
-	TInt ll = aLhs.Length();
-	TInt rl = aRhs.Length();
-	TInt len = Min(ll, rl);
-	TInt k = _strnicmp((const char*)aLhs.Ptr(), (const char*)aRhs.Ptr(), len);
-	return k != 0 ? k : ll - rl;
-	}
-
-GLDEF_C TInt MultiProperty(TInt (*aHandler)(TAny* aObj, const char*), TAny* aPtr, const char* aProperty)
-	{
-	const char* value = Property::GetString(aProperty);
-	if (!value)
-		return KErrNone;
-	for (;;)
-		{
-		TInt r = aHandler(aPtr, value);
-		if (r != KErrNone)
-			return r;
-		const char* ev = strchr(value, ';');
-		if (!ev)
-			break;
-		value = ev + 1;
-		}
-	return KErrNone;
-	}
-
-class DWinsGuiPowerHandler : public DPowerHandler
-	{
-public: // from DPowerHandler
-	void PowerDown(TPowerState);
-	void PowerUp();
-public:
-	static DWinsGuiPowerHandler* New();
-	void ScreenOn();
-	void ScreenOff();
-	void ScreenOn(TInt aScreen);
-	void ScreenOff(TInt aScreen);
-public:
-	DWinsGuiPowerHandler();
-	TBool ProcessEvent(const TRawEvent* aEvent);
-	TBool ProcessEventDfc(const TRawEvent* aEvent);
-	TBool	iStandby;
-	};
-
-static DWinsGuiPowerHandler* WinsGuiPowerHandler;
-
-_LIT(KWinsGuiName, "WinsGui");
-
-DWinsGuiPowerHandler* DWinsGuiPowerHandler::New()
-	{
-	DWinsGuiPowerHandler* self = new DWinsGuiPowerHandler();
-	if (!self)
-		return NULL;
-	self->Add();
-
-	return self;
-	}
-
-DWinsGuiPowerHandler::DWinsGuiPowerHandler() : DPowerHandler(KWinsGuiName)
-	{
-	}
-
-void DWinsGuiPowerHandler::ScreenOff()
-	{
-	for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
-		ScreenOff(ix);
-	}
-
-void DWinsGuiPowerHandler::ScreenOn()
-	{
-	for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
-		ScreenOn(ix);
-	}
-
-void DWinsGuiPowerHandler::ScreenOff(TInt aScreen)
-	{
-	PostMessageA(TheWin[aScreen], WM_EMUL_POWER_ON, FALSE, NULL);
-	systemIni->iScreens[aScreen]->iScreenOff = ETrue;
-	}
-
-void DWinsGuiPowerHandler::ScreenOn(TInt aScreen)
-	{
-	PostMessageA(TheWin[aScreen], WM_EMUL_POWER_ON, TRUE, NULL);
-	systemIni->iScreens[aScreen]->iScreenOff = EFalse;
-	}
-
-void DWinsGuiPowerHandler::PowerDown(TPowerState aState)
-	{
-	if (aState == EPwStandby)
-		iStandby = ETrue;
-	ScreenOff();
-	PowerDownDone();
-	}
-
-
-void DWinsGuiPowerHandler::PowerUp()
-	{
-	iStandby = EFalse;
-	ScreenOn();
-	PowerUpDone();
-	}
-
-// called in the interrupt context
-TBool DWinsGuiPowerHandler::ProcessEvent(const TRawEvent* aEvent)
-	{
-	if (!iStandby)
-		// Pass through 
-		return EFalse;
-
-	if ((aEvent->Type() == TRawEvent::EKeyDown))
-			{
-			Wins::Self() -> AssertWakeupSignal();
-			}
-	
-	// Ignore
-	return ETrue;
-	}
-
-// called in DFC
-TBool DWinsGuiPowerHandler::ProcessEventDfc(const TRawEvent* aEvent)
-	{
-	if (aEvent->Type() == TRawEvent::EKeyDown)
-		{
-		Wins::Self() -> WakeupEvent();
-		if (aEvent->ScanCode() == EStdKeyF5)
-			{
-			// Simulate a media change interrupt (media removed)
-			Wins::MediaChangeCallBack();
-			*Wins::MediaDoorOpenPtr()=ETrue;
-			// Ignore
-			return ETrue;
-			}
-		if (aEvent->ScanCode() == EStdKeyF8)
-			{
-			TRawEvent v;
-			v.Set(TRawEvent::ECaseClose);
-			Kern::AddEvent(v);
-			// Ignore
-			return ETrue;
-			}
-		if (aEvent->ScanCode() == EStdKeyF8)
-			{
-			TRawEvent v;
-			v.Set(TRawEvent::ECaseClose);
-			Kern::AddEvent(v);
-			// Ignore
-			return ETrue;
-			}
-		if (aEvent->ScanCode() == EStdKeyOff)
-			{
-			// Pass through
-			return EFalse;
-			}
-		if (aEvent->ScanCode() == EStdKeyF10)
-			{
-			TRawEvent v;
-			v.Set(TRawEvent::ESwitchOff);
-			Kern::AddEvent(v);
-			// Ignore
-			return ETrue;
-			}
-		if (aEvent->ScanCode() == EStdKeyF11)
-			{
-			TRawEvent v;
-			v.Set(TRawEvent::ECaseOpen);
-			Kern::AddEvent(v);
-			// Ignore
-			return ETrue;
-			}
-		}
-	else if (aEvent->Type() == TRawEvent::EKeyUp)
-		{
-		if (aEvent->ScanCode() == EStdKeyF10)
-			// Ignore
-			return ETrue;
-
-		if (aEvent->ScanCode() == EStdKeyF5)
-			{
-			// Simulate a media change interrupt (media Present)
-			*Wins::MediaDoorOpenPtr()=EFalse;
-			return ETrue;
-			}
-		}
-
-	// Path through
-	return EFalse;
-	}
-
-class EventQ
-	{
-	enum {ESize = 16};
-public:
-	EventQ();
-	void Add(const TRawEvent& aEvent);
-private:
-	static void Dfc(TAny* aPtr);
-	void Empty();
-private:
-	TDfc iDfc;
-	TRawEvent* iTail;
-	TRawEvent iQ[ESize];
-	};
-
-EventQ::EventQ()
-	:iDfc(&EventQ::Dfc, this, Kern::DfcQue0(), 6), iTail(iQ)
-	{}
-
-
-void EventQ::Add(const TRawEvent& aEvent)
-	{
-	StartOfInterrupt();	
-	if (WinsGuiPowerHandler->ProcessEvent(&aEvent)) 
-		{
-		EndOfInterrupt();
-		return;
-		}
-
-	TRawEvent* pE = iTail;
-	if (pE != &iQ[ESize])
-		{
-		*pE = aEvent;
-		iTail = pE + 1;
-		if (pE == iQ)
-			iDfc.Add();
-		}
-	EndOfInterrupt();
-	}
-
-void EventQ::Dfc(TAny* aPtr)
-	{
-	static_cast<EventQ*>(aPtr)->Empty();
-	}
-
-void EventQ::Empty()
-//
-// Called in the DFC
-//
-	{
-	TInt irq;
-	TRawEvent* pE = iQ;
-	for (;;)
-		{
-		if (!WinsGuiPowerHandler->ProcessEventDfc(pE)) 
-			Kern::AddEvent(*pE);
-		++pE;
-		irq = NKern::DisableAllInterrupts();
-		if (pE == iTail)
-			break;
-		NKern::RestoreInterrupts(irq);
-		}
-	iTail = iQ;
-	NKern::RestoreInterrupts(irq);
-	}
-
-LOCAL_D EventQ TheEventQ;
-
-// Virtual keys
-
-
-VirtualKey::VirtualKey(const TInt aCommandData, const TEmulCommand aCommand) : iCommand(aCommand), iData(aCommandData)
-	{
-	}
-
-TBool VKRect::Contains(TInt aX, TInt aY) const
-	{
-	return (aX >= iLeft && aX < iRight && aY >= iTop && aY < iBottom);
-	}
-
-VKRect::VKRect(const TInt aCommandData, const TEmulCommand aCommand, TInt aX, TInt aY, TInt aWidth, TInt aHeight) :
-	VirtualKey(aCommandData, aCommand)
-	{
-	iLeft = aX;
-	iTop = aY;
-	iRight = aX + aWidth;
-	iBottom = aY + aHeight;
-	}
-
-
-
-void VKRect::Draw(HDC aHdc,COLORREF aColor) const
-	{
-	HPEN pen;
-	pen=CreatePen(PS_SOLID, 2, aColor);
-	SelectObject(aHdc, pen);
-	POINT point;
-
-	MoveToEx(aHdc, (int)iLeft, (int)iTop, &point);
-	LineTo(aHdc, (int)iLeft, (int)iBottom);
-	LineTo(aHdc, (int)iRight, (int)iBottom);
-	LineTo(aHdc, (int)iRight, (int)iTop);
-	LineTo(aHdc, (int)iLeft, (int)iTop);
-	}
-
-
-KeyCombination::KeyCombination(const TInt aCommandData, TEmulCommand aCommand):
-	iData(aCommandData),
-	iCommand(aCommand)
-{
-	for (TInt i=0;i<KMaxHotKeyCombinationLength;i++) 
-		{
-		iCombination[i]=EStdKeyNull;
-		}
-}
-
-TBool KeyCombination::CheckCombinationPressed()
-{
-	for (TInt j=0;(j<KMaxHotKeyCombinationLength && iCombination[j]!=0);j++)
-		{
-		if (GetAsyncKeyState(MapVirtualKey(iCombination[j],1))>=0)//if at least one key is not pressed, we return false
-			return EFalse;				
-		}
-	return ETrue;	
-}
-
-TBool KeyCombination::AddKey(TStdScanCode aKey)
-{
-	TInt i;
-	for (i=0;i<KMaxHotKeyCombinationLength;i++) 
-		{
-		if (iCombination[i]==EStdKeyNull) 
-			break;
-		}
-	if (KMaxHotKeyCombinationLength==i)
-		return EFalse;
-	else		
-		iCombination[i]=aKey;	
-
-	return ETrue;
-}
-
-
-DScreenProperties::DScreenProperties()
-	{
-	memset(this,0,sizeof(DScreenProperties));
-	iColorDepth=KDefaultColorDepth;
-	
-	iViewport = TViewport(this);
-	}
-
-
-LOCAL_C TInt MaskGceOnly(TInt aModeBits)
-	{	   //All HAL modes are now reported. The GCE may refuse to register the surfaces.
-	return aModeBits&KEmulModes;	//previous useful settings: //(KEmulPixPerLong2|KEmulPixPerLong1);	//|KEmulPixPerLong4;
-	}
-	
-LOCAL_C TInt BitsForSingleMode(TInt aModeColor)
-	{	//only 1 bit should be set in aModeColor
-	switch (aModeColor)
-		{
-		case KEmulGray2:	return 1;	
-		case KEmulGray4:	return 2;	
-		case KEmulGray16:	return 4;
-		case KEmulGray256:	return 8;
-		case KEmulColor16:	return 4;
-		case KEmulColor256:	return 8;
-		case KEmulColor4K:	return 12;
-		case KEmulColor64K:	return 16;
-		case KEmulColor16M:	return 24;
-		default:	return 32;
-		}
-	
-	}
-
-DScreenProperties::~DScreenProperties() 
-	{
-	}
-
-TWindowState DScreenProperties::GetWindowState()
-	{
-	TWindowState state;
-	state.iWinPlace = iWinPlace;
-	state.iFlipstate = iScreenRotation;
-	state.iXoffset = iViewport.GetViewportOffsetX();
-	state.iYoffset = iViewport.GetViewportOffsetY();
-	return state;
-	}
-	
-TInt DScreenProperties::SetupProperties(TInt aConf, TInt aScreen)
-	{
-	char property[50];
-
-	// Calculate maximum dimensions
-	TInt configurations = Property::GetInt("ConfigCount", 0);
-	if (configurations == 0)
-		return KErrGeneral;
-
-	TInt count, screenWidth, screenHeight, physicalScreenWidth, physicalScreenHeight;
-	for (count = 0; count < configurations; ++count)
-		{
-		wsprintfA(property, "Configuration[%d][%d]ScreenWidth", count, aScreen);
-		screenWidth = Property::GetInt(property, KScreenWidth);
-		screenWidth = (screenWidth + 3) & ~3;
-		if (screenWidth > iMaxScreenWidth)
-			iMaxScreenWidth = screenWidth;
-		wsprintfA(property, "Configuration[%d][%d]ScreenHeight", count, aScreen);
-		screenHeight = Property::GetInt(property, KScreenHeight);
-		screenHeight = (screenHeight + 3) & ~3;
-		if (screenHeight > iMaxScreenHeight)
-			iMaxScreenHeight = screenHeight;
-//
-		wsprintfA(property, "Configuration[%d][%d]PhysicalScreenWidth", count, aScreen);
-		physicalScreenWidth = Property::GetInt(property);
-		if (physicalScreenWidth > iMaxPhysicalScreenWidth)
-			iMaxPhysicalScreenWidth = physicalScreenWidth;
-		wsprintfA(property, "Configuration[%d][%d]PhysicalScreenHeight", count, aScreen);
-		physicalScreenHeight = Property::GetInt(property);
-		if (physicalScreenHeight > iMaxPhysicalScreenHeight)
-			iMaxPhysicalScreenHeight = physicalScreenHeight;
-		}
-
-	// Read figures for current configuration
-	TInt givenWidth, givenHeight;
-	wsprintfA(property, "Configuration[%d][%d]ScreenWidth",aConf,aScreen);
-	givenWidth = Property::GetInt(property, KScreenWidth);
-	iScreenWidth = (givenWidth + 3) & ~3;
-	wsprintfA(property, "Configuration[%d][%d]ScreenHeight",aConf,aScreen);
-	givenHeight = Property::GetInt(property, KScreenHeight);
-	iScreenHeight = (givenHeight + 3) & ~3;
-	// Width of screen should be multiple number of 4 pixels.
-	if (givenWidth & 3 || givenHeight & 3)
-		{
-		Kern::Printf("Width and Height of Screen should be multiple number of 4 pixels.\n"
-				"\tWidth of screen[%d] set to: %d\n\tHeight of screen[%d] set to: %d", 
-				aScreen, iScreenWidth, aScreen, iScreenHeight);
-		}
-
-//
-	wsprintfA(property, "Configuration[%d][%d]PhysicalScreenWidth",aConf,aScreen);
-	iPhysicalScreenWidth = Property::GetInt(property);
-	wsprintfA(property, "Configuration[%d][%d]PhysicalScreenHeight",aConf,aScreen);
-	iPhysicalScreenHeight = Property::GetInt(property);
-//
-	wsprintfA(property, "Configuration[%d][%d]ScreenOffsetX",aConf,aScreen);
-	iScreenOffsetX = Property::GetInt(property, KScreenOffsetX);
-	wsprintfA(property, "Configuration[%d][%d]ScreenOffsetY",aConf,aScreen);
-	iScreenOffsetY = Property::GetInt(property, KScreenOffsetY);
-	
-	wsprintfA(property, "Configuration[%d][%d]CompositionBuffers",aConf,aScreen);
-	iCompositionBuffers = Property::GetInt(property, KCompositionBuffers);
-
-	wsprintfA(property, "Configuration[%d][%d]RefreshRateHz",aConf,aScreen);
-	iRefreshRateHz = Property::GetInt(property, KRefreshRateHz);
-
-
-	wsprintfA(property, "Configuration[%d][%d]ColorDepth",aConf,aScreen);
-	const char* colors = Property::GetString(property);
-	if (colors)
-		{
-		TUint colorDepth=0;
-		const char* end = colors;
-		for (;;)
-			{
-			const char* beg = skipws(end);
-			if(*beg==';')
-				break;
-			if (!*beg)
-				break;
-			end	= skiptok(beg);
-			if (_strnicmp("Gray2",beg,end-beg) == 0)
-				{
-				colorDepth|=KEmulGray2|KEmulIsBitMask;
-				}
-			else if (_strnicmp("Gray4",beg,end-beg) == 0)
-				{
-				colorDepth|=KEmulGray4|KEmulIsBitMask;
-				}
-			else if (_strnicmp("Gray16",beg,end-beg) == 0)
-				{
-				colorDepth|=KEmulGray16|KEmulIsBitMask;
-				}
-			else if (_strnicmp("Gray256",beg,end-beg) == 0)
-				{
-				colorDepth|=KEmulGray256|KEmulIsBitMask;
-				}
-			else if (_strnicmp("Color16",beg,end-beg) == 0)
-				{
-				colorDepth|=KEmulColor16|KEmulIsBitMask;
-				}
-			else if (_strnicmp("Color256",beg,end-beg) == 0)
-				{
-				colorDepth|=KEmulColor256|KEmulIsBitMask;
-				}
-			else if (_strnicmp("Color4K",beg,end-beg) == 0)
-				{
-				colorDepth|=KEmulColor4K|KEmulIsBitMask;
-				}
-			else if (_strnicmp("Color64K",beg,end-beg) == 0)
-				{
-				colorDepth|=KEmulColor64K|KEmulIsBitMask;
-				}
-			else if (_strnicmp("Color16M",beg,end-beg) == 0)
-				{
-				colorDepth|=KEmulColor16M|KEmulIsBitMask;
-				}
-			else
-				return KErrArgument;
-			}
-		iColorDepth = colorDepth;
-		
-		}
-	//multiple mode support is currently only for GCE. 
-	//I fill this array in before knowing if GCE will be instanced.
-	if (iColorDepth&KEmulIsBitMask)
-		{
-		//iModeDepths is only used by GCE
-		TInt colorDepth=MaskGceOnly(iColorDepth);
-		TInt setMode=0;
-		for (TInt i=1;i!=KEmulIsBitMask;i+=i)
-			if (colorDepth&i)
-				iModeDepths[setMode++]=BitsForSingleMode(i);
-		iMaxModes= setMode;	
-		iModeDepths[setMode++]=0;	//a bit width of 0 is illegal	
-		}
-	else
-		{
-		iModeDepths[0]=iColorDepth;
-		iMaxModes=1;
-		iModeDepths[1]=0;	//a bit width of 0 is illegal
-		}
-
-	wsprintfA(property, "Configuration[%d][%d]FasciaBitmap",aConf,aScreen);
-	const char* fascia = Property::GetString(property);
-	if (fascia)
-		{
-		TInt len = strlen(fascia);
-		//the path may have quotes at the start and end
-		//need to work out if this is an absolute or relative path
-		if (fascia[0] == '\"')
-			{
-			++fascia;
-			--len;
-			if (--len > 0 && fascia[len-1] == '\"')
-				--len;
-			}
-		char* p = iFasciaFileName;
-		if (fascia[0] != '\\' && (len < 3 || fascia[1] != ':'))
-			{
-			//relative path
-			strcpy(p, Property::GetString("EmulatorDataPath"));
-			p += strlen(p);
-			}
-		memcpy(p, fascia, len);
-		p[len] = '\0';
-		}
-	else
-		{
-		// default to machine name
-		strcpy(iFasciaFileName, Property::GetString("EmulatorDataPath"));
-		strcat(iFasciaFileName, Property::GetString("MachineName"));
-		strcat(iFasciaFileName, ".bmp");
-		}
-	return KErrNone;
-	}
-
-TViewport::TViewport() 
-	:iScreenProps(NULL),iViewportWidth(0), iViewportHeight(0), iViewportOffsetX(0), iViewportOffsetY(0)
-	{
-	}
-
-TViewport::TViewport(DScreenProperties* aScreenProps)
-	:iScreenProps(aScreenProps),iViewportWidth(0), iViewportHeight(0), iViewportOffsetX(0), iViewportOffsetY(0)
-	{	
-	}	
-TViewport::~TViewport()
-	{
-	}
-	
-
-/**
-Changes the logical position of the viewport within the input area
-of the emulator screen. The method may adjust the position so that
-the viewport stays within the input area.
-@param aPosition The new Y position of the top left hand corner of the viewport.
-@param aHwnd The window associated with the viewport
-*/
-void TViewport::ScrollToY(TInt aPosition, HWND aHwnd)
-	{
-
-	SCROLLINFO scrollinfo;
-	scrollinfo.cbSize=sizeof(scrollinfo);
-
-	//save for later
-	scrollinfo.fMask=SIF_POS;
-	GetScrollInfo(aHwnd, SB_VERT, &scrollinfo);
-	TInt oldY=scrollinfo.nPos;
-
-	if(aPosition<0)
-	{
-		scrollinfo.nPos = 0;
-	}
-	else if( (aPosition+GetViewportHeight())>GetMaxHeight())
-	{
-		scrollinfo.nPos = max(0,GetMaxHeight() - GetViewportHeight() );
-	}
-	else
-	{
-		scrollinfo.nPos=aPosition;
-	}
-
-	SetViewportOffsetY(scrollinfo.nPos);
-	scrollinfo.fMask=SIF_POS;
-	SetScrollInfo(aHwnd,SB_VERT, &scrollinfo, TRUE );
-	ScrollWindowEx(aHwnd, 0, oldY-scrollinfo.nPos, 0, 0, NULL, NULL, SW_INVALIDATE);
-	
-	UpdateChildPos(aHwnd);
-	}
-	
-/**
-As for ScrollToY but for the X direction
-*/
-void TViewport::ScrollToX(TInt aPosition, HWND aHwnd)
-	{
-	SCROLLINFO scrollinfo;
-	scrollinfo.cbSize=sizeof(scrollinfo);
-	
-	//save for later
-	scrollinfo.fMask=SIF_POS;
-	GetScrollInfo(aHwnd, SB_HORZ, &scrollinfo);
-	TInt oldX=scrollinfo.nPos;
-
-	if(aPosition<0)
-	{
-		scrollinfo.nPos = 0;
-	}
-	else if( (aPosition+GetViewportWidth())>GetMaxWidth())
-	{
-		scrollinfo.nPos = max(0,GetMaxWidth() - GetViewportWidth() );
-	}
-	else
-	{
-		scrollinfo.nPos=aPosition;
-	}
-
-	SetViewportOffsetX(scrollinfo.nPos);
-	scrollinfo.fMask=SIF_POS;
-	SetScrollInfo(aHwnd,SB_HORZ, &scrollinfo, TRUE );
-	ScrollWindowEx(aHwnd, oldX-scrollinfo.nPos, 0, 0, 0, NULL, NULL, SW_INVALIDATE);
-
-	UpdateChildPos(aHwnd);
-	}
-	
-//Forward declaration
-LOCAL_C TInt ScreenFromHWND(HWND aHwnd,HWND* pWin);
-
-/**
-Move the child window to it's correct position.
-
-@param aHwnd The HWND of the parent window
-*/
-void TViewport::UpdateChildPos(HWND aHwnd)
-	{
-	TInt screenNumber = ::ScreenFromHWND(aHwnd,TheWin);
-	HWND childWin = TheChildWin[screenNumber];
-
-	switch (iScreenProps->iScreenRotation)
-		{
-		case EEmulatorFlipRestore:
-			MoveWindow(
-				childWin,
-				iScreenProps->iScreenOffsetX - GetViewportOffsetX(),
-				iScreenProps->iScreenOffsetY - GetViewportOffsetY(),
-				iScreenProps->iScreenWidth,
-				iScreenProps->iScreenHeight,
-				TRUE
-				);
-			break;
-		case EEmulatorFlipInvert:
-			MoveWindow(
-				childWin,
-				iScreenProps->iXYInputWidth-(iScreenProps->iScreenOffsetX+iScreenProps->iScreenWidth) - GetViewportOffsetX(),
-				iScreenProps->iXYInputHeight-(iScreenProps->iScreenOffsetY+iScreenProps->iScreenHeight) - GetViewportOffsetY(),
-				iScreenProps->iScreenWidth,
-				iScreenProps->iScreenHeight,
-				TRUE
-				);
-			break;
-		case EEmulatorFlipLeft:
-			MoveWindow(
-				childWin,
-				iScreenProps->iScreenOffsetY - GetViewportOffsetX(),
-				iScreenProps->iXYInputWidth-(iScreenProps->iScreenOffsetX+iScreenProps->iScreenWidth)- GetViewportOffsetY(),
-				iScreenProps->iScreenHeight,
-				iScreenProps->iScreenWidth,
-				TRUE
-				);
-			break;
-		case EEmulatorFlipRight:
-			MoveWindow(
-				childWin,
-				iScreenProps->iXYInputHeight-(iScreenProps->iScreenOffsetY+iScreenProps->iScreenHeight) - GetViewportOffsetX(),
-				iScreenProps->iScreenOffsetX - GetViewportOffsetY(),
-				iScreenProps->iScreenHeight,
-				iScreenProps->iScreenWidth,
-				TRUE
-				);
-			break;
-		}
-
-	}
-	
-/**
-Update the range of the horizontal scrollbar,
-to take account of the current viewport width.
-
-@param aHwnd The window to be updated
-*/
-void TViewport::UpdateScrollBarH(HWND aHwnd)
-	{
-
-	SCROLLINFO scrollinfoHor;
-	scrollinfoHor.cbSize=sizeof(scrollinfoHor);
-	scrollinfoHor.fMask=SIF_RANGE|SIF_PAGE;
-	scrollinfoHor.nMin=0;
-	scrollinfoHor.nMax= GetMaxWidth()-1;
-	
-	
-	TInt newPage = GetViewportWidth() ;
-	TBool redraw=EFalse; //redraw window if a resize has caused a scrollbar to disappear and reveal image.
-	if ( newPage>= scrollinfoHor.nMax -GetSystemMetrics(SM_CXVSCROLL)
-		&& newPage < scrollinfoHor.nMax+1)
-		{
-		redraw=ETrue;
-		newPage=GetMaxWidth();
-
-		}
-	scrollinfoHor.nPage= newPage;
-
-	SetScrollInfo(aHwnd,SB_HORZ, &scrollinfoHor, TRUE );
-	if(redraw)
-		{
-		ScrollToX(0, aHwnd); //in case egde of fascia was against edge of vertical scrollbar
-		InvalidateRect(aHwnd, NULL, TRUE);
-		}
-	}
-	
-/**
-Update the range of the vertical scrollbar,
-to take account of the current viewport width.
-
-@param aHwnd The window to be updated
-*/	
-void TViewport::UpdateScrollBarV(HWND aHwnd)
-	{
-	SCROLLINFO scrollinfoVer;
-	scrollinfoVer.cbSize=sizeof(scrollinfoVer);
-	scrollinfoVer.fMask=SIF_RANGE|SIF_PAGE;
-	scrollinfoVer.nMin=0;
-	scrollinfoVer.nMax= GetMaxHeight()-1;
-	
-	TInt newPage = GetViewportHeight() ;
-	TBool redraw=EFalse; //redraw window if a resize has caused a scrollbar to disappear and reveal image.
-	if ( newPage>= scrollinfoVer.nMax -GetSystemMetrics(SM_CYHSCROLL)
-		&& newPage < scrollinfoVer.nMax+1)
-		{
-		redraw=ETrue;
-		newPage=GetMaxHeight();
-		}
-	scrollinfoVer.nPage= newPage;
-
-	SetScrollInfo(aHwnd,SB_VERT, &scrollinfoVer, TRUE );
-	if(redraw)
-		{
-		ScrollToY(0, aHwnd); //in case egde of fascia was against edge of vertical scrollbar
-		InvalidateRect(aHwnd, NULL, TRUE);
-		}
-	}
-
-/**
-Returns the max width for the viewport window (non-client area) so that it
-may be bounded. Takes account of scrollbar.
-
-@return Max width
-*/	
-TInt TViewport::GetMaxWindowWidth() const
-	{
-	
-	RECT rect = {0,0,0,0};
-	
-	switch(iScreenProps->iScreenRotation)
-		{
-		case EEmulatorFlipRestore:
-		case EEmulatorFlipInvert:
-			{
-			rect.right=iScreenProps->iXYInputWidth;
-			rect.bottom=iScreenProps->iXYInputHeight;
-			break;
-			}
-		case EEmulatorFlipLeft:
-		case EEmulatorFlipRight:
-			{
-			rect.right=iScreenProps->iXYInputHeight;
-			rect.bottom=iScreenProps->iXYInputWidth;
-			break;
-			}
-		}
-	AdjustWindowRect(//take account of window decorations
-		&rect,
-		KWinStyle,
-		FALSE
-		);
-	
-	
-	return (rect.right-rect.left);
-	}
-	
-/**
-Returns the max height for the viewport window (non-client area) so that it
-may be bounded. Takes account of scrollbar.
-
-@return Max height
-*/
-TInt TViewport::GetMaxWindowHeight() const
-	{
-	
-	RECT rect ={0,0,0,0};
-
-	switch(iScreenProps->iScreenRotation)
-		{
-		case EEmulatorFlipRestore:
-		case EEmulatorFlipInvert:
-			{
-			rect.right=iScreenProps->iXYInputWidth;
-			rect.bottom=iScreenProps->iXYInputHeight;
-			break;
-			}
-		case EEmulatorFlipLeft:
-		case EEmulatorFlipRight:
-			{
-			rect.right=iScreenProps->iXYInputHeight;
-			rect.bottom=iScreenProps->iXYInputWidth;
-			break;
-			}
-		}
-	AdjustWindowRect(//take account of window decorations
-		&rect,
-		KWinStyle,
-		FALSE
-		);
-	return (rect.bottom-rect.top);
-	}
-
-/**
-Returns the maximum width for the viewport (client area only).
-Allowing for the orientation of the emulator.
-
-@return Max width
-*/
-TInt TViewport::GetMaxWidth() const
-	{
-	TInt width=0;
-	switch(iScreenProps->iScreenRotation)
-		{
-		case EEmulatorFlipRestore:
-		case EEmulatorFlipInvert:
-			{
-			width = iScreenProps->iXYInputWidth;
-			break;
-			}
-		case EEmulatorFlipLeft:
-		case EEmulatorFlipRight:
-			{
-			width = iScreenProps->iXYInputHeight;
-			break;
-			}
-		}
-	
-	return width;
-	}
-
-/**
-Returns the maximum height for the viewport (client area only).
-Allowing for the orientation of the emulator.
-
-@return Max height
-*/
-TInt TViewport::GetMaxHeight() const
-	{
-	TInt height=0;
-	switch(iScreenProps->iScreenRotation)
-		{
-		case EEmulatorFlipRestore:
-		case EEmulatorFlipInvert:
-			{
-			height = iScreenProps->iXYInputHeight;
-			break;
-			}
-		case EEmulatorFlipLeft:
-		case EEmulatorFlipRight:
-			{
-			height =  iScreenProps->iXYInputWidth;
-			break;
-			}
-		}
-	
-	return height;
-	
-	}
-
-/**
-Sets the X offset of the viewport from the edge of the input area
-@param aOffset The X offset
-*/
-void TViewport::SetViewportOffsetX(TInt aOffset)
-	{
-	iViewportOffsetX = aOffset;
-	}
-
-/**
-Sets the Y offset of the viewport from the edge of the input area
-@param aOffset The Y offset
-*/
-void TViewport::SetViewportOffsetY(TInt aOffset)
-	{
-	iViewportOffsetY = aOffset;
-	}
-
-TInt TViewport::GetViewportOffsetX() const
-	{
-	return iViewportOffsetX;	
-	}
-TInt TViewport::GetViewportOffsetY() const
-	{
-	return iViewportOffsetY;
-	}
-	
-/**
-Sets the viewport width, this is equal to the width
-of the window's client area
-@param aWidth The width
-*/
-void TViewport::SetViewportWidth(TInt aWidth)
-	{
-	iViewportWidth=aWidth;
-	}
-
-/**
-Sets the viewport height, this is equal to the height
-of the window's client area
-@param aHeight The height
-*/
-void TViewport::SetViewportHeight(TInt aHeight)
-	{
-	iViewportHeight=aHeight;
-	}
-
-TInt TViewport::GetViewportWidth() const
-	{
-	return iViewportWidth;
-	}
-TInt TViewport::GetViewportHeight() const
-	{
-	return iViewportHeight;
-	}
-
-// the UI class
-
-DWinsUi::DWinsUi()
-	:iVirtualKeys(10),
-	iControlHotKeys(10)
-	{}
-
-/// Returns the current mode's depth. Remember current mode is never set!
-TUint DWinsUi::ColorDepth(TInt aScreenNumber)
-	{
-	TVideoInfoV01 info;
-	VideoInfo(aScreenNumber, info);
-	return info.iBitsPerPixel;
-	}
-
-TInt DWinsUi::SetFlip(TEmulatorFlip aFlip, TInt aScreenNumber)
-	{
-	if(TUint(aScreenNumber)>=TUint(systemIni->iScreens.Count()))
-		return KErrArgument;
-	int r1 = PostMessageA(TheChildWin[aScreenNumber],WM_FLIP_MESSAGE,(TUint)aFlip,NULL);
-	return r1 ? KErrNone : KErrGeneral;
-	}
-
-void DWinsUi::Info(TVariantInfoV01& aInfo)
-	{
-	aInfo.iLedCapabilities=0x3;
-	}
-
-HWND DWinsUi::HWnd()
-	{
-	return TheControlWin;
-	}
-
-TInt DWinsUi::SetupProperties(TInt aId)
-	
-//
-// load UI settings from the emulator properties
-//
-	{
-	//setup the screens
-	TInt screens = Property::GetInt("[screens]", 1);
- 
- 	for (TInt x = 0; x < screens; ++x)
- 		{
- 		DScreenProperties * pScr = new DScreenProperties();
- 		if (!pScr)
- 			return KErrNoMemory;
- 		
- 		TInt ret = pScr->SetupProperties(aId,x);
- 		if (KErrNone == ret)
- 			ret = iScreens.Append(pScr);
- 
- 		if (KErrNone != ret)
- 			{
- 			delete pScr;
- 			return ret;
- 			}
- 		}
-//
-	char property[50];
-	wsprintfA(property, "Configuration[%d]LedSize",aId);
-	iLedSize = Property::GetInt(property, KLedSize);
-	wsprintfA(property, "Configuration[%d]LedArrangeVertically",aId);
-	iLedVertical = Property::GetBool(property, KLedVertical);
-	wsprintfA(property, "Configuration[%d]LedArrangeHorizontally",aId);
-	if (Property::GetBool(property))
-		iLedVertical = EFalse;
-	wsprintfA(property, "Configuration[%d]LedOffsetX",aId);
-	iLedOffsetX = Property::GetInt(property, KLedLeft);
-	wsprintfA(property, "Configuration[%d]LedOffsetY",aId);
-	iLedOffsetY = Property::GetInt(property, KLedTop);
-	wsprintfA(property, "Configuration[%d]LedGap",aId);
-	iLedGap = Property::GetInt(property, KLedGap);
-//
-	wsprintfA(property, "Configuration[%d]PointerType",aId);
-	const char* pointer = Property::GetString(property, "Pen");
-	if (_stricmp(pointer, "None") == 0)
-		{
-		iPointerType=_S8("NONE");
-		iXYInputType=EXYInputNone;
-		}
-	else if (_stricmp(pointer,"Pen") == 0)
-		{
-		iPointerType=_S8("PEN");
-		iXYInputType=EXYInputPointer;
-		}
-	else if (_stricmp(pointer,"Mouse") == 0)
-		{
-		iPointerType=_S8("MOUSE");
-		iXYInputType=EXYInputMouse;
-		}
-	else if (_stricmp(pointer,"Delta-Mouse") == 0)
-		{
-		iPointerType=_S8("MOUSE");
-		iXYInputType=EXYInputDeltaMouse;
-		}
-	else
-		return KErrArgument;
-//
-	wsprintfA(property, "Configuration[%d]DigitizerOffsetX",aId);
-	iDigitizerOffsetX = Property::GetInt(property, -iScreens[0]->iScreenOffsetX);
-	wsprintfA(property, "Configuration[%d]DigitizerOffsetY",aId);
-	iDigitizerOffsetY = Property::GetInt(property, -iScreens[0]->iScreenOffsetY);
-	wsprintfA(property, "Configuration[%d]DigitizerWidth",aId);
-	iDigitizerWidth = Property::GetInt(property,-1);
-	wsprintfA(property, "Configuration[%d]DigitizerHeight",aId);
-	iDigitizerHeight = Property::GetInt(property,-1);
-	wsprintfA(property, "Configuration[%d]DisableDigitizer",aId);
-	iDigitizerEnabled = !Property::GetBool(property);
-//	To enable the multitouch 
-	wsprintfA(property, "EnableMultiTouch");
-	iMultiTouchEnabled = Property::GetBool(property,EFalse);
-	wsprintfA(property, "SYMBIAN_BASE_USE_GCE");
-	iGCEEnabled = Property::GetBool(property,EFalse);
-	wsprintfA(property, "MultiTouchProximityStep");
-	iMultiTouchProximityStep = Property::GetInt(property,-1);
-	wsprintfA(property, "MultiTouchPressureStep");
-	iMultiTouchPressureStep = Property::GetInt(property,-1);
-//
-	strcpy(iSysIniFileName, Property::GetString("EmulatorDataPath"));
-	strcat(iSysIniFileName, "emulator\\");
-	if (!Emulator::CreateAllDirectories(iSysIniFileName))
-		return Emulator::LastError();
-	strcat(iSysIniFileName, Property::GetString("MachineName"));
-	strcat(iSysIniFileName, ".sys.ini");
-//
-	TInt r = iKeyboard.Init(aId);
-	if (r != KErrNone)
-		return r;
-
-	wsprintfA(property, "Configuration[%d]VirtualKey",aId);
-	r = MultiProperty(&DWinsUi::DoDefineVirtualKey, this, property);
-	if (r != KErrNone)
-		return r;
-//
-
-	wsprintfA(property, "Configuration[%d]NoVersionInfo",aId);
-	iDisplayVersionInfo = !Property::GetBool(property);
-	
-	wsprintfA(property, "Configuration[%d]WindowTitle",aId);
-	const char * p = Property::GetString(property);
-	if (p && (strlen(p) <= KMaxNameSize))
-		strcpy(iWindowTitle, p);
-	else
-		strcpy(iWindowTitle, DefaultWindowTitle);
-
-	if (iDisplayVersionInfo)
-		{
-		TInt wtLen = strlen(iWindowTitle);
-		TInt vtLen = strlen(VersionText);
-		if ((wtLen + vtLen) > KMaxNameSize)
-			iWindowTitle[KMaxNameSize-vtLen] = '\0';
-		strcat(iWindowTitle, VersionText);
-		}
-
-	wsprintfA(property, "Configuration[%d]OnActivation",aId);
-	pointer = Property::GetString(property);	
-	//example	OnActivation 270 EKeyScreenDimension1
-	//params are rotation(int) and key(string)
-	if (pointer)
-		{
-		char * next;
-	
-		//skip any white space
-		const char* beg = skipws(pointer);
-		
-		//get the number
-		long rotation = strtol(beg, &next, 0);
-		if (next == beg)
-			return KErrArgument;
-
-		switch (rotation)
-			{
-			case 0:
-				iScreens[0]->iScreenRotation = EEmulatorFlipRestore;
-				break;
-			case 90:
-				iScreens[0]->iScreenRotation = EEmulatorFlipRight;
-				break;
-			case 180:
-				iScreens[0]->iScreenRotation = EEmulatorFlipInvert;
-				break;
-			case 270:
-				iScreens[0]->iScreenRotation = EEmulatorFlipLeft;
-				break;
-			default:
-				r = KErrArgument;
-			}
-		if (r != KErrNone)
-			return r;
-		
-		beg = skipws(next);
-		
-		//beg should now point to the keycode
-		TInt key = iKeyboard.GetEPOCKeyCode(TPtrC8((const TUint8*)beg, strlen(beg)));
-		if (key == KErrNotFound)
-			return key;
-		iInitialFlipMsg = key;
-		}
-
-	//EmulatorControl messages are a bit like virtual keys
-	wsprintfA(property, "Configuration[%d]EmulatorControl",aId);
-	r = MultiProperty(&DWinsUi::DoDefineEmulatorControl, this, property);
-	if (r != KErrNone)
-		return r;
-
-	wsprintfA(property, "Configuration[%d]EmulatorControlHotKey",aId);
-	r = MultiProperty(&DWinsUi::DoDefineEmulatorControlHotKey, this, property);
-	if (r != KErrNone)
-		return r;
-	
-	return KErrNone;
-	}
-
-TInt DWinsUi::NumberOfScreens()
-	{
-	return iScreens.Count();
-	}
-
-/**
-Return the highest bit depth from an emulator mode mask.
-@param aModeMask	A bitwise combination of KEmul... display mode mask values.
-@return A color depth in bits per pixel.
-*/
-LOCAL_C TInt MaximumBitDepthFromMask(TInt aModeMask)
-	{
-	// Choose the highest bits per pixel based on the display mode mask.
-	if (aModeMask & KEmulColor16M)
-		{
-		return 24;
-		}
-	if (aModeMask & KEmulColor64K)
-		{
-		return 16;
-		}
-	if (aModeMask & KEmulColor4K)
-		{
-		return 12;
-		}
-
-	// Lower bit depths are not supported, so use the default
-	return 24;
-	}
-
-
-/**
-Return the TDisplayRotation corresponding to the given TEmulatorFlip.
-@param aFlip	A screen rotation as a TEmulatorFlip.
-@return The screen rotation as a TDisplayRotation.
-*/
-LOCAL_C RDisplayChannel::TDisplayRotation FlipToDisplayRotation(TEmulatorFlip aFlip)
-	{
-	switch (aFlip)
-		{
-		case EEmulatorFlipLeft:
-			return RDisplayChannel::ERotation90CW;
-		case EEmulatorFlipInvert:
-			return RDisplayChannel::ERotation180;
-		case EEmulatorFlipRight:
-			return RDisplayChannel::ERotation270CW;
-		}
-	return RDisplayChannel::ERotationNormal;
-	}
-
-
-TInt DWinsUi::SetDisplayChannel(TInt aScreenNumber, DDisplayChannel* aDisplay)
-	{
-	return systemIni->SetDisplayChannelImpl(aScreenNumber,aDisplay);
-	}
-
-
-TInt DWinsUi::SetDisplayChannelImpl(TInt aScreenNumber, DDisplayChannel* aDisplay)
-	{
-	if (TUint(aScreenNumber) >= TUint(NumberOfScreens()))
-		{
-		// Screen number is either negative or too big.
-		return KErrArgument;
-		}
-
-	TInt r = KErrNone;
-	HWND hWnd = TheChildWin[aScreenNumber];
-	TBufferSet& buffer = masterIni->iBufferSet[aScreenNumber];
-	
-	if (aDisplay)
-		{
-		// Display driver connecting
-		DScreenProperties* screen = iScreens[aScreenNumber];
-		RDisplayChannel::TDisplayInfo info;
-
-		TInt pixelBytes = 2;
-		info.iBitsPerPixel = MaximumBitDepthFromMask(screen->iColorDepth);
-
-		switch (info.iBitsPerPixel)
-			{
-			case 12:	// XRGB4444
-				info.iPixelFormat = EUidPixelFormatXRGB_4444;
-				break;
-			case 16:	// RGB565
-				info.iPixelFormat = EUidPixelFormatRGB_565;
-				break;
-			default:
-				// Force anything else to packed RGB888
-				pixelBytes = 4;
-				info.iBitsPerPixel = 24;
-				info.iPixelFormat = EUidPixelFormatXRGB_8888;
-				break;
-			}
-
-		TInt width = screen->iMaxScreenWidth;
-		TInt height = screen->iMaxScreenHeight;
-
-		info.iRefreshRateHz = screen->iRefreshRateHz;
-		info.iAvailableRotations = RDisplayChannel::ERotationNormal | RDisplayChannel::ERotation90CW |
-									RDisplayChannel::ERotation180 | RDisplayChannel::ERotation270CW;
-		info.iNormal.iWidth = width;
-		info.iNormal.iHeight = height;
-		// Windows requires rounding up to 4-bytes words
-		info.iNormal.iOffsetBetweenLines = _ALIGN_UP(width * pixelBytes, 4);
-		info.iFlipped.iWidth = height;
-		info.iFlipped.iHeight = width;
-		// Windows requires rounding up to 4-bytes words
-		info.iFlipped.iOffsetBetweenLines = _ALIGN_UP(height * pixelBytes, 4);
-	
-		TInt maxSize=0;	 
-		//ensure legacy buffer is large enough for all supported modes.
-		//It would be a very strange setup for the max size to not be the max bpp,
-		//but we don't know which mode is max bpp anyway!
-		TVideoInfoV01 videoInfo;
-		for (TInt mode=0,maxMode=screen->iMaxModes;mode<maxMode;mode++)
-			{
-			if (systemIni->VideoInfoForDisplayDriver(aScreenNumber,mode, videoInfo))	//can't actually fail currently
-				{
-				TInt dwSize=videoInfo.iOffsetToFirstPixel+videoInfo.iOffsetBetweenLines*videoInfo.iSizeInPixels.iHeight;
-				if (dwSize>maxSize)
-					maxSize=dwSize;
-				}
-			else
-				{
-				Fault(EGuiVideoInfoUnavailable);
-				}
-			//rotated mode may use more RAM?? Height may be >Width or may not be a multiple of stride quantum
-			if (systemIni->VideoInfoForDisplayDriver(aScreenNumber,mode|KModeFlagFlipped, videoInfo))	//can't actually fail currently
-				{
-				TInt dwSize=videoInfo.iOffsetToFirstPixel+videoInfo.iOffsetBetweenLines*videoInfo.iSizeInPixels.iWidth;
-				if (dwSize>maxSize)
-					{
-					maxSize=dwSize;
-					}
-				}
-			else
-				{
-				Fault(EGuiVideoInfoUnavailable);
-				}
-			}
-
-		masterIni->iMaxSizeInBytes = maxSize;
-		if (__e32_atomic_add_ord32(&buffer.iDisplayDriverCount, 1) == 0)
-			{
-			// First driver to connect, allocate frame buffers.
-			// +1 frame buffer is ui legacy buffer at [0], so does need to take account of stride and offset
-			r = masterIni->AllocateFrameBuffers(aScreenNumber, screen->iCompositionBuffers + 1, maxSize);
-			}
-
-		if (r == KErrNone)
-			{
-			buffer.iScreenBuffer.iDisplayBufferOffset = 0;
-			masterIni->iBufferSet[aScreenNumber].iDisplayChannel = aDisplay;
-			masterIni->InitBitmapHeader(*screen, &buffer.iInfo);
-			masterIni->InitBufferFormat(*screen, buffer.iBufferFormat);
-			if(systemIni->VideoInfoForDisplayDriver(aScreenNumber,screen->iCurrentMode, videoInfo, ETrue))
-				{
-					r = aDisplay->Initialize(info,
-											 FlipToDisplayRotation(screen->iScreenRotation),
-											 hWnd, buffer.iScreenBuffer.iFrameBuffers,
-											 buffer.iScreenBuffer.iMemChunks,
-											 buffer.iDsaBuffer,
-						                     videoInfo.iSizeInPixels,videoInfo.iSizeInTwips,
-						                     masterIni->iSupportedPixelFormatTable,
-						                     masterIni->iSupportedPixelFormatTableSize,
-						                     buffer.iBufferFormat);
-				}
-			else
-				{
-				Fault(EGuiVideoInfoUnavailable);
-				}
-			}
-
-		if (r != KErrNone && __e32_atomic_tas_ord32(&buffer.iDisplayDriverCount, 1, -1, 0) == 1)
-			{
-			// Release any that were allocated
-			masterIni->ReleaseFrameBuffers(aScreenNumber);
-			}
-		}
-	else
-		{
-		// Display driver disconnected
-		if (__e32_atomic_tas_ord32(&buffer.iDisplayDriverCount, 1, -1, 0) == 1)
-			{
-			// All drivers disconnected, deallocate memory.
-			masterIni->ReleaseFrameBuffers(aScreenNumber);
-			}
-		}
-
-	return r;
-	}
-
-
-void DWinsUi::SetVirtualKey(const TBool aProcessing, const TInt aCommandData, const TEmulCommand aCommand)
-	{
-	iProcessingVirtualKey = aProcessing;
-	iFakedVirtualKey = aCommandData;
-	iVirtualKeyCommand = aCommand;
-	}
-
-TBool DWinsUi::WasVirtualKey(TInt& aCommandData, TEmulCommand& aCommand)
-	{
-	if (iProcessingVirtualKey)
-		{
-
-		aCommandData = iFakedVirtualKey;
-		aCommand = iVirtualKeyCommand;
-		}
-	return iProcessingVirtualKey;
-	}
-
-
-TInt DWinsUi::DoDefineEmulatorControl(TAny* aPtr, const char* aValue)
-	{
-	return static_cast<DWinsUi*>(aPtr)->DefineEmulatorControl(aValue);
-	}
-
-
-TInt DWinsUi::DefineEmulatorControl(const char* aValue)
-	{
-
-	//example EmulatorControl SelectConfig 2 rect 223,640 29,22
-	//example EmulatorControl NextConfig rect 223,640 29,22
-	const char* beg = skipws(aValue);
-	const char* end = skiptok(beg);
-	TInt err = KErrNone;
-	
-	TEmulCommand command = ENoCommand;
-	TInt data = 0;
-	if (_strnicmp(beg, "SelectConfig", end-beg) == 0)
-		{
-		//get the int param which is the config to switch to
-		beg = end;
-		char * e;
-		data = strtol(beg, &e,0);
-		if (beg == e)
-			err = KErrArgument;
-		end = e;
-		command = ESelectConfig;
-		}
-	else if(_strnicmp(beg, "NextConfig", end-beg) == 0)
-
-		{
-		command = ENextConfig;
-		}
-	else
-		err = KErrArgument;
-
-	if (err != KErrNone)
-		return err;
-	
-	//get the shape
-	beg = skipws(end);
-	end = skiptok(beg);
-	if (end - beg != 4 || _strnicmp(beg, "rect", 4) != 0)
-		return KErrArgument;
-		
-	// get the parameters
-	beg = skipws(end);
-	char* end2;
-	TInt x = strtol(beg, &end2, 10);
-	if (beg == end2 || *end2++ != ',')
-		return KErrArgument;
-	beg = end2;
-	TInt y = strtol(beg, &end2, 10);
-	if (beg == end2)
-		return KErrArgument;
-	beg = skipws(end2);
-	TInt w = strtol(beg, &end2, 10);
-	if (beg == end2 || *end2++ != ',')
-		return KErrArgument;
-	beg = end2;
-	TInt h = strtol(beg, &end2, 10);
-	if (beg == end2)
-		return KErrArgument;
-	
-	VKRect* pRect = new VKRect(data, command, x, y, w, h);
-	if (!pRect)
+// Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// wins\specific\gui.cpp
+// 
+//
+#define WINVER 0x0500
+
+#include "gui.h"
+#include <emulator.h>
+#include <assp.h>
+#include <kernel/kern_priv.h>
+#include <kernel/kpower.h>
+#include "variant.h"
+#include "resource.h"
+#include "winsgui.h"
+#include "display_chan.h"
+#include "pixelformats.h"
+#include "multitouch.h"
+
+#include "monitors.h"
+
+#include <kernel/sproperty.h>
+
+//Define these so that emulator generates varying values for gce stride and offset.
+//By default in emulator, stride is exactly right for display resolution and offset is zero
+//Setting these will identify code which incorrectly calculates these factors instead of requesting them
+//Note that multiples of 4 bytes are preferred for various reasons.
+//[3/5/07 The Secure presentation burffer ignores stride extra because it uses a windows bitmap header to render.]
+// #define TEST_GCE_VARIABLE_STRIDE_EXTRA	16		 	//This constant is added to each mode's scanline length in bytes. It may cause a break if enabled because the iDisplayBufferOffset is not being set
+// #define TEST_GCE_VARIABLE_START_EXTRA	16			//A multiple of this is added to each mode's start address in bytes
+// #define ASSYMETRIC_SQUARE_STRIDE						//If this is defined and the width==height the the stride will not be the same!
+
+enum  
+	{
+		KMaskModeNum=0x0FFFFFFF,
+		KMaskModeFlag8=0x80000000,
+		KMaskModeFlag4=0x40000000,
+		KMaskModeFlag2=0x20000000,
+		KMaskModeFlag1=0x10000000,
+		
+		KModeFlagFlipped=KMaskModeFlag8,
+		
+	};
+enum  
+	{
+		KMaskScreenNum=0x0FFF,
+		KMaskScreenFlag8=0x8000,
+		KMaskScreenFlag4=0x4000,
+		KMaskScreenFlag2=0x2000,
+		KMaskScreenFlag1=0x1000,
+		
+		KScreenFlagSecure=KMaskScreenFlag8,
+		
+	};
+const TInt KMaxDisplayColors=16777216;
+const TInt KMaxDisplayContrast=1;
+
+static TEmulatorFlip* CurrentFlipState=NULL;
+static TInt CurrentConfiguration = 0;
+static TInt SavedFlipMessage = 0;
+
+DWinsUi *systemIni=NULL;
+DMasterIni* masterIni;
+
+DMultiTouch* TheMultiTouch;
+static HWND TheControlWin;
+static HWND* TheChildWin=NULL;
+static HWND* TheWin=NULL;
+static HWND hwndStatus; // To display the X,Y,Z information of each mouse
+static TInt VirtualKeyPressed = EStdKeyNull;
+static HBITMAP* TheScreenBitmap=NULL;
+static TUint LedMask;
+static TBool WsSwitchOnScreen;
+
+const char * DefaultWindowTitle = "Symbian OS Emulator";
+
+#ifdef __VC32__
+
+#ifdef _DEBUG
+const char * VersionText = " - wins udeb";
+#else
+const char * VersionText = " - wins urel";
+#endif
+
+#else
+#ifdef __CW32__
+
+#ifdef _DEBUG
+const char * VersionText = " - winscw udeb";
+#else
+const char * VersionText = " - winscw urel";
+#endif
+
+#else
+//not winscw or wins!
+#ifdef _DEBUG
+const char * VersionText = " - unknown udeb";
+#else
+const char * VersionText = " - unknown urel");
+#endif
+
+#endif
+#endif
+
+void Inactive();
+void Active();
+void DrawLeds();
+void UpdateModifiers(); 
+TInt DisplayHalFunction(TAny*, TInt aFunction, TAny* a1, TAny* a2);
+LOCAL_C TBool PaintWindowFromBuffer(HWND hWnd);
+
+GLDEF_C const char* skipws(const char* aPtr)
+	{
+	while (isspace(*aPtr))
+		++aPtr;
+	return aPtr;
+	}
+
+GLDEF_C const char* skiptok(const char* aPtr)
+	{
+	while (isalnum(*aPtr))
+		++aPtr;
+	return aPtr;
+	}
+
+GLDEF_C TInt CompareI(const TDesC8& aLhs, const TDesC8& aRhs)
+//
+// Case insensitive comparison of descriptors
+// (TDesC::CompareF not available to kernel side code)
+//
+	{
+	TInt ll = aLhs.Length();
+	TInt rl = aRhs.Length();
+	TInt len = Min(ll, rl);
+	TInt k = _strnicmp((const char*)aLhs.Ptr(), (const char*)aRhs.Ptr(), len);
+	return k != 0 ? k : ll - rl;
+	}
+
+GLDEF_C TInt MultiProperty(TInt (*aHandler)(TAny* aObj, const char*), TAny* aPtr, const char* aProperty)
+	{
+	const char* value = Property::GetString(aProperty);
+	if (!value)
+		return KErrNone;
+	for (;;)
+		{
+		TInt r = aHandler(aPtr, value);
+		if (r != KErrNone)
+			return r;
+		const char* ev = strchr(value, ';');
+		if (!ev)
+			break;
+		value = ev + 1;
+		}
+	return KErrNone;
+	}
+
+class DWinsGuiPowerHandler : public DPowerHandler
+	{
+public: // from DPowerHandler
+	void PowerDown(TPowerState);
+	void PowerUp();
+public:
+	static DWinsGuiPowerHandler* New();
+	void ScreenOn();
+	void ScreenOff();
+	void ScreenOn(TInt aScreen);
+	void ScreenOff(TInt aScreen);
+public:
+	DWinsGuiPowerHandler();
+	TBool ProcessEvent(const TRawEvent* aEvent);
+	TBool ProcessEventDfc(const TRawEvent* aEvent);
+	TBool	iStandby;
+	};
+	
+class DWinsGuiRotateHandler
+	{
+public:
+	static DWinsGuiRotateHandler* New();
+	TBool ProcessEventDfc(const TRawEvent* aEvent);
+
+private:
+	RPropertyRef iOrientationProperty;
+	};
+
+static DWinsGuiPowerHandler* WinsGuiPowerHandler;
+
+static DWinsGuiRotateHandler* WinsGuiRotateHandler;
+
+
+_LIT(KWinsGuiName, "WinsGui");
+
+DWinsGuiPowerHandler* DWinsGuiPowerHandler::New()
+	{
+	DWinsGuiPowerHandler* self = new DWinsGuiPowerHandler();
+	if (!self)
+		return NULL;
+	self->Add();
+
+	return self;
+	}
+
+DWinsGuiPowerHandler::DWinsGuiPowerHandler() : DPowerHandler(KWinsGuiName)
+	{
+	}
+
+void DWinsGuiPowerHandler::ScreenOff()
+	{
+	for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
+		ScreenOff(ix);
+	}
+
+void DWinsGuiPowerHandler::ScreenOn()
+	{
+	for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
+		ScreenOn(ix);
+	}
+
+void DWinsGuiPowerHandler::ScreenOff(TInt aScreen)
+	{
+	PostMessageA(TheWin[aScreen], WM_EMUL_POWER_ON, FALSE, NULL);
+	systemIni->iScreens[aScreen]->iScreenOff = ETrue;
+	}
+
+void DWinsGuiPowerHandler::ScreenOn(TInt aScreen)
+	{
+	PostMessageA(TheWin[aScreen], WM_EMUL_POWER_ON, TRUE, NULL);
+	systemIni->iScreens[aScreen]->iScreenOff = EFalse;
+	}
+
+void DWinsGuiPowerHandler::PowerDown(TPowerState aState)
+	{
+	if (aState == EPwStandby)
+		iStandby = ETrue;
+	ScreenOff();
+	PowerDownDone();
+	}
+
+
+void DWinsGuiPowerHandler::PowerUp()
+	{
+	iStandby = EFalse;
+	ScreenOn();
+	PowerUpDone();
+	}
+
+// called in the interrupt context
+TBool DWinsGuiPowerHandler::ProcessEvent(const TRawEvent* aEvent)
+	{
+	if (!iStandby)
+		// Pass through 
+		return EFalse;
+
+	if ((aEvent->Type() == TRawEvent::EKeyDown))
+			{
+			Wins::Self() -> AssertWakeupSignal();
+			}
+	
+	// Ignore
+	return ETrue;
+	}
+
+// called in DFC
+TBool DWinsGuiPowerHandler::ProcessEventDfc(const TRawEvent* aEvent)
+	{
+	if (aEvent->Type() == TRawEvent::EKeyDown)
+		{
+		Wins::Self() -> WakeupEvent();
+		if (aEvent->ScanCode() == EStdKeyF5)
+			{
+			// Simulate a media change interrupt (media removed)
+			Wins::MediaChangeCallBack();
+			*Wins::MediaDoorOpenPtr()=ETrue;
+			// Ignore
+			return ETrue;
+			}
+		if (aEvent->ScanCode() == EStdKeyF8)
+			{
+			TRawEvent v;
+			v.Set(TRawEvent::ECaseClose);
+			Kern::AddEvent(v);
+			// Ignore
+			return ETrue;
+			}
+		if (aEvent->ScanCode() == EStdKeyF8)
+			{
+			TRawEvent v;
+			v.Set(TRawEvent::ECaseClose);
+			Kern::AddEvent(v);
+			// Ignore
+			return ETrue;
+			}
+		if (aEvent->ScanCode() == EStdKeyOff)
+			{
+			// Pass through
+			return EFalse;
+			}
+		if (aEvent->ScanCode() == EStdKeyF10)
+			{
+			TRawEvent v;
+			v.Set(TRawEvent::ESwitchOff);
+			Kern::AddEvent(v);
+			// Ignore
+			return ETrue;
+			}
+		if (aEvent->ScanCode() == EStdKeyF11)
+			{
+			TRawEvent v;
+			v.Set(TRawEvent::ECaseOpen);
+			Kern::AddEvent(v);
+			// Ignore
+			return ETrue;
+			}
+		}
+	else if (aEvent->Type() == TRawEvent::EKeyUp)
+		{
+		if (aEvent->ScanCode() == EStdKeyF10)
+			// Ignore
+			return ETrue;
+
+		if (aEvent->ScanCode() == EStdKeyF5)
+			{
+			// Simulate a media change interrupt (media Present)
+			*Wins::MediaDoorOpenPtr()=EFalse;
+			return ETrue;
+			}
+		}
+
+	// Path through
+	return EFalse;
+	}
+
+DWinsGuiRotateHandler* DWinsGuiRotateHandler::New()
+	{
+	DWinsGuiRotateHandler* self = new DWinsGuiRotateHandler();
+	if (!self)
+		{	
+		__KTRACE_OPT(KEXTENSION,Kern::Printf("Failed to alloc DWinsGuiRotateHandler"));
+		return NULL;
+		}
+
+	// Publish startup mode property
+	_LIT_SECURITY_POLICY_PASS(readPolicy);
+	_LIT_SECURITY_POLICY_C1(writePolicy, ECapabilityWriteDeviceData);
+	
+	TInt r = self->iOrientationProperty.Attach(KUidSystemCategory, KSystemEmulatorOrientationKey);
+	if (r!=KErrNone)
+		{
+		delete self;
+		__KTRACE_OPT(KEXTENSION,Kern::Printf("DWinsGuiRotateHandler RPropertyRef::Attach Failed Err:%d", r));
+		return NULL;
+		}
+
+	r = self->iOrientationProperty.Define(RProperty::EInt, readPolicy, writePolicy);
+
+	return self;
+	}
+
+TBool DWinsGuiRotateHandler::ProcessEventDfc(const TRawEvent* aEvent)
+	{
+	//Obtain rotation from ScanCode.
+	TInt rotation = aEvent->ScanCode() - ESpecialKeyBase;
+	TInt r;
+	//Check this is a valid rotation and publish property.
+	if((rotation >= EEmulatorFlipRestore) && (rotation <= EEmulatorFlipRight))
+		{
+		if (aEvent->Type() == TRawEvent::EKeyDown)
+			{
+			Wins::Self()->WakeupEvent();
+			__KTRACE_OPT(KEXTENSION,Kern::Printf("Orientation change (%d) event:%x", rotation, aEvent->ScanCode()));
+			r = iOrientationProperty.Set(rotation);
+			__KTRACE_OPT(KEXTENSION, if (r != KErrNone) {Kern::Printf("RProperty::Set Failed Err:%d", r);});
+			}
+		// Swallow event
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+	
+class EventQ
+	{
+	enum {ESize = 16};
+public:
+	EventQ();
+	void Add(const TRawEvent& aEvent);
+private:
+	static void Dfc(TAny* aPtr);
+	void Empty();
+private:
+	TDfc iDfc;
+	TRawEvent* iTail;
+	TRawEvent iQ[ESize];
+	};
+
+EventQ::EventQ()
+	:iDfc(&EventQ::Dfc, this, Kern::DfcQue0(), 6), iTail(iQ)
+	{}
+
+
+void EventQ::Add(const TRawEvent& aEvent)
+	{
+	StartOfInterrupt();	
+	if (WinsGuiPowerHandler->ProcessEvent(&aEvent)) 
+		{
+		EndOfInterrupt();
+		return;
+		}
+
+	TRawEvent* pE = iTail;
+	if (pE != &iQ[ESize])
+		{
+		*pE = aEvent;
+		iTail = pE + 1;
+		if (pE == iQ)
+			iDfc.Add();
+		}
+	EndOfInterrupt();
+	}
+
+void EventQ::Dfc(TAny* aPtr)
+	{
+	static_cast<EventQ*>(aPtr)->Empty();
+	}
+
+void EventQ::Empty()
+//
+// Called in the DFC
+//
+	{
+	TInt irq;
+	TRawEvent* pE = iQ;
+	for (;;)
+		{
+		if (!WinsGuiRotateHandler->ProcessEventDfc(pE))
+			if (!WinsGuiPowerHandler->ProcessEventDfc(pE)) 
+				Kern::AddEvent(*pE);
+				
+		++pE;
+		irq = NKern::DisableAllInterrupts();
+		if (pE == iTail)
+			break;
+		NKern::RestoreInterrupts(irq);
+		}
+	iTail = iQ;
+	NKern::RestoreInterrupts(irq);
+	}
+
+LOCAL_D EventQ TheEventQ;
+
+// Virtual keys
+
+
+VirtualKey::VirtualKey(const TInt aCommandData, const TEmulCommand aCommand) : iCommand(aCommand), iData(aCommandData)
+	{
+	}
+
+TBool VKRect::Contains(TInt aX, TInt aY) const
+	{
+	return (aX >= iLeft && aX < iRight && aY >= iTop && aY < iBottom);
+	}
+
+VKRect::VKRect(const TInt aCommandData, const TEmulCommand aCommand, TInt aX, TInt aY, TInt aWidth, TInt aHeight) :
+	VirtualKey(aCommandData, aCommand)
+	{
+	iLeft = aX;
+	iTop = aY;
+	iRight = aX + aWidth;
+	iBottom = aY + aHeight;
+	}
+
+
+
+void VKRect::Draw(HDC aHdc,COLORREF aColor) const
+	{
+	HPEN pen;
+	pen=CreatePen(PS_SOLID, 2, aColor);
+	SelectObject(aHdc, pen);
+	POINT point;
+
+	MoveToEx(aHdc, (int)iLeft, (int)iTop, &point);
+	LineTo(aHdc, (int)iLeft, (int)iBottom);
+	LineTo(aHdc, (int)iRight, (int)iBottom);
+	LineTo(aHdc, (int)iRight, (int)iTop);
+	LineTo(aHdc, (int)iLeft, (int)iTop);
+	}
+
+
+KeyCombination::KeyCombination(const TInt aCommandData, TEmulCommand aCommand):
+	iData(aCommandData),
+	iCommand(aCommand)
+{
+	for (TInt i=0;i<KMaxHotKeyCombinationLength;i++) 
+		{
+		iCombination[i]=EStdKeyNull;
+		}
+}
+
+TBool KeyCombination::CheckCombinationPressed()
+{
+	for (TInt j=0;(j<KMaxHotKeyCombinationLength && iCombination[j]!=0);j++)
+		{
+		if (GetAsyncKeyState(MapVirtualKey(iCombination[j],1))>=0)//if at least one key is not pressed, we return false
+			return EFalse;				
+		}
+	return ETrue;	
+}
+
+TBool KeyCombination::AddKey(TStdScanCode aKey)
+{
+	TInt i;
+	for (i=0;i<KMaxHotKeyCombinationLength;i++) 
+		{
+		if (iCombination[i]==EStdKeyNull) 
+			break;
+		}
+	if (KMaxHotKeyCombinationLength==i)
+		return EFalse;
+	else		
+		iCombination[i]=aKey;	
+
+	return ETrue;
+}
+
+
+DScreenProperties::DScreenProperties()
+	{
+	memset(this,0,sizeof(DScreenProperties));
+	iColorDepth=KDefaultColorDepth;
+	
+	iViewport = TViewport(this);
+	}
+
+
+LOCAL_C TInt MaskGceOnly(TInt aModeBits)
+	{	   //All HAL modes are now reported. The GCE may refuse to register the surfaces.
+	return aModeBits&KEmulModes;	//previous useful settings: //(KEmulPixPerLong2|KEmulPixPerLong1);	//|KEmulPixPerLong4;
+	}
+	
+LOCAL_C TInt BitsForSingleMode(TInt aModeColor)
+	{	//only 1 bit should be set in aModeColor
+	switch (aModeColor)
+		{
+		case KEmulGray2:	return 1;	
+		case KEmulGray4:	return 2;	
+		case KEmulGray16:	return 4;
+		case KEmulGray256:	return 8;
+		case KEmulColor16:	return 4;
+		case KEmulColor256:	return 8;
+		case KEmulColor4K:	return 12;
+		case KEmulColor64K:	return 16;
+		case KEmulColor16M:	return 24;
+		default:	return 32;
+		}
+	
+	}
+
+DScreenProperties::~DScreenProperties() 
+	{
+	}
+
+TWindowState DScreenProperties::GetWindowState()
+	{
+	TWindowState state;
+	state.iWinPlace = iWinPlace;
+	state.iFlipstate = iScreenRotation;
+	state.iXoffset = iViewport.GetViewportOffsetX();
+	state.iYoffset = iViewport.GetViewportOffsetY();
+	return state;
+	}
+	
+TInt DScreenProperties::SetupProperties(TInt aConf, TInt aScreen)
+	{
+	char property[50];
+
+	// Calculate maximum dimensions
+	TInt configurations = Property::GetInt("ConfigCount", 0);
+	if (configurations == 0)
+		return KErrGeneral;
+
+	TInt count, screenWidth, screenHeight, physicalScreenWidth, physicalScreenHeight;
+	for (count = 0; count < configurations; ++count)
+		{
+		wsprintfA(property, "Configuration[%d][%d]ScreenWidth", count, aScreen);
+		screenWidth = Property::GetInt(property, KScreenWidth);
+		screenWidth = (screenWidth + 3) & ~3;
+		if (screenWidth > iMaxScreenWidth)
+			iMaxScreenWidth = screenWidth;
+		wsprintfA(property, "Configuration[%d][%d]ScreenHeight", count, aScreen);
+		screenHeight = Property::GetInt(property, KScreenHeight);
+		screenHeight = (screenHeight + 3) & ~3;
+		if (screenHeight > iMaxScreenHeight)
+			iMaxScreenHeight = screenHeight;
+//
+		wsprintfA(property, "Configuration[%d][%d]PhysicalScreenWidth", count, aScreen);
+		physicalScreenWidth = Property::GetInt(property);
+		if (physicalScreenWidth > iMaxPhysicalScreenWidth)
+			iMaxPhysicalScreenWidth = physicalScreenWidth;
+		wsprintfA(property, "Configuration[%d][%d]PhysicalScreenHeight", count, aScreen);
+		physicalScreenHeight = Property::GetInt(property);
+		if (physicalScreenHeight > iMaxPhysicalScreenHeight)
+			iMaxPhysicalScreenHeight = physicalScreenHeight;
+		}
+
+	// Read figures for current configuration
+	TInt givenWidth, givenHeight;
+	wsprintfA(property, "Configuration[%d][%d]ScreenWidth",aConf,aScreen);
+	givenWidth = Property::GetInt(property, KScreenWidth);
+	iScreenWidth = (givenWidth + 3) & ~3;
+	wsprintfA(property, "Configuration[%d][%d]ScreenHeight",aConf,aScreen);
+	givenHeight = Property::GetInt(property, KScreenHeight);
+	iScreenHeight = (givenHeight + 3) & ~3;
+	// Width of screen should be multiple number of 4 pixels.
+	if (givenWidth & 3 || givenHeight & 3)
+		{
+		Kern::Printf("Width and Height of Screen should be multiple number of 4 pixels.\n"
+				"\tWidth of screen[%d] set to: %d\n\tHeight of screen[%d] set to: %d", 
+				aScreen, iScreenWidth, aScreen, iScreenHeight);
+		}
+
+//
+	wsprintfA(property, "Configuration[%d][%d]PhysicalScreenWidth",aConf,aScreen);
+	iPhysicalScreenWidth = Property::GetInt(property);
+	wsprintfA(property, "Configuration[%d][%d]PhysicalScreenHeight",aConf,aScreen);
+	iPhysicalScreenHeight = Property::GetInt(property);
+//
+	wsprintfA(property, "Configuration[%d][%d]ScreenOffsetX",aConf,aScreen);
+	iScreenOffsetX = Property::GetInt(property, KScreenOffsetX);
+	wsprintfA(property, "Configuration[%d][%d]ScreenOffsetY",aConf,aScreen);
+	iScreenOffsetY = Property::GetInt(property, KScreenOffsetY);
+	
+	wsprintfA(property, "Configuration[%d][%d]CompositionBuffers",aConf,aScreen);
+	iCompositionBuffers = Property::GetInt(property, KCompositionBuffers);
+
+	wsprintfA(property, "Configuration[%d][%d]RefreshRateHz",aConf,aScreen);
+	iRefreshRateHz = Property::GetInt(property, KRefreshRateHz);
+
+
+	wsprintfA(property, "Configuration[%d][%d]ColorDepth",aConf,aScreen);
+	const char* colors = Property::GetString(property);
+	if (colors)
+		{
+		TUint colorDepth=0;
+		const char* end = colors;
+		for (;;)
+			{
+			const char* beg = skipws(end);
+			if(*beg==';')
+				break;
+			if (!*beg)
+				break;
+			end	= skiptok(beg);
+			if (_strnicmp("Gray2",beg,end-beg) == 0)
+				{
+				colorDepth|=KEmulGray2|KEmulIsBitMask;
+				}
+			else if (_strnicmp("Gray4",beg,end-beg) == 0)
+				{
+				colorDepth|=KEmulGray4|KEmulIsBitMask;
+				}
+			else if (_strnicmp("Gray16",beg,end-beg) == 0)
+				{
+				colorDepth|=KEmulGray16|KEmulIsBitMask;
+				}
+			else if (_strnicmp("Gray256",beg,end-beg) == 0)
+				{
+				colorDepth|=KEmulGray256|KEmulIsBitMask;
+				}
+			else if (_strnicmp("Color16",beg,end-beg) == 0)
+				{
+				colorDepth|=KEmulColor16|KEmulIsBitMask;
+				}
+			else if (_strnicmp("Color256",beg,end-beg) == 0)
+				{
+				colorDepth|=KEmulColor256|KEmulIsBitMask;
+				}
+			else if (_strnicmp("Color4K",beg,end-beg) == 0)
+				{
+				colorDepth|=KEmulColor4K|KEmulIsBitMask;
+				}
+			else if (_strnicmp("Color64K",beg,end-beg) == 0)
+				{
+				colorDepth|=KEmulColor64K|KEmulIsBitMask;
+				}
+			else if (_strnicmp("Color16M",beg,end-beg) == 0)
+				{
+				colorDepth|=KEmulColor16M|KEmulIsBitMask;
+				}
+			else
+				return KErrArgument;
+			}
+		iColorDepth = colorDepth;
+		
+		}
+	//multiple mode support is currently only for GCE. 
+	//I fill this array in before knowing if GCE will be instanced.
+	if (iColorDepth&KEmulIsBitMask)
+		{
+		//iModeDepths is only used by GCE
+		TInt colorDepth=MaskGceOnly(iColorDepth);
+		TInt setMode=0;
+		for (TInt i=1;i!=KEmulIsBitMask;i+=i)
+			if (colorDepth&i)
+				iModeDepths[setMode++]=BitsForSingleMode(i);
+		iMaxModes= setMode;	
+		iModeDepths[setMode++]=0;	//a bit width of 0 is illegal	
+		}
+	else
+		{
+		iModeDepths[0]=iColorDepth;
+		iMaxModes=1;
+		iModeDepths[1]=0;	//a bit width of 0 is illegal
+		}
+
+	wsprintfA(property, "Configuration[%d][%d]FasciaBitmap",aConf,aScreen);
+	const char* fascia = Property::GetString(property);
+	if (fascia)
+		{
+		TInt len = strlen(fascia);
+		//the path may have quotes at the start and end
+		//need to work out if this is an absolute or relative path
+		if (fascia[0] == '\"')
+			{
+			++fascia;
+			--len;
+			if (--len > 0 && fascia[len-1] == '\"')
+				--len;
+			}
+		char* p = iFasciaFileName;
+		if (fascia[0] != '\\' && (len < 3 || fascia[1] != ':'))
+			{
+			//relative path
+			strcpy(p, Property::GetString("EmulatorDataPath"));
+			p += strlen(p);
+			}
+		memcpy(p, fascia, len);
+		p[len] = '\0';
+		}
+	else
+		{
+		// default to machine name
+		strcpy(iFasciaFileName, Property::GetString("EmulatorDataPath"));
+		strcat(iFasciaFileName, Property::GetString("MachineName"));
+		strcat(iFasciaFileName, ".bmp");
+		}
+	return KErrNone;
+	}
+
+TViewport::TViewport() 
+	:iScreenProps(NULL),iViewportWidth(0), iViewportHeight(0), iViewportOffsetX(0), iViewportOffsetY(0)
+	{
+	}
+
+TViewport::TViewport(DScreenProperties* aScreenProps)
+	:iScreenProps(aScreenProps),iViewportWidth(0), iViewportHeight(0), iViewportOffsetX(0), iViewportOffsetY(0)
+	{	
+	}	
+TViewport::~TViewport()
+	{
+	}
+	
+
+/**
+Changes the logical position of the viewport within the input area
+of the emulator screen. The method may adjust the position so that
+the viewport stays within the input area.
+@param aPosition The new Y position of the top left hand corner of the viewport.
+@param aHwnd The window associated with the viewport
+*/
+void TViewport::ScrollToY(TInt aPosition, HWND aHwnd)
+	{
+
+	SCROLLINFO scrollinfo;
+	scrollinfo.cbSize=sizeof(scrollinfo);
+
+	//save for later
+	scrollinfo.fMask=SIF_POS;
+	GetScrollInfo(aHwnd, SB_VERT, &scrollinfo);
+	TInt oldY=scrollinfo.nPos;
+
+	if(aPosition<0)
+	{
+		scrollinfo.nPos = 0;
+	}
+	else if( (aPosition+GetViewportHeight())>GetMaxHeight())
+	{
+		scrollinfo.nPos = max(0,GetMaxHeight() - GetViewportHeight() );
+	}
+	else
+	{
+		scrollinfo.nPos=aPosition;
+	}
+
+	SetViewportOffsetY(scrollinfo.nPos);
+	scrollinfo.fMask=SIF_POS;
+	SetScrollInfo(aHwnd,SB_VERT, &scrollinfo, TRUE );
+	ScrollWindowEx(aHwnd, 0, oldY-scrollinfo.nPos, 0, 0, NULL, NULL, SW_INVALIDATE);
+	
+	UpdateChildPos(aHwnd);
+	}
+	
+/**
+As for ScrollToY but for the X direction
+*/
+void TViewport::ScrollToX(TInt aPosition, HWND aHwnd)
+	{
+	SCROLLINFO scrollinfo;
+	scrollinfo.cbSize=sizeof(scrollinfo);
+	
+	//save for later
+	scrollinfo.fMask=SIF_POS;
+	GetScrollInfo(aHwnd, SB_HORZ, &scrollinfo);
+	TInt oldX=scrollinfo.nPos;
+
+	if(aPosition<0)
+	{
+		scrollinfo.nPos = 0;
+	}
+	else if( (aPosition+GetViewportWidth())>GetMaxWidth())
+	{
+		scrollinfo.nPos = max(0,GetMaxWidth() - GetViewportWidth() );
+	}
+	else
+	{
+		scrollinfo.nPos=aPosition;
+	}
+
+	SetViewportOffsetX(scrollinfo.nPos);
+	scrollinfo.fMask=SIF_POS;
+	SetScrollInfo(aHwnd,SB_HORZ, &scrollinfo, TRUE );
+	ScrollWindowEx(aHwnd, oldX-scrollinfo.nPos, 0, 0, 0, NULL, NULL, SW_INVALIDATE);
+
+	UpdateChildPos(aHwnd);
+	}
+	
+//Forward declaration
+LOCAL_C TInt ScreenFromHWND(HWND aHwnd,HWND* pWin);
+
+/**
+Move the child window to it's correct position.
+
+@param aHwnd The HWND of the parent window
+*/
+void TViewport::UpdateChildPos(HWND aHwnd)
+	{
+	TInt screenNumber = ::ScreenFromHWND(aHwnd,TheWin);
+	HWND childWin = TheChildWin[screenNumber];
+
+	switch (iScreenProps->iScreenRotation)
+		{
+		case EEmulatorFlipRestore:
+			MoveWindow(
+				childWin,
+				iScreenProps->iScreenOffsetX - GetViewportOffsetX(),
+				iScreenProps->iScreenOffsetY - GetViewportOffsetY(),
+				iScreenProps->iScreenWidth,
+				iScreenProps->iScreenHeight,
+				TRUE
+				);
+			break;
+		case EEmulatorFlipInvert:
+			MoveWindow(
+				childWin,
+				iScreenProps->iXYInputWidth-(iScreenProps->iScreenOffsetX+iScreenProps->iScreenWidth) - GetViewportOffsetX(),
+				iScreenProps->iXYInputHeight-(iScreenProps->iScreenOffsetY+iScreenProps->iScreenHeight) - GetViewportOffsetY(),
+				iScreenProps->iScreenWidth,
+				iScreenProps->iScreenHeight,
+				TRUE
+				);
+			break;
+		case EEmulatorFlipLeft:
+			MoveWindow(
+				childWin,
+				iScreenProps->iScreenOffsetY - GetViewportOffsetX(),
+				iScreenProps->iXYInputWidth-(iScreenProps->iScreenOffsetX+iScreenProps->iScreenWidth)- GetViewportOffsetY(),
+				iScreenProps->iScreenHeight,
+				iScreenProps->iScreenWidth,
+				TRUE
+				);
+			break;
+		case EEmulatorFlipRight:
+			MoveWindow(
+				childWin,
+				iScreenProps->iXYInputHeight-(iScreenProps->iScreenOffsetY+iScreenProps->iScreenHeight) - GetViewportOffsetX(),
+				iScreenProps->iScreenOffsetX - GetViewportOffsetY(),
+				iScreenProps->iScreenHeight,
+				iScreenProps->iScreenWidth,
+				TRUE
+				);
+			break;
+		}
+
+	}
+	
+/**
+Update the range of the horizontal scrollbar,
+to take account of the current viewport width.
+
+@param aHwnd The window to be updated
+*/
+void TViewport::UpdateScrollBarH(HWND aHwnd)
+	{
+
+	SCROLLINFO scrollinfoHor;
+	scrollinfoHor.cbSize=sizeof(scrollinfoHor);
+	scrollinfoHor.fMask=SIF_RANGE|SIF_PAGE;
+	scrollinfoHor.nMin=0;
+	scrollinfoHor.nMax= GetMaxWidth()-1;
+	
+	
+	TInt newPage = GetViewportWidth() ;
+	TBool redraw=EFalse; //redraw window if a resize has caused a scrollbar to disappear and reveal image.
+	if ( newPage>= scrollinfoHor.nMax -GetSystemMetrics(SM_CXVSCROLL)
+		&& newPage < scrollinfoHor.nMax+1)
+		{
+		redraw=ETrue;
+		newPage=GetMaxWidth();
+
+		}
+	scrollinfoHor.nPage= newPage;
+
+	SetScrollInfo(aHwnd,SB_HORZ, &scrollinfoHor, TRUE );
+	if(redraw)
+		{
+		ScrollToX(0, aHwnd); //in case egde of fascia was against edge of vertical scrollbar
+		InvalidateRect(aHwnd, NULL, TRUE);
+		}
+	}
+	
+/**
+Update the range of the vertical scrollbar,
+to take account of the current viewport width.
+
+@param aHwnd The window to be updated
+*/	
+void TViewport::UpdateScrollBarV(HWND aHwnd)
+	{
+	SCROLLINFO scrollinfoVer;
+	scrollinfoVer.cbSize=sizeof(scrollinfoVer);
+	scrollinfoVer.fMask=SIF_RANGE|SIF_PAGE;
+	scrollinfoVer.nMin=0;
+	scrollinfoVer.nMax= GetMaxHeight()-1;
+	
+	TInt newPage = GetViewportHeight() ;
+	TBool redraw=EFalse; //redraw window if a resize has caused a scrollbar to disappear and reveal image.
+	if ( newPage>= scrollinfoVer.nMax -GetSystemMetrics(SM_CYHSCROLL)
+		&& newPage < scrollinfoVer.nMax+1)
+		{
+		redraw=ETrue;
+		newPage=GetMaxHeight();
+		}
+	scrollinfoVer.nPage= newPage;
+
+	SetScrollInfo(aHwnd,SB_VERT, &scrollinfoVer, TRUE );
+	if(redraw)
+		{
+		ScrollToY(0, aHwnd); //in case egde of fascia was against edge of vertical scrollbar
+		InvalidateRect(aHwnd, NULL, TRUE);
+		}
+	}
+
+/**
+Returns the max width for the viewport window (non-client area) so that it
+may be bounded. Takes account of scrollbar.
+
+@return Max width
+*/	
+TInt TViewport::GetMaxWindowWidth() const
+	{
+	
+	RECT rect = {0,0,0,0};
+	
+	switch(iScreenProps->iScreenRotation)
+		{
+		case EEmulatorFlipRestore:
+		case EEmulatorFlipInvert:
+			{
+			rect.right=iScreenProps->iXYInputWidth;
+			rect.bottom=iScreenProps->iXYInputHeight;
+			break;
+			}
+		case EEmulatorFlipLeft:
+		case EEmulatorFlipRight:
+			{
+			rect.right=iScreenProps->iXYInputHeight;
+			rect.bottom=iScreenProps->iXYInputWidth;
+			break;
+			}
+		}
+	AdjustWindowRect(//take account of window decorations
+		&rect,
+		KWinStyle,
+		FALSE
+		);
+	
+	
+	return (rect.right-rect.left);
+	}
+	
+/**
+Returns the max height for the viewport window (non-client area) so that it
+may be bounded. Takes account of scrollbar.
+
+@return Max height
+*/
+TInt TViewport::GetMaxWindowHeight() const
+	{
+	
+	RECT rect ={0,0,0,0};
+
+	switch(iScreenProps->iScreenRotation)
+		{
+		case EEmulatorFlipRestore:
+		case EEmulatorFlipInvert:
+			{
+			rect.right=iScreenProps->iXYInputWidth;
+			rect.bottom=iScreenProps->iXYInputHeight;
+			break;
+			}
+		case EEmulatorFlipLeft:
+		case EEmulatorFlipRight:
+			{
+			rect.right=iScreenProps->iXYInputHeight;
+			rect.bottom=iScreenProps->iXYInputWidth;
+			break;
+			}
+		}
+	AdjustWindowRect(//take account of window decorations
+		&rect,
+		KWinStyle,
+		FALSE
+		);
+	return (rect.bottom-rect.top);
+	}
+
+/**
+Returns the maximum width for the viewport (client area only).
+Allowing for the orientation of the emulator.
+
+@return Max width
+*/
+TInt TViewport::GetMaxWidth() const
+	{
+	TInt width=0;
+	switch(iScreenProps->iScreenRotation)
+		{
+		case EEmulatorFlipRestore:
+		case EEmulatorFlipInvert:
+			{
+			width = iScreenProps->iXYInputWidth;
+			break;
+			}
+		case EEmulatorFlipLeft:
+		case EEmulatorFlipRight:
+			{
+			width = iScreenProps->iXYInputHeight;
+			break;
+			}
+		}
+	
+	return width;
+	}
+
+/**
+Returns the maximum height for the viewport (client area only).
+Allowing for the orientation of the emulator.
+
+@return Max height
+*/
+TInt TViewport::GetMaxHeight() const
+	{
+	TInt height=0;
+	switch(iScreenProps->iScreenRotation)
+		{
+		case EEmulatorFlipRestore:
+		case EEmulatorFlipInvert:
+			{
+			height = iScreenProps->iXYInputHeight;
+			break;
+			}
+		case EEmulatorFlipLeft:
+		case EEmulatorFlipRight:
+			{
+			height =  iScreenProps->iXYInputWidth;
+			break;
+			}
+		}
+	
+	return height;
+	
+	}
+
+/**
+Sets the X offset of the viewport from the edge of the input area
+@param aOffset The X offset
+*/
+void TViewport::SetViewportOffsetX(TInt aOffset)
+	{
+	iViewportOffsetX = aOffset;
+	}
+
+/**
+Sets the Y offset of the viewport from the edge of the input area
+@param aOffset The Y offset
+*/
+void TViewport::SetViewportOffsetY(TInt aOffset)
+	{
+	iViewportOffsetY = aOffset;
+	}
+
+TInt TViewport::GetViewportOffsetX() const
+	{
+	return iViewportOffsetX;	
+	}
+TInt TViewport::GetViewportOffsetY() const
+	{
+	return iViewportOffsetY;
+	}
+	
+/**
+Sets the viewport width, this is equal to the width
+of the window's client area
+@param aWidth The width
+*/
+void TViewport::SetViewportWidth(TInt aWidth)
+	{
+	iViewportWidth=aWidth;
+	}
+
+/**
+Sets the viewport height, this is equal to the height
+of the window's client area
+@param aHeight The height
+*/
+void TViewport::SetViewportHeight(TInt aHeight)
+	{
+	iViewportHeight=aHeight;
+	}
+
+TInt TViewport::GetViewportWidth() const
+	{
+	return iViewportWidth;
+	}
+TInt TViewport::GetViewportHeight() const
+	{
+	return iViewportHeight;
+	}
+
+// the UI class
+
+DWinsUi::DWinsUi()
+	:iVirtualKeys(10),
+	iControlHotKeys(10)
+	{}
+
+/// Returns the current mode's depth. Remember current mode is never set!
+TUint DWinsUi::ColorDepth(TInt aScreenNumber)
+	{
+	TVideoInfoV01 info;
+	VideoInfo(aScreenNumber, info);
+	return info.iBitsPerPixel;
+	}
+
+TInt DWinsUi::SetFlip(TEmulatorFlip aFlip, TInt aScreenNumber)
+	{
+	if(TUint(aScreenNumber)>=TUint(systemIni->iScreens.Count()))
+		return KErrArgument;
+	int r1 = PostMessageA(TheChildWin[aScreenNumber],WM_FLIP_MESSAGE,(TUint)aFlip,NULL);
+	return r1 ? KErrNone : KErrGeneral;
+	}
+
+void DWinsUi::Info(TVariantInfoV01& aInfo)
+	{
+	aInfo.iLedCapabilities=0x3;
+	}
+
+HWND DWinsUi::HWnd()
+	{
+	return TheControlWin;
+	}
+
+TInt DWinsUi::SetupProperties(TInt aId)
+	
+//
+// load UI settings from the emulator properties
+//
+	{
+	//setup the screens
+	TInt screens = Property::GetInt("[screens]", 1);
+ 
+ 	for (TInt x = 0; x < screens; ++x)
+ 		{
+ 		DScreenProperties * pScr = new DScreenProperties();
+ 		if (!pScr)
+ 			return KErrNoMemory;
+ 		
+ 		TInt ret = pScr->SetupProperties(aId,x);
+ 		if (KErrNone == ret)
+ 			ret = iScreens.Append(pScr);
+ 
+ 		if (KErrNone != ret)
+ 			{
+ 			delete pScr;
+ 			return ret;
+ 			}
+ 		}
+//
+	char property[50];
+	wsprintfA(property, "Configuration[%d]LedSize",aId);
+	iLedSize = Property::GetInt(property, KLedSize);
+	wsprintfA(property, "Configuration[%d]LedArrangeVertically",aId);
+	iLedVertical = Property::GetBool(property, KLedVertical);
+	wsprintfA(property, "Configuration[%d]LedArrangeHorizontally",aId);
+	if (Property::GetBool(property))
+		iLedVertical = EFalse;
+	wsprintfA(property, "Configuration[%d]LedOffsetX",aId);
+	iLedOffsetX = Property::GetInt(property, KLedLeft);
+	wsprintfA(property, "Configuration[%d]LedOffsetY",aId);
+	iLedOffsetY = Property::GetInt(property, KLedTop);
+	wsprintfA(property, "Configuration[%d]LedGap",aId);
+	iLedGap = Property::GetInt(property, KLedGap);
+//
+	wsprintfA(property, "Configuration[%d]PointerType",aId);
+	const char* pointer = Property::GetString(property, "Pen");
+	if (_stricmp(pointer, "None") == 0)
+		{
+		iPointerType=_S8("NONE");
+		iXYInputType=EXYInputNone;
+		}
+	else if (_stricmp(pointer,"Pen") == 0)
+		{
+		iPointerType=_S8("PEN");
+		iXYInputType=EXYInputPointer;
+		}
+	else if (_stricmp(pointer,"Mouse") == 0)
+		{
+		iPointerType=_S8("MOUSE");
+		iXYInputType=EXYInputMouse;
+		}
+	else if (_stricmp(pointer,"Delta-Mouse") == 0)
+		{
+		iPointerType=_S8("MOUSE");
+		iXYInputType=EXYInputDeltaMouse;
+		}
+	else
+		return KErrArgument;
+//
+	wsprintfA(property, "Configuration[%d]DigitizerOffsetX",aId);
+	iDigitizerOffsetX = Property::GetInt(property, -iScreens[0]->iScreenOffsetX);
+	wsprintfA(property, "Configuration[%d]DigitizerOffsetY",aId);
+	iDigitizerOffsetY = Property::GetInt(property, -iScreens[0]->iScreenOffsetY);
+	wsprintfA(property, "Configuration[%d]DigitizerWidth",aId);
+	iDigitizerWidth = Property::GetInt(property,-1);
+	wsprintfA(property, "Configuration[%d]DigitizerHeight",aId);
+	iDigitizerHeight = Property::GetInt(property,-1);
+	wsprintfA(property, "Configuration[%d]DisableDigitizer",aId);
+	iDigitizerEnabled = !Property::GetBool(property);
+//	To enable the multitouch 
+	wsprintfA(property, "EnableMultiTouch");
+	iMultiTouchEnabled = Property::GetBool(property,EFalse);
+	wsprintfA(property, "SYMBIAN_BASE_USE_GCE");
+	iGCEEnabled = Property::GetBool(property,EFalse);
+	wsprintfA(property, "MultiTouchProximityStep");
+	iMultiTouchProximityStep = Property::GetInt(property,-1);
+	wsprintfA(property, "MultiTouchPressureStep");
+	iMultiTouchPressureStep = Property::GetInt(property,-1);
+//
+	strcpy(iSysIniFileName, Property::GetString("EmulatorDataPath"));
+	strcat(iSysIniFileName, "emulator\\");
+	if (!Emulator::CreateAllDirectories(iSysIniFileName))
+		return Emulator::LastError();
+	strcat(iSysIniFileName, Property::GetString("MachineName"));
+	strcat(iSysIniFileName, ".sys.ini");
+//
+	TInt r = iKeyboard.Init(aId);
+	if (r != KErrNone)
+		return r;
+
+	wsprintfA(property, "Configuration[%d]VirtualKey",aId);
+	r = MultiProperty(&DWinsUi::DoDefineVirtualKey, this, property);
+	if (r != KErrNone)
+		return r;
+//
+
+	wsprintfA(property, "Configuration[%d]NoVersionInfo",aId);
+	iDisplayVersionInfo = !Property::GetBool(property);
+	
+	wsprintfA(property, "Configuration[%d]WindowTitle",aId);
+	const char * p = Property::GetString(property);
+	if (p && (strlen(p) <= KMaxNameSize))
+		strcpy(iWindowTitle, p);
+	else
+		strcpy(iWindowTitle, DefaultWindowTitle);
+
+	if (iDisplayVersionInfo)
+		{
+		TInt wtLen = strlen(iWindowTitle);
+		TInt vtLen = strlen(VersionText);
+		if ((wtLen + vtLen) > KMaxNameSize)
+			iWindowTitle[KMaxNameSize-vtLen] = '\0';
+		strcat(iWindowTitle, VersionText);
+		}
+
+	wsprintfA(property, "Configuration[%d]OnActivation",aId);
+	pointer = Property::GetString(property);	
+	//example	OnActivation 270 EKeyScreenDimension1
+	//params are rotation(int) and key(string)
+	if (pointer)
+		{
+		TInt i;
+		char * next;
+	
+		//skip any white space
+		const char* beg = skipws(pointer);
+		
+		//get the number
+		long rotation = strtol(beg, &next, 0);
+		if (next == beg)
+			return KErrArgument;
+
+		switch (rotation)
+			{
+			case 0:
+				for (i = 0; i < screens; ++i)
+					{
+					iScreens[i]->iScreenRotation = EEmulatorFlipRestore;
+					iScreens[i]->iRotateBuffer = NULL;
+					}
+				break;
+			case 90:
+				for (i = 0; i < screens; ++i)
+					{
+					iScreens[i]->iScreenRotation = EEmulatorFlipRight;
+					iScreens[i]->iRotateBuffer = (DWORD*)malloc(iScreens[i]->iScreenWidth*iScreens[i]->iScreenHeight*4);
+					if(!iScreens[i]->iRotateBuffer)
+						return KErrNoMemory;
+					}
+				break;
+			case 180:
+				for (i = 0; i < screens; ++i)
+					{
+					iScreens[i]->iScreenRotation = EEmulatorFlipInvert;
+					iScreens[i]->iRotateBuffer = (DWORD*)malloc(iScreens[i]->iScreenWidth*iScreens[i]->iScreenHeight*4);
+					if(!iScreens[i]->iRotateBuffer)
+						return KErrNoMemory;
+					}
+				break;
+			case 270:
+				for (i = 0; i < screens; ++i)
+					{
+					iScreens[i]->iScreenRotation = EEmulatorFlipLeft;
+					iScreens[i]->iRotateBuffer = (DWORD*)malloc(iScreens[i]->iScreenWidth*iScreens[i]->iScreenHeight*4);
+					if(!iScreens[i]->iRotateBuffer)
+						return KErrNoMemory;
+					}
+				break;
+			default:
+				r = KErrArgument;
+			}
+		if (r != KErrNone)
+			return r;
+			
+		iInitialFlipMsg = TStdScanCode(ESpecialKeyBase + iScreens[0]->iScreenRotation);
+		
+		beg = skipws(next);
+		
+		//beg should now point to the keycode
+		TInt key = iKeyboard.GetEPOCKeyCode(TPtrC8((const TUint8*)beg, strlen(beg)));
+		if (key == KErrNotFound)
+			return key;
+		//Currently no use for key
+		}
+
+	//EmulatorControl messages are a bit like virtual keys
+	wsprintfA(property, "Configuration[%d]EmulatorControl",aId);
+	r = MultiProperty(&DWinsUi::DoDefineEmulatorControl, this, property);
+	if (r != KErrNone)
+		return r;
+
+	wsprintfA(property, "Configuration[%d]EmulatorControlHotKey",aId);
+	r = MultiProperty(&DWinsUi::DoDefineEmulatorControlHotKey, this, property);
+	if (r != KErrNone)
+		return r;
+	
+	return KErrNone;
+	}
+
+TInt DWinsUi::NumberOfScreens()
+	{
+	return iScreens.Count();
+	}
+
+/**
+Return the highest bit depth from an emulator mode mask.
+@param aModeMask	A bitwise combination of KEmul... display mode mask values.
+@return A color depth in bits per pixel.
+*/
+LOCAL_C TInt MaximumBitDepthFromMask(TInt aModeMask)
+	{
+	// Choose the highest bits per pixel based on the display mode mask.
+	if (aModeMask & KEmulColor16M)
+		{
+		return 24;
+		}
+	if (aModeMask & KEmulColor64K)
+		{
+		return 16;
+		}
+	if (aModeMask & KEmulColor4K)
+		{
+		return 12;
+		}
+
+	// Lower bit depths are not supported, so use the default
+	return 24;
+	}
+
+
+/**
+Return the TDisplayRotation corresponding to the given TEmulatorFlip.
+@param aFlip	A screen rotation as a TEmulatorFlip.
+@return The screen rotation as a TDisplayRotation.
+*/
+LOCAL_C RDisplayChannel::TDisplayRotation FlipToDisplayRotation(TEmulatorFlip aFlip)
+	{
+	switch (aFlip)
+		{
+		case EEmulatorFlipLeft:
+			return RDisplayChannel::ERotation90CW;
+		case EEmulatorFlipInvert:
+			return RDisplayChannel::ERotation180;
+		case EEmulatorFlipRight:
+			return RDisplayChannel::ERotation270CW;
+		}
+	return RDisplayChannel::ERotationNormal;
+	}
+
+
+TInt DWinsUi::SetDisplayChannel(TInt aScreenNumber, DDisplayChannel* aDisplay)
+	{
+	return systemIni->SetDisplayChannelImpl(aScreenNumber,aDisplay);
+	}
+
+
+TInt DWinsUi::SetDisplayChannelImpl(TInt aScreenNumber, DDisplayChannel* aDisplay)
+	{
+	if (TUint(aScreenNumber) >= TUint(NumberOfScreens()))
+		{
+		// Screen number is either negative or too big.
+		return KErrArgument;
+		}
+
+	TInt r = KErrNone;
+	HWND hWnd = TheChildWin[aScreenNumber];
+	TBufferSet& buffer = masterIni->iBufferSet[aScreenNumber];
+	
+	if (aDisplay)
+		{
+		// Display driver connecting
+		DScreenProperties* screen = iScreens[aScreenNumber];
+		RDisplayChannel::TDisplayInfo info;
+
+		TInt pixelBytes = 2;
+		info.iBitsPerPixel = MaximumBitDepthFromMask(screen->iColorDepth);
+
+		switch (info.iBitsPerPixel)
+			{
+			case 12:	// XRGB4444
+				info.iPixelFormat = EUidPixelFormatXRGB_4444;
+				break;
+			case 16:	// RGB565
+				info.iPixelFormat = EUidPixelFormatRGB_565;
+				break;
+			default:
+				// Force anything else to packed RGB888
+				pixelBytes = 4;
+				info.iBitsPerPixel = 24;
+				info.iPixelFormat = EUidPixelFormatXRGB_8888;
+				break;
+			}
+
+		TInt width = screen->iMaxScreenWidth;
+		TInt height = screen->iMaxScreenHeight;
+
+		info.iRefreshRateHz = screen->iRefreshRateHz;
+		info.iAvailableRotations = RDisplayChannel::ERotationNormal | RDisplayChannel::ERotation90CW |
+									RDisplayChannel::ERotation180 | RDisplayChannel::ERotation270CW;
+		info.iNormal.iWidth = width;
+		info.iNormal.iHeight = height;
+		// Windows requires rounding up to 4-bytes words
+		info.iNormal.iOffsetBetweenLines = _ALIGN_UP(width * pixelBytes, 4);
+		info.iFlipped.iWidth = height;
+		info.iFlipped.iHeight = width;
+		// Windows requires rounding up to 4-bytes words
+		info.iFlipped.iOffsetBetweenLines = _ALIGN_UP(height * pixelBytes, 4);
+	
+		TInt maxSize=0;	 
+		//ensure legacy buffer is large enough for all supported modes.
+		//It would be a very strange setup for the max size to not be the max bpp,
+		//but we don't know which mode is max bpp anyway!
+		TVideoInfoV01 videoInfo;
+		for (TInt mode=0,maxMode=screen->iMaxModes;mode<maxMode;mode++)
+			{
+			if (systemIni->VideoInfoForDisplayDriver(aScreenNumber,mode, videoInfo))	//can't actually fail currently
+				{
+				TInt dwSize=videoInfo.iOffsetToFirstPixel+videoInfo.iOffsetBetweenLines*videoInfo.iSizeInPixels.iHeight;
+				if (dwSize>maxSize)
+					maxSize=dwSize;
+				}
+			else
+				{
+				Fault(EGuiVideoInfoUnavailable);
+				}
+			//rotated mode may use more RAM?? Height may be >Width or may not be a multiple of stride quantum
+			if (systemIni->VideoInfoForDisplayDriver(aScreenNumber,mode|KModeFlagFlipped, videoInfo))	//can't actually fail currently
+				{
+				TInt dwSize=videoInfo.iOffsetToFirstPixel+videoInfo.iOffsetBetweenLines*videoInfo.iSizeInPixels.iWidth;
+				if (dwSize>maxSize)
+					{
+					maxSize=dwSize;
+					}
+				}
+			else
+				{
+				Fault(EGuiVideoInfoUnavailable);
+				}
+			}
+
+		masterIni->iMaxSizeInBytes = maxSize;
+		if (__e32_atomic_add_ord32(&buffer.iDisplayDriverCount, 1) == 0)
+			{
+			// First driver to connect, allocate frame buffers.
+			// +1 frame buffer is ui legacy buffer at [0], so does need to take account of stride and offset
+			r = masterIni->AllocateFrameBuffers(aScreenNumber, screen->iCompositionBuffers + 1, maxSize);
+			}
+
+		if (r == KErrNone)
+			{
+			buffer.iScreenBuffer.iDisplayBufferOffset = 0;
+			masterIni->iBufferSet[aScreenNumber].iDisplayChannel = aDisplay;
+			masterIni->InitBitmapHeader(*screen, &buffer.iInfo);
+			masterIni->InitBufferFormat(*screen, buffer.iBufferFormat);
+			if(systemIni->VideoInfoForDisplayDriver(aScreenNumber,screen->iCurrentMode, videoInfo, ETrue))
+				{
+					r = aDisplay->Initialize(info,
+											 FlipToDisplayRotation(screen->iScreenRotation),
+											 hWnd, buffer.iScreenBuffer.iFrameBuffers,
+											 buffer.iScreenBuffer.iMemChunks,
+											 buffer.iDsaBuffer,
+						                     videoInfo.iSizeInPixels,videoInfo.iSizeInTwips,
+						                     masterIni->iSupportedPixelFormatTable,
+						                     masterIni->iSupportedPixelFormatTableSize,
+						                     buffer.iBufferFormat);
+				}
+			else
+				{
+				Fault(EGuiVideoInfoUnavailable);
+				}
+			}
+
+		if (r != KErrNone && __e32_atomic_tas_ord32(&buffer.iDisplayDriverCount, 1, -1, 0) == 1)
+			{
+			// Release any that were allocated
+			masterIni->ReleaseFrameBuffers(aScreenNumber);
+			}
+		}
+	else
+		{
+		// Display driver disconnected
+		if (__e32_atomic_tas_ord32(&buffer.iDisplayDriverCount, 1, -1, 0) == 1)
+			{
+			// All drivers disconnected, deallocate memory.
+			masterIni->ReleaseFrameBuffers(aScreenNumber);
+			}
+		}
+
+	return r;
+	}
+
+
+void DWinsUi::SetVirtualKey(const TBool aProcessing, const TInt aCommandData, const TEmulCommand aCommand)
+	{
+	iProcessingVirtualKey = aProcessing;
+	iFakedVirtualKey = aCommandData;
+	iVirtualKeyCommand = aCommand;
+	}
+
+TBool DWinsUi::WasVirtualKey(TInt& aCommandData, TEmulCommand& aCommand)
+	{
+	if (iProcessingVirtualKey)
+		{
+
+		aCommandData = iFakedVirtualKey;
+		aCommand = iVirtualKeyCommand;
+		}
+	return iProcessingVirtualKey;
+	}
+
+
+TInt DWinsUi::DoDefineEmulatorControl(TAny* aPtr, const char* aValue)
+	{
+	return static_cast<DWinsUi*>(aPtr)->DefineEmulatorControl(aValue);
+	}
+
+
+TInt DWinsUi::DefineEmulatorControl(const char* aValue)
+	{
+
+	//example EmulatorControl SelectConfig 2 rect 223,640 29,22
+	//example EmulatorControl NextConfig rect 223,640 29,22
+	const char* beg = skipws(aValue);
+	const char* end = skiptok(beg);
+	TInt err = KErrNone;
+	
+	TEmulCommand command = ENoCommand;
+	TInt data = 0;
+	if (_strnicmp(beg, "SelectConfig", end-beg) == 0)
+		{
+		//get the int param which is the config to switch to
+		beg = end;
+		char * e;
+		data = strtol(beg, &e,0);
+		if (beg == e)
+			err = KErrArgument;
+		end = e;
+		command = ESelectConfig;
+		}
+	else if(_strnicmp(beg, "NextConfig", end-beg) == 0)
+
+		{
+		command = ENextConfig;
+		}
+	else
+		err = KErrArgument;
+
+	if (err != KErrNone)
+		return err;
+	
+	//get the shape
+	beg = skipws(end);
+	end = skiptok(beg);
+	if (end - beg != 4 || _strnicmp(beg, "rect", 4) != 0)
+		return KErrArgument;
+		
+	// get the parameters
+	beg = skipws(end);
+	char* end2;
+	TInt x = strtol(beg, &end2, 10);
+	if (beg == end2 || *end2++ != ',')
+		return KErrArgument;
+	beg = end2;
+	TInt y = strtol(beg, &end2, 10);
+	if (beg == end2)
+		return KErrArgument;
+	beg = skipws(end2);
+	TInt w = strtol(beg, &end2, 10);
+	if (beg == end2 || *end2++ != ',')
+		return KErrArgument;
+	beg = end2;
+	TInt h = strtol(beg, &end2, 10);
+	if (beg == end2)
+		return KErrArgument;
+	
+	VKRect* pRect = new VKRect(data, command, x, y, w, h);
+	if (!pRect)
+		return KErrNoMemory;
+	return iVirtualKeys.Append(pRect);
+
+	}
+
+
+TInt DWinsUi::DoDefineVirtualKey(TAny* aPtr, const char* aValue)
+	{
+	return static_cast<DWinsUi*>(aPtr)->DefineVirtualKey(aValue);
+	}
+
+TInt DWinsUi::DefineVirtualKey(const char* aValue)
+	{
+	// Get the key to map
+	const char* beg = skipws(aValue);
+	const char* end = skiptok(beg);
+	TInt key = iKeyboard.GetEPOCKeyCode(TPtrC8((const TUint8*)beg, end-beg));
+	if (key == KErrNotFound)
+		return key;
+
+	//get the shape
+	beg = skipws(end);
+	end = skiptok(beg);
+	if (end - beg != 4 || _strnicmp(beg, "rect", 4) != 0)
+		return KErrArgument;
+		
+	// get the parameters
+	beg = skipws(end);
+	char* end2;
+	TInt x = strtol(beg, &end2, 10);
+	if (beg == end2 || *end2++ != ',')
+		return KErrArgument;
+	beg = end2;
+	TInt y = strtol(beg, &end2, 10);
+	if (beg == end2)
+		return KErrArgument;
+	beg = skipws(end2);
+	TInt w = strtol(beg, &end2, 10);
+	if (beg == end2 || *end2++ != ',')
+		return KErrArgument;
+	beg = end2;
+	TInt h = strtol(beg, &end2, 10);
+	if (beg == end2)
+		return KErrArgument;
+	
+	VKRect* pRect = new VKRect(key, EKey, x, y, w, h);
+	if (!pRect)
+		return KErrNoMemory;
+	return iVirtualKeys.Append(pRect);
+	}
+
+
+LOCAL_C TInt readBitmapInfo(PBITMAPINFOHEADER aHeader, const char* aFileName)
+	{
+	PBITMAPFILEHEADER pbmfh=NULL;
+	PBITMAPINFOHEADER pbmih=NULL;
+	TInt bfOffBits;
+
+	HANDLE fh=CreateFileA(aFileName,GENERIC_READ,NULL,NULL,OPEN_EXISTING,NULL,NULL);
+	if (!fh || fh==INVALID_HANDLE_VALUE)
+		return KErrNotFound;
+
+	TInt r=KErrNone;
+
+	// read in the bitmap file header.  save the offset to bits.
+	pbmfh = (PBITMAPFILEHEADER)LocalAlloc(LPTR, sizeof(BITMAPFILEHEADER));
+	if (pbmfh==NULL)
+		{
+		r=KErrNotFound;
+        goto exit;
+		}
+	DWORD bytesRead;
+	ReadFile(fh, (LPVOID)pbmfh, sizeof(BITMAPFILEHEADER), &bytesRead, NULL);
+	bfOffBits=pbmfh->bfOffBits;
+
+	// read in the bitmap info header and the color table right after it.
+	pbmih = (PBITMAPINFOHEADER)LocalAlloc(LPTR, bfOffBits- sizeof(BITMAPFILEHEADER));
+	if (pbmih==NULL)
+		{
+		r=KErrNotFound;
+        goto exit;
+		}
+	ReadFile(fh, (LPVOID)pbmih, bfOffBits-sizeof(BITMAPFILEHEADER),&bytesRead,NULL);
+	*aHeader=*pbmih;
+exit:
+	LocalFree(LocalHandle ((LPSTR)pbmih));
+	LocalFree(LocalHandle ((LPSTR)pbmfh));
+	CloseHandle(fh);
+	return r;
+	}
+
+HBITMAP readBitmap(HDC aHdc, const char* aFileName)
+//
+// reads a BMP file from disk and returns a HBITMAP
+//
+	{
+	HBITMAP hbm=NULL;
+	PBITMAPFILEHEADER pbmfh=NULL;
+	PBITMAPINFOHEADER pbmih=NULL;
+	TUint8 *pBits=NULL;
+	TInt bfOffBits;
+	TInt nbytes;
+
+	HANDLE fh=CreateFileA(aFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, NULL, NULL);
+	if (!fh || fh==INVALID_HANDLE_VALUE)
+		return NULL;
+
+	nbytes=GetFileSize((HANDLE)fh, NULL);
+	// read in the bitmap file header.  save the offset to bits.
+	pbmfh = (PBITMAPFILEHEADER)LocalAlloc(LPTR, sizeof(BITMAPFILEHEADER));
+	if (pbmfh==NULL)
+        goto exit;
+	DWORD bytesRead;
+	ReadFile(fh, (LPVOID)pbmfh, sizeof(BITMAPFILEHEADER),&bytesRead,NULL);
+	bfOffBits=pbmfh->bfOffBits;
+
+	// read in the bitmap info header and the color table right after it.
+	pbmih = (PBITMAPINFOHEADER)LocalAlloc(LPTR, bfOffBits- sizeof(BITMAPFILEHEADER));
+	if (pbmih==NULL)
+        goto exit;
+	ReadFile(fh, (LPVOID)pbmih, bfOffBits-sizeof(BITMAPFILEHEADER),&bytesRead,NULL);
+
+	// finally read in the bit data.
+	pBits = (PBYTE)LocalAlloc (LPTR, (nbytes - bfOffBits));
+	if (pBits==NULL)
+        goto exit;
+	ReadFile(fh, (LPVOID)pBits, nbytes-bfOffBits,&bytesRead,NULL);
+		
+	hbm=CreateDIBitmap(aHdc, pbmih, CBM_INIT, pBits,(PBITMAPINFO) pbmih, DIB_RGB_COLORS);
+exit:
+	LocalFree(LocalHandle ((LPSTR)pBits));
+	LocalFree(LocalHandle ((LPSTR)pbmih));
+	LocalFree(LocalHandle ((LPSTR)pbmfh));
+	CloseHandle(fh);
+	return hbm;
+	}
+
+void LoadFasciaBitmap(TInt aScreen)
+	{
+	HDC hdc=GetDC(TheWin[aScreen]);
+	RECT windowRect = {0};
+	windowRect.right=systemIni->iScreens[aScreen]->iXYInputWidth;
+	windowRect.bottom=systemIni->iScreens[aScreen]->iXYInputHeight;
+	HBITMAP screenBitmap=readBitmap(hdc, systemIni->iScreens[aScreen]->iFasciaFileName);
+	if (screenBitmap==NULL)
+		{
+		screenBitmap=CreateCompatibleBitmap(hdc, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top);
+		HDC hdcMem=CreateCompatibleDC(hdc);
+		SelectObject(hdcMem, screenBitmap);
+		PatBlt(hdcMem, 0, 0, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, BLACKNESS);
+		DeleteDC(hdcMem);
+		}
+	__ASSERT_ALWAYS(screenBitmap!=NULL,Fault(EGuiCreateBitmap));
+	TheScreenBitmap[aScreen]=screenBitmap;
+
+	DrawLeds();
+
+	ReleaseDC(TheWin[aScreen], hdc);
+	}
+TBool DWinsUi::MultiTouchEnabled() const
+	{
+	return iMultiTouchEnabled;
+	}
+
+TBool DWinsUi::GCEEnabled() const
+	{
+	return iGCEEnabled;
+	}
+
+TInt DWinsUi::MultiTouchProximityStep() const
+	{
+	return iMultiTouchProximityStep;
+	}
+
+TInt DWinsUi::MultiTouchPressureStep() const
+	{
+	return iMultiTouchPressureStep;
+	}
+
+TBool DWinsUi::OnDigitizer(TInt aX, TInt aY) const
+	{
+	if (!iDigitizerEnabled)
+		return EFalse;
+	aX -= iDigitizerOffsetX;
+	aY -= iDigitizerOffsetY;
+	return (TUint(aX) < TUint(iDigitizerWidth) && TUint(aY) < TUint(iDigitizerHeight));
+	}
+
+LOCAL_C void addMouseEvent(TRawEvent::TType aType,TInt aXpos,TInt aYpos)
+//
+// Add a mouse event.
+//
+	{
+	if (systemIni->OnDigitizer(aXpos, aYpos))
+		{
+		TRawEvent v;
+		v.Set(aType,aXpos,aYpos);
+		TheEventQ.Add(v);
+		}
+	}
+
+LOCAL_C void addMouseEvent(TRawEvent::TType aType,TInt aXpos,TInt aYpos,TInt aZpos, TInt aPointerId=0)
+//
+// Add a multitouch mouse event.
+//
+	{
+	if (systemIni->OnDigitizer(aXpos, aYpos))
+		{
+		TRawEvent v;
+		v.Set(aType,aXpos,aYpos, aZpos);
+		v.SetPointerNumber(static_cast<const TUint8>(aPointerId));
+		TheEventQ.Add(v);
+		}
+	}
+	
+LOCAL_C void addKeyEvent(TRawEvent::TType aType,TInt aKey)
+	{
+	TRawEvent v;
+	v.Set(aType, aKey);
+	TheEventQ.Add(v);
+	}
+
+
+LOCAL_C void SwitchConfiguration(TInt aData, TBool aSendFlipKey = ETrue)
+	{
+	if (aData < 0 || aData >= masterIni->iSystemInis.Count())
+		return;
+
+	CurrentConfiguration = aData;
+	systemIni = masterIni->iSystemInis[aData];
+	
+	//get the correct fascia bitmaps
+	TInt screens=systemIni->iScreens.Count();
+	TInt i;
+	TUint disabledWinType=ENormalResolution;
+	for(i=0;i<screens;i++)
+		{
+		DeleteObject(TheScreenBitmap[i]);
+		LoadFasciaBitmap(i);
+		if (masterIni->iBufferSet[i].iDisplayState!=ENormalResolution)
+			{
+			disabledWinType=masterIni->iBufferSet[i].iDisplayState;
+			}
+		}
+	
+	//update the window title
+	if (disabledWinType!=ENormalResolution && disabledWinType < 4)	//hardwired 4 because the code below is hardwired
+		{	//string may be multi-part indexed by disable type, or it may not
+		CHAR* firstsemi=strchr(systemIni->iWindowTitle,';');
+		CHAR* secondsemi=NULL;
+		if (firstsemi)
+			{
+			secondsemi=strchr(firstsemi+1,';');
+			}
+		if (firstsemi&&secondsemi)
+			{
+			*firstsemi='\0';
+			*secondsemi='\0';
+			char* ptr[4]={0,systemIni->iWindowTitle,firstsemi+1,secondsemi+1};
+			SetWindowTextA(TheControlWin, ptr[disabledWinType]);
+			*firstsemi=';';
+			*secondsemi=';';
+			}
+		else
+			{
+			SetWindowTextA(TheControlWin, systemIni->iWindowTitle);
+			}
+		
+		}
+	else
+		{
+		SetWindowTextA(TheControlWin, systemIni->iWindowTitle);
+		}
+	//resize and repaint the current window anyway.
+	//the text window server doesn't respond to orientation messages
+	for(i=0;i<screens;i++)
+		{
+		InvalidateRect(TheWin[i], NULL, false);
+		SendMessage(TheWin[i], WM_FLIP_MESSAGE, systemIni->iScreens[i]->iScreenRotation,0);
+		}
+
+	//Broadcast new orientation to Symbian OS
+	if (aSendFlipKey)
+		{
+		if (!WinsGuiPowerHandler->iStandby)
+			{
+			addKeyEvent(TRawEvent::EKeyDown, systemIni->iInitialFlipMsg);
+			}
+		else
+			{
+			//remember so we can broadcast new orientation to Symbian OS
+			SavedFlipMessage = systemIni->iInitialFlipMsg;
+			}
+		}
+	}
+/**
+Sets the specified screen to the given width and height, if available.
+
+The configurations are searched to find a match, taking the display state into
+account. If no configuration is available, the request is ignored.
+
+@param aScreenNumber	the screen index
+@param aWidth 			the desired width
+@param aHeight			the desired height
+**/
+void DMasterIni::SetDisplaySize(TInt aDisplayNumber, TInt aWidth, TInt aHeight)
+	{
+	TInt displayCount = iBufferSet.Count();
+
+	if (aDisplayNumber < 0 || aDisplayNumber >= displayCount)
+		{
+		// Invalid screen number, discard.
+		return;
+		}
+
+	if (iBufferSet[aDisplayNumber].iDisplayState != ENormalResolution)
+		{
+		// No (non-zero) resolutions available, discard.
+		return;
+		}
+
+	TInt count = iSystemInis.Count();
+	TInt index;
+	for (index = 0; index < count; index++)
+		{
+		DWinsUi* newIni = masterIni->iSystemInis[index];
+		DScreenProperties* newProps = newIni->iScreens[aDisplayNumber];
+
+		if (newProps->iScreenWidth == aWidth && newProps->iScreenHeight == aHeight)
+			{
+			// Found a potential match. Check other screens match their current size.
+			if (newIni == systemIni)
+				{
+				// Current configuration, already in use. Nothing to do.
+				break;
+				}
+			
+			TInt display;
+			for (display = 0; display < displayCount; display++)
+				{
+				if (display == aDisplayNumber)
+					{
+					// No need to check the display we are changing
+					continue;
+					}
+
+				DScreenProperties* currentPropsN = systemIni->iScreens[display];
+				DScreenProperties* newPropsN = newIni->iScreens[display];
+				
+				if (newPropsN->iScreenWidth != currentPropsN->iScreenWidth ||
+						newPropsN->iScreenHeight != currentPropsN->iScreenHeight)
+					{
+					// Resolution mismatch, try next configuration.
+					break;
+					}
+				}
+			
+			if (display == displayCount)
+				{
+				// Match found, switch to this configuration and stop. Force
+				// rotation to the same as the current rotation.
+				newProps->iScreenRotation = systemIni->iScreens[aDisplayNumber]->iScreenRotation;
+				SwitchConfiguration(index);
+				break;
+				}
+			}
+		}
+	}
+
+
+void DMasterIni::SetBufferFormat(TInt aDisplayNumber, TUint aAggregateSize, RDisplayChannel::TPixelFormat aPixelFormat)
+	{
+	TInt displayCount = iBufferSet.Count();
+
+	if (aDisplayNumber < 0 || aDisplayNumber >= displayCount)
+		{
+		// Invalid screen number, discard.
+		return;
+		}
+	
+	LPBITMAPV4HEADER info = &iBufferSet[aDisplayNumber].iInfo;
+	
+	// update the bitmap header taking in consideration the new pixel format
+	switch (aPixelFormat)
+		{
+		case EUidPixelFormatXRGB_4444:
+		case EUidPixelFormatARGB_4444:
+			info->bV4BitCount=16;
+			info->bV4V4Compression = BI_BITFIELDS;
+			info->bV4RedMask   = 0x0F00;
+			info->bV4GreenMask = 0x00F0;
+			info->bV4BlueMask  = 0x000F;
+			break;
+		case EUidPixelFormatRGB_565:
+			info->bV4BitCount=16;
+			info->bV4V4Compression = BI_BITFIELDS;
+			info->bV4RedMask   = 0xF800;
+			info->bV4GreenMask = 0x07E0;
+			info->bV4BlueMask  = 0x001F;
+			break;
+		case EUidPixelFormatXRGB_8888:	// Really 32bpp, but top 8 unused
+		case EUidPixelFormatARGB_8888:
+		case EUidPixelFormatARGB_8888_PRE:
+			info->bV4BitCount=32;
+			info->bV4V4Compression = BI_RGB;
+			// Mask is implicit for BI_RGB compression
+			break;
+		default:
+			// We got an error, it seems. Let's ignore the message
+			return;
+		}
+	iBufferSet[aDisplayNumber].iBufferFormat.iPixelFormat = aPixelFormat;
+	
+	// taking advantage of limiting the width and size to KMaxTInt16
+	TInt width = aAggregateSize & 0x0000ffff;
+	TInt height = (aAggregateSize >> 16) & 0x0000ffff;
+
+	// let's deal with the new size just received
+	iBufferSet[aDisplayNumber].iBufferFormat.iSize.iWidth = width;
+	iBufferSet[aDisplayNumber].iBufferFormat.iSize.iHeight = height;
+	
+	// update the bitmap header, taking in consideration the rotation
+	switch (CurrentFlipState[aDisplayNumber])
+		{
+		case EEmulatorFlipRestore:
+		case EEmulatorFlipInvert:
+			info->bV4Width = width;
+			info->bV4Height = -height;
+			break;
+		case EEmulatorFlipLeft:
+		case EEmulatorFlipRight:
+			info->bV4Width = height;
+			info->bV4Height = -width;
+			break;
+		}
+	// finally, update the image size
+	SetImageSize(aDisplayNumber);
+	}
+
+void DMasterIni::SetImageSize(TInt aScreenNumber)
+	{
+	TInt displayCount = iBufferSet.Count();
+
+	if (aScreenNumber >= 0 && aScreenNumber < displayCount)
+		{
+		LPBITMAPV4HEADER info = &iBufferSet[aScreenNumber].iInfo;
+		TInt bpp = _ALIGN_UP(info->bV4BitCount, 16); //12 & 16 --> 16 ; 24 & 32 --> 32
+		TInt widthInBpp = info->bV4Width * bpp;
+		//rounding to 32 bits (4 octets) and converting, then, bits to octets;
+		TInt scanLineInBytes = _ALIGN_UP(widthInBpp, 32) >> 3;
+		// info->bV4Height is negative or zero
+		info->bV4SizeImage = -info->bV4Height * scanLineInBytes;
+		}
+	}
+
+LOCAL_C void NextConfiguration()
+	{
+	TInt config = CurrentConfiguration;
+	if (++config == masterIni->iSystemInis.Count())
+		config = 0;
+	SwitchConfiguration(config);
+	}
+
+
+
+LOCAL_C TBool ProcessedByEmulatorKey(TInt aScanCode, HWND hWnd,TUint message,TUint wParam,TUint lParam)
+	{
+
+	TBool rVal = EFalse;
+	rVal = ETrue;
+	for (TInt i=0;i<systemIni->iControlHotKeys.Count();i++)//check key combinations
+		{
+		if (systemIni->iControlHotKeys[i]->CheckCombinationPressed()) 
+			{				
+			switch (systemIni->iControlHotKeys[i]->iCommand)
+				{
+				
+				case ENextConfig:
+					NextConfiguration();
+					break;
+		
+				case ESelectConfig:
+					SwitchConfiguration(systemIni->iControlHotKeys[i]->iData);
+					break;
+							
+				}
+			return ETrue;
+			}
+		}
+	switch (aScanCode)
+	{
+	
+	case EStdKeyF4:
+		{
+		// Simulate a change of media card
+		TInt irq = NKern::DisableAllInterrupts();
+		if (*Wins::MediaDoorOpenPtr())
+			{
+			*Wins::CurrentPBusDevicePtr() += 1;
+			if (*Wins::CurrentPBusDevicePtr() == 2)
+				{
+				*Wins::CurrentPBusDevicePtr() = -1;
+				}
+			}
+		NKern::RestoreInterrupts(irq);
+		
+		// pass on to the windows system so that if
+		// Alt-F4 is pressed the window will close
+		if (hWnd)
+			DefWindowProcA(hWnd,message,wParam,lParam);
+		break;
+		}
+
+	default:
+		rVal = EFalse;
+		break;
+	}
+	return rVal;
+	}
+
+LOCAL_C void MultiChildWndPointer(TUint aMessage,TInt aXpos,TInt aYpos, TInt aZ, TInt aPointerId)
+//
+// Handle a multi-touch pointer event in the Symbian OS screen window 
+//
+	{
+	TInt phoneX, phoneY;
+	TRawEvent::TType eventType=TRawEvent::ENone;
+	CHAR buf[50];
+	
+	systemIni->TranslateMouseCoords(CurrentFlipState[0], aXpos, aYpos, systemIni->iScreens[0]->iScreenWidth, systemIni->iScreens[0]->iScreenHeight, phoneX, phoneY);
+
+	if (aZ <= TheMultiTouch->iZMaxRange) //negative
+		{
+		eventType = TRawEvent::EPointer3DOutOfRange;
+		wsprintf((LPTSTR)buf, (LPCTSTR)TEXT("Out Of Range"));
+		SendMessage(hwndStatus, SB_SETTEXT, aPointerId , (LPARAM)(buf));					
+		}
+	else 
+		{
+		wsprintf((LPTSTR)buf, (LPCTSTR)TEXT("%d: %d,%d,%d"), aPointerId, phoneX,phoneY,aZ);
+		SendMessage(hwndStatus, SB_SETTEXT, aPointerId , (LPARAM)(buf));					
+		switch (aMessage)
+	    	{
+			case WM_MOUSEMOVE:
+				{
+				eventType=TRawEvent::EPointerMove;
+				break;
+				}
+			case WM_LBUTTONDOWN:
+				{
+				SetCapture(TheChildWin[0]);
+				eventType = TRawEvent::EButton1Down;
+				}
+				break;
+			case WM_LBUTTONUP:
+				{
+				ReleaseCapture();
+				eventType = TRawEvent::EButton1Up;
+				break;
+				}
+			case WM_RBUTTONDOWN:
+				{
+				eventType = TRawEvent::EButton3Down;
+				break;
+				}
+			case WM_RBUTTONUP:
+				{
+				eventType = TRawEvent::EButton3Up;
+				break;
+				}
+			case WM_MOUSEWHEEL:
+				{
+				eventType = TRawEvent::EPointerMove;
+				break;
+				}
+			default:
+				return;
+			}
+		}
+
+	if (!WinsGuiPowerHandler->iStandby)
+		{
+		addMouseEvent(eventType, phoneX, phoneY, aZ, aPointerId);
+		}
+	}
+
+LOCAL_C void ChildWndPointer(TUint message,TInt aXpos,TInt aYpos)
+//
+// Handle a pointer event in the Symbian OS screen window
+//
+	{
+	// Enable the multitouch if the cursor is inside the main client window
+	if (DMultiTouch::iMultiTouchCreated)
+		{
+		RECT client;
+		WINDOWINFO info;
+		GetWindowInfo(TheChildWin[0], &info);
+		POINT pt = {aXpos+(TInt)info.rcClient.left, aYpos+(TInt)info.rcClient.top};
+		if (GetWindowRect(TheChildWin[0], &client) &&
+				(PtInRect(&client,pt)!=NULL) && !DMultiTouch::iMultiTouchTempEnabled)	// within the window
+			{
+			if (systemIni->MultiTouchEnabled() && systemIni->GCEEnabled())
+				{
+				if(TheMultiTouch->Register())	// Register successfully
+					{
+					DMultiTouch::iMultiTouchTempEnabled = TRUE;
+					//Show the status bars at the bottom of the emulator
+					SetWindowPos(hwndStatus,0,0,0,0,0,SWP_SHOWWINDOW);
+					SetFocus(TheWin[0]);
+					SetCursor(LoadCursorA(NULL,MAKEINTRESOURCEA(32512)));
+					}
+				}
+			}
+		}
+	TRawEvent::TType eventType=TRawEvent::ENone;
+	switch (message)
+    	{
+	case WM_MOUSEMOVE:
+		eventType=TRawEvent::EPointerMove;
+		break;
+	case WM_LBUTTONDOWN:
+		{
+		SetCapture(TheChildWin[0]);
+		eventType=TRawEvent::EButton1Down;
+		}
+		break;
+	case WM_LBUTTONUP:
+		ReleaseCapture();
+		eventType=TRawEvent::EButton1Up;
+		break;
+	case WM_RBUTTONDOWN:
+		eventType=TRawEvent::EButton3Down;
+		break;
+	case WM_RBUTTONUP:
+		eventType=TRawEvent::EButton3Up;
+		break;
+	case WM_MBUTTONDOWN:
+		eventType=TRawEvent::EButton2Down;
+		break;
+	case WM_MBUTTONUP:
+		eventType=TRawEvent::EButton2Up;
+		break;
+		}
+	if (!WinsGuiPowerHandler->iStandby)
+		{
+		TInt newX, newY;
+		systemIni->TranslateMouseCoords(CurrentFlipState[0], aXpos, aYpos, systemIni->iScreens[0]->iScreenWidth, systemIni->iScreens[0]->iScreenHeight, newX, newY);
+		addMouseEvent(eventType, newX, newY);
+		}
+	}
+
+LOCAL_C void FrameWndPointer(TUint message,TInt aXpos,TInt aYpos, TInt aScreenNumber, TInt aPointerId = 0)
+//
+// Handle a frame wnd pointer event.
+//
+	{
+	static bool	processingScreenOn=FALSE;
+	TEmulCommand command = ENoCommand;
+	TInt commandData = 0;
+	TBool mouseEvent = ETrue;
+	
+	TRawEvent::TType eventType=TRawEvent::ENone;
+	
+	TViewport& viewport = systemIni->iScreens[aScreenNumber]->iViewport;
+	aXpos += viewport.GetViewportOffsetX(); // make mouse-coords relative to fascia edge even if window is scrolled
+	aYpos += viewport.GetViewportOffsetY();
+	
+	switch (message)
+    	{
+	case WM_MOUSEMOVE:
+		{
+		TInt newX, newY;
+		systemIni->TranslateMouseCoords(CurrentFlipState[0], aXpos, aYpos, systemIni->iScreens[0]->iXYInputWidth, systemIni->iScreens[0]->iXYInputHeight, newX, newY);
+
+		if (aPointerId == 0)
+			{ // only system pointer changes shape
+		if (systemIni->GetVirtualKey(command, newX, newY) >= 0)
+			{
+			HMODULE hmodule = GetModuleHandleA("winsgui.dll");
+			SetCursor(LoadCursorA((HINSTANCE)hmodule,MAKEINTRESOURCEA(OVERKEY)));		//hand cursor
+			}
+		else
+			SetCursor(LoadCursorA(NULL,MAKEINTRESOURCEA(32512))); //ICD_ARROW
+				}
+
+		eventType=TRawEvent::EPointerMove;
+		
+		}
+		break;
+	case WM_LBUTTONDOWN:
+		{
+		SetCapture(TheWin[0]);
+		//check the configuration
+		TInt newX, newY;
+		
+		//if the emulator screen is rotated, rotate/flip the current mouse cursor position
+		//so it can be checked to see if it is in a key region.
+		systemIni->TranslateMouseCoords(CurrentFlipState[0], aXpos, aYpos, systemIni->iScreens[0]->iXYInputWidth, systemIni->iScreens[0]->iXYInputHeight, newX, newY);
+		commandData = systemIni->GetVirtualKey(command, newX, newY);
+		
+		if (commandData >= 0)
+			{
+			eventType=TRawEvent::EKeyDown;
+			mouseEvent = EFalse;
+			systemIni->SetVirtualKey(ETrue, commandData, command);
+			}
+		else
+			eventType=TRawEvent::EButton1Down;
+		}
+		break;
+	case WM_LBUTTONUP:
+		ReleaseCapture();
+		if (processingScreenOn)
+			{
+			// ignore button up - button down was switching things on
+			processingScreenOn=FALSE;
+			return;
+			}
+		if (systemIni->WasVirtualKey(commandData, command))
+			{
+			eventType=TRawEvent::EKeyUp;
+			mouseEvent = EFalse;
+			systemIni->SetVirtualKey(EFalse, EStdKeyNull, ENoCommand);
+			}
+		else
+			eventType=TRawEvent::EButton1Up;
+		break;
+	case WM_RBUTTONDOWN:
+		eventType=TRawEvent::EButton3Down;
+		break;
+	case WM_RBUTTONUP:
+		eventType=TRawEvent::EButton3Up;
+		break;
+	case WM_MBUTTONDOWN:
+		eventType=TRawEvent::EButton2Down;
+		break;
+	case WM_MBUTTONUP:
+		eventType=TRawEvent::EButton2Up;
+		break;
+		}
+	if (mouseEvent)
+		{
+		
+		if (!WinsGuiPowerHandler->iStandby)
+			{
+			/*
+			mouse events are relative to the child window position
+			and are clipped to the digitzer region in addMouseEvent
+			so all the mouse clicks are passed on here after being translated 
+			to the child window coordinate system (under the current rotation)
+			*/
+			TInt newX, newY;
+			switch (CurrentFlipState[0])
+				{
+				case EEmulatorFlipRestore:
+				default:
+					newX = aXpos - systemIni->iScreens[0]->iScreenOffsetX;
+					newY = aYpos - systemIni->iScreens[0]->iScreenOffsetY;
+					break;
+				case EEmulatorFlipInvert:
+					newX = aXpos - (systemIni->iScreens[0]->iXYInputWidth - systemIni->iScreens[0]->iScreenWidth - systemIni->iScreens[0]->iScreenOffsetX);
+					newY = aYpos - (systemIni->iScreens[0]->iXYInputHeight - systemIni->iScreens[0]->iScreenHeight - systemIni->iScreens[0]->iScreenOffsetY);
+					break;
+				case EEmulatorFlipLeft:
+					newX = aXpos - systemIni->iScreens[0]->iScreenOffsetY;
+					newY = aYpos - (systemIni->iScreens[0]->iXYInputWidth - systemIni->iScreens[0]->iScreenWidth - systemIni->iScreens[0]->iScreenOffsetX);
+					break;	
+				case EEmulatorFlipRight:
+					newX = aXpos - (systemIni->iScreens[0]->iXYInputHeight - systemIni->iScreens[0]->iScreenHeight - systemIni->iScreens[0]->iScreenOffsetY);
+					newY = aYpos - systemIni->iScreens[0]->iScreenOffsetX;
+					break;
+				}
+			addMouseEvent(eventType, newX, newY);
+			}
+		}
+	else if ((((message == WM_LBUTTONDOWN && command == EKey) && !ProcessedByEmulatorKey((TUint8)commandData,0,0,0,0)))
+			|| (message == WM_LBUTTONUP))
+		{
+			switch (command)
+			{
+			case EKey:
+				if (!WinsGuiPowerHandler->iStandby)
+					addKeyEvent(eventType, (TUint8)commandData);
+				break;
+
+			case ENextConfig:
+				NextConfiguration();
+				break;
+			
+			case ESelectConfig:
+				SwitchConfiguration(commandData);
+				break;
+			}
+		}
+	}
+
+LOCAL_C TInt ScreenFromHWND(HWND aHwnd,HWND* pWin)
+	{
+	TInt screens=systemIni->iScreens.Count();
+	TInt r=-1;
+	for(TInt i=0;i<screens;i++)
+		{
+		if(pWin[i]==aHwnd)
+			{
+			r=i;
+			break;
+			}
+		}
+	return r;
+	}
+void MultiTouchWndPointer(TUint message,TInt aXpos,TInt aYpos, TInt aZ, TInt aPointerId)
+	{
+	WINDOWINFO info;
+	info.cbSize = sizeof(WINDOWINFO);
+	if (GetWindowInfo(TheWin[0], &info))
+		{
+		POINT pt = {aXpos,aYpos};
+		if (PtInRect(&info.rcWindow,pt))
+			{
+			RECT client;
+			if (GetWindowRect(TheChildWin[0], &client) && PtInRect(&client,pt))	// within the window
+				{
+				MultiChildWndPointer(message, aXpos-client.left, aYpos-client.top, aZ, aPointerId);
+				}
+			else  
+				{		
+				//	Disable the multitouch if the cursor is outside the application window
+				if (DMultiTouch::iMultiTouchTempEnabled)	// within the window
+					{
+					DMultiTouch::iMultiTouchTempEnabled = FALSE;
+					if(TheMultiTouch->UnRegister())
+						{
+						SetWindowPos(hwndStatus,0,0,0,0,0,SWP_HIDEWINDOW);
+						}
+					}
+				FrameWndPointer(message, aXpos-info.rcClient.left, aYpos-info.rcClient.top, 0, aPointerId);	
+				}
+			}
+		}
+	}
+
+LOCAL_C DScreenProperties* ScreenPropsFromHWND(HWND aHwnd, HWND* pWin)
+	{
+	TInt screenNumber =  ScreenFromHWND(aHwnd, pWin);
+	
+	if(screenNumber >=0)
+		{
+		return systemIni->iScreens[screenNumber];
+		}
+	return NULL;
+
+	}
+
+
+TInt APIENTRY childWinProc(HWND hWnd,TUint message,TUint wParam,TUint lParam)
+//
+// The child window function.
+//
+	{
+	TInt screenNumber = 0;
+	TRawEvent v;
+    switch (message)
+    	{
+	case WM_FLIP_MESSAGE: // pass the flip message onto the parent window
+		{
+		screenNumber =ScreenFromHWND(hWnd,TheChildWin);
+		if(TUint(screenNumber) < TUint(systemIni->iScreens.Count()))
+			PostMessageA(TheWin[screenNumber],WM_FLIP_MESSAGE,wParam,NULL);
+		break;
+		}
+	case WM_LBUTTONDOWN:
+	case WM_LBUTTONUP:
+	case WM_MOUSEMOVE:
+	case WM_RBUTTONDOWN:
+	case WM_RBUTTONUP:
+	case WM_MBUTTONDOWN:
+	case WM_MBUTTONUP:
+		{
+		if (DMultiTouch::iMultiTouchTempEnabled)
+			{
+			DMultiTouch::iMultiTouchTempEnabled = FALSE;
+			}
+		screenNumber=ScreenFromHWND(hWnd,TheChildWin);
+		if(screenNumber==0)
+			{
+			ChildWndPointer(message,(TInt16)(lParam&0xFFFF),(TInt16)((lParam>>16)&0xFFFF));
+			}
+		break;
+		}
+    case WM_PAINT:
+		if (!PaintWindowFromBuffer(hWnd))
+			{
+			// Original behaviour
+			ValidateRect(hWnd,NULL);
+			v.Set(TRawEvent::ERedraw);
+			TheEventQ.Add(v);
+			}
+        break;
+    case WM_ACTIVATE:
+	case WM_SYSKEYDOWN:
+	case WM_KEYDOWN:
+	case WM_SYSKEYUP:
+	case WM_KEYUP:
+		Fault(EGuiChildWinProc);
+		break;
+    case WM_DESTROY:
+		break;
+
+	case WM_CHAR:
+	case WM_SYSCHAR:
+	case WM_DEADCHAR:
+	case WM_SYSDEADCHAR:
+        break;
+
+	case WMU_SET_DISPLAY_BUFFER:
+		screenNumber = ScreenFromHWND(hWnd, TheChildWin);
+		if (TUint(screenNumber) < TUint(systemIni->iScreens.Count()))
+			{
+			masterIni->iBufferSet[screenNumber].iDisplayBuffer = (LPVOID)lParam;
+			}
+		break;
+	case WMU_SET_DISPLAY_SIZE:
+		screenNumber = ScreenFromHWND(hWnd, TheChildWin);
+		masterIni->SetDisplaySize(screenNumber, wParam, lParam);
+		break;
+		
+	case WMU_SET_BUFFER_FORMAT:
+		screenNumber = ScreenFromHWND(hWnd, TheChildWin);
+		masterIni->SetBufferFormat(screenNumber, wParam, (RDisplayChannel::TPixelFormat) lParam);
+		break;
+		
+ 	default:
+        return(DefWindowProcA(hWnd,message,wParam,lParam));
+	    }
+    return(FALSE);
+	}
+
+
+LOCAL_C TBool PaintWindowFromBuffer(HWND hWnd)
+	{
+	TInt screenNumber = ScreenFromHWND(hWnd,TheChildWin);
+	
+	if (TUint(screenNumber) >= TUint(masterIni->iBufferSet.Count()))
+		{
+		return EFalse;
+		}
+
+	LPVOID displayBuffer = masterIni->iBufferSet[screenNumber].iDisplayBuffer;
+	if (!displayBuffer)
+		{
+		return EFalse;
+		}
+
+	TInt   frameOffset = masterIni->iBufferSet[screenNumber].iScreenBuffer.iDisplayBufferOffset;
+	displayBuffer=LPVOID(frameOffset+(char*)displayBuffer);
+	
+	LPBITMAPINFO info = (LPBITMAPINFO)&masterIni->iBufferSet[screenNumber].iInfo;
+	WORD width = (WORD)info->bmiHeader.biWidth;
+	WORD height = (WORD)-info->bmiHeader.biHeight;	// stored -ve in info
+	LPVOID pDisplayBuffer;
+	
+	switch(CurrentFlipState[screenNumber])
+	{
+	case EEmulatorFlipRestore:
+		{
+		//No rotation to do.
+		pDisplayBuffer = displayBuffer;
+		}
+	break;
+
+	case EEmulatorFlipInvert:
+		{	
+		//rotate display buffer: Map phone display onto window buffer which has been rotated
+		DWORD* pRotatedPtr = systemIni->iScreens[screenNumber]->iRotateBuffer;
+		for (int y = 0; y < height; y++)
+			for (int x = 0; x < width; x++)
+				*pRotatedPtr++ = *((DWORD*)(displayBuffer) + ((height - y - 1) * (width)) + (width - x -1));
+
+		pDisplayBuffer = systemIni->iScreens[screenNumber]->iRotateBuffer;
+		}
+	break;
+	
+	case EEmulatorFlipLeft:
+		{
+		//rotate display buffer: Map phone display onto window buffer which has been rotated
+		DWORD* pRotatedPtr = systemIni->iScreens[screenNumber]->iRotateBuffer;
+		
+		for (int y = 0; y < height; y++)
+			for (int x = 0; x < width; x++)
+				*pRotatedPtr++ = *((DWORD*)(displayBuffer) + (x * height) + (height - y -1));
+				
+		pDisplayBuffer = systemIni->iScreens[screenNumber]->iRotateBuffer;
+		}
+	break;
+	
+	case EEmulatorFlipRight:
+		{
+		//rotate display buffer: Map phone display onto window buffer which has been rotated
+		DWORD* pRotatedPtr = systemIni->iScreens[screenNumber]->iRotateBuffer;
+		
+		for (int y = 0; y < height; y++)
+			for (int x = 0; x < width; x++)
+				*pRotatedPtr++ = *((DWORD*)(displayBuffer) + ((width - x - 1) * (height)) + y);
+				
+		pDisplayBuffer = systemIni->iScreens[screenNumber]->iRotateBuffer;
+		}
+	break;
+	
+	default:
+		{
+		Kern::Printf("Error PaintWindowFromBuffer - unknown orientation");
+		return EFalse;
+		}
+	}
+
+	PAINTSTRUCT ps;
+	BeginPaint(hWnd, &ps);
+
+	SetDIBitsToDevice(	ps.hdc,
+						0, 0, 			// Dst X, Y
+						width, height,	// Src W, H
+						0, 0,			// Src X, Y
+						0,				// Src offset to first line
+						height,			// Src lines available
+						pDisplayBuffer,	// Src pointer to pixels
+						info,			// Src info
+						DIB_RGB_COLORS);
+
+	EndPaint(hWnd, &ps);
+
+	return ETrue;
+	}
+
+
+LOCAL_C void CalcTextPos(TInt aScreen, TInt& aX, TInt& aY)
+	{
+	switch (CurrentFlipState[aScreen])
+		{
+	case EEmulatorFlipInvert:
+		aX = systemIni->iScreens[aScreen]->iXYInputWidth-(systemIni->iScreens[aScreen]->iScreenOffsetX+systemIni->iScreens[aScreen]->iScreenWidth);
+		aY = systemIni->iScreens[aScreen]->iXYInputHeight-(systemIni->iScreens[aScreen]->iScreenOffsetY+systemIni->iScreens[aScreen]->iScreenHeight);
+		break;
+	case EEmulatorFlipLeft:
+		aX = systemIni->iScreens[aScreen]->iScreenOffsetY;
+		aY = systemIni->iScreens[aScreen]->iXYInputWidth-(systemIni->iScreens[aScreen]->iScreenOffsetX+systemIni->iScreens[aScreen]->iScreenWidth);
+		break;
+	case EEmulatorFlipRight:
+		aX = systemIni->iScreens[aScreen]->iXYInputHeight-(systemIni->iScreens[aScreen]->iScreenOffsetY+systemIni->iScreens[aScreen]->iScreenHeight);
+		aY = systemIni->iScreens[aScreen]->iScreenOffsetX;
+		break;
+	case EEmulatorFlipRestore:
+	default:
+		aX = systemIni->iScreens[aScreen]->iScreenOffsetX;
+		aY = systemIni->iScreens[aScreen]->iScreenOffsetY;
+	break;
+		}
+	//subtract viewport offset here
+	aX -= systemIni->iScreens[aScreen]->iViewport.GetViewportOffsetX();
+	aY -= systemIni->iScreens[aScreen]->iViewport.GetViewportOffsetY();
+	}
+
+TInt APIENTRY ctrlwinProc(HWND hWnd,TUint message,TUint wParam,TUint lParam)
+//
+// The control window function
+//
+	{
+	switch(message)
+	{
+		case WM_SYSCOMMAND:
+			{
+				switch(wParam)
+				{
+					case 1:
+						{
+						NextConfiguration();
+						return 0;
+						}
+					case SC_MINIMIZE:
+					case SC_RESTORE:
+						{
+						if (wParam == SC_RESTORE) 
+							Active();
+						for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
+							{
+							SendMessage(TheWin[ix],message,wParam,lParam);
+							}
+						if (wParam == SC_MINIMIZE) 
+							Inactive();
+						}			
+				}
+				return(DefWindowProcA(hWnd,message,wParam,lParam));
+			}
+		case WM_CLOSE: // tell all emulator screen windows to close
+			{
+			for(TInt i=0;i<systemIni->iScreens.Count();i++)
+				{
+				DestroyWindow(TheWin[i]);
+				}
+			DestroyWindow(hWnd);
+			break;
+			}
+		case WM_DESTROY:
+			{
+			// save the main window position information
+			HANDLE hSysIni;
+			hSysIni = CreateFileA(systemIni->iSysIniFileName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
+			DScreenProperties* screenProps;
+			if (hSysIni != INVALID_HANDLE_VALUE)
+				{
+				DWORD numWritten;
+				//write an identifier into file so that program can avoid loading old version
+				WriteFile(hSysIni, &KDatFileVersion, sizeof(TInt), &numWritten, 0);
+				
+				//record current configuration at start of file.
+				WriteFile(hSysIni, &CurrentConfiguration, sizeof(TInt), &numWritten, 0);
+				
+				//Write out the state for each window.
+				for(TInt i=0;i<systemIni->iScreens.Count();i++)
+					{
+					screenProps= systemIni->iScreens[i];
+					
+					TWindowState winState= screenProps->GetWindowState();
+					WriteFile(hSysIni, &winState, sizeof(TWindowState), &numWritten, 0);
+					
+					
+					}
+				}
+			CloseHandle(hSysIni);
+
+			PostQuitMessage(KErrNone);
+			break;
+			}
+		case WM_INPUT:
+			{
+			if (!DMultiTouch::iMultiTouchTempEnabled)
+				{
+				for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
+					{
+					DMultiTouch::iMultiTouchTempEnabled = TRUE;
+
+					SendMessage(TheWin[ix],message,wParam,lParam);
+					}
+				}
+			else if (systemIni->MultiTouchEnabled() && DMultiTouch::iMultiTouchSupported && systemIni->GCEEnabled())
+				{
+			   	TheMultiTouch->OnWmInput(hWnd, message, wParam, lParam,TheChildWin[0]);	
+				}
+			else
+				{
+				Fault(EGuiInvalidMultiTouch);
+				}
+		   	break;
+			}	
+		default:
+			return(DefWindowProcA(hWnd,message,wParam,lParam));
+	}
+	return(FALSE);
+	}
+
+TInt APIENTRY winProc(HWND hWnd,TUint message,TUint wParam,TUint lParam)
+//
+// The border window function.
+//
+	{
+
+	TRawEvent v;
+	
+	switch (message)
+    	{
+		case WM_GETMINMAXINFO:
+			{
+			DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
+			if(screenProps == NULL)
+				{
+				return DefWindowProcA(hWnd, message, wParam, lParam);
+				}
+						
+			MINMAXINFO* minMaxInfo = reinterpret_cast<MINMAXINFO*>(lParam);
+			minMaxInfo->ptMaxTrackSize.x = screenProps->iViewport.GetMaxWindowWidth();
+			minMaxInfo->ptMaxTrackSize.y = screenProps->iViewport.GetMaxWindowHeight();
+
+			minMaxInfo->ptMaxSize.x = minMaxInfo->ptMaxTrackSize.x;
+			minMaxInfo->ptMaxSize.y = minMaxInfo->ptMaxTrackSize.y;
+			DefWindowProcA(hWnd, message, wParam, lParam);
+			
+			break;
+			}
+	   
+    	    		
+ 	    	
+    	case WM_SIZE:
+    		{
+    		DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
+			if(screenProps == NULL)
+				{
+				return DefWindowProcA(hWnd, message, wParam, lParam);
+				}
+    		TViewport& viewport = screenProps->iViewport;
+    		//update size of viewport
+    		viewport.SetViewportWidth(LOWORD(lParam));
+    		viewport.SetViewportHeight(HIWORD(lParam));
+    		
+    		
+			//If resize goes beyond boundary of emulator then scroll to compensate
+			TInt ox = viewport.GetViewportOffsetX();
+    		TInt xs = ox + LOWORD(lParam) - viewport.GetMaxWidth();
+    		if (xs>0) 
+    			{    			
+    			viewport.ScrollToX(ox-xs, hWnd);
+    			}
+    		
+    		TInt oy = viewport.GetViewportOffsetY();
+    		TInt ys = oy + HIWORD(lParam) - viewport.GetMaxHeight();
+    		if (ys>0) 
+    			{    			
+    			viewport.ScrollToY(oy-ys, hWnd);
+    			}
+    	
+    		//Adjust ranges of scroll bars
+    	   	viewport.UpdateScrollBarH(hWnd);
+    		viewport.UpdateScrollBarV(hWnd);
+    		    		
+    		
+    		
+    		break;    		
+    		}
+    	case WM_HSCROLL:
+    		{
+    		DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
+			if(screenProps == NULL)
+				{
+				return DefWindowProcA(hWnd, message, wParam, lParam);
+				}
+    		TViewport& viewport = screenProps->iViewport;
+    		
+    		switch (LOWORD(wParam)) 
+    			{
+    			case SB_THUMBTRACK:
+    				{
+    				viewport.ScrollToX(HIWORD(wParam),hWnd);
+    				break;
+    				}
+				case SB_PAGELEFT:
+					{
+					viewport.ScrollToX(viewport.GetViewportOffsetX() - viewport.GetViewportWidth(), hWnd );
+					break;
+					}
+				case SB_PAGERIGHT:
+					{
+					viewport.ScrollToX(viewport.GetViewportOffsetX() + viewport.GetViewportWidth() , hWnd);
+					break;
+					}
+				case SB_LINEUP:
+					{
+					viewport.ScrollToX(viewport.GetViewportOffsetX() - 1, hWnd);
+					break;
+					}
+				case SB_LINEDOWN:
+					{
+					viewport.ScrollToX(viewport.GetViewportOffsetX() + 1, hWnd);
+					break;
+					}
+    			
+    			}
+    		   		
+   
+    		break;
+    		}
+    	
+    	case WM_VSCROLL:
+    		{
+    		DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
+			if(screenProps == NULL)
+				{
+				return DefWindowProcA(hWnd, message, wParam, lParam);
+				}
+    		TViewport& viewport = screenProps->iViewport;
+    		
+			
+			switch (LOWORD(wParam)) 
+    			{
+    			case SB_THUMBTRACK:
+    				{
+    				viewport.ScrollToY(HIWORD(wParam), hWnd);
+    				break;
+    				}
+				case SB_PAGELEFT:
+					{
+					viewport.ScrollToY(viewport.GetViewportOffsetY() - viewport.GetViewportHeight() , hWnd);
+					break;
+					}
+				case SB_PAGERIGHT:
+					{
+					viewport.ScrollToY(viewport.GetViewportOffsetY() + viewport.GetViewportHeight(), hWnd );
+					break;
+					}
+				case SB_LINEUP:
+					{
+					viewport.ScrollToY(viewport.GetViewportOffsetY() - 1, hWnd);
+					break;
+					}
+				case SB_LINEDOWN:
+					{
+					viewport.ScrollToY(viewport.GetViewportOffsetY() + 1, hWnd);
+					break;
+					}
+    			
+    			}
+    		
+    		break;
+    		
+    		}
+    	
+    	 		
+		case WM_FLIP_MESSAGE:
+			{
+			DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
+			if(screenProps == NULL)
+				{
+				return DefWindowProcA(hWnd, message, wParam, lParam);
+
+				}
+			
+			TViewport& viewport = screenProps->iViewport;
+			RECT windowRect={0,0,0,0};
+			GetClientRect(hWnd, &windowRect);
+			
+			TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
+			if(TUint(screenNumber) >= TUint(systemIni->iScreens.Count()))
+				break;
+			PBITMAPV4HEADER info = &masterIni->iBufferSet[screenNumber].iInfo;
+			CurrentFlipState[screenNumber]=(TEmulatorFlip)wParam;
+			TBufferSet* bufferSet = &masterIni->iBufferSet[screenNumber];
+			switch (CurrentFlipState[screenNumber])
+				{
+				case EEmulatorFlipRestore:
+				case EEmulatorFlipInvert:
+					windowRect.right=systemIni->iScreens[screenNumber]->iXYInputWidth;
+					windowRect.bottom=systemIni->iScreens[screenNumber]->iXYInputHeight;
+					info->bV4Width = bufferSet->iBufferFormat.iSize.iWidth;
+					info->bV4Height = -bufferSet->iBufferFormat.iSize.iHeight;
+					break;
+				case EEmulatorFlipLeft:
+				case EEmulatorFlipRight:
+					windowRect.right=systemIni->iScreens[screenNumber]->iXYInputHeight;
+					windowRect.bottom=systemIni->iScreens[screenNumber]->iXYInputWidth;
+					info->bV4Width = bufferSet->iBufferFormat.iSize.iHeight;
+					info->bV4Height = -bufferSet->iBufferFormat.iSize.iWidth;
+					break;
+				}
+			AdjustWindowRect(&windowRect,KWinStyle,FALSE);
+    		
+    		
+			viewport.ScrollToX(0, hWnd);
+			viewport.ScrollToY(0, hWnd);
+
+			
+			screenProps->iScreenRotation = (TEmulatorFlip)wParam; 
+			
+						
+			RECT currentWindowRect;
+			GetWindowRect(hWnd,&currentWindowRect);
+			InvalidateRect(hWnd,NULL,FALSE);
+			MoveWindow(
+				TheWin[screenNumber],
+				max(currentWindowRect.left,0), // so the window doesn't disappear off the screen
+				max(currentWindowRect.top,0),
+				windowRect.right-windowRect.left,
+				windowRect.bottom-windowRect.top,
+				TRUE
+				);
+			// move the child window
+			screenProps->iViewport.UpdateChildPos(hWnd);
+			
+			viewport.UpdateScrollBarH(hWnd);
+    		viewport.UpdateScrollBarV(hWnd);
+
+			InvalidateRect(hWnd,NULL,TRUE);
+			UpdateWindow(hWnd);
+			
+			break;
+			}
+		case WM_SYSKEYDOWN:
+		case WM_KEYDOWN:
+			if (!(HIWORD(lParam)&KF_REPEAT))
+				{
+				
+				
+				TUint scanCode=DWinsKeyboard::ScanCodeToStandardKey(HIWORD(lParam));
+				TUint newScanCode = systemIni->iKeyboard.ScanCodeToRemappedKey(HIWORD(lParam));
+				MSG msg={hWnd,message,wParam,lParam,GetMessageTime(),GetMessagePos()};
+				TranslateMessage(&msg);
+				TUint charCode=0;
+				// look in the message queue to get character associated with keypress
+				// so long as the control, shift and alt keys aren't depressed
+				if (!(HIBYTE(GetKeyState(VK_CONTROL)) && HIBYTE(GetKeyState(VK_MENU)) && HIBYTE(GetKeyState(VK_SHIFT))))
+					if (PeekMessageA(&msg,hWnd,WM_CHAR,WM_CHAR,PM_NOREMOVE) &&
+						scanCode == newScanCode) //no remapping
+						charCode=msg.wParam;
+				// Pass the character as the HIWORD of the Epoc scan code
+				
+				scanCode = newScanCode;
+				v.Set(TRawEvent::EKeyDown,(charCode<<16)|scanCode);
+				if (!ProcessedByEmulatorKey(scanCode,hWnd,message,wParam,lParam))
+   					TheEventQ.Add(v);
+				
+				}
+			break;
+		case WM_TIMER:
+			break;
+		case WM_EMUL_POWER_ON:
+			{
+			TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
+			if(TUint(screenNumber) >= TUint(systemIni->iScreens.Count()))
+				break;
+//			HWND win = systemIni->iSecureDisplay ? TheSecureChildWin : TheChildWin;
+			HWND win = TheChildWin[screenNumber];
+			if (wParam==TRUE)
+				{
+				ShowWindow(win, SW_HIDE);
+				ShowWindow(win, SW_SHOWNORMAL);
+				if (SavedFlipMessage)
+					{
+					addKeyEvent(TRawEvent::EKeyDown, SavedFlipMessage);
+					SavedFlipMessage = 0;
+					}
+				}
+			else
+				{
+				ShowWindow(win, SW_SHOWNORMAL);
+				ShowWindow(win, SW_HIDE);
+				}
+			}
+			break;
+		case WM_SYSKEYUP:
+		case WM_KEYUP:
+			{
+			//get the key code, this will pick up if it has been remapped or not.
+			TUint scanCode = systemIni->iKeyboard.ScanCodeToRemappedKey(HIWORD(lParam));
+	   /*
+		* We could do this to support generation of special characters using Alt+KeyPadNum
+		* combinations, but we would need to find a way to suppress the generation of
+		* home/end scancodes etc., so leave it for the moment.
+					MSG msg={hWnd,message,wParam,lParam,GetMessageTime(),GetMessagePos()};
+					TranslateMessage(&msg);
+					TUint charCode=0;
+					// look in the message queue to get character associated with keypress
+					if (PeekMessageU()(&msg,hWnd,WM_CHAR,WM_CHAR,PM_NOREMOVE))
+						charCode=msg.wParam;
+					// Pass the character as the HIWORD of the Epoc scan code
+					v.Set(TRawEvent::EKeyUp,(charCode<<16)|scanCode);
+		*/
+					v.Set(TRawEvent::EKeyUp,scanCode);
+	    			TheEventQ.Add(v);
+			break;
+			}
+		case WM_MOUSEMOVE:
+		case WM_LBUTTONDOWN:
+		case WM_LBUTTONUP:
+		case WM_RBUTTONDOWN:
+		case WM_RBUTTONUP:
+		case WM_MBUTTONDOWN:
+		case WM_MBUTTONUP:
+				{
+				//only handle mouse clicks on screen 0
+				TInt xpos=((TInt16)(lParam&0xffff));
+				TInt ypos = (TInt16)((lParam>>16)&0xFFFF);
+				if (DMultiTouch::iMultiTouchTempEnabled)
+					{
+					MultiChildWndPointer(message,xpos,ypos,0,0);
+					DMultiTouch::iMultiTouchTempEnabled = FALSE;				
+					}
+				else
+					{
+					TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
+					if(screenNumber!=0)
+						break;
+					FrameWndPointer(message,xpos,ypos,screenNumber);
+					}
+				break;
+				}
+		case WM_PAINT:
+			{
+			DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
+			if(screenProps == NULL)
+				{
+				return DefWindowProcA(hWnd, message, wParam, lParam);
+				}
+    		TViewport& viewport = screenProps->iViewport;
+    		TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
+
+			PAINTSTRUCT p;
+
+			BeginPaint(hWnd,&p);
+	   		HDC hdcBits;
+			BITMAP bm;
+    		hdcBits=CreateCompatibleDC(p.hdc);
+			GetObjectA(TheScreenBitmap[screenNumber],sizeof(BITMAP),&bm);
+    		SelectObject(hdcBits,TheScreenBitmap[screenNumber]);
+		
+			RECT windowRect;
+			GetClientRect(TheWin[screenNumber],&windowRect);
+			
+			viewport.SetViewportHeight(windowRect.bottom);
+			viewport.SetViewportWidth(windowRect.right);
+			
+			
+			switch (CurrentFlipState[screenNumber])
+				{
+				case EEmulatorFlipRestore:
+					{
+					BitBlt(p.hdc,0,0,windowRect.right,windowRect.bottom,hdcBits,
+						viewport.GetViewportOffsetX(),viewport.GetViewportOffsetY(),SRCCOPY);
+					break;
+					}
+				case EEmulatorFlipInvert:
+					{
+					TInt sourceX = screenProps->iXYInputWidth - viewport.GetViewportWidth() - viewport.GetViewportOffsetX();
+					if(sourceX<0)
+						sourceX=0;
+					TInt sourceY = screenProps->iXYInputHeight - viewport.GetViewportHeight() - viewport.GetViewportOffsetY();
+					if(sourceY<0)
+						sourceY=0;
+					TInt sourceWidth = viewport.GetMaxWidth()-sourceX - viewport.GetViewportOffsetX();
+					TInt sourceHeight = viewport.GetMaxHeight()-sourceY - viewport.GetViewportOffsetY();
+					
+					//when inverted it is necessary to translate the image by 1 pixel up and to the left,
+					//to avoid a glitch when scrolling using ScrollWindowEx()
+					POINT arrayPoints[3]={
+						{sourceWidth-1,sourceHeight-1},
+						{-1,sourceHeight-1},
+						{sourceWidth-1,-1}
+						};
+					PlgBlt(p.hdc,arrayPoints,hdcBits,sourceX,sourceY,sourceWidth,sourceHeight,NULL,NULL,NULL);
+					break;
+					}
+				case EEmulatorFlipLeft:
+					{
+					TInt offsetX = screenProps->iXYInputWidth- viewport.GetViewportHeight()  - viewport.GetViewportOffsetY(); 	
+					TInt offsetY = viewport.GetViewportOffsetX(); 	
+		
+					POINT arrayPoints[3]={{0,windowRect.bottom},{0,0},{windowRect.right,windowRect.bottom}};
+					PlgBlt(p.hdc,arrayPoints,hdcBits,offsetX,offsetY,viewport.GetViewportHeight(),viewport.GetViewportWidth(),NULL,NULL,NULL);
+					break;
+					}
+				case EEmulatorFlipRight:
+					{
+					TInt offsetX = viewport.GetViewportOffsetY(); 
+					TInt offsetY = screenProps->iXYInputHeight - viewport.GetViewportWidth() - viewport.GetViewportOffsetX(); 	
+									
+					POINT arrayPoints[3]={{windowRect.right,0},{windowRect.right,windowRect.bottom},{0,0}};
+					PlgBlt(p.hdc,arrayPoints,hdcBits,offsetX,offsetY,viewport.GetViewportHeight(),viewport.GetViewportWidth(),NULL,NULL,NULL);
+					break;
+					}
+				}
+
+			
+			DeleteDC(hdcBits);
+			if (WinsGuiPowerHandler->iStandby)
+				{
+				TInt x,y;
+				CalcTextPos(screenNumber, x, y);
+				TextOutA(p.hdc, x, y, "Standby", 7);
+				}
+			else if (systemIni->iScreens[screenNumber]->iScreenOff)
+				{
+				TInt x,y;
+				CalcTextPos(screenNumber, x, y);
+				TextOutA(p.hdc, x, y, "Screen Off", 10);
+				}
+ 			EndPaint(hWnd,&p);
+			break;
+			}
+		case WM_ACTIVATE:
+			//Added so that change in modifier keys can be detected without sending
+			//EActive/EInActive to wserv as it results in switching the timers
+   			if((wParam & 0xffff)!= WA_INACTIVE)
+   				UpdateModifiers();
+			break;
+		case WM_CHAR:
+		case WM_SYSCHAR:
+		case WM_DEADCHAR:
+		case WM_SYSDEADCHAR:
+			break;
+		case WM_CLOSE: //pass on message to control window, it will then destroy all e,ulator windows
+			SendMessage(TheControlWin,WM_CLOSE, NULL, NULL);
+			break;
+		case WM_DESTROY:
+			{
+			DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
+			if(screenProps == NULL)
+				{
+				return DefWindowProcA(hWnd, message, wParam, lParam);
+				}
+    					
+			// save window's position information
+			screenProps->iWinPlace.length = sizeof(WINDOWPLACEMENT);
+			GetWindowPlacement(hWnd, &screenProps->iWinPlace);
+			
+			break;
+			}
+		case WM_INPUT:
+			{
+			if (systemIni->MultiTouchEnabled() && DMultiTouch::iMultiTouchSupported && systemIni->GCEEnabled())
+				{
+				TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
+				if(screenNumber==0)
+					{
+					TheMultiTouch->OnWmInput(hWnd, message, wParam, lParam,TheChildWin[screenNumber]);	
+					}
+				}
+			else
+				{
+				Fault(EGuiInvalidMultiTouch);
+				}
+		   	break;
+			}
+		default:
+	        return(DefWindowProcA(hWnd,message,wParam,lParam));
+	    }
+    return(FALSE);
+	
+	}
+
+void SetStatusBarFont(HWND& aStatusBar)
+	{
+	int statwidths[] = {100,200,300,400,500,600,700,800};
+	SendMessage(aStatusBar, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
+	HFONT hOrigFont = (HFONT) SendMessage(aStatusBar, WM_GETFONT, 0, 0);
+	SetProp(aStatusBar, TEXT("PROP_ORIGINAL_FONT"), (HANDLE) hOrigFont);
+	LOGFONT lf;
+	GetObject(hOrigFont, sizeof(lf), &lf);
+	lf.lfHeight = (long)(lf.lfHeight / 1.5);
+	lf.lfWeight = FW_NORMAL;
+	HFONT hFont = CreateFontIndirect(&lf);
+	SetProp(aStatusBar, TEXT("PROP_ITALIC_FONT"), (HANDLE) hFont);
+	hFont = (HFONT) GetProp(hwndStatus, TEXT("PROP_ITALIC_FONT"));
+	SendMessage(aStatusBar, WM_SETFONT, (WPARAM) hFont, FALSE);
+	}
+
+DWORD WINAPI KernelWindowThread(LPVOID aArg)
+//
+// The kernel window thread.
+//
+	{
+	HMODULE hmodule = GetModuleHandleA("winsgui.dll");
+	__ASSERT_ALWAYS(hmodule!=NULL,Fault(EGuiGetModuleHandle));
+
+	WNDCLASSA w;
+	memclr(&w, sizeof(WNDCLASSA));
+   	w.style=CS_OWNDC|CS_VREDRAW|CS_HREDRAW;
+   	w.lpfnWndProc=(WNDPROC)ctrlwinProc;
+   	w.hInstance=(HINSTANCE)aArg;
+   	w.hIcon=LoadIconA((HINSTANCE)hmodule,MAKEINTRESOURCEA(EPOC_ICON));
+   	w.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
+   	w.lpszClassName="E32KernelControlWindow";
+	
+	ATOM a=RegisterClassA(&w);
+	__ASSERT_ALWAYS(a!=0,Fault(EGuiRegisterWindow));
+
+	RECT ctlrwindowRect={0,0,270,0};
+	AdjustWindowRect(&ctlrwindowRect,KControlWinStyle,FALSE);
+	TInt ctrlwindowWidth=ctlrwindowRect.right-ctlrwindowRect.left;
+	TInt ctrlwindowHeight=ctlrwindowRect.bottom-ctlrwindowRect.top;
+
+    TheControlWin=CreateWindowA(
+		"E32KernelControlWindow",
+		systemIni->iWindowTitle,
+		KInvisibleControlWinStyle,
+		KWinPosX,
+		KWinPosY,
+		ctrlwindowWidth,
+		ctrlwindowHeight,
+		(HWND)NULL,
+		NULL,
+		(HINSTANCE)aArg,
+		(LPSTR)NULL
+		);
+	__ASSERT_ALWAYS(TheControlWin!=NULL,Fault(EGuiKernelWindowCreate));
+
+	memclr(&w, sizeof(WNDCLASSA));
+   	w.style=CS_OWNDC;
+   	w.lpfnWndProc=(WNDPROC)winProc;
+   	w.hInstance=(HINSTANCE)aArg;
+   	w.hIcon=LoadIconA((HINSTANCE)hmodule,MAKEINTRESOURCEA(EPOC_ICON));
+   	w.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
+   	w.lpszClassName="E32KernelWindow";
+
+	a=RegisterClassA(&w);
+	__ASSERT_ALWAYS(a!=0,Fault(EGuiRegisterWindow));
+
+	memclr(&w, sizeof(WNDCLASSA));
+	w.style=CS_OWNDC;
+	w.lpfnWndProc=(WNDPROC)childWinProc;
+	w.hInstance=(HINSTANCE)aArg;
+	w.hCursor=LoadCursorA(NULL,MAKEINTRESOURCEA(32512)); //ICD_ARROW
+	w.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
+	w.lpszMenuName=NULL;
+	w.lpszClassName="E32KernelChildWindow";
+	a=RegisterClassA(&w);
+	__ASSERT_ALWAYS(a!=0,Fault(EGuiRegisterChildWindow));
+
+	if (masterIni && masterIni->iSystemInis.Count() > 1)	
+		{
+		//add Configuration Items to the system menu if there's > 1 config
+		HMENU hMenu = GetSystemMenu(TheControlWin, FALSE);
+		InsertMenu(hMenu,5, MF_BYPOSITION|MF_SEPARATOR,0,NULL);
+		InsertMenuA(hMenu,6, MF_BYPOSITION|MF_STRING, 1, "Next Config...");
+		}
+	
+	ShowWindow(TheControlWin,SW_SHOWDEFAULT);
+	UpdateWindow(TheControlWin);
+
+	//Create frame windows and child windows
+	for(TInt screen=0;screen<systemIni->iScreens.Count();screen++)
+		{
+	
+		RECT windowRect={0,0,systemIni->iScreens[screen]->iXYInputWidth,systemIni->iScreens[screen]->iXYInputHeight};
+		AdjustWindowRect(&windowRect,KWinStyle,FALSE);
+		TInt windowWidth=windowRect.right-windowRect.left;
+		TInt windowHeight=windowRect.bottom-windowRect.top;
+    
+		CHAR title[20];
+		wsprintfA(title, "Screen %d", screen);
+
+		TheWin[screen]=CreateWindowA(
+			"E32KernelWindow",
+			title,
+			KInvisibleWinStyle,
+			KWinPosX,
+			KWinPosY,
+			windowWidth,
+			windowHeight,
+			(HWND)NULL,
+			NULL,
+			(HINSTANCE)aArg,
+			(LPSTR)NULL
+			);
+		__ASSERT_ALWAYS(TheWin[screen]!=NULL,Fault(EGuiKernelWindowCreate));
+		
+		LoadFasciaBitmap(screen);
+
+		TheChildWin[screen]=CreateWindowA(
+			"E32KernelChildWindow",
+			"",
+			WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
+			systemIni->iScreens[screen]->iScreenOffsetX,
+			systemIni->iScreens[screen]->iScreenOffsetY,
+			systemIni->iScreens[screen]->iScreenWidth,
+			systemIni->iScreens[screen]->iScreenHeight,
+			TheWin[screen],
+			NULL,
+			(HINSTANCE)aArg,
+			(LPSTR)NULL
+			);
+		__ASSERT_ALWAYS(TheChildWin[screen]!=NULL,Fault(EGuiKernelChildWindowCreate));
+		
+		// Create status bars
+		if (systemIni->MultiTouchEnabled() && systemIni->GCEEnabled())
+			{
+			HMODULE hmodComCtl = LoadLibrary(TEXT("comctl32.dll"));
+			typedef int (WINAPI* FNINITCC)();
+			FNINITCC pfnInitCommonControls = GetProcAddress(hmodComCtl, "InitCommonControls");
+			pfnInitCommonControls();
+			hwndStatus = CreateWindowExA(0, STATUSCLASSNAMEA, NULL,
+								WS_CHILD | WS_VISIBLE | CCS_BOTTOM ,
+									0,0,0,0,
+									TheWin[0], NULL, GetModuleHandle(NULL), NULL);                 
+			SetStatusBarFont(hwndStatus);
+			SetWindowPos(hwndStatus,NULL, 0,0,0,0,SWP_HIDEWINDOW);
+			}
+		}
+	
+	//Restore window data from ini file if it exists. 
+	HANDLE hSysIni = CreateFileA(systemIni->iSysIniFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
+	TBool success=(hSysIni != INVALID_HANDLE_VALUE) ? ETrue : EFalse;
+	
+	DWORD numRead;
+	TInt fileVersion=0;
+	if(success) 
+		{
+		ReadFile(hSysIni, &fileVersion, sizeof(TInt), &numRead, 0);
+		}
+	
+	//Check we are using a dat file created by this version of the program.
+	if(success && (fileVersion==KDatFileVersion) )
+		{
+				
+		TInt savedConfiguration=0; //set this to default configuration
+				
+		if(ReadFile(hSysIni, &savedConfiguration, sizeof(TInt), &numRead, 0) && (numRead>0) )
+			{
+			//Don't restore the saved configuration, see INC114502.
+			//This could be reenabled in future as an optional operation
+			//dependent on an entry in the epoc.ini file.
+
+			//SwitchConfiguration(savedConfiguration);
+			}
+	
+		//restore each window to saved state
+		for(TInt screen=0;screen<systemIni->iScreens.Count();screen++)
+			{
+		
+			//	If the .ini file was opened, get the saved settings for the windows position the last time
+			//	this emulator was run, if any, and move the window accordingly.
+			
+			TWindowState savedState;
+			
+			TBool stateLoaded = ReadFile(hSysIni, &savedState, sizeof(TWindowState), &numRead, 0) && (numRead>0);
+			 			
+			if (stateLoaded)
+				{				
+				//only allow window to be restored to 
+				//maximized or normal mode,
+				//this prevents it being restored in minimized mode
+				//or others.
+				if(savedState.iWinPlace.showCmd != SW_MAXIMIZE)
+						savedState.iWinPlace.showCmd= SW_NORMAL;
+				
+				//if starting in same configuration and/or rotation as last time emulator was run
+				//it makes sense to restore scroll offset, window position,
+				//and dimensions, if not, only restore position and window (ie. maximized/normal) state.
+				if(savedConfiguration == CurrentConfiguration &&
+					savedState.iFlipstate == CurrentFlipState[screen])
+					{
+					//Restore window placement
+					SetWindowPlacement(TheWin[screen], &savedState.iWinPlace);
+					
+					TViewport& viewport = systemIni->iScreens[screen]->iViewport;
+								
+					viewport.ScrollToX(savedState.iXoffset, TheWin[screen]);
+					viewport.ScrollToY(savedState.iYoffset, TheWin[screen]);
+					}
+				else
+					{
+					
+					RECT oldRect;
+					GetWindowRect(TheWin[screen], &oldRect);
+					//save default window dimensions
+					TInt width=oldRect.right-oldRect.left;
+					TInt height=oldRect.bottom - oldRect.top;
+
+					//restore position and window state from file
+					SetWindowPlacement(TheWin[screen], &savedState.iWinPlace);
+					
+					RECT currentRect;
+					GetWindowRect(TheWin[screen], &currentRect);
+					//keep default size.
+					MoveWindow(TheWin[screen],currentRect.left, currentRect.top, width, height, TRUE);
+					
+					}
+
+
+				// Check that enough of the recorded window position is visible on the screen
+
+				TBool enoughVisible = false;
+
+				// vague values for ensuring we have enough of the window title bar to grab
+				// if the window is partly off screen 
+				const TInt KTitleBarGrabX=80;
+				const TInt KTitleBarGrabY=50;
+
+				//inspect dimensions of the window to be restored.
+				RECT savedRect;
+				GetWindowRect(TheWin[screen], &savedRect);
+
+				SystemMonitors monitors;
+
+				if (monitors.Count() == 1)		/* Original algorithm */
+					{
+					RECT rcIntersect, rcScreen;
+
+					SetRect(&rcScreen, KTitleBarGrabX, savedRect.bottom-savedRect.top,
+						GetSystemMetrics(SM_CXSCREEN)-KTitleBarGrabX, GetSystemMetrics(SM_CYSCREEN)-KTitleBarGrabY);
+
+					enoughVisible = IntersectRect(&rcIntersect, &savedRect, &rcScreen);
+					}
+				else							/* > 1 monitor; do it differently */
+					{
+					RECT cornerBox1, cornerBox2;
+
+					// The top-left corner box
+					SetRect(&cornerBox1, savedRect.left, savedRect.top,
+						savedRect.left + KTitleBarGrabX, savedRect.top + KTitleBarGrabY);
+
+					// The top-right corner box
+					SetRect(&cornerBox2, savedRect.right - KTitleBarGrabX, savedRect.top,
+						savedRect.right, savedRect.top + KTitleBarGrabY);
+
+					// Require one of these rectangles to be all on one monitor
+					enoughVisible = monitors.RectAllOnOne(cornerBox1) || monitors.RectAllOnOne(cornerBox2);
+					}
+
+				if (!enoughVisible)
+					{
+					SetWindowPos(TheWin[screen], HWND_TOP, 0,0,0,0, SWP_NOSIZE);
+					}
+
+				}
+			else //if there was no stored info for this screen
+				{
+				ShowWindow(TheWin[screen],SW_MAXIMIZE);
+				}
+			}
+		}
+	else
+		{
+		//use default configuration and make windows visible
+		SwitchConfiguration(CurrentConfiguration);
+		for(TInt screen=0;screen<systemIni->iScreens.Count();screen++)
+			{
+			ShowWindow(TheWin[screen],SW_MAXIMIZE);
+			UpdateWindow(TheWin[screen]);
+			}
+		}
+
+	//close file if it was opened	
+	if(success) 
+		{
+		CloseHandle(hSysIni);
+		}
+		
+			
+	if (systemIni->iInitialFlipMsg != 0)
+		{
+		addKeyEvent(TRawEvent::EKeyDown,systemIni->iInitialFlipMsg);
+		}
+
+	SetFocus(TheWin[0]);
+
+	MSG m;
+	while (GetMessageA(&m,NULL,0,0))
+    	{
+        DispatchMessageA(&m);
+	    }
+	
+	ExitProcess(m.wParam);
+	return 0;
+	}
+
+SystemMonitors::SystemMonitors(void)
+	{
+	TInt n;
+
+	iCount = 1;
+	iHaveMultiMonFunctions = false;
+
+	if ((n = GetSystemMetrics(SM_CMONITORS)) <= 1)
+		{
+		return;
+		}
+
+	HMODULE huser32 = GetModuleHandleA("user32.dll");
+
+	// Get pointers to the APIs we want
+	if (huser32 == NULL ||
+		(ipMonitorFromRect =
+		(HMONITOR (WINAPI *)(LPCRECT lprcScreenCoords, UINT uFlags))
+		GetProcAddress(huser32, "MonitorFromRect")) == NULL ||
+		(ipGetMonitorInfo =
+		(BOOL (WINAPI *)(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo))
+		GetProcAddress(huser32, "GetMonitorInfoA")) == NULL)
+		{
+		return;
+		}
+
+	iCount = n;
+	iHaveMultiMonFunctions = true;
+	}
+
+TBool SystemMonitors::RectAllOnOne(RECT& rect)
+	{
+	HMONITOR monitor = MonitorFromRect(rect);
+	if (monitor == NULL)
+		{
+		return false;
+		}
+
+	MONITORINFO monInfo;
+	monInfo.cbSize = sizeof(MONITORINFO);
+
+	if (! GetMonitorInfo(monitor, &monInfo))
+		{
+		return false;
+		}
+
+	RECT overlap;
+
+	if (IntersectRect(&overlap, &rect, &monInfo.rcWork) &&
+		EqualRect(&overlap, &rect))
+		{
+		return true;
+		}
+
+	return false;
+	}
+
+HMONITOR SystemMonitors::MonitorFromRect(const RECT& rect, UINT flags)
+	{
+	if (! iHaveMultiMonFunctions)
+		{
+		return NULL;
+		}
+
+	return (*ipMonitorFromRect)(&rect, flags);
+	}
+
+TBool SystemMonitors::GetMonitorInfo(HMONITOR monitor, LPMONITORINFO pMonInfo)
+	{
+	if (! iHaveMultiMonFunctions)
+		{
+		return false;
+		}
+
+	return (*ipGetMonitorInfo)(monitor, pMonInfo);
+	}
+
+void DrawLeds()
+	{
+	HDC winDC = GetDC(TheWin[0]);
+	HDC hdcBits;
+	hdcBits=CreateCompatibleDC(winDC);
+	SelectObject(hdcBits,TheScreenBitmap[0]);
+	HPEN pen=CreatePen(PS_SOLID,0,RGB(0,0,0));
+	SelectObject(hdcBits,pen);
+	HBRUSH brush;
+	LOGBRUSH redbrush={BS_SOLID, RGB(0xff,0,0)};
+	LOGBRUSH greenbrush={BS_SOLID, RGB(0,0xff,0)};
+	LOGBRUSH blackbrush={BS_SOLID, RGB(0,0,0)};
+	// red
+	if (LedMask & KLedMaskRed1)
+		brush=CreateBrushIndirect(&redbrush);
+	else
+		brush=CreateBrushIndirect(&blackbrush);
+	SelectObject(hdcBits,brush);
+	DWinsUi *ini=systemIni;
+	Ellipse(hdcBits, ini->iLedOffsetX, ini->iLedOffsetY, ini->iLedOffsetX+ini->iLedSize, ini->iLedOffsetY+ini->iLedSize);
+	DeleteObject(brush);
+	// green
+	if (LedMask & KLedMaskGreen1)
+		brush=CreateBrushIndirect(&greenbrush);
+	else
+		brush=CreateBrushIndirect(&blackbrush);
+	SelectObject(hdcBits,brush);
+	if (ini->iLedVertical)
+		Ellipse(hdcBits, ini->iLedOffsetX, ini->iLedOffsetY+ini->iLedSize+ini->iLedGap,
+		ini->iLedOffsetX+ini->iLedSize, ini->iLedOffsetY+ini->iLedSize+ini->iLedGap+ini->iLedSize);
+	else
+		Ellipse(hdcBits, ini->iLedOffsetX+ini->iLedSize+ini->iLedGap, ini->iLedOffsetY,
+		ini->iLedOffsetX+ini->iLedSize+ini->iLedGap+ini->iLedSize, ini->iLedOffsetY+ini->iLedSize);
+	DeleteObject(brush);
+	DeleteObject(pen);
+	DeleteDC(hdcBits);
+	ReleaseDC(TheWin[0], winDC);
+	if (ini->iLedVertical)
+		{
+		RECT r={ini->iLedOffsetX,
+			ini->iLedOffsetY,
+			ini->iLedOffsetX+ini->iLedSize,
+			ini->iLedOffsetY+ini->iLedSize+ini->iLedGap+ini->iLedSize};
+		InvalidateRect(TheWin[0], &r, FALSE);
+		}
+	else
+		{
+		RECT r={ini->iLedOffsetX,
+			ini->iLedOffsetY,
+			ini->iLedOffsetX+ini->iLedSize+ini->iLedGap+ini->iLedSize,
+			ini->iLedOffsetY+ini->iLedSize};
+		InvalidateRect(TheWin[0], &r, FALSE);
+		}
+	}
+
+void DWinsUi::ScreenInfo(TScreenInfoV01& aInfo)
+//
+// Return screen 0 info to the window server.
+//
+	{
+	aInfo.iWindowHandleValid=ETrue;
+	aInfo.iWindowHandle=TheChildWin[0];
+	aInfo.iScreenAddressValid=EFalse;
+	aInfo.iScreenAddress=NULL;
+	aInfo.iScreenSize.iWidth = iScreens[0]->iMaxScreenWidth;
+	aInfo.iScreenSize.iHeight = iScreens[0]->iMaxScreenHeight;
+	}
+	
+	
+TBool DWinsUi::VideoInfo(TInt aScreenNumber, TVideoInfoV01& aInfo)
+	{
+	return VideoInfo(aScreenNumber,iScreens[aScreenNumber&KMaskScreenNum]->iCurrentMode,aInfo);
+	}
+	
+/// Could fail if flip mode is not supported
+TBool DWinsUi::VideoInfo(TInt aScreenNumber,TInt aModeNumber, TVideoInfoV01& aInfo)
+	{
+	aScreenNumber &= KMaskScreenNum;
+	if (aScreenNumber>=iScreens.Count())
+		return EFalse;
+	if (masterIni->iBufferSet.Count() && masterIni->iBufferSet[aScreenNumber].iDisplayDriverCount > 0)
+		{
+			return VideoInfoForDisplayDriver(aScreenNumber,aModeNumber,aInfo);
+		}
+	else
+		{
+		if ((aModeNumber&KMaskModeNum)>=1)
+			return EFalse;	//non-gce emulator doesn't support changing the mode number.
+		DScreenProperties* screenProperties=iScreens[aScreenNumber];
+		aInfo.iSizeInPixels.iWidth = screenProperties->iMaxScreenWidth;
+		aInfo.iSizeInPixels.iHeight = screenProperties->iMaxScreenHeight;
+		aInfo.iSizeInTwips.iWidth = screenProperties->iMaxPhysicalScreenWidth ? screenProperties->iMaxPhysicalScreenWidth : TInt(screenProperties->iScreenWidth*KDefaultPixelsToTwipsX);
+		aInfo.iSizeInTwips.iHeight = screenProperties->iMaxPhysicalScreenHeight ? screenProperties->iMaxPhysicalScreenHeight : TInt(screenProperties->iScreenHeight*KDefaultPixelsToTwipsY);
+		aInfo.iIsMono = EFalse;
+		aInfo.iIsPalettized = EFalse;
+		aInfo.iDisplayMode=screenProperties->iCurrentMode;
+		aInfo.iIsPixelOrderRGB = ETrue;
+		aInfo.iIsPixelOrderLandscape=ETrue;
+
+		aInfo.iVideoAddress =  (TInt)TheChildWin[aScreenNumber];
+		aInfo.iBitsPerPixel = screenProperties->iColorDepth;
+		aInfo.iOffsetToFirstPixel=0;
+		aInfo.iOffsetBetweenLines=0;
+		}
+	return ETrue;	
+	}
+
+/** Could fail if flip mode is not supported.
+ Note that this method is inteneded to be called directly to parameterise the setting up of the display driver,
+ so it must survive absense of the display driver installation!
+**/
+ 
+TBool DWinsUi::VideoInfoForDisplayDriver(TInt aScreenNumber,TInt aModeNumber, TVideoInfoV01& aInfo,  TBool aRealWidthAndHeight)
+	{
+	aScreenNumber &= KMaskScreenNum;
+	DScreenProperties* screenProperties = iScreens[aScreenNumber];
+	if ((aModeNumber&KMaskModeNum) >= screenProperties->iMaxModes)
+		{
+		return EFalse;
+		}
+		
+	aInfo.iSizeInPixels.iWidth = aRealWidthAndHeight ? screenProperties->iScreenWidth : screenProperties->iMaxScreenWidth;
+	aInfo.iSizeInPixels.iHeight = aRealWidthAndHeight ? screenProperties->iScreenHeight : screenProperties->iMaxScreenHeight;
+	
+	if (aRealWidthAndHeight==EFalse)
+		{
+		aInfo.iSizeInTwips.iWidth = screenProperties->iMaxPhysicalScreenWidth ?	screenProperties->iMaxPhysicalScreenWidth : TInt(screenProperties->iScreenWidth*KDefaultPixelsToTwipsX);
+		aInfo.iSizeInTwips.iHeight = screenProperties->iMaxPhysicalScreenHeight ? screenProperties->iMaxPhysicalScreenHeight : TInt(screenProperties->iScreenHeight*KDefaultPixelsToTwipsY);
+		}
+	else
+		{
+		aInfo.iSizeInTwips.iWidth = screenProperties->iPhysicalScreenWidth ? screenProperties->iPhysicalScreenWidth : TInt(screenProperties->iScreenWidth*KDefaultPixelsToTwipsX);
+		aInfo.iSizeInTwips.iHeight = screenProperties->iPhysicalScreenHeight ? screenProperties->iPhysicalScreenHeight : TInt(screenProperties->iScreenHeight*KDefaultPixelsToTwipsY);
+		}
+	
+	aInfo.iIsMono = EFalse;
+	aInfo.iIsPalettized = EFalse;
+	aInfo.iDisplayMode=screenProperties->iCurrentMode;
+	aInfo.iIsPixelOrderRGB = ETrue;
+	aInfo.iIsPixelOrderLandscape=ETrue;
+	
+	// Set memory to iVideoAddress to NULL to trigger the HAL code into querying the video address
+	// separately
+	aInfo.iVideoAddress = NULL;
+
+	TInt bpp=screenProperties->iModeDepths[aModeNumber&KMaskModeNum];												
+	aInfo.iBitsPerPixel=bpp;
+	if (bpp>8)
+		{
+		bpp=(bpp+15)&-16;	//12 & 16 --> 16 ; 24 & 32 --> 32
+		}
+	
+	aInfo.iOffsetToFirstPixel=0;
+#ifdef TEST_GCE_VARIABLE_START_EXTRA
+	aInfo.iOffsetToFirstPixel+= TEST_GCE_VARIABLE_START_EXTRA*(1+aModeNumber&KMaskScreenModeNum);
+	if ((aModeNumber& KModeFlagFlipped)
+		{
+#ifndef ASSYMETRIC_SQUARE_STRIDE		
+		if (aInfo.iSizeInPixels.iWidth!=aInfo.iSizeInPixels.iHeight)
+#endif
+			aInfo.iOffsetToFirstPixel+= TEST_GCE_VARIABLE_START_EXTRA*KEmulMaxNumModes;	
+		}
+#endif
+	if (aModeNumber& KModeFlagFlipped)
+		{
+		// we calculate the number of bytes per scanline that MUST be a multiple of 32 bits word (alignment)
+		// screenProperties->iMaxScreenHeight * bpp represnts the number of bits per scanline
+		// +31 is the ceiling
+		// we shift right (>>3) because there are 8 bits/byte
+		// we mask with ~3 because we are intrested in the octet value
+		aInfo.iOffsetBetweenLines=((screenProperties->iMaxScreenHeight * bpp + 31) >> 3) & ~3;
+		}
+	else
+		{
+		// please see the comment above
+		aInfo.iOffsetBetweenLines=((screenProperties->iMaxScreenWidth * bpp + 31) >> 3) & ~3;
+		}
+#ifdef  TEST_GCE_VARIABLE_STRIDE_EXTRA
+	aInfo.iOffsetBetweenLines+=TEST_GCE_VARIABLE_STRIDE_EXTRA;
+#endif	
+
+	return ETrue;	
+	}
+
+TInt DMasterIni::DoHalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
+	{
+	return masterIni->HalFunction((TInt)aPtr,aFunction,a1,a2);
+	}
+
+
+TInt DMasterIni::HalFunction(TInt aDeviceNumber, TInt aFunction, TAny* a1, TAny* a2)
+	{
+	if (TUint(aDeviceNumber) >= TUint(systemIni->iScreens.Count()))
+		return KErrArgument;
+	
+	TInt mode;
+	TInt maxMode=1;
+	TInt r=KErrNone;
+	switch(aFunction)
+		{
+		case EDisplayHalScreenInfo:
+			{
+			TPckgBuf<TScreenInfoV01> vPckg;
+			systemIni->ScreenInfo(vPckg());
+			Kern::InfoCopy(*(TDes8*)a1,vPckg);
+			break;
+			}
+		case EDisplayHalWsRegisterSwitchOnScreenHandling:
+			WsSwitchOnScreen=(TBool)a1;
+			break;
+		case EDisplayHalSetState:
+			{
+			if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
+				return KErrPermissionDenied;
+			if ((TBool)a1)
+				WinsGuiPowerHandler->ScreenOn(aDeviceNumber);
+			else
+				WinsGuiPowerHandler->ScreenOff(aDeviceNumber);
+			}
+			break;
+
+		case EDisplayHalState:
+			*(TInt*)a1=!systemIni->iScreens[aDeviceNumber]->iScreenOff;
+			break;
+		case EDisplayHalWsSwitchOnScreen:
+			WinsGuiPowerHandler->ScreenOn();
+			break;
+		case EDisplayHalMaxDisplayContrast:
+			kumemput32(a1,&KMaxDisplayContrast,sizeof(KMaxDisplayContrast));
+			break;
+		case EDisplayHalDisplayContrast:
+			kumemput32(a1,&systemIni->iScreens[aDeviceNumber]->iDisplayContrast,sizeof(systemIni->iScreens[aDeviceNumber]->iDisplayContrast));
+			break;
+		case EDisplayHalSetDisplayContrast:
+			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayContrast")))
+				return KErrPermissionDenied;
+			if (TUint(a1) <= TUint(KMaxDisplayContrast))
+				systemIni->iScreens[aDeviceNumber]->iDisplayContrast = TInt(a1);
+			else
+				r = KErrArgument;
+			break;
+		case EDisplayHalBacklightOn:
+			{
+			TBool c = EFalse;
+			kumemput32(a1,&c,sizeof(TBool));
+			}
+			break;
+		
+		case EDisplayHalCurrentModeInfo:
+			{
+			//a1 has ptr to buffer for results
+			TPckgBuf<TVideoInfoV01> vPckg;
+			if (systemIni->VideoInfo(aDeviceNumber, vPckg()))
+				Kern::InfoCopy(*(TDes8*)a1,vPckg);
+			else
+				r=KErrNotSupported;
+			}
+			break;
+
+		case EDisplayHalSpecifiedModeInfo:
+			{
+			kumemget32(&mode, a1, sizeof(mode));
+			TPckgBuf<TVideoInfoV01> vPckg;
+			if (!systemIni->VideoInfo(aDeviceNumber, mode, vPckg()))
+				return KErrArgument;
+			Kern::InfoCopy(*(TDes8*)a2, vPckg);
+			}
+			break;
+
+		case EDisplayHalSetMode:
+// 			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
+// 				return KErrPermissionDenied;
+
+			//Note that at present the HAL mode does not apparently get set when the CFbsScreenDevice requires a different mode.
+			//At least in the emulator and default h4 implementation...
+			
+			mode=KMaskModeNum&(TInt) a1;
+			maxMode=1;
+			//can't avoid this behaviour change test against gce loaded 
+			if (masterIni->iBufferSet.Count() &&  masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount > 0)
+				maxMode=systemIni->iScreens[aDeviceNumber]->iMaxModes;
+			if (mode >=maxMode || mode<0)
+				{
+				r = KErrArgument;
+				break;
+				}
+			//Harmless/Pointless in vanilla wins mode.
+			systemIni->iScreens[aDeviceNumber]->iCurrentMode=mode;
+			
+			break;
+		
+		case EDisplayHalMode:
+			{
+			//This is always 0 in non-gce emulator
+			kumemput32(a1,&systemIni->iScreens[aDeviceNumber]->iCurrentMode,sizeof(systemIni->iScreens[aDeviceNumber]->iCurrentMode));
+			}
+			break;
+
+		case EDisplayHalModeCount:
+			{
+			//Need to actually count them here!
+			//GCE will ignore modes<=8
+			TInt encodedMode=1;
+			if (masterIni->iBufferSet.Count() &&  masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount > 0)
+				encodedMode=systemIni->iScreens[aDeviceNumber]->iMaxModes;
+			kumemput32(a1,&encodedMode,sizeof(encodedMode));
+			}
+			break;
+
+		case EDisplayHalColors:
+			{
+			TInt deepestMode=0;
+			if (masterIni->iBufferSet.Count()==0 ||  masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount <= 0)
+				{
+				deepestMode = KMaxDisplayColors;  	//I could try and work it out, but this is what used to happen!
+				}
+			else
+				{
+				TInt maxBpp=0;
+				for (TInt i=0,maxI=systemIni->iScreens[aDeviceNumber]->iMaxModes;i<maxI;i++)	
+					if (systemIni->iScreens[aDeviceNumber]->iModeDepths[i]>maxBpp)
+						maxBpp=systemIni->iScreens[aDeviceNumber]->iModeDepths[i];
+				deepestMode= 1<<maxBpp;
+				}
+
+			kumemput32(a1,&deepestMode,sizeof(deepestMode));
+			}
+			break;
+		case EDisplayHalGetDisplayMemoryHandle:
+			{
+			TInt val = 0;
+			TInt passedIn = 0;
+			kumemget32(&passedIn, a1, sizeof(TInt));
+			if (passedIn != -1)	//not from a getall
+				{
+				NKern::ThreadEnterCS();
+				if (!(masterIni->iBufferSet.Count() == 0 || masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount <= 0 ))
+					{
+						r = masterIni->DisplayMemoryHandle(aDeviceNumber, val); 
+					}
+				else
+					{
+					r = KErrArgument;
+					}
+				NKern::ThreadLeaveCS();
+				}
+			kumemput32(a1, &val, sizeof(TInt));
+
+			}
+			break;
+
+		case EDisplayHalGetDisplayMemoryAddress:
+			{
+			TInt val = 0;
+			TInt passedIn = 0;
+			kumemget32(&passedIn, a1, sizeof(TInt));
+			if (passedIn != -1)	//not from a getall
+				{
+				if (!(masterIni->iBufferSet.Count() == 0 || masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount <= 0 ))
+					{
+					r = masterIni->DisplayMemoryAddress(aDeviceNumber, val);
+					}
+				else
+					{
+					r = KErrArgument;
+					}
+				}
+			kumemput32(a1, &val, sizeof(TInt));
+			}
+			break;
+
+		case EDisplayHalNumberOfResolutions:
+			{
+			r = NumberOfResolutions(aDeviceNumber, a1, a2);
+			}
+			break;
+		case EDisplayHalSpecificScreenInfo:
+			{
+			r = SpecificScreenInfo(aDeviceNumber, a1, a2);
+			}
+			break;
+		case EDisplayHalCurrentScreenInfo:
+			{
+			r = CurrentScreenInfo(aDeviceNumber, a1, a2);			
+			}
+			break;
+		case EDisplayHalSetDisplayState:
+			{
+			//increase the spinner at both beginning and end of resetting the display state
+			NKern::LockedInc(iBufferSet[aDeviceNumber].iStateChangeCount);
+			kumemget32(&iBufferSet[aDeviceNumber].iDisplayState, a1, sizeof(TInt));
+
+			switch(iBufferSet[aDeviceNumber].iDisplayState)
+				{
+				case ENoResolution:
+				case EDisconnect:
+				case ESingleResolution:
+					// the fascia effect of 0x0 resolution
+					SetDisplaySize(aDeviceNumber, 0, 0);
+					break;
+				}
+
+			NKern::LockedInc(iBufferSet[aDeviceNumber].iStateChangeCount);
+			}
+			break;
+		case EDisplayHalGetStateSpinner:
+			{
+			kumemput32(a1,&iBufferSet[aDeviceNumber].iStateChangeCount,
+					sizeof(iBufferSet[aDeviceNumber].iStateChangeCount));
+			}
+			break;
+		default:
+			r=KErrNotSupported;
+			break;
+		}
+	return r;
+	}
+
+TInt DMasterIni::NumberOfResolutions(TInt aDeviceNumber, TAny* a1, TAny* a2)
+	{
+	TInt numberOfConfigs;
+	switch(iBufferSet[aDeviceNumber].iDisplayState)
+		{
+		case ENoResolution:
+			{
+			numberOfConfigs = 0;
+			}
+			break;
+		case EDisconnect:
+			{
+			return KErrDisconnected;
+			}
+			break;
+		case ESingleResolution:
+			{
+			numberOfConfigs = 1;
+			}
+			break;
+		case ENormalResolution:
+		default:
+			{
+			numberOfConfigs = iSystemInis.Count();
+			if (numberOfConfigs > 1)
+				{
+				TVideoInfoV01 info1;
+				TVideoInfoV01 info2;
+				iSystemInis[0]->VideoInfoForDisplayDriver(aDeviceNumber, 0, info1, ETrue);
+				iSystemInis[1]->VideoInfoForDisplayDriver(aDeviceNumber, 0, info2, ETrue);
+				if (info1.iSizeInPixels.iWidth == info2.iSizeInPixels.iWidth &&
+						info1.iSizeInPixels.iHeight == info2.iSizeInPixels.iHeight)
+					{
+					numberOfConfigs = 1;	//It looks like all resolutions for this device are the same
+					}
+				}
+			}
+		}
+	kumemput32(a1,&numberOfConfigs,sizeof(numberOfConfigs));
+	if(a2)
+		{
+		kumemput32(a2,&(iBufferSet[aDeviceNumber].iStateChangeCount),sizeof(iBufferSet[aDeviceNumber].iStateChangeCount));
+		}
+	return KErrNone;
+	}
+
+TInt DMasterIni::SpecificScreenInfo(TInt aDeviceNumber, TAny* a1, TAny* a2)
+	{
+	TInt config;
+	switch(iBufferSet[aDeviceNumber].iDisplayState)
+		{
+		case ENoResolution: //Do Nothing
+			break;
+		case EDisconnect:
+			{
+			return KErrDisconnected;
+			}
+			break;
+		case ESingleResolution: //fill (0,0) as the only element in resolution array
+			{
+			if(*(TInt*)a1 == 0)
+				{
+				TVideoInfoV01 info;
+				info.iSizeInPixels.iHeight = 0;
+				info.iSizeInPixels.iWidth = 0;
+				info.iSizeInTwips.iHeight = 0;
+				info.iSizeInTwips.iWidth = 0;
+				TPtr8 infoPtr((TUint8*)&info, sizeof(info), sizeof(info));
+				Kern::InfoCopy(*(TDes8*)a2, infoPtr);
+				}
+			}
+			break;
+		case ENormalResolution:
+		default:
+			{
+			kumemget32(&config, a1, sizeof(config));
+			TPckgBuf<TVideoInfoV01> vPckg;
+			iSystemInis[config]->VideoInfoForDisplayDriver(aDeviceNumber, 0, vPckg(), ETrue);
+			Kern::InfoCopy(*(TDes8*)a2,vPckg);
+			}
+		}
+	return KErrNone;
+	}
+
+TInt DMasterIni::CurrentScreenInfo(TInt aDeviceNumber, TAny* a1, TAny* /*a2*/)
+	{
+	switch(iBufferSet[aDeviceNumber].iDisplayState)
+		{
+		case ENoResolution: //Do Nothing
+			break;
+		case EDisconnect:
+			{
+			return KErrDisconnected;
+			}
+			break;
+		case ESingleResolution: //fill (0,0)
+			{
+			TVideoInfoV01 info;
+			info.iSizeInPixels.iHeight = 0;
+			info.iSizeInPixels.iWidth = 0;
+			info.iSizeInTwips.iHeight = 0;
+			info.iSizeInTwips.iWidth = 0;
+			TPtr8 infoPtr((TUint8*)&info, sizeof(info), sizeof(info));
+			Kern::InfoCopy(*(TDes8*)a1, infoPtr);
+			}
+			break;
+		case ENormalResolution:
+		default:
+			{
+			TPckgBuf<TVideoInfoV01> vPckg;
+			systemIni->VideoInfoForDisplayDriver(aDeviceNumber, 0, vPckg(), ETrue);
+			Kern::InfoCopy(*(TDes8*)a1,vPckg);
+			}
+		}
+	return KErrNone;
+	}
+
+TInt DMasterIni::DoXYHalFunction(TAny* aThis, TInt aFunction, TAny* a1, TAny* a2)
+	{
+	return static_cast<DMasterIni*>(aThis)->XYHalFunction(aFunction,a1,a2);
+	}
+
+TInt DMasterIni::XYHalFunction(TInt aFunction, TAny* a1, TAny* a2)
+	{
+	TInt r=KErrNone;
+	switch(aFunction)
+		{
+		case EDigitiserHalXYInfo:
+			{
+			if(systemIni->iXYInputType==EXYInputPointer)
+				{
+				TPckgBuf<TDigitiserInfoV01> vPckg;
+				TDigitiserInfoV01& xyinfo=vPckg();
+				xyinfo.iDigitiserSize.iWidth=max(systemIni->iScreens[0]->iXYInputWidth,systemIni->iScreens[0]->iMaxScreenWidth+systemIni->iScreens[0]->iScreenOffsetX);		
+				xyinfo.iDigitiserSize.iHeight=max(systemIni->iScreens[0]->iXYInputHeight,systemIni->iScreens[0]->iMaxScreenHeight+systemIni->iScreens[0]->iScreenOffsetY);
+				xyinfo.iOffsetToDisplay.iX=systemIni->iScreens[0]->iScreenOffsetX;
+				xyinfo.iOffsetToDisplay.iY=systemIni->iScreens[0]->iScreenOffsetY;
+				Kern::InfoCopy(*(TDes8*)a1,vPckg);
+				}
+			else
+				r=KErrNotSupported;
+			}
+			break;
+			
+		// a2 = TBool aSet (ETrue for setting, EFalse for retrieval) 
+		// a1 = TDigitizerOrientation (set)
+		// a1 = &TDigitizerOrientation (get)
+		// Assume screen [0] here as this HAL function is only registered for
+		// screen 0 on the emulator platform. Function only called if display==0
+		case EDigitiserOrientation:	
+			if ((TBool)a2)
+				{
+				// Set the orientation attribute
+				// In case user thread, check it has WDD capability
+				if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDigitiserOrientation")))
+					return KErrPermissionDenied;
+				systemIni->iScreens[0]->iXYOrientation = (TInt)a1;
+				}
+			else
+				{
+				// Get the orientation attribute, safe copy it into user memory
+				kumemput32(a1, &(systemIni->iScreens[0]->iXYOrientation), sizeof(TInt));	
+				}
+			break; 
+			
+		default:
+			r=KErrNotSupported;
+			break;
+		}
+	return r;
+	}
+
+TInt DMasterIni::DoMouseHalFunction(TAny* aThis, TInt aFunction, TAny* a1, TAny* a2)
+	{
+	return static_cast<DMasterIni*>(aThis)->MouseHalFunction(aFunction,a1,a2);
+	}
+
+TInt DMasterIni::MouseHalFunction(TInt aFunction, TAny* a1, TAny* /*a2*/)
+	{
+	TInt r=KErrNone;
+	switch(aFunction)
+		{
+		case EMouseHalMouseInfo:
+			{
+			if(systemIni->iXYInputType==EXYInputMouse || systemIni->iXYInputType==EXYInputDeltaMouse)
+				{
+				TPckgBuf<TMouseInfoV01> vPckg;
+				TMouseInfoV01& xyinfo=vPckg();
+				xyinfo.iMouseButtons=2;
+				xyinfo.iMouseAreaSize.iWidth=max(systemIni->iScreens[0]->iXYInputWidth,systemIni->iScreens[0]->iMaxScreenWidth+systemIni->iScreens[0]->iScreenOffsetX);		
+				xyinfo.iMouseAreaSize.iHeight=max(systemIni->iScreens[0]->iXYInputHeight,systemIni->iScreens[0]->iMaxScreenHeight+systemIni->iScreens[0]->iScreenOffsetY);
+				xyinfo.iOffsetToDisplay.iX=systemIni->iScreens[0]->iScreenOffsetX;
+				xyinfo.iOffsetToDisplay.iY=systemIni->iScreens[0]->iScreenOffsetY;
+				Kern::InfoCopy(*(TDes8*)a1,vPckg);
+				}
+			else
+				r=KErrNotSupported;
+			}
+			break;
+		default:
+			r=KErrNotSupported;
+			break;
+		}
+	return r;
+	}
+
+TInt DMasterIni::DoKbdHalFunction(TAny* /*aThis*/, TInt aFunction, TAny* /*a1*/, TAny* /*a2*/)
+	{
+	// don't actually do anything, just enough to report a Keyboard is present
+	TInt r=KErrNone;
+	if(aFunction!=EKeyboardHalKeyboardInfo)
+		r=KErrNotSupported;
+	return r;
+	}
+
+void Inactive()
+//
+// Window has been minimised.
+//
+    {
+
+	TRawEvent v;
+	v.Set(TRawEvent::EInactive);
+    TheEventQ.Add(v);
+    }
+
+void UpdateModifiers()
+//Updates the modifier key states and sends an event to wserv about the 
+//change in state
+	{
+	TRawEvent v;
+	TInt modifiers=0;
+    if(GetKeyState(VK_SCROLL)&1)
+        modifiers|=EModifierScrollLock;
+    if(GetKeyState(VK_NUMLOCK)&1)
+        modifiers|=EModifierNumLock;
+    if(GetKeyState(VK_CAPITAL)&1)
+        modifiers|=EModifierCapsLock;
+    v.Set(TRawEvent::EUpdateModifiers,modifiers);
+    TheEventQ.Add(v);
+	}
+	
+void Active()
+//
+// Window has been restored.
+// Update the toggling modifiers, reset any others
+//
+    {
+	TRawEvent v;
+    UpdateModifiers();
+    v.Set(TRawEvent::EActive);
+    TheEventQ.Add(v);
+    }
+
+
+void ClearScreen()
+    {
+
+    }
+
+
+TInt DWinsUi::GetVirtualKey(TEmulCommand& aCommand, TInt aX, TInt aY)
+	{
+	//if the point is in the list of shapes, set the key and return true
+	for (TInt keyCount = iVirtualKeys.Count(); --keyCount >= 0; )
+		{
+		const VirtualKey& vk = *iVirtualKeys[keyCount];
+		if (vk.Contains(aX, aY))
+			{
+			aCommand = vk.Command();
+			return vk.Value();
+			}
+		}
+	return -1;
+	}
+
+void DWinsUi::TranslateMouseCoords(const TEmulatorFlip aFlipState, const TInt aX, const TInt aY, const TInt aRegionWidth, const TInt aRegionHeight, TInt& aNewX, TInt& aNewY)
+	{
+	switch (aFlipState)
+		{
+		case EEmulatorFlipRestore:
+			aNewX = aX;
+			aNewY = aY;
+			break;
+		
+		case EEmulatorFlipInvert:
+			aNewX = aRegionWidth - aX;
+			aNewY = aRegionHeight - aY;
+			break;
+		
+		case EEmulatorFlipLeft:
+			aNewX = aRegionWidth - aY;
+			aNewY = aX;
+			break;
+
+		case EEmulatorFlipRight:
+			aNewX = aY;
+			aNewY = aRegionHeight - aX;
+			break;
+		}
+	}
+
+
+TBool DWinsUi::OnScreen(TInt aScreen, TInt ax, TInt ay) const
+//
+// Checks if a point within the Emulator window is on the screen
+//
+	{
+	return (TUint(ax) < TUint(systemIni->iScreens[aScreen]->iScreenWidth) && TUint(ay) < TUint(systemIni->iScreens[aScreen]->iScreenHeight));
+	}
+
+TInt DWinsUi::Create(TInt aId)
+	{
+	TInt r = SetupProperties(aId);
+	if (r != KErrNone)
+		return r;
+	TInt screen;
+	DScreenProperties* currentScreen = NULL;
+	for(screen=0;screen<iScreens.Count();screen++)
+		{
+		BITMAPINFOHEADER bitmapinfo;
+		currentScreen = iScreens[screen];
+		if (readBitmapInfo(&bitmapinfo, currentScreen->iFasciaFileName) == KErrNone)
+			{
+			currentScreen->iXYInputWidth=bitmapinfo.biWidth;
+			currentScreen->iXYInputHeight=bitmapinfo.biHeight;
+			}
+		currentScreen->iXYInputWidth=max(currentScreen->iXYInputWidth,currentScreen->iScreenWidth+currentScreen->iScreenOffsetX);
+		currentScreen->iXYInputHeight=max(currentScreen->iXYInputHeight,currentScreen->iScreenHeight+currentScreen->iScreenOffsetY);
+		}
+
+	currentScreen = iScreens[0];
+	//note digitizer offsets are relative to EPOC screen 0
+	if (-1 == iDigitizerWidth)
+		iDigitizerWidth = currentScreen->iXYInputWidth - 
+			(currentScreen->iScreenOffsetX + iDigitizerOffsetX);
+	else
+		currentScreen->iXYInputWidth=max(currentScreen->iXYInputWidth,iDigitizerWidth);
+
+	if (-1 == iDigitizerHeight)
+		iDigitizerHeight = currentScreen->iXYInputHeight - 
+			(currentScreen->iScreenOffsetY + iDigitizerOffsetY);
+	else
+		currentScreen->iXYInputHeight=max(currentScreen->iXYInputHeight,iDigitizerHeight);
+
+	return r;
+	}
+
+const RDisplayChannel::TPixelFormat DMasterIni::iSupportedPixelFormatTable[] =
+	{
+		EUidPixelFormatXRGB_8888,
+		EUidPixelFormatARGB_8888,
+		EUidPixelFormatARGB_8888_PRE,
+		EUidPixelFormatXRGB_4444,
+		EUidPixelFormatARGB_4444,
+		EUidPixelFormatRGB_565 
+	};
+
+const TInt DMasterIni::iSupportedPixelFormatTableSize = static_cast<TInt>(sizeof(iSupportedPixelFormatTable)/
+		                                                                  sizeof(iSupportedPixelFormatTable[0]));
+
+void DMasterIni::InitBufferFormat(DScreenProperties& aScreenProperties, RDisplayChannel::TBufferFormat& aBufferFormat)
+	{
+	TUint bitsPerPixel = MaximumBitDepthFromMask(aScreenProperties.iColorDepth);
+	
+	aBufferFormat.iSize.iWidth = aScreenProperties.iMaxScreenWidth;
+	aBufferFormat.iSize.iHeight = aScreenProperties.iMaxScreenHeight;
+	switch (bitsPerPixel)
+		{
+	case 12:	// XRGB4444
+		aBufferFormat.iPixelFormat = EUidPixelFormatXRGB_4444;
+		break;
+	case 16:	// RGB565
+		aBufferFormat.iPixelFormat = EUidPixelFormatRGB_565;
+			break;
+	case 24:	// Really 32bpp, but top 8 unused
+	case 32:	// While 32bpp, top 8 will not be used
+	default:
+		aBufferFormat.iPixelFormat = EUidPixelFormatXRGB_8888;
+			break;
+		}
+	}
+
+TInt DMasterIni::Create()
+	{
+	TInt configurations = Property::GetInt("ConfigCount", 0);
+	if (configurations == 0)
+		return KErrGeneral;
+
+	// the pixel formats table is, at present, configuration independent
+	TInt count;
+	TInt r = KErrNone;
+	for (count = 0; count < configurations && r == KErrNone; ++count)
+		{
+		DWinsUi* dwi = new DWinsUi;
+		if (dwi)
+			r = dwi->Create(count);
+
+		if (r == KErrNone)
+			iSystemInis.Append(dwi);
+		}
+	if (r != KErrNone)
+		return r;
+
+	systemIni = masterIni->iSystemInis[0];
+
+	WinsGuiPowerHandler = DWinsGuiPowerHandler::New();
+	if (!WinsGuiPowerHandler)
 		return KErrNoMemory;
-	return iVirtualKeys.Append(pRect);
-
-	}
-
-
-TInt DWinsUi::DoDefineVirtualKey(TAny* aPtr, const char* aValue)
-	{
-	return static_cast<DWinsUi*>(aPtr)->DefineVirtualKey(aValue);
-	}
-
-TInt DWinsUi::DefineVirtualKey(const char* aValue)
-	{
-	// Get the key to map
-	const char* beg = skipws(aValue);
-	const char* end = skiptok(beg);
-	TInt key = iKeyboard.GetEPOCKeyCode(TPtrC8((const TUint8*)beg, end-beg));
-	if (key == KErrNotFound)
-		return key;
-
-	//get the shape
-	beg = skipws(end);
-	end = skiptok(beg);
-	if (end - beg != 4 || _strnicmp(beg, "rect", 4) != 0)
-		return KErrArgument;
-		
-	// get the parameters
-	beg = skipws(end);
-	char* end2;
-	TInt x = strtol(beg, &end2, 10);
-	if (beg == end2 || *end2++ != ',')
-		return KErrArgument;
-	beg = end2;
-	TInt y = strtol(beg, &end2, 10);
-	if (beg == end2)
-		return KErrArgument;
-	beg = skipws(end2);
-	TInt w = strtol(beg, &end2, 10);
-	if (beg == end2 || *end2++ != ',')
-		return KErrArgument;
-	beg = end2;
-	TInt h = strtol(beg, &end2, 10);
-	if (beg == end2)
-		return KErrArgument;
-	
-	VKRect* pRect = new VKRect(key, EKey, x, y, w, h);
-	if (!pRect)
-		return KErrNoMemory;
-	return iVirtualKeys.Append(pRect);
-	}
-
-
-LOCAL_C TInt readBitmapInfo(PBITMAPINFOHEADER aHeader, const char* aFileName)
-	{
-	PBITMAPFILEHEADER pbmfh=NULL;
-	PBITMAPINFOHEADER pbmih=NULL;
-	TInt bfOffBits;
-
-	HANDLE fh=CreateFileA(aFileName,GENERIC_READ,NULL,NULL,OPEN_EXISTING,NULL,NULL);
-	if (!fh || fh==INVALID_HANDLE_VALUE)
-		return KErrNotFound;
-
-	TInt r=KErrNone;
-
-	// read in the bitmap file header.  save the offset to bits.
-	pbmfh = (PBITMAPFILEHEADER)LocalAlloc(LPTR, sizeof(BITMAPFILEHEADER));
-	if (pbmfh==NULL)
-		{
-		r=KErrNotFound;
-        goto exit;
-		}
-	DWORD bytesRead;
-	ReadFile(fh, (LPVOID)pbmfh, sizeof(BITMAPFILEHEADER), &bytesRead, NULL);
-	bfOffBits=pbmfh->bfOffBits;
-
-	// read in the bitmap info header and the color table right after it.
-	pbmih = (PBITMAPINFOHEADER)LocalAlloc(LPTR, bfOffBits- sizeof(BITMAPFILEHEADER));
-	if (pbmih==NULL)
-		{
-		r=KErrNotFound;
-        goto exit;
-		}
-	ReadFile(fh, (LPVOID)pbmih, bfOffBits-sizeof(BITMAPFILEHEADER),&bytesRead,NULL);
-	*aHeader=*pbmih;
-exit:
-	LocalFree(LocalHandle ((LPSTR)pbmih));
-	LocalFree(LocalHandle ((LPSTR)pbmfh));
-	CloseHandle(fh);
-	return r;
-	}
-
-HBITMAP readBitmap(HDC aHdc, const char* aFileName)
-//
-// reads a BMP file from disk and returns a HBITMAP
-//
-	{
-	HBITMAP hbm=NULL;
-	PBITMAPFILEHEADER pbmfh=NULL;
-	PBITMAPINFOHEADER pbmih=NULL;
-	TUint8 *pBits=NULL;
-	TInt bfOffBits;
-	TInt nbytes;
-
-	HANDLE fh=CreateFileA(aFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, NULL, NULL);
-	if (!fh || fh==INVALID_HANDLE_VALUE)
-		return NULL;
-
-	nbytes=GetFileSize((HANDLE)fh, NULL);
-	// read in the bitmap file header.  save the offset to bits.
-	pbmfh = (PBITMAPFILEHEADER)LocalAlloc(LPTR, sizeof(BITMAPFILEHEADER));
-	if (pbmfh==NULL)
-        goto exit;
-	DWORD bytesRead;
-	ReadFile(fh, (LPVOID)pbmfh, sizeof(BITMAPFILEHEADER),&bytesRead,NULL);
-	bfOffBits=pbmfh->bfOffBits;
-
-	// read in the bitmap info header and the color table right after it.
-	pbmih = (PBITMAPINFOHEADER)LocalAlloc(LPTR, bfOffBits- sizeof(BITMAPFILEHEADER));
-	if (pbmih==NULL)
-        goto exit;
-	ReadFile(fh, (LPVOID)pbmih, bfOffBits-sizeof(BITMAPFILEHEADER),&bytesRead,NULL);
-
-	// finally read in the bit data.
-	pBits = (PBYTE)LocalAlloc (LPTR, (nbytes - bfOffBits));
-	if (pBits==NULL)
-        goto exit;
-	ReadFile(fh, (LPVOID)pBits, nbytes-bfOffBits,&bytesRead,NULL);
-		
-	hbm=CreateDIBitmap(aHdc, pbmih, CBM_INIT, pBits,(PBITMAPINFO) pbmih, DIB_RGB_COLORS);
-exit:
-	LocalFree(LocalHandle ((LPSTR)pBits));
-	LocalFree(LocalHandle ((LPSTR)pbmih));
-	LocalFree(LocalHandle ((LPSTR)pbmfh));
-	CloseHandle(fh);
-	return hbm;
-	}
-
-void LoadFasciaBitmap(TInt aScreen)
-	{
-	HDC hdc=GetDC(TheWin[aScreen]);
-	RECT windowRect = {0};
-	windowRect.right=systemIni->iScreens[aScreen]->iXYInputWidth;
-	windowRect.bottom=systemIni->iScreens[aScreen]->iXYInputHeight;
-	HBITMAP screenBitmap=readBitmap(hdc, systemIni->iScreens[aScreen]->iFasciaFileName);
-	if (screenBitmap==NULL)
-		{
-		screenBitmap=CreateCompatibleBitmap(hdc, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top);
-		HDC hdcMem=CreateCompatibleDC(hdc);
-		SelectObject(hdcMem, screenBitmap);
-		PatBlt(hdcMem, 0, 0, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, BLACKNESS);
-		DeleteDC(hdcMem);
-		}
-	__ASSERT_ALWAYS(screenBitmap!=NULL,Fault(EGuiCreateBitmap));
-	TheScreenBitmap[aScreen]=screenBitmap;
-
-	DrawLeds();
-
-	ReleaseDC(TheWin[aScreen], hdc);
-	}
-TBool DWinsUi::MultiTouchEnabled() const
-	{
-	return iMultiTouchEnabled;
-	}
-
-TBool DWinsUi::GCEEnabled() const
-	{
-	return iGCEEnabled;
-	}
-
-TInt DWinsUi::MultiTouchProximityStep() const
-	{
-	return iMultiTouchProximityStep;
-	}
-
-TInt DWinsUi::MultiTouchPressureStep() const
-	{
-	return iMultiTouchPressureStep;
-	}
-
-TBool DWinsUi::OnDigitizer(TInt aX, TInt aY) const
-	{
-	if (!iDigitizerEnabled)
-		return EFalse;
-	switch(CurrentFlipState[0])
-		{
-		case EEmulatorFlipRestore:
-			{
-			aX -= iDigitizerOffsetX;
-			aY -= iDigitizerOffsetY;
-			break;
-			}
-		case EEmulatorFlipInvert:
-			{
-			aX -= systemIni->iScreens[0]->iScreenWidth - iDigitizerOffsetX - iDigitizerWidth;
-			aY -= systemIni->iScreens[0]->iScreenHeight - iDigitizerOffsetY - iDigitizerHeight;
-			break;
-			}
-		case EEmulatorFlipRight:
-			{
-			TInt oldY = aY;
-			aY = aX - (systemIni->iScreens[0]->iScreenHeight - iDigitizerOffsetY - iDigitizerHeight);
-			aX = oldY - iDigitizerOffsetX;
-			break;
-			}
-		case EEmulatorFlipLeft:
-			{
-			TInt oldY = aY;
-			aY = aX - iDigitizerOffsetY;
-			aX = oldY - (systemIni->iScreens[0]->iScreenWidth - iDigitizerOffsetX - iDigitizerWidth);
-			break;
-			}
-		}
-	return (TUint(aX) < TUint(iDigitizerWidth) && TUint(aY) < TUint(iDigitizerHeight));
-	}
-
-LOCAL_C void addMouseEvent(TRawEvent::TType aType,TInt aXpos,TInt aYpos)
-//
-// Add a mouse event.
-//
-	{
-	if (systemIni->OnDigitizer(aXpos, aYpos))
-		{
-		TRawEvent v;
-		v.Set(aType,aXpos,aYpos);
-		TheEventQ.Add(v);
-		}
-	}
-
-LOCAL_C void addMouseEvent(TRawEvent::TType aType,TInt aXpos,TInt aYpos,TInt aZpos, TInt aPointerId=0)
-//
-// Add a multitouch mouse event.
-//
-	{
-	if (systemIni->OnDigitizer(aXpos, aYpos))
-		{
-		TRawEvent v;
-		v.Set(aType,aXpos,aYpos, aZpos);
-		v.SetPointerNumber(static_cast<const TUint8>(aPointerId));
-		TheEventQ.Add(v);
-		}
-	}
-LOCAL_C void addKeyEvent(TRawEvent::TType aType,TInt aKey)
-	{
-	TRawEvent v;
-	v.Set(aType, aKey);
-	TheEventQ.Add(v);
-	}
-
-
-LOCAL_C void SwitchConfiguration(TInt aData, TBool aSendFlipKey = ETrue)
-	{
-	if (aData < 0 || aData >= masterIni->iSystemInis.Count())
-		return;
-
-	CurrentConfiguration = aData;
-	systemIni = masterIni->iSystemInis[aData];
-	
-	//get the correct fascia bitmaps
-	TInt screens=systemIni->iScreens.Count();
-	TInt i;
-	TUint disabledWinType=ENormalResolution;
-	for(i=0;i<screens;i++)
-		{
-		DeleteObject(TheScreenBitmap[i]);
-		LoadFasciaBitmap(i);
-		if (masterIni->iBufferSet[i].iDisplayState!=ENormalResolution)
-			{
-			disabledWinType=masterIni->iBufferSet[i].iDisplayState;
-			}
-		}
-	
-	//update the window title
-	if (disabledWinType!=ENormalResolution && disabledWinType < 4)	//hardwired 4 because the code below is hardwired
-		{	//string may be multi-part indexed by disable type, or it may not
-		CHAR* firstsemi=strchr(systemIni->iWindowTitle,';');
-		CHAR* secondsemi=NULL;
-		if (firstsemi)
-			{
-			secondsemi=strchr(firstsemi+1,';');
-			}
-		if (firstsemi&&secondsemi)
-			{
-			*firstsemi='\0';
-			*secondsemi='\0';
-			char* ptr[4]={0,systemIni->iWindowTitle,firstsemi+1,secondsemi+1};
-			SetWindowTextA(TheControlWin, ptr[disabledWinType]);
-			*firstsemi=';';
-			*secondsemi=';';
-			}
-		else
-			{
-			SetWindowTextA(TheControlWin, systemIni->iWindowTitle);
-			}
-		
-		}
-	else
-		{
-		SetWindowTextA(TheControlWin, systemIni->iWindowTitle);
-		}
-	//resize and repaint the current window anyway.
-	//the text window server doesn't respond to orientation messages
-	for(i=0;i<screens;i++)
-		{
-		InvalidateRect(TheWin[i], NULL, false);
-		SendMessage(TheWin[i], WM_FLIP_MESSAGE, systemIni->iScreens[i]->iScreenRotation,0);
-		}
-
-	//pass on the orientation key to the windows server
-	if (aSendFlipKey)
-		{
-		if (!WinsGuiPowerHandler->iStandby)
-			{
-			addKeyEvent(TRawEvent::EKeyDown, systemIni->iInitialFlipMsg);
-			addKeyEvent(TRawEvent::EKeyUp, systemIni->iInitialFlipMsg);
-			}
-		else
-			{
-			//remember the flip message so we can send it to the window server when we come out of standby
-			SavedFlipMessage = systemIni->iInitialFlipMsg;
-			}
-		}
-	}
-/**
-Sets the specified screen to the given width and height, if available.
-
-The configurations are searched to find a match, taking the display state into
-account. If no configuration is available, the request is ignored.
-
-@param aScreenNumber	the screen index
-@param aWidth 			the desired width
-@param aHeight			the desired height
-**/
-void DMasterIni::SetDisplaySize(TInt aDisplayNumber, TInt aWidth, TInt aHeight)
-	{
-	TInt displayCount = iBufferSet.Count();
-
-	if (aDisplayNumber < 0 || aDisplayNumber >= displayCount)
-		{
-		// Invalid screen number, discard.
-		return;
-		}
-
-	if (iBufferSet[aDisplayNumber].iDisplayState != ENormalResolution)
-		{
-		// No (non-zero) resolutions available, discard.
-		return;
-		}
-
-	TInt count = iSystemInis.Count();
-	TInt index;
-	for (index = 0; index < count; index++)
-		{
-		DWinsUi* newIni = masterIni->iSystemInis[index];
-		DScreenProperties* newProps = newIni->iScreens[aDisplayNumber];
-
-		if (newProps->iScreenWidth == aWidth && newProps->iScreenHeight == aHeight)
-			{
-			// Found a potential match. Check other screens match their current size.
-			if (newIni == systemIni)
-				{
-				// Current configuration, already in use. Nothing to do.
-				break;
-				}
-			
-			TInt display;
-			for (display = 0; display < displayCount; display++)
-				{
-				if (display == aDisplayNumber)
-					{
-					// No need to check the display we are changing
-					continue;
-					}
-
-				DScreenProperties* currentPropsN = systemIni->iScreens[display];
-				DScreenProperties* newPropsN = newIni->iScreens[display];
-				
-				if (newPropsN->iScreenWidth != currentPropsN->iScreenWidth ||
-						newPropsN->iScreenHeight != currentPropsN->iScreenHeight)
-					{
-					// Resolution mismatch, try next configuration.
-					break;
-					}
-				}
-			
-			if (display == displayCount)
-				{
-				// Match found, switch to this configuration and stop. Force
-				// rotation to the same as the current rotation.
-				newProps->iScreenRotation = systemIni->iScreens[aDisplayNumber]->iScreenRotation;
-				SwitchConfiguration(index);
-				break;
-				}
-			}
-		}
-	}
-
-
-void DMasterIni::SetBufferFormat(TInt aDisplayNumber, TUint aAggregateSize, RDisplayChannel::TPixelFormat aPixelFormat)
-	{
-	TInt displayCount = iBufferSet.Count();
-
-	if (aDisplayNumber < 0 || aDisplayNumber >= displayCount)
-		{
-		// Invalid screen number, discard.
-		return;
-		}
-	
-	LPBITMAPV4HEADER info = &iBufferSet[aDisplayNumber].iInfo;
-	
-	// update the bitmap header taking in consideration the new pixel format
-	switch (aPixelFormat)
-		{
-		case EUidPixelFormatXRGB_4444:
-		case EUidPixelFormatARGB_4444:
-			info->bV4BitCount=16;
-			info->bV4V4Compression = BI_BITFIELDS;
-			info->bV4RedMask   = 0x0F00;
-			info->bV4GreenMask = 0x00F0;
-			info->bV4BlueMask  = 0x000F;
-			break;
-		case EUidPixelFormatRGB_565:
-			info->bV4BitCount=16;
-			info->bV4V4Compression = BI_BITFIELDS;
-			info->bV4RedMask   = 0xF800;
-			info->bV4GreenMask = 0x07E0;
-			info->bV4BlueMask  = 0x001F;
-			break;
-		case EUidPixelFormatXRGB_8888:	// Really 32bpp, but top 8 unused
-		case EUidPixelFormatARGB_8888:
-		case EUidPixelFormatARGB_8888_PRE:
-			info->bV4BitCount=32;
-			info->bV4V4Compression = BI_RGB;
-			// Mask is implicit for BI_RGB compression
-			break;
-		default:
-			// We got an error, it seems. Let's ignore the message
-			return;
-		}
-	iBufferSet[aDisplayNumber].iBufferFormat.iPixelFormat = aPixelFormat;
-	
-	// taking advantage of limiting the width and size to KMaxTInt16
-	TInt width = aAggregateSize & 0x0000ffff;
-	TInt height = (aAggregateSize >> 16) & 0x0000ffff;
-
-	// let's deal with the new size just received
-	iBufferSet[aDisplayNumber].iBufferFormat.iSize.iWidth = width;
-	iBufferSet[aDisplayNumber].iBufferFormat.iSize.iHeight = height;
-	
-	// update the bitmap header, taking in consideration the rotation
-	switch (CurrentFlipState[aDisplayNumber])
-		{
-		case EEmulatorFlipRestore:
-		case EEmulatorFlipInvert:
-			info->bV4Width = width;
-			info->bV4Height = -height;
-			break;
-		case EEmulatorFlipLeft:
-		case EEmulatorFlipRight:
-			info->bV4Width = height;
-			info->bV4Height = -width;
-			break;
-		}
-	// finally, update the image size
-	SetImageSize(aDisplayNumber);
-	}
-
-void DMasterIni::SetImageSize(TInt aScreenNumber)
-	{
-	TInt displayCount = iBufferSet.Count();
-
-	if (aScreenNumber >= 0 && aScreenNumber < displayCount)
-		{
-		LPBITMAPV4HEADER info = &iBufferSet[aScreenNumber].iInfo;
-		TInt bpp = _ALIGN_UP(info->bV4BitCount, 16); //12 & 16 --> 16 ; 24 & 32 --> 32
-		TInt widthInBpp = info->bV4Width * bpp;
-		//rounding to 32 bits (4 octets) and converting, then, bits to octets;
-		TInt scanLineInBytes = _ALIGN_UP(widthInBpp, 32) >> 3;
-		// info->bV4Height is negative or zero
-		info->bV4SizeImage = -info->bV4Height * scanLineInBytes;
-		}
-	}
-
-LOCAL_C void NextConfiguration()
-	{
-	TInt config = CurrentConfiguration;
-	if (++config == masterIni->iSystemInis.Count())
-		config = 0;
-	SwitchConfiguration(config);
-	}
-
-
-
-LOCAL_C TBool ProcessedByEmulatorKey(TInt aScanCode, HWND hWnd,TUint message,TUint wParam,TUint lParam)
-	{
-
-	TBool rVal = EFalse;
-	rVal = ETrue;
-	for (TInt i=0;i<systemIni->iControlHotKeys.Count();i++)//check key combinations
-		{
-		if (systemIni->iControlHotKeys[i]->CheckCombinationPressed()) 
-			{				
-			switch (systemIni->iControlHotKeys[i]->iCommand)
-				{
-				
-				case ENextConfig:
-					NextConfiguration();
-					break;
-		
-				case ESelectConfig:
-					SwitchConfiguration(systemIni->iControlHotKeys[i]->iData);
-					break;
-							
-				}
-			return ETrue;
-			}
-		}
-	switch (aScanCode)
-	{
-	
-	case EStdKeyF4:
-		{
-		// Simulate a change of media card
-		TInt irq = NKern::DisableAllInterrupts();
-		if (*Wins::MediaDoorOpenPtr())
-			{
-			*Wins::CurrentPBusDevicePtr() += 1;
-			if (*Wins::CurrentPBusDevicePtr() == 2)
-				{
-				*Wins::CurrentPBusDevicePtr() = -1;
-				}
-			}
-		NKern::RestoreInterrupts(irq);
-		
-		// pass on to the windows system so that if
-		// Alt-F4 is pressed the window will close
-		if (hWnd)
-			DefWindowProcA(hWnd,message,wParam,lParam);
-		break;
-		}
-
-	default:
-		rVal = EFalse;
-		break;
-	}
-	return rVal;
-	}
-
-LOCAL_C void MultiChildWndPointer(TUint aMessage,TInt aXpos,TInt aYpos, TInt aZ, TInt aPointerId)
-//
-// Handle a multi-touch pointer event in the Symbian OS screen window 
-//
-	{
-	TRawEvent::TType eventType=TRawEvent::ENone;
-	CHAR buf[50];
-	
-	if (aZ <= TheMultiTouch->iZMaxRange) //negative
-		{
-		eventType = TRawEvent::EPointer3DOutOfRange;
-		wsprintf((LPTSTR)buf, (LPCTSTR)TEXT("Out Of Range"));
-		SendMessage(hwndStatus, SB_SETTEXT, aPointerId , (LPARAM)(buf));					
-		}
-	else 
-		{
-		wsprintf((LPTSTR)buf, (LPCTSTR)TEXT("%d: %d,%d,%d"), aPointerId, aXpos,aYpos,aZ);
-		SendMessage(hwndStatus, SB_SETTEXT, aPointerId , (LPARAM)(buf));					
-		switch (aMessage)
-	    	{
-			case WM_MOUSEMOVE:
-				{
-				eventType=TRawEvent::EPointerMove;
-				break;
-				}
-			case WM_LBUTTONDOWN:
-				{
-				SetCapture(TheChildWin[0]);
-				eventType = TRawEvent::EButton1Down;
-				}
-				break;
-			case WM_LBUTTONUP:
-				{
-				ReleaseCapture();
-				eventType = TRawEvent::EButton1Up;
-				break;
-				}
-			case WM_RBUTTONDOWN:
-				{
-				eventType = TRawEvent::EButton3Down;
-				break;
-				}
-			case WM_RBUTTONUP:
-				{
-				eventType = TRawEvent::EButton3Up;
-				break;
-				}
-			case WM_MOUSEWHEEL:
-				{
-				eventType = TRawEvent::EPointerMove;
-				break;
-				}
-			default:
-				return;
-			}
-		}
-
-	if (!WinsGuiPowerHandler->iStandby)
-		{
-		addMouseEvent(eventType, aXpos, aYpos, aZ, aPointerId);
-		}
-	}
-
-LOCAL_C void ChildWndPointer(TUint message,TInt aXpos,TInt aYpos)
-//
-// Handle a pointer event in the Symbian OS screen window
-//
-	{
-	// Enable the multitouch if the cursor is inside the main client window
-	if (DMultiTouch::iMultiTouchCreated)
-		{
-		RECT client;
-		WINDOWINFO info;
-		GetWindowInfo(TheChildWin[0], &info);
-		POINT pt = {aXpos+(TInt)info.rcClient.left, aYpos+(TInt)info.rcClient.top};
-		if (GetWindowRect(TheChildWin[0], &client) &&
-				(PtInRect(&client,pt)!=NULL) && !DMultiTouch::iMultiTouchTempEnabled)	// within the window
-			{
-			if (systemIni->MultiTouchEnabled() && systemIni->GCEEnabled())
-				{
-				if(TheMultiTouch->Register())	// Register successfully
-					{
-					DMultiTouch::iMultiTouchTempEnabled = TRUE;
-					//Show the status bars at the bottom of the emulator
-					SetWindowPos(hwndStatus,0,0,0,0,0,SWP_SHOWWINDOW);
-					SetFocus(TheWin[0]);
-					SetCursor(LoadCursorA(NULL,MAKEINTRESOURCEA(32512)));
-					}
-				}
-			}
-		}
-	TRawEvent::TType eventType=TRawEvent::ENone;
-	switch (message)
-    	{
-	case WM_MOUSEMOVE:
-		eventType=TRawEvent::EPointerMove;
-		break;
-	case WM_LBUTTONDOWN:
-		{
-		SetCapture(TheChildWin[0]);
-		eventType=TRawEvent::EButton1Down;
-		}
-		break;
-	case WM_LBUTTONUP:
-		ReleaseCapture();
-		eventType=TRawEvent::EButton1Up;
-		break;
-	case WM_RBUTTONDOWN:
-		eventType=TRawEvent::EButton3Down;
-		break;
-	case WM_RBUTTONUP:
-		eventType=TRawEvent::EButton3Up;
-		break;
-	case WM_MBUTTONDOWN:
-		eventType=TRawEvent::EButton2Down;
-		break;
-	case WM_MBUTTONUP:
-		eventType=TRawEvent::EButton2Up;
-		break;
-		}
-	if (!WinsGuiPowerHandler->iStandby)
-		{
-		addMouseEvent(eventType, aXpos, aYpos);
-		}
-	}
-
-LOCAL_C void FrameWndPointer(TUint message,TInt aXpos,TInt aYpos, TInt aScreenNumber, TInt aPointerId = 0)
-//
-// Handle a frame wnd pointer event.
-//
-	{
-	static bool	processingScreenOn=FALSE;
-	TEmulCommand command = ENoCommand;
-	TInt commandData = 0;
-	TBool mouseEvent = ETrue;
-	
-	TRawEvent::TType eventType=TRawEvent::ENone;
-	
-	TViewport& viewport = systemIni->iScreens[aScreenNumber]->iViewport;
-	aXpos += viewport.GetViewportOffsetX(); // make mouse-coords relative to fascia edge even if window is scrolled
-	aYpos += viewport.GetViewportOffsetY();
-	
-	switch (message)
-    	{
-	case WM_MOUSEMOVE:
-		{
-		TInt newX, newY;
-		systemIni->TranslateMouseCoords(CurrentFlipState[0], aXpos, aYpos, systemIni->iScreens[0]->iXYInputWidth, systemIni->iScreens[0]->iXYInputHeight, newX, newY);
-
-		if (aPointerId == 0)
-			{ // only system pointer changes shape
-		if (systemIni->GetVirtualKey(command, newX, newY) >= 0)
-			{
-			HMODULE hmodule = GetModuleHandleA("winsgui.dll");
-			SetCursor(LoadCursorA((HINSTANCE)hmodule,MAKEINTRESOURCEA(OVERKEY)));		//hand cursor
-			}
-		else
-			SetCursor(LoadCursorA(NULL,MAKEINTRESOURCEA(32512))); //ICD_ARROW
-				}
-
-		eventType=TRawEvent::EPointerMove;
-		
-		}
-		break;
-	case WM_LBUTTONDOWN:
-		{
-		SetCapture(TheWin[0]);
-		//check the configuration
-		TInt newX, newY;
-		
-		//if the emulator screen is rotated, rotate/flip the current mouse cursor position
-		//so it can be checked to see if it is in a key region.
-		systemIni->TranslateMouseCoords(CurrentFlipState[0], aXpos, aYpos, systemIni->iScreens[0]->iXYInputWidth, systemIni->iScreens[0]->iXYInputHeight, newX, newY);
-		commandData = systemIni->GetVirtualKey(command, newX, newY);
-		
-		if (commandData >= 0)
-			{
-			eventType=TRawEvent::EKeyDown;
-			mouseEvent = EFalse;
-			systemIni->SetVirtualKey(ETrue, commandData, command);
-			}
-		else
-			eventType=TRawEvent::EButton1Down;
-		}
-		break;
-	case WM_LBUTTONUP:
-		ReleaseCapture();
-		if (processingScreenOn)
-			{
-			// ignore button up - button down was switching things on
-			processingScreenOn=FALSE;
-			return;
-			}
-		if (systemIni->WasVirtualKey(commandData, command))
-			{
-			eventType=TRawEvent::EKeyUp;
-			mouseEvent = EFalse;
-			systemIni->SetVirtualKey(EFalse, EStdKeyNull, ENoCommand);
-			}
-		else
-			eventType=TRawEvent::EButton1Up;
-		break;
-	case WM_RBUTTONDOWN:
-		eventType=TRawEvent::EButton3Down;
-		break;
-	case WM_RBUTTONUP:
-		eventType=TRawEvent::EButton3Up;
-		break;
-	case WM_MBUTTONDOWN:
-		eventType=TRawEvent::EButton2Down;
-		break;
-	case WM_MBUTTONUP:
-		eventType=TRawEvent::EButton2Up;
-		break;
-		}
-	if (mouseEvent)
-		{
 		
-		if (!WinsGuiPowerHandler->iStandby)
-			{
-			/*
-			mouse events are relative to the child window position
-			and are clipped to the digitzer region in addMouseEvent
-			so all the mouse clicks are passed on here after being translated 
-			to the child window coordinate system (under the current rotation)
-			*/
-			TInt newX, newY;
-			switch (CurrentFlipState[0])
-				{
-				case EEmulatorFlipRestore:
-				default:
-					newX = aXpos - systemIni->iScreens[0]->iScreenOffsetX;
-					newY = aYpos - systemIni->iScreens[0]->iScreenOffsetY;
-					break;
-				case EEmulatorFlipInvert:
-					newX = aXpos - (systemIni->iScreens[0]->iXYInputWidth - systemIni->iScreens[0]->iScreenWidth - systemIni->iScreens[0]->iScreenOffsetX);
-					newY = aYpos - (systemIni->iScreens[0]->iXYInputHeight - systemIni->iScreens[0]->iScreenHeight - systemIni->iScreens[0]->iScreenOffsetY);
-					break;
-				case EEmulatorFlipLeft:
-					newX = aXpos - systemIni->iScreens[0]->iScreenOffsetY;
-					newY = aYpos - (systemIni->iScreens[0]->iXYInputWidth - systemIni->iScreens[0]->iScreenWidth - systemIni->iScreens[0]->iScreenOffsetX);
-					break;	
-				case EEmulatorFlipRight:
-					newX = aXpos - (systemIni->iScreens[0]->iXYInputHeight - systemIni->iScreens[0]->iScreenHeight - systemIni->iScreens[0]->iScreenOffsetY);
-					newY = aYpos - systemIni->iScreens[0]->iScreenOffsetX;
-					break;
-				}
-			addMouseEvent(eventType, newX, newY);
-			}
-		}
-	else if ((((message == WM_LBUTTONDOWN && command == EKey) && !ProcessedByEmulatorKey((TUint8)commandData,0,0,0,0)))
-			|| (message == WM_LBUTTONUP))
-		{
-			switch (command)
-			{
-			case EKey:
-				if (!WinsGuiPowerHandler->iStandby)
-					addKeyEvent(eventType, (TUint8)commandData);
-				break;
-
-			case ENextConfig:
-				NextConfiguration();
-				break;
-			
-			case ESelectConfig:
-				SwitchConfiguration(commandData);
-				break;
-			}
-		}
-	}
-
-LOCAL_C TInt ScreenFromHWND(HWND aHwnd,HWND* pWin)
-	{
-	TInt screens=systemIni->iScreens.Count();
-	TInt r=-1;
-	for(TInt i=0;i<screens;i++)
-		{
-		if(pWin[i]==aHwnd)
-			{
-			r=i;
-			break;
-			}
-		}
-	return r;
-	}
-void MultiTouchWndPointer(TUint message,TInt aXpos,TInt aYpos, TInt aZ, TInt aPointerId)
-	{
-	WINDOWINFO info;
-	info.cbSize = sizeof(WINDOWINFO);
-	if (GetWindowInfo(TheWin[0], &info))
-		{
-		POINT pt = {aXpos,aYpos};
-		if (PtInRect(&info.rcWindow,pt))
-			{
-			RECT client;
-			if (GetWindowRect(TheChildWin[0], &client) && PtInRect(&client,pt))	// within the window
-				{
-				MultiChildWndPointer(message, aXpos-client.left, aYpos-client.top, aZ, aPointerId);
-				}
-			else  
-				{		
-				//	Disable the multitouch if the cursor is outside the application window
-				if (DMultiTouch::iMultiTouchTempEnabled)	// within the window
-					{
-					DMultiTouch::iMultiTouchTempEnabled = FALSE;
-					if(TheMultiTouch->UnRegister())
-						{
-						SetWindowPos(hwndStatus,0,0,0,0,0,SWP_HIDEWINDOW);
-						}
-					}
-				FrameWndPointer(message, aXpos-info.rcClient.left, aYpos-info.rcClient.top, 0, aPointerId);	
-				}
-			}
-		}
-	}
-
-LOCAL_C DScreenProperties* ScreenPropsFromHWND(HWND aHwnd, HWND* pWin)
-	{
-	TInt screenNumber =  ScreenFromHWND(aHwnd, pWin);
-	
-	if(screenNumber >=0)
-		{
-		return systemIni->iScreens[screenNumber];
-		}
-	return NULL;
-
-	}
-
-
-TInt APIENTRY childWinProc(HWND hWnd,TUint message,TUint wParam,TUint lParam)
-//
-// The child window function.
-//
-	{
-	TInt screenNumber = 0;
-	TRawEvent v;
-    switch (message)
-    	{
-	case WM_FLIP_MESSAGE: // pass the flip message onto the parent window
-		{
-		screenNumber =ScreenFromHWND(hWnd,TheChildWin);
-		if(TUint(screenNumber) < TUint(systemIni->iScreens.Count()))
-			PostMessageA(TheWin[screenNumber],WM_FLIP_MESSAGE,wParam,NULL);
-		break;
-		}
-	case WM_LBUTTONDOWN:
-	case WM_LBUTTONUP:
-	case WM_MOUSEMOVE:
-	case WM_RBUTTONDOWN:
-	case WM_RBUTTONUP:
-	case WM_MBUTTONDOWN:
-	case WM_MBUTTONUP:
-		{
-		if (DMultiTouch::iMultiTouchTempEnabled)
-			{
-			DMultiTouch::iMultiTouchTempEnabled = FALSE;
-			}
-		screenNumber=ScreenFromHWND(hWnd,TheChildWin);
-		if(screenNumber==0)
-			{
-			ChildWndPointer(message,(TInt16)(lParam&0xFFFF),(TInt16)((lParam>>16)&0xFFFF));
-			}
-		break;
-		}
-    case WM_PAINT:
-		if (!PaintWindowFromBuffer(hWnd))
-			{
-			// Original behaviour
-			ValidateRect(hWnd,NULL);
-			v.Set(TRawEvent::ERedraw);
-			TheEventQ.Add(v);
-			}
-        break;
-    case WM_ACTIVATE:
-	case WM_SYSKEYDOWN:
-	case WM_KEYDOWN:
-	case WM_SYSKEYUP:
-	case WM_KEYUP:
-		Fault(EGuiChildWinProc);
-		break;
-    case WM_DESTROY:
-		break;
-
-	case WM_CHAR:
-	case WM_SYSCHAR:
-	case WM_DEADCHAR:
-	case WM_SYSDEADCHAR:
-        break;
-
-	case WMU_SET_DISPLAY_BUFFER:
-		screenNumber = ScreenFromHWND(hWnd, TheChildWin);
-		if (TUint(screenNumber) < TUint(systemIni->iScreens.Count()))
-			{
-			masterIni->iBufferSet[screenNumber].iDisplayBuffer = (LPVOID)lParam;
-			}
-		break;
-	case WMU_SET_DISPLAY_SIZE:
-		screenNumber = ScreenFromHWND(hWnd, TheChildWin);
-		masterIni->SetDisplaySize(screenNumber, wParam, lParam);
-		break;
-		
-	case WMU_SET_BUFFER_FORMAT:
-		screenNumber = ScreenFromHWND(hWnd, TheChildWin);
-		masterIni->SetBufferFormat(screenNumber, wParam, (RDisplayChannel::TPixelFormat) lParam);
-		break;
-		
- 	default:
-        return(DefWindowProcA(hWnd,message,wParam,lParam));
-	    }
-    return(FALSE);
-	}
-
-
-LOCAL_C TBool PaintWindowFromBuffer(HWND hWnd)
-	{
-	TInt screenNumber = ScreenFromHWND(hWnd,TheChildWin);
-	if (TUint(screenNumber) >= TUint(masterIni->iBufferSet.Count()))
-		{
-		return EFalse;
-		}
-
-	LPVOID displayBuffer = masterIni->iBufferSet[screenNumber].iDisplayBuffer;
-	if (!displayBuffer)
-		{
-		return EFalse;
-		}
-
-	TInt   frameOffset = masterIni->iBufferSet[screenNumber].iScreenBuffer.iDisplayBufferOffset;
-	displayBuffer=LPVOID(frameOffset+(char*)displayBuffer);
-
-	PAINTSTRUCT ps;
-	BeginPaint(hWnd, &ps);
-
-	// Paint directly from the buffer to the window
-	LPBITMAPINFO info = (LPBITMAPINFO)&masterIni->iBufferSet[screenNumber].iInfo;
-	WORD width = (WORD)info->bmiHeader.biWidth;
-	WORD height = (WORD)-info->bmiHeader.biHeight;	// stored -ve in info
-	SetDIBitsToDevice(ps.hdc,
-						0, 0, 	// Dst X, Y
-						width, height,	// Src W, H
-						0, 0,	// Src X, Y
-						0,		// Src offset to first line
-						height,	// Src lines available
-						displayBuffer,	// Src pointer to pixels
-						info,			// Src info
-						DIB_RGB_COLORS);
-
-	EndPaint(hWnd, &ps);
-
-	return TRUE;
-	}
-
-
-LOCAL_C void CalcTextPos(TInt aScreen, TInt& aX, TInt& aY)
-	{
-	switch (CurrentFlipState[aScreen])
-		{
-	case EEmulatorFlipInvert:
-		aX = systemIni->iScreens[aScreen]->iXYInputWidth-(systemIni->iScreens[aScreen]->iScreenOffsetX+systemIni->iScreens[aScreen]->iScreenWidth);
-		aY = systemIni->iScreens[aScreen]->iXYInputHeight-(systemIni->iScreens[aScreen]->iScreenOffsetY+systemIni->iScreens[aScreen]->iScreenHeight);
-		break;
-	case EEmulatorFlipLeft:
-		aX = systemIni->iScreens[aScreen]->iScreenOffsetY;
-		aY = systemIni->iScreens[aScreen]->iXYInputWidth-(systemIni->iScreens[aScreen]->iScreenOffsetX+systemIni->iScreens[aScreen]->iScreenWidth);
-		break;
-	case EEmulatorFlipRight:
-		aX = systemIni->iScreens[aScreen]->iXYInputHeight-(systemIni->iScreens[aScreen]->iScreenOffsetY+systemIni->iScreens[aScreen]->iScreenHeight);
-		aY = systemIni->iScreens[aScreen]->iScreenOffsetX;
-		break;
-	case EEmulatorFlipRestore:
-	default:
-		aX = systemIni->iScreens[aScreen]->iScreenOffsetX;
-		aY = systemIni->iScreens[aScreen]->iScreenOffsetY;
-	break;
-		}
-	//subtract viewport offset here
-	aX -= systemIni->iScreens[aScreen]->iViewport.GetViewportOffsetX();
-	aY -= systemIni->iScreens[aScreen]->iViewport.GetViewportOffsetY();
-	}
-
-TInt APIENTRY ctrlwinProc(HWND hWnd,TUint message,TUint wParam,TUint lParam)
-//
-// The control window function
-//
-	{
-	switch(message)
-	{
-		case WM_SYSCOMMAND:
-			{
-				switch(wParam)
-				{
-					case 1:
-						{
-						NextConfiguration();
-						return 0;
-						}
-					case SC_MINIMIZE:
-					case SC_RESTORE:
-						{
-						if (wParam == SC_RESTORE) 
-							Active();
-						for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
-							{
-							SendMessage(TheWin[ix],message,wParam,lParam);
-							}
-						if (wParam == SC_MINIMIZE) 
-							Inactive();
-						}			
-				}
-				return(DefWindowProcA(hWnd,message,wParam,lParam));
-			}
-		case WM_CLOSE: // tell all emulator screen windows to close
-			{
-			for(TInt i=0;i<systemIni->iScreens.Count();i++)
-				{
-				DestroyWindow(TheWin[i]);
-				}
-			DestroyWindow(hWnd);
-			break;
-			}
-		case WM_DESTROY:
-			{
-			// save the main window position information
-			HANDLE hSysIni;
-			hSysIni = CreateFileA(systemIni->iSysIniFileName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
-			DScreenProperties* screenProps;
-			if (hSysIni != INVALID_HANDLE_VALUE)
-				{
-				DWORD numWritten;
-				//write an identifier into file so that program can avoid loading old version
-				WriteFile(hSysIni, &KDatFileVersion, sizeof(TInt), &numWritten, 0);
-				
-				//record current configuration at start of file.
-				WriteFile(hSysIni, &CurrentConfiguration, sizeof(TInt), &numWritten, 0);
-				
-				//Write out the state for each window.
-				for(TInt i=0;i<systemIni->iScreens.Count();i++)
-					{
-					screenProps= systemIni->iScreens[i];
-					
-					TWindowState winState= screenProps->GetWindowState();
-					WriteFile(hSysIni, &winState, sizeof(TWindowState), &numWritten, 0);
-					
-					
-					}
-				}
-			CloseHandle(hSysIni);
-
-			PostQuitMessage(KErrNone);
-			break;
-			}
-		case WM_INPUT:
-			{
-			if (!DMultiTouch::iMultiTouchTempEnabled)
-				{
-				for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
-					{
-					DMultiTouch::iMultiTouchTempEnabled = TRUE;
-
-					SendMessage(TheWin[ix],message,wParam,lParam);
-					}
-				}
-			else if (systemIni->MultiTouchEnabled() && DMultiTouch::iMultiTouchSupported && systemIni->GCEEnabled())
-				{
-			   	TheMultiTouch->OnWmInput(hWnd, message, wParam, lParam,TheChildWin[0]);	
-				}
-			else
-				{
-				Fault(EGuiInvalidMultiTouch);
-				}
-		   	break;
-			}	
-		default:
-			return(DefWindowProcA(hWnd,message,wParam,lParam));
-	}
-	return(FALSE);
-	}
-
-TInt APIENTRY winProc(HWND hWnd,TUint message,TUint wParam,TUint lParam)
-//
-// The border window function.
-//
-	{
-
-	TRawEvent v;
-	
-	switch (message)
-    	{
-		case WM_GETMINMAXINFO:
-			{
-			DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
-			if(screenProps == NULL)
-				{
-				return DefWindowProcA(hWnd, message, wParam, lParam);
-				}
-						
-			MINMAXINFO* minMaxInfo = reinterpret_cast<MINMAXINFO*>(lParam);
-			minMaxInfo->ptMaxTrackSize.x = screenProps->iViewport.GetMaxWindowWidth();
-			minMaxInfo->ptMaxTrackSize.y = screenProps->iViewport.GetMaxWindowHeight();
-
-			minMaxInfo->ptMaxSize.x = minMaxInfo->ptMaxTrackSize.x;
-			minMaxInfo->ptMaxSize.y = minMaxInfo->ptMaxTrackSize.y;
-			DefWindowProcA(hWnd, message, wParam, lParam);
-			
-			break;
-			}
-	   
-    	    		
- 	    	
-    	case WM_SIZE:
-    		{
-    		DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
-			if(screenProps == NULL)
-				{
-				return DefWindowProcA(hWnd, message, wParam, lParam);
-				}
-    		TViewport& viewport = screenProps->iViewport;
-    		//update size of viewport
-    		viewport.SetViewportWidth(LOWORD(lParam));
-    		viewport.SetViewportHeight(HIWORD(lParam));
-    		
-    		
-			//If resize goes beyond boundary of emulator then scroll to compensate
-			TInt ox = viewport.GetViewportOffsetX();
-    		TInt xs = ox + LOWORD(lParam) - viewport.GetMaxWidth();
-    		if (xs>0) 
-    			{    			
-    			viewport.ScrollToX(ox-xs, hWnd);
-    			}
-    		
-    		TInt oy = viewport.GetViewportOffsetY();
-    		TInt ys = oy + HIWORD(lParam) - viewport.GetMaxHeight();
-    		if (ys>0) 
-    			{    			
-    			viewport.ScrollToY(oy-ys, hWnd);
-    			}
-    	
-    		//Adjust ranges of scroll bars
-    	   	viewport.UpdateScrollBarH(hWnd);
-    		viewport.UpdateScrollBarV(hWnd);
-    		    		
-    		
-    		
-    		break;    		
-    		}
-    	case WM_HSCROLL:
-    		{
-    		DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
-			if(screenProps == NULL)
-				{
-				return DefWindowProcA(hWnd, message, wParam, lParam);
-				}
-    		TViewport& viewport = screenProps->iViewport;
-    		
-    		switch (LOWORD(wParam)) 
-    			{
-    			case SB_THUMBTRACK:
-    				{
-    				viewport.ScrollToX(HIWORD(wParam),hWnd);
-    				break;
-    				}
-				case SB_PAGELEFT:
-					{
-					viewport.ScrollToX(viewport.GetViewportOffsetX() - viewport.GetViewportWidth(), hWnd );
-					break;
-					}
-				case SB_PAGERIGHT:
-					{
-					viewport.ScrollToX(viewport.GetViewportOffsetX() + viewport.GetViewportWidth() , hWnd);
-					break;
-					}
-				case SB_LINEUP:
-					{
-					viewport.ScrollToX(viewport.GetViewportOffsetX() - 1, hWnd);
-					break;
-					}
-				case SB_LINEDOWN:
-					{
-					viewport.ScrollToX(viewport.GetViewportOffsetX() + 1, hWnd);
-					break;
-					}
-    			
-    			}
-    		   		
-   
-    		break;
-    		}
-    	
-    	case WM_VSCROLL:
-    		{
-    		DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
-			if(screenProps == NULL)
-				{
-				return DefWindowProcA(hWnd, message, wParam, lParam);
-				}
-    		TViewport& viewport = screenProps->iViewport;
-    		
-			
-			switch (LOWORD(wParam)) 
-    			{
-    			case SB_THUMBTRACK:
-    				{
-    				viewport.ScrollToY(HIWORD(wParam), hWnd);
-    				break;
-    				}
-				case SB_PAGELEFT:
-					{
-					viewport.ScrollToY(viewport.GetViewportOffsetY() - viewport.GetViewportHeight() , hWnd);
-					break;
-					}
-				case SB_PAGERIGHT:
-					{
-					viewport.ScrollToY(viewport.GetViewportOffsetY() + viewport.GetViewportHeight(), hWnd );
-					break;
-					}
-				case SB_LINEUP:
-					{
-					viewport.ScrollToY(viewport.GetViewportOffsetY() - 1, hWnd);
-					break;
-					}
-				case SB_LINEDOWN:
-					{
-					viewport.ScrollToY(viewport.GetViewportOffsetY() + 1, hWnd);
-					break;
-					}
-    			
-    			}
-    		
-    		break;
-    		
-    		}
-    	
-    	 		
-		case WM_FLIP_MESSAGE:
-			{
-			DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
-			if(screenProps == NULL)
-				{
-				return DefWindowProcA(hWnd, message, wParam, lParam);
-
-				}
-			
-			TViewport& viewport = screenProps->iViewport;
-			RECT windowRect={0,0,0,0};
-			GetClientRect(hWnd, &windowRect);
-			
-			TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
-			if(TUint(screenNumber) >= TUint(systemIni->iScreens.Count()))
-				break;
-			PBITMAPV4HEADER info = &masterIni->iBufferSet[screenNumber].iInfo;
-			CurrentFlipState[screenNumber]=(TEmulatorFlip)wParam;
-			TBufferSet* bufferSet = &masterIni->iBufferSet[screenNumber];
-			switch (CurrentFlipState[screenNumber])
-				{
-				case EEmulatorFlipRestore:
-				case EEmulatorFlipInvert:
-					windowRect.right=systemIni->iScreens[screenNumber]->iXYInputWidth;
-					windowRect.bottom=systemIni->iScreens[screenNumber]->iXYInputHeight;
-					info->bV4Width = bufferSet->iBufferFormat.iSize.iWidth;
-					info->bV4Height = -bufferSet->iBufferFormat.iSize.iHeight;
-					break;
-				case EEmulatorFlipLeft:
-				case EEmulatorFlipRight:
-					windowRect.right=systemIni->iScreens[screenNumber]->iXYInputHeight;
-					windowRect.bottom=systemIni->iScreens[screenNumber]->iXYInputWidth;
-					info->bV4Width = bufferSet->iBufferFormat.iSize.iHeight;
-					info->bV4Height = -bufferSet->iBufferFormat.iSize.iWidth;
-					break;
-				}
-			AdjustWindowRect(&windowRect,KWinStyle,FALSE);
-    		
-    		
-			viewport.ScrollToX(0, hWnd);
-			viewport.ScrollToY(0, hWnd);
-
-			
-			screenProps->iScreenRotation = (TEmulatorFlip)wParam; 
-			
-						
-			RECT currentWindowRect;
-			GetWindowRect(hWnd,&currentWindowRect);
-			InvalidateRect(hWnd,NULL,FALSE);
-			MoveWindow(
-				TheWin[screenNumber],
-				max(currentWindowRect.left,0), // so the window doesn't disappear off the screen
-				max(currentWindowRect.top,0),
-				windowRect.right-windowRect.left,
-				windowRect.bottom-windowRect.top,
-				TRUE
-				);
-			// move the child window
-			screenProps->iViewport.UpdateChildPos(hWnd);
-			
-			viewport.UpdateScrollBarH(hWnd);
-    		viewport.UpdateScrollBarV(hWnd);
-
-			InvalidateRect(hWnd,NULL,TRUE);
-			UpdateWindow(hWnd);
-			
-			break;
-			}
-		case WM_SYSKEYDOWN:
-		case WM_KEYDOWN:
-			if (!(HIWORD(lParam)&KF_REPEAT))
-				{
-				
-				
-				TUint scanCode=DWinsKeyboard::ScanCodeToStandardKey(HIWORD(lParam));
-				TUint newScanCode = systemIni->iKeyboard.ScanCodeToRemappedKey(HIWORD(lParam));
-				MSG msg={hWnd,message,wParam,lParam,GetMessageTime(),GetMessagePos()};
-				TranslateMessage(&msg);
-				TUint charCode=0;
-				// look in the message queue to get character associated with keypress
-				// so long as the control, shift and alt keys aren't depressed
-				if (!(HIBYTE(GetKeyState(VK_CONTROL)) && HIBYTE(GetKeyState(VK_MENU)) && HIBYTE(GetKeyState(VK_SHIFT))))
-					if (PeekMessageA(&msg,hWnd,WM_CHAR,WM_CHAR,PM_NOREMOVE) &&
-						scanCode == newScanCode) //no remapping
-						charCode=msg.wParam;
-				// Pass the character as the HIWORD of the Epoc scan code
-				
-				scanCode = newScanCode;
-				v.Set(TRawEvent::EKeyDown,(charCode<<16)|scanCode);
-				if (!ProcessedByEmulatorKey(scanCode,hWnd,message,wParam,lParam))
-   					TheEventQ.Add(v);
-				
-				}
-			break;
-		case WM_TIMER:
-			break;
-		case WM_EMUL_POWER_ON:
-			{
-			TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
-			if(TUint(screenNumber) >= TUint(systemIni->iScreens.Count()))
-				break;
-//			HWND win = systemIni->iSecureDisplay ? TheSecureChildWin : TheChildWin;
-			HWND win = TheChildWin[screenNumber];
-			if (wParam==TRUE)
-				{
-				ShowWindow(win, SW_HIDE);
-				ShowWindow(win, SW_SHOWNORMAL);
-				if (SavedFlipMessage)
-					{
-					addKeyEvent(TRawEvent::EKeyDown, SavedFlipMessage);
-					addKeyEvent(TRawEvent::EKeyUp, SavedFlipMessage);
-					SavedFlipMessage = 0;
-					}
-				}
-			else
-				{
-				ShowWindow(win, SW_SHOWNORMAL);
-				ShowWindow(win, SW_HIDE);
-				}
-			}
-			break;
-		case WM_SYSKEYUP:
-		case WM_KEYUP:
-			{
-			//get the key code, this will pick up if it has been remapped or not.
-			TUint scanCode = systemIni->iKeyboard.ScanCodeToRemappedKey(HIWORD(lParam));
-	   /*
-		* We could do this to support generation of special characters using Alt+KeyPadNum
-		* combinations, but we would need to find a way to suppress the generation of
-		* home/end scancodes etc., so leave it for the moment.
-					MSG msg={hWnd,message,wParam,lParam,GetMessageTime(),GetMessagePos()};
-					TranslateMessage(&msg);
-					TUint charCode=0;
-					// look in the message queue to get character associated with keypress
-					if (PeekMessageU()(&msg,hWnd,WM_CHAR,WM_CHAR,PM_NOREMOVE))
-						charCode=msg.wParam;
-					// Pass the character as the HIWORD of the Epoc scan code
-					v.Set(TRawEvent::EKeyUp,(charCode<<16)|scanCode);
-		*/
-					v.Set(TRawEvent::EKeyUp,scanCode);
-	    			TheEventQ.Add(v);
-			break;
-			}
-		case WM_MOUSEMOVE:
-		case WM_LBUTTONDOWN:
-		case WM_LBUTTONUP:
-		case WM_RBUTTONDOWN:
-		case WM_RBUTTONUP:
-		case WM_MBUTTONDOWN:
-		case WM_MBUTTONUP:
-				{
-				//only handle mouse clicks on screen 0
-				TInt xpos=((TInt16)(lParam&0xffff));
-				TInt ypos = (TInt16)((lParam>>16)&0xFFFF);
-				if (DMultiTouch::iMultiTouchTempEnabled)
-					{
-					MultiChildWndPointer(message,xpos,ypos,0,0);
-					DMultiTouch::iMultiTouchTempEnabled = FALSE;				
-					}
-				else
-					{
-					TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
-					if(screenNumber!=0)
-						break;
-					FrameWndPointer(message,xpos,ypos,screenNumber);
-					}
-				break;
-				}
-		case WM_PAINT:
-			{
-			DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
-			if(screenProps == NULL)
-				{
-				return DefWindowProcA(hWnd, message, wParam, lParam);
-				}
-    		TViewport& viewport = screenProps->iViewport;
-    		TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
-
-			PAINTSTRUCT p;
-
-			BeginPaint(hWnd,&p);
-	   		HDC hdcBits;
-			BITMAP bm;
-    		hdcBits=CreateCompatibleDC(p.hdc);
-			GetObjectA(TheScreenBitmap[screenNumber],sizeof(BITMAP),&bm);
-    		SelectObject(hdcBits,TheScreenBitmap[screenNumber]);
-		
-			RECT windowRect;
-			GetClientRect(TheWin[screenNumber],&windowRect);
-			
-			viewport.SetViewportHeight(windowRect.bottom);
-			viewport.SetViewportWidth(windowRect.right);
-			
-			
-			switch (CurrentFlipState[screenNumber])
-				{
-				case EEmulatorFlipRestore:
-					{
-					BitBlt(p.hdc,0,0,windowRect.right,windowRect.bottom,hdcBits,
-						viewport.GetViewportOffsetX(),viewport.GetViewportOffsetY(),SRCCOPY);
-					break;
-					}
-				case EEmulatorFlipInvert:
-					{
-					TInt sourceX = screenProps->iXYInputWidth - viewport.GetViewportWidth() - viewport.GetViewportOffsetX();
-					if(sourceX<0)
-						sourceX=0;
-					TInt sourceY = screenProps->iXYInputHeight - viewport.GetViewportHeight() - viewport.GetViewportOffsetY();
-					if(sourceY<0)
-						sourceY=0;
-					TInt sourceWidth = viewport.GetMaxWidth()-sourceX - viewport.GetViewportOffsetX();
-					TInt sourceHeight = viewport.GetMaxHeight()-sourceY - viewport.GetViewportOffsetY();
-					
-					//when inverted it is necessary to translate the image by 1 pixel up and to the left,
-					//to avoid a glitch when scrolling using ScrollWindowEx()
-					POINT arrayPoints[3]={
-						{sourceWidth-1,sourceHeight-1},
-						{-1,sourceHeight-1},
-						{sourceWidth-1,-1}
-						};
-					PlgBlt(p.hdc,arrayPoints,hdcBits,sourceX,sourceY,sourceWidth,sourceHeight,NULL,NULL,NULL);
-					break;
-					}
-				case EEmulatorFlipLeft:
-					{
-					TInt offsetX = screenProps->iXYInputWidth- viewport.GetViewportHeight()  - viewport.GetViewportOffsetY(); 	
-					TInt offsetY = viewport.GetViewportOffsetX(); 	
-		
-					POINT arrayPoints[3]={{0,windowRect.bottom},{0,0},{windowRect.right,windowRect.bottom}};
-					PlgBlt(p.hdc,arrayPoints,hdcBits,offsetX,offsetY,viewport.GetViewportHeight(),viewport.GetViewportWidth(),NULL,NULL,NULL);
-					break;
-					}
-				case EEmulatorFlipRight:
-					{
-					TInt offsetX = viewport.GetViewportOffsetY(); 
-					TInt offsetY = screenProps->iXYInputHeight - viewport.GetViewportWidth() - viewport.GetViewportOffsetX(); 	
-									
-					POINT arrayPoints[3]={{windowRect.right,0},{windowRect.right,windowRect.bottom},{0,0}};
-					PlgBlt(p.hdc,arrayPoints,hdcBits,offsetX,offsetY,viewport.GetViewportHeight(),viewport.GetViewportWidth(),NULL,NULL,NULL);
-					break;
-					}
-				}
-
-			
-			DeleteDC(hdcBits);
-			if (WinsGuiPowerHandler->iStandby)
-				{
-				TInt x,y;
-				CalcTextPos(screenNumber, x, y);
-				TextOutA(p.hdc, x, y, "Standby", 7);
-				}
-			else if (systemIni->iScreens[screenNumber]->iScreenOff)
-				{
-				TInt x,y;
-				CalcTextPos(screenNumber, x, y);
-				TextOutA(p.hdc, x, y, "Screen Off", 10);
-				}
- 			EndPaint(hWnd,&p);
-			break;
-			}
-		case WM_ACTIVATE:
-			//Added so that change in modifier keys can be detected without sending
-			//EActive/EInActive to wserv as it results in switching the timers
-   			if((wParam & 0xffff)!= WA_INACTIVE)
-   				UpdateModifiers();
-			break;
-		case WM_CHAR:
-		case WM_SYSCHAR:
-		case WM_DEADCHAR:
-		case WM_SYSDEADCHAR:
-			break;
-		case WM_CLOSE: //pass on message to control window, it will then destroy all e,ulator windows
-			SendMessage(TheControlWin,WM_CLOSE, NULL, NULL);
-			break;
-		case WM_DESTROY:
-			{
-			DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
-			if(screenProps == NULL)
-				{
-				return DefWindowProcA(hWnd, message, wParam, lParam);
-				}
-    					
-			// save window's position information
-			screenProps->iWinPlace.length = sizeof(WINDOWPLACEMENT);
-			GetWindowPlacement(hWnd, &screenProps->iWinPlace);
-			
-			break;
-			}
-		case WM_INPUT:
-			{
-			if (systemIni->MultiTouchEnabled() && DMultiTouch::iMultiTouchSupported && systemIni->GCEEnabled())
-				{
-				TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
-				if(screenNumber==0)
-					{
-					TheMultiTouch->OnWmInput(hWnd, message, wParam, lParam,TheChildWin[screenNumber]);	
-					}
-				}
-			else
-				{
-				Fault(EGuiInvalidMultiTouch);
-				}
-		   	break;
-			}
-		default:
-	        return(DefWindowProcA(hWnd,message,wParam,lParam));
-	    }
-    return(FALSE);
-	
-	}
-
-void SetStatusBarFont(HWND& aStatusBar)
-	{
-	int statwidths[] = {100,200,300,400,500,600,700,800};
-	SendMessage(aStatusBar, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
-	HFONT hOrigFont = (HFONT) SendMessage(aStatusBar, WM_GETFONT, 0, 0);
-	SetProp(aStatusBar, TEXT("PROP_ORIGINAL_FONT"), (HANDLE) hOrigFont);
-	LOGFONT lf;
-	GetObject(hOrigFont, sizeof(lf), &lf);
-	lf.lfHeight = (long)(lf.lfHeight / 1.5);
-	lf.lfWeight = FW_NORMAL;
-	HFONT hFont = CreateFontIndirect(&lf);
-	SetProp(aStatusBar, TEXT("PROP_ITALIC_FONT"), (HANDLE) hFont);
-	hFont = (HFONT) GetProp(hwndStatus, TEXT("PROP_ITALIC_FONT"));
-	SendMessage(aStatusBar, WM_SETFONT, (WPARAM) hFont, FALSE);
-	}
-
-DWORD WINAPI KernelWindowThread(LPVOID aArg)
-//
-// The kernel window thread.
-//
-	{
-	HMODULE hmodule = GetModuleHandleA("winsgui.dll");
-	__ASSERT_ALWAYS(hmodule!=NULL,Fault(EGuiGetModuleHandle));
-
-	WNDCLASSA w;
-	memclr(&w, sizeof(WNDCLASSA));
-   	w.style=CS_OWNDC|CS_VREDRAW|CS_HREDRAW;
-   	w.lpfnWndProc=(WNDPROC)ctrlwinProc;
-   	w.hInstance=(HINSTANCE)aArg;
-   	w.hIcon=LoadIconA((HINSTANCE)hmodule,MAKEINTRESOURCEA(EPOC_ICON));
-   	w.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
-   	w.lpszClassName="E32KernelControlWindow";
-	
-	ATOM a=RegisterClassA(&w);
-	__ASSERT_ALWAYS(a!=0,Fault(EGuiRegisterWindow));
-
-	RECT ctlrwindowRect={0,0,270,0};
-	AdjustWindowRect(&ctlrwindowRect,KControlWinStyle,FALSE);
-	TInt ctrlwindowWidth=ctlrwindowRect.right-ctlrwindowRect.left;
-	TInt ctrlwindowHeight=ctlrwindowRect.bottom-ctlrwindowRect.top;
-
-    TheControlWin=CreateWindowA(
-		"E32KernelControlWindow",
-		systemIni->iWindowTitle,
-		KInvisibleControlWinStyle,
-		KWinPosX,
-		KWinPosY,
-		ctrlwindowWidth,
-		ctrlwindowHeight,
-		(HWND)NULL,
-		NULL,
-		(HINSTANCE)aArg,
-		(LPSTR)NULL
-		);
-	__ASSERT_ALWAYS(TheControlWin!=NULL,Fault(EGuiKernelWindowCreate));
-
-	memclr(&w, sizeof(WNDCLASSA));
-   	w.style=CS_OWNDC;
-   	w.lpfnWndProc=(WNDPROC)winProc;
-   	w.hInstance=(HINSTANCE)aArg;
-   	w.hIcon=LoadIconA((HINSTANCE)hmodule,MAKEINTRESOURCEA(EPOC_ICON));
-   	w.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
-   	w.lpszClassName="E32KernelWindow";
-
-	a=RegisterClassA(&w);
-	__ASSERT_ALWAYS(a!=0,Fault(EGuiRegisterWindow));
-
-	memclr(&w, sizeof(WNDCLASSA));
-	w.style=CS_OWNDC;
-	w.lpfnWndProc=(WNDPROC)childWinProc;
-	w.hInstance=(HINSTANCE)aArg;
-	w.hCursor=LoadCursorA(NULL,MAKEINTRESOURCEA(32512)); //ICD_ARROW
-	w.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
-	w.lpszMenuName=NULL;
-	w.lpszClassName="E32KernelChildWindow";
-	a=RegisterClassA(&w);
-	__ASSERT_ALWAYS(a!=0,Fault(EGuiRegisterChildWindow));
-
-	if (masterIni && masterIni->iSystemInis.Count() > 1)	
-		{
-		//add Configuration Items to the system menu if there's > 1 config
-		HMENU hMenu = GetSystemMenu(TheControlWin, FALSE);
-		InsertMenu(hMenu,5, MF_BYPOSITION|MF_SEPARATOR,0,NULL);
-		InsertMenuA(hMenu,6, MF_BYPOSITION|MF_STRING, 1, "Next Config...");
-		}
-	
-	ShowWindow(TheControlWin,SW_SHOWDEFAULT);
-	UpdateWindow(TheControlWin);
-
-	//Create frame windows and child windows
-	for(TInt screen=0;screen<systemIni->iScreens.Count();screen++)
-		{
-	
-		RECT windowRect={0,0,systemIni->iScreens[screen]->iXYInputWidth,systemIni->iScreens[screen]->iXYInputHeight};
-		AdjustWindowRect(&windowRect,KWinStyle,FALSE);
-		TInt windowWidth=windowRect.right-windowRect.left;
-		TInt windowHeight=windowRect.bottom-windowRect.top;
-    
-		CHAR title[20];
-		wsprintfA(title, "Screen %d", screen);
-
-		TheWin[screen]=CreateWindowA(
-			"E32KernelWindow",
-			title,
-			KInvisibleWinStyle,
-			KWinPosX,
-			KWinPosY,
-			windowWidth,
-			windowHeight,
-			(HWND)NULL,
-			NULL,
-			(HINSTANCE)aArg,
-			(LPSTR)NULL
-			);
-		__ASSERT_ALWAYS(TheWin[screen]!=NULL,Fault(EGuiKernelWindowCreate));
-		
-		LoadFasciaBitmap(screen);
-
-		TheChildWin[screen]=CreateWindowA(
-			"E32KernelChildWindow",
-			"",
-			WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
-			systemIni->iScreens[screen]->iScreenOffsetX,
-			systemIni->iScreens[screen]->iScreenOffsetY,
-			systemIni->iScreens[screen]->iScreenWidth,
-			systemIni->iScreens[screen]->iScreenHeight,
-			TheWin[screen],
-			NULL,
-			(HINSTANCE)aArg,
-			(LPSTR)NULL
-			);
-		__ASSERT_ALWAYS(TheChildWin[screen]!=NULL,Fault(EGuiKernelChildWindowCreate));
-		
-		// Create status bars
-		if (systemIni->MultiTouchEnabled() && systemIni->GCEEnabled())
-			{
-			HMODULE hmodComCtl = LoadLibrary(TEXT("comctl32.dll"));
-			typedef int (WINAPI* FNINITCC)();
-			FNINITCC pfnInitCommonControls = GetProcAddress(hmodComCtl, "InitCommonControls");
-			pfnInitCommonControls();
-			hwndStatus = CreateWindowExA(0, STATUSCLASSNAMEA, NULL,
-								WS_CHILD | WS_VISIBLE | CCS_BOTTOM ,
-									0,0,0,0,
-									TheWin[0], NULL, GetModuleHandle(NULL), NULL);                 
-			SetStatusBarFont(hwndStatus);
-			SetWindowPos(hwndStatus,NULL, 0,0,0,0,SWP_HIDEWINDOW);
-			}
-		}
-	
-	//Restore window data from ini file if it exists. 
-	HANDLE hSysIni = CreateFileA(systemIni->iSysIniFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
-	TBool success=(hSysIni != INVALID_HANDLE_VALUE) ? ETrue : EFalse;
-	
-	DWORD numRead;
-	TInt fileVersion=0;
-	if(success) 
-		{
-		ReadFile(hSysIni, &fileVersion, sizeof(TInt), &numRead, 0);
-		}
-	
-	//Check we are using a dat file created by this version of the program.
-	if(success && (fileVersion==KDatFileVersion) )
-		{
-				
-		TInt savedConfiguration=0; //set this to default configuration
-				
-		if(ReadFile(hSysIni, &savedConfiguration, sizeof(TInt), &numRead, 0) && (numRead>0) )
-			{
-			//Don't restore the saved configuration, see INC114502.
-			//This could be reenabled in future as an optional operation
-			//dependent on an entry in the epoc.ini file.
-
-			//SwitchConfiguration(savedConfiguration);
-			}
-	
-		//restore each window to saved state
-		for(TInt screen=0;screen<systemIni->iScreens.Count();screen++)
-			{
-		
-			//	If the .ini file was opened, get the saved settings for the windows position the last time
-			//	this emulator was run, if any, and move the window accordingly.
-			
-			TWindowState savedState;
-			
-			TBool stateLoaded = ReadFile(hSysIni, &savedState, sizeof(TWindowState), &numRead, 0) && (numRead>0);
-			 			
-			if (stateLoaded)
-				{				
-				//only allow window to be restored to 
-				//maximized or normal mode,
-				//this prevents it being restored in minimized mode
-				//or others.
-				if(savedState.iWinPlace.showCmd != SW_MAXIMIZE)
-						savedState.iWinPlace.showCmd= SW_NORMAL;
-				
-				//if starting in same configuration and/or rotation as last time emulator was run
-				//it makes sense to restore scroll offset, window position,
-				//and dimensions, if not, only restore position and window (ie. maximized/normal) state.
-				if(savedConfiguration == CurrentConfiguration &&
-					savedState.iFlipstate == CurrentFlipState[screen])
-					{
-					//Restore window placement
-					SetWindowPlacement(TheWin[screen], &savedState.iWinPlace);
-					
-					TViewport& viewport = systemIni->iScreens[screen]->iViewport;
-								
-					viewport.ScrollToX(savedState.iXoffset, TheWin[screen]);
-					viewport.ScrollToY(savedState.iYoffset, TheWin[screen]);
-					}
-				else
-					{
-					
-					RECT oldRect;
-					GetWindowRect(TheWin[screen], &oldRect);
-					//save default window dimensions
-					TInt width=oldRect.right-oldRect.left;
-					TInt height=oldRect.bottom - oldRect.top;
-
-					//restore position and window state from file
-					SetWindowPlacement(TheWin[screen], &savedState.iWinPlace);
-					
-					RECT currentRect;
-					GetWindowRect(TheWin[screen], &currentRect);
-					//keep default size.
-					MoveWindow(TheWin[screen],currentRect.left, currentRect.top, width, height, TRUE);
-					
-					}
-
-
-				// Check that enough of the recorded window position is visible on the screen
-
-				TBool enoughVisible = false;
-
-				// vague values for ensuring we have enough of the window title bar to grab
-				// if the window is partly off screen 
-				const TInt KTitleBarGrabX=80;
-				const TInt KTitleBarGrabY=50;
-
-				//inspect dimensions of the window to be restored.
-				RECT savedRect;
-				GetWindowRect(TheWin[screen], &savedRect);
-
-				SystemMonitors monitors;
-
-				if (monitors.Count() == 1)		/* Original algorithm */
-					{
-					RECT rcIntersect, rcScreen;
-
-					SetRect(&rcScreen, KTitleBarGrabX, savedRect.bottom-savedRect.top,
-						GetSystemMetrics(SM_CXSCREEN)-KTitleBarGrabX, GetSystemMetrics(SM_CYSCREEN)-KTitleBarGrabY);
-
-					enoughVisible = IntersectRect(&rcIntersect, &savedRect, &rcScreen);
-					}
-				else							/* > 1 monitor; do it differently */
-					{
-					RECT cornerBox1, cornerBox2;
-
-					// The top-left corner box
-					SetRect(&cornerBox1, savedRect.left, savedRect.top,
-						savedRect.left + KTitleBarGrabX, savedRect.top + KTitleBarGrabY);
-
-					// The top-right corner box
-					SetRect(&cornerBox2, savedRect.right - KTitleBarGrabX, savedRect.top,
-						savedRect.right, savedRect.top + KTitleBarGrabY);
-
-					// Require one of these rectangles to be all on one monitor
-					enoughVisible = monitors.RectAllOnOne(cornerBox1) || monitors.RectAllOnOne(cornerBox2);
-					}
-
-				if (!enoughVisible)
-					{
-					SetWindowPos(TheWin[screen], HWND_TOP, 0,0,0,0, SWP_NOSIZE);
-					}
-
-				}
-			else //if there was no stored info for this screen
-				{
-				ShowWindow(TheWin[screen],SW_MAXIMIZE);
-				}
-			}
-		}
-	else
-		{
-		//use default configuration and make windows visible
-		SwitchConfiguration(CurrentConfiguration);
-		for(TInt screen=0;screen<systemIni->iScreens.Count();screen++)
-			{
-			ShowWindow(TheWin[screen],SW_MAXIMIZE);
-			UpdateWindow(TheWin[screen]);
-			}
-		}
-
-	//close file if it was opened	
-	if(success) 
-		{
-		CloseHandle(hSysIni);
-		}
-		
-			
-	if (systemIni->iInitialFlipMsg != 0)
-		{
-		addKeyEvent(TRawEvent::EKeyDown,systemIni->iInitialFlipMsg);
-		addKeyEvent(TRawEvent::EKeyUp,systemIni->iInitialFlipMsg);
-		}
-
-	SetFocus(TheWin[0]);
-
-	MSG m;
-	while (GetMessageA(&m,NULL,0,0))
-    	{
-        DispatchMessageA(&m);
-	    }
-	
-	ExitProcess(m.wParam);
-	return 0;
-	}
-
-SystemMonitors::SystemMonitors(void)
-	{
-	TInt n;
-
-	iCount = 1;
-	iHaveMultiMonFunctions = false;
-
-	if ((n = GetSystemMetrics(SM_CMONITORS)) <= 1)
-		{
-		return;
-		}
-
-	HMODULE huser32 = GetModuleHandleA("user32.dll");
-
-	// Get pointers to the APIs we want
-	if (huser32 == NULL ||
-		(ipMonitorFromRect =
-		(HMONITOR (WINAPI *)(LPCRECT lprcScreenCoords, UINT uFlags))
-		GetProcAddress(huser32, "MonitorFromRect")) == NULL ||
-		(ipGetMonitorInfo =
-		(BOOL (WINAPI *)(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo))
-		GetProcAddress(huser32, "GetMonitorInfoA")) == NULL)
-		{
-		return;
-		}
-
-	iCount = n;
-	iHaveMultiMonFunctions = true;
-	}
-
-TBool SystemMonitors::RectAllOnOne(RECT& rect)
-	{
-	HMONITOR monitor = MonitorFromRect(rect);
-	if (monitor == NULL)
-		{
-		return false;
-		}
-
-	MONITORINFO monInfo;
-	monInfo.cbSize = sizeof(MONITORINFO);
-
-	if (! GetMonitorInfo(monitor, &monInfo))
-		{
-		return false;
-		}
-
-	RECT overlap;
-
-	if (IntersectRect(&overlap, &rect, &monInfo.rcWork) &&
-		EqualRect(&overlap, &rect))
-		{
-		return true;
-		}
-
-	return false;
-	}
-
-HMONITOR SystemMonitors::MonitorFromRect(const RECT& rect, UINT flags)
-	{
-	if (! iHaveMultiMonFunctions)
-		{
-		return NULL;
-		}
-
-	return (*ipMonitorFromRect)(&rect, flags);
-	}
-
-TBool SystemMonitors::GetMonitorInfo(HMONITOR monitor, LPMONITORINFO pMonInfo)
-	{
-	if (! iHaveMultiMonFunctions)
-		{
-		return false;
-		}
-
-	return (*ipGetMonitorInfo)(monitor, pMonInfo);
-	}
-
-void DrawLeds()
-	{
-	HDC winDC = GetDC(TheWin[0]);
-	HDC hdcBits;
-	hdcBits=CreateCompatibleDC(winDC);
-	SelectObject(hdcBits,TheScreenBitmap[0]);
-	HPEN pen=CreatePen(PS_SOLID,0,RGB(0,0,0));
-	SelectObject(hdcBits,pen);
-	HBRUSH brush;
-	LOGBRUSH redbrush={BS_SOLID, RGB(0xff,0,0)};
-	LOGBRUSH greenbrush={BS_SOLID, RGB(0,0xff,0)};
-	LOGBRUSH blackbrush={BS_SOLID, RGB(0,0,0)};
-	// red
-	if (LedMask & KLedMaskRed1)
-		brush=CreateBrushIndirect(&redbrush);
-	else
-		brush=CreateBrushIndirect(&blackbrush);
-	SelectObject(hdcBits,brush);
-	DWinsUi *ini=systemIni;
-	Ellipse(hdcBits, ini->iLedOffsetX, ini->iLedOffsetY, ini->iLedOffsetX+ini->iLedSize, ini->iLedOffsetY+ini->iLedSize);
-	DeleteObject(brush);
-	// green
-	if (LedMask & KLedMaskGreen1)
-		brush=CreateBrushIndirect(&greenbrush);
-	else
-		brush=CreateBrushIndirect(&blackbrush);
-	SelectObject(hdcBits,brush);
-	if (ini->iLedVertical)
-		Ellipse(hdcBits, ini->iLedOffsetX, ini->iLedOffsetY+ini->iLedSize+ini->iLedGap,
-		ini->iLedOffsetX+ini->iLedSize, ini->iLedOffsetY+ini->iLedSize+ini->iLedGap+ini->iLedSize);
-	else
-		Ellipse(hdcBits, ini->iLedOffsetX+ini->iLedSize+ini->iLedGap, ini->iLedOffsetY,
-		ini->iLedOffsetX+ini->iLedSize+ini->iLedGap+ini->iLedSize, ini->iLedOffsetY+ini->iLedSize);
-	DeleteObject(brush);
-	DeleteObject(pen);
-	DeleteDC(hdcBits);
-	ReleaseDC(TheWin[0], winDC);
-	if (ini->iLedVertical)
-		{
-		RECT r={ini->iLedOffsetX,
-			ini->iLedOffsetY,
-			ini->iLedOffsetX+ini->iLedSize,
-			ini->iLedOffsetY+ini->iLedSize+ini->iLedGap+ini->iLedSize};
-		InvalidateRect(TheWin[0], &r, FALSE);
-		}
-	else
-		{
-		RECT r={ini->iLedOffsetX,
-			ini->iLedOffsetY,
-			ini->iLedOffsetX+ini->iLedSize+ini->iLedGap+ini->iLedSize,
-			ini->iLedOffsetY+ini->iLedSize};
-		InvalidateRect(TheWin[0], &r, FALSE);
-		}
-	}
-
-void DWinsUi::ScreenInfo(TScreenInfoV01& aInfo)
-//
-// Return screen 0 info to the window server.
-//
-	{
-	aInfo.iWindowHandleValid=ETrue;
-	aInfo.iWindowHandle=TheChildWin[0];
-	aInfo.iScreenAddressValid=EFalse;
-	aInfo.iScreenAddress=NULL;
-	aInfo.iScreenSize.iWidth = iScreens[0]->iMaxScreenWidth;
-	aInfo.iScreenSize.iHeight = iScreens[0]->iMaxScreenHeight;
-	}
-	
-	
-TBool DWinsUi::VideoInfo(TInt aScreenNumber, TVideoInfoV01& aInfo)
-	{
-	return VideoInfo(aScreenNumber,iScreens[aScreenNumber&KMaskScreenNum]->iCurrentMode,aInfo);
-	}
-	
-/// Could fail if flip mode is not supported
-TBool DWinsUi::VideoInfo(TInt aScreenNumber,TInt aModeNumber, TVideoInfoV01& aInfo)
-	{
-	aScreenNumber &= KMaskScreenNum;
-	if (aScreenNumber>=iScreens.Count())
-		return EFalse;
-	if (masterIni->iBufferSet.Count() && masterIni->iBufferSet[aScreenNumber].iDisplayDriverCount > 0)
-		{
-			return VideoInfoForDisplayDriver(aScreenNumber,aModeNumber,aInfo);
-		}
-	else
-		{
-		if ((aModeNumber&KMaskModeNum)>=1)
-			return EFalse;	//non-gce emulator doesn't support changing the mode number.
-		DScreenProperties* screenProperties=iScreens[aScreenNumber];
-		aInfo.iSizeInPixels.iWidth = screenProperties->iMaxScreenWidth;
-		aInfo.iSizeInPixels.iHeight = screenProperties->iMaxScreenHeight;
-		aInfo.iSizeInTwips.iWidth = screenProperties->iMaxPhysicalScreenWidth ? screenProperties->iMaxPhysicalScreenWidth : TInt(screenProperties->iScreenWidth*KDefaultPixelsToTwipsX);
-		aInfo.iSizeInTwips.iHeight = screenProperties->iMaxPhysicalScreenHeight ? screenProperties->iMaxPhysicalScreenHeight : TInt(screenProperties->iScreenHeight*KDefaultPixelsToTwipsY);
-		aInfo.iIsMono = EFalse;
-		aInfo.iIsPalettized = EFalse;
-		aInfo.iDisplayMode=screenProperties->iCurrentMode;
-		aInfo.iIsPixelOrderRGB = ETrue;
-		aInfo.iIsPixelOrderLandscape=ETrue;
-
-		aInfo.iVideoAddress =  (TInt)TheChildWin[aScreenNumber];
-		aInfo.iBitsPerPixel = screenProperties->iColorDepth;
-		aInfo.iOffsetToFirstPixel=0;
-		aInfo.iOffsetBetweenLines=0;
-		}
-	return ETrue;	
-	}
-
-/** Could fail if flip mode is not supported.
- Note that this method is inteneded to be called directly to parameterise the setting up of the display driver,
- so it must survive absense of the display driver installation!
-**/
- 
-TBool DWinsUi::VideoInfoForDisplayDriver(TInt aScreenNumber,TInt aModeNumber, TVideoInfoV01& aInfo,  TBool aRealWidthAndHeight)
-	{
-	aScreenNumber &= KMaskScreenNum;
-	DScreenProperties* screenProperties = iScreens[aScreenNumber];
-	if ((aModeNumber&KMaskModeNum) >= screenProperties->iMaxModes)
-		{
-		return EFalse;
-		}
-		
-	aInfo.iSizeInPixels.iWidth = aRealWidthAndHeight ? screenProperties->iScreenWidth : screenProperties->iMaxScreenWidth;
-	aInfo.iSizeInPixels.iHeight = aRealWidthAndHeight ? screenProperties->iScreenHeight : screenProperties->iMaxScreenHeight;
-	
-	if (aRealWidthAndHeight==EFalse)
-		{
-		aInfo.iSizeInTwips.iWidth = screenProperties->iMaxPhysicalScreenWidth ?	screenProperties->iMaxPhysicalScreenWidth : TInt(screenProperties->iScreenWidth*KDefaultPixelsToTwipsX);
-		aInfo.iSizeInTwips.iHeight = screenProperties->iMaxPhysicalScreenHeight ? screenProperties->iMaxPhysicalScreenHeight : TInt(screenProperties->iScreenHeight*KDefaultPixelsToTwipsY);
-		}
-	else
-		{
-		aInfo.iSizeInTwips.iWidth = screenProperties->iPhysicalScreenWidth ? screenProperties->iPhysicalScreenWidth : TInt(screenProperties->iScreenWidth*KDefaultPixelsToTwipsX);
-		aInfo.iSizeInTwips.iHeight = screenProperties->iPhysicalScreenHeight ? screenProperties->iPhysicalScreenHeight : TInt(screenProperties->iScreenHeight*KDefaultPixelsToTwipsY);
-		}
-	
-	aInfo.iIsMono = EFalse;
-	aInfo.iIsPalettized = EFalse;
-	aInfo.iDisplayMode=screenProperties->iCurrentMode;
-	aInfo.iIsPixelOrderRGB = ETrue;
-	aInfo.iIsPixelOrderLandscape=ETrue;
-	
-	// Set memory to iVideoAddress to NULL to trigger the HAL code into querying the video address
-	// separately
-	aInfo.iVideoAddress = NULL;
-
-	TInt bpp=screenProperties->iModeDepths[aModeNumber&KMaskModeNum];												
-	aInfo.iBitsPerPixel=bpp;
-	if (bpp>8)
-		{
-		bpp=(bpp+15)&-16;	//12 & 16 --> 16 ; 24 & 32 --> 32
-		}
-	
-	aInfo.iOffsetToFirstPixel=0;
-#ifdef TEST_GCE_VARIABLE_START_EXTRA
-	aInfo.iOffsetToFirstPixel+= TEST_GCE_VARIABLE_START_EXTRA*(1+aModeNumber&KMaskScreenModeNum);
-	if ((aModeNumber& KModeFlagFlipped)
-		{
-#ifndef ASSYMETRIC_SQUARE_STRIDE		
-		if (aInfo.iSizeInPixels.iWidth!=aInfo.iSizeInPixels.iHeight)
-#endif
-			aInfo.iOffsetToFirstPixel+= TEST_GCE_VARIABLE_START_EXTRA*KEmulMaxNumModes;	
-		}
-#endif
-	if (aModeNumber& KModeFlagFlipped)
-		{
-		// we calculate the number of bytes per scanline that MUST be a multiple of 32 bits word (alignment)
-		// screenProperties->iMaxScreenHeight * bpp represnts the number of bits per scanline
-		// +31 is the ceiling
-		// we shift right (>>3) because there are 8 bits/byte
-		// we mask with ~3 because we are intrested in the octet value
-		aInfo.iOffsetBetweenLines=((screenProperties->iMaxScreenHeight * bpp + 31) >> 3) & ~3;
-		}
-	else
-		{
-		// please see the comment above
-		aInfo.iOffsetBetweenLines=((screenProperties->iMaxScreenWidth * bpp + 31) >> 3) & ~3;
-		}
-#ifdef  TEST_GCE_VARIABLE_STRIDE_EXTRA
-	aInfo.iOffsetBetweenLines+=TEST_GCE_VARIABLE_STRIDE_EXTRA;
-#endif	
-
-	return ETrue;	
-	}
-
-TInt DMasterIni::DoHalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
-	{
-	return masterIni->HalFunction((TInt)aPtr,aFunction,a1,a2);
-	}
-
-
-TInt DMasterIni::HalFunction(TInt aDeviceNumber, TInt aFunction, TAny* a1, TAny* a2)
-	{
-	if (TUint(aDeviceNumber) >= TUint(systemIni->iScreens.Count()))
-		return KErrArgument;
-	
-	TInt mode;
-	TInt maxMode=1;
-	TInt r=KErrNone;
-	switch(aFunction)
-		{
-		case EDisplayHalScreenInfo:
-			{
-			TPckgBuf<TScreenInfoV01> vPckg;
-			systemIni->ScreenInfo(vPckg());
-			Kern::InfoCopy(*(TDes8*)a1,vPckg);
-			break;
-			}
-		case EDisplayHalWsRegisterSwitchOnScreenHandling:
-			WsSwitchOnScreen=(TBool)a1;
-			break;
-		case EDisplayHalSetState:
-			{
-			if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
-				return KErrPermissionDenied;
-			if ((TBool)a1)
-				WinsGuiPowerHandler->ScreenOn(aDeviceNumber);
-			else
-				WinsGuiPowerHandler->ScreenOff(aDeviceNumber);
-			}
-			break;
-
-		case EDisplayHalState:
-			*(TInt*)a1=!systemIni->iScreens[aDeviceNumber]->iScreenOff;
-			break;
-		case EDisplayHalWsSwitchOnScreen:
-			WinsGuiPowerHandler->ScreenOn();
-			break;
-		case EDisplayHalMaxDisplayContrast:
-			kumemput32(a1,&KMaxDisplayContrast,sizeof(KMaxDisplayContrast));
-			break;
-		case EDisplayHalDisplayContrast:
-			kumemput32(a1,&systemIni->iScreens[aDeviceNumber]->iDisplayContrast,sizeof(systemIni->iScreens[aDeviceNumber]->iDisplayContrast));
-			break;
-		case EDisplayHalSetDisplayContrast:
-			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayContrast")))
-				return KErrPermissionDenied;
-			if (TUint(a1) <= TUint(KMaxDisplayContrast))
-				systemIni->iScreens[aDeviceNumber]->iDisplayContrast = TInt(a1);
-			else
-				r = KErrArgument;
-			break;
-		case EDisplayHalBacklightOn:
-			{
-			TBool c = EFalse;
-			kumemput32(a1,&c,sizeof(TBool));
-			}
-			break;
-		
-		case EDisplayHalCurrentModeInfo:
-			{
-			//a1 has ptr to buffer for results
-			TPckgBuf<TVideoInfoV01> vPckg;
-			if (systemIni->VideoInfo(aDeviceNumber, vPckg()))
-				Kern::InfoCopy(*(TDes8*)a1,vPckg);
-			else
-				r=KErrNotSupported;
-			}
-			break;
-
-		case EDisplayHalSpecifiedModeInfo:
-			{
-			kumemget32(&mode, a1, sizeof(mode));
-			TPckgBuf<TVideoInfoV01> vPckg;
-			if (!systemIni->VideoInfo(aDeviceNumber, mode, vPckg()))
-				return KErrArgument;
-			Kern::InfoCopy(*(TDes8*)a2, vPckg);
-			}
-			break;
-
-		case EDisplayHalSetMode:
-// 			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
-// 				return KErrPermissionDenied;
-
-			//Note that at present the HAL mode does not apparently get set when the CFbsScreenDevice requires a different mode.
-			//At least in the emulator and default h4 implementation...
-			
-			mode=KMaskModeNum&(TInt) a1;
-			maxMode=1;
-			//can't avoid this behaviour change test against gce loaded 
-			if (masterIni->iBufferSet.Count() &&  masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount > 0)
-				maxMode=systemIni->iScreens[aDeviceNumber]->iMaxModes;
-			if (mode >=maxMode || mode<0)
-				{
-				r = KErrArgument;
-				break;
-				}
-			//Harmless/Pointless in vanilla wins mode.
-			systemIni->iScreens[aDeviceNumber]->iCurrentMode=mode;
-			
-			break;
-		
-		case EDisplayHalMode:
-			{
-			//This is always 0 in non-gce emulator
-			kumemput32(a1,&systemIni->iScreens[aDeviceNumber]->iCurrentMode,sizeof(systemIni->iScreens[aDeviceNumber]->iCurrentMode));
-			}
-			break;
-
-		case EDisplayHalModeCount:
-			{
-			//Need to actually count them here!
-			//GCE will ignore modes<=8
-			TInt encodedMode=1;
-			if (masterIni->iBufferSet.Count() &&  masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount > 0)
-				encodedMode=systemIni->iScreens[aDeviceNumber]->iMaxModes;
-			kumemput32(a1,&encodedMode,sizeof(encodedMode));
-			}
-			break;
-
-		case EDisplayHalColors:
-			{
-			TInt deepestMode=0;
-			if (masterIni->iBufferSet.Count()==0 ||  masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount <= 0)
-				{
-				deepestMode = KMaxDisplayColors;  	//I could try and work it out, but this is what used to happen!
-				}
-			else
-				{
-				TInt maxBpp=0;
-				for (TInt i=0,maxI=systemIni->iScreens[aDeviceNumber]->iMaxModes;i<maxI;i++)	
-					if (systemIni->iScreens[aDeviceNumber]->iModeDepths[i]>maxBpp)
-						maxBpp=systemIni->iScreens[aDeviceNumber]->iModeDepths[i];
-				deepestMode= 1<<maxBpp;
-				}
-
-			kumemput32(a1,&deepestMode,sizeof(deepestMode));
-			}
-			break;
-		case EDisplayHalGetDisplayMemoryHandle:
-			{
-			TInt val = 0;
-			TInt passedIn = 0;
-			kumemget32(&passedIn, a1, sizeof(TInt));
-			if (passedIn != -1)	//not from a getall
-				{
-				NKern::ThreadEnterCS();
-				if (!(masterIni->iBufferSet.Count() == 0 || masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount <= 0 ))
-					{
-						r = masterIni->DisplayMemoryHandle(aDeviceNumber, val); 
-					}
-				else
-					{
-					r = KErrArgument;
-					}
-				NKern::ThreadLeaveCS();
-				}
-			kumemput32(a1, &val, sizeof(TInt));
-
-			}
-			break;
-
-		case EDisplayHalGetDisplayMemoryAddress:
-			{
-			TInt val = 0;
-			TInt passedIn = 0;
-			kumemget32(&passedIn, a1, sizeof(TInt));
-			if (passedIn != -1)	//not from a getall
-				{
-				if (!(masterIni->iBufferSet.Count() == 0 || masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount <= 0 ))
-					{
-					r = masterIni->DisplayMemoryAddress(aDeviceNumber, val);
-					}
-				else
-					{
-					r = KErrArgument;
-					}
-				}
-			kumemput32(a1, &val, sizeof(TInt));
-			}
-			break;
-
-		case EDisplayHalNumberOfResolutions:
-			{
-			r = NumberOfResolutions(aDeviceNumber, a1, a2);
-			}
-			break;
-		case EDisplayHalSpecificScreenInfo:
-			{
-			r = SpecificScreenInfo(aDeviceNumber, a1, a2);
-			}
-			break;
-		case EDisplayHalCurrentScreenInfo:
-			{
-			r = CurrentScreenInfo(aDeviceNumber, a1, a2);			
-			}
-			break;
-		case EDisplayHalSetDisplayState:
-			{
-			//increase the spinner at both beginning and end of resetting the display state
-			NKern::LockedInc(iBufferSet[aDeviceNumber].iStateChangeCount);
-			kumemget32(&iBufferSet[aDeviceNumber].iDisplayState, a1, sizeof(TInt));
-
-			switch(iBufferSet[aDeviceNumber].iDisplayState)
-				{
-				case ENoResolution:
-				case EDisconnect:
-				case ESingleResolution:
-					// the fascia effect of 0x0 resolution
-					SetDisplaySize(aDeviceNumber, 0, 0);
-					break;
-				}
-
-			NKern::LockedInc(iBufferSet[aDeviceNumber].iStateChangeCount);
-			}
-			break;
-		case EDisplayHalGetStateSpinner:
-			{
-			kumemput32(a1,&iBufferSet[aDeviceNumber].iStateChangeCount,
-					sizeof(iBufferSet[aDeviceNumber].iStateChangeCount));
-			}
-			break;
-		default:
-			r=KErrNotSupported;
-			break;
-		}
-	return r;
-	}
-
-TInt DMasterIni::NumberOfResolutions(TInt aDeviceNumber, TAny* a1, TAny* a2)
-	{
-	TInt numberOfConfigs;
-	switch(iBufferSet[aDeviceNumber].iDisplayState)
-		{
-		case ENoResolution:
-			{
-			numberOfConfigs = 0;
-			}
-			break;
-		case EDisconnect:
-			{
-			return KErrDisconnected;
-			}
-			break;
-		case ESingleResolution:
-			{
-			numberOfConfigs = 1;
-			}
-			break;
-		case ENormalResolution:
-		default:
-			{
-			numberOfConfigs = iSystemInis.Count();
-			if (numberOfConfigs > 1)
-				{
-				TVideoInfoV01 info1;
-				TVideoInfoV01 info2;
-				iSystemInis[0]->VideoInfoForDisplayDriver(aDeviceNumber, 0, info1, ETrue);
-				iSystemInis[1]->VideoInfoForDisplayDriver(aDeviceNumber, 0, info2, ETrue);
-				if (info1.iSizeInPixels.iWidth == info2.iSizeInPixels.iWidth &&
-						info1.iSizeInPixels.iHeight == info2.iSizeInPixels.iHeight)
-					{
-					numberOfConfigs = 1;	//It looks like all resolutions for this device are the same
-					}
-				}
-			}
-		}
-	kumemput32(a1,&numberOfConfigs,sizeof(numberOfConfigs));
-	if(a2)
-		{
-		kumemput32(a2,&(iBufferSet[aDeviceNumber].iStateChangeCount),sizeof(iBufferSet[aDeviceNumber].iStateChangeCount));
-		}
-	return KErrNone;
-	}
-
-TInt DMasterIni::SpecificScreenInfo(TInt aDeviceNumber, TAny* a1, TAny* a2)
-	{
-	TInt config;
-	switch(iBufferSet[aDeviceNumber].iDisplayState)
-		{
-		case ENoResolution: //Do Nothing
-			break;
-		case EDisconnect:
-			{
-			return KErrDisconnected;
-			}
-			break;
-		case ESingleResolution: //fill (0,0) as the only element in resolution array
-			{
-			if(*(TInt*)a1 == 0)
-				{
-				TVideoInfoV01 info;
-				info.iSizeInPixels.iHeight = 0;
-				info.iSizeInPixels.iWidth = 0;
-				info.iSizeInTwips.iHeight = 0;
-				info.iSizeInTwips.iWidth = 0;
-				TPtr8 infoPtr((TUint8*)&info, sizeof(info), sizeof(info));
-				Kern::InfoCopy(*(TDes8*)a2, infoPtr);
-				}
-			}
-			break;
-		case ENormalResolution:
-		default:
-			{
-			kumemget32(&config, a1, sizeof(config));
-			TPckgBuf<TVideoInfoV01> vPckg;
-			iSystemInis[config]->VideoInfoForDisplayDriver(aDeviceNumber, 0, vPckg(), ETrue);
-			Kern::InfoCopy(*(TDes8*)a2,vPckg);
-			}
-		}
-	return KErrNone;
-	}
-
-TInt DMasterIni::CurrentScreenInfo(TInt aDeviceNumber, TAny* a1, TAny* /*a2*/)
-	{
-	switch(iBufferSet[aDeviceNumber].iDisplayState)
-		{
-		case ENoResolution: //Do Nothing
-			break;
-		case EDisconnect:
-			{
-			return KErrDisconnected;
-			}
-			break;
-		case ESingleResolution: //fill (0,0)
-			{
-			TVideoInfoV01 info;
-			info.iSizeInPixels.iHeight = 0;
-			info.iSizeInPixels.iWidth = 0;
-			info.iSizeInTwips.iHeight = 0;
-			info.iSizeInTwips.iWidth = 0;
-			TPtr8 infoPtr((TUint8*)&info, sizeof(info), sizeof(info));
-			Kern::InfoCopy(*(TDes8*)a1, infoPtr);
-			}
-			break;
-		case ENormalResolution:
-		default:
-			{
-			TPckgBuf<TVideoInfoV01> vPckg;
-			systemIni->VideoInfoForDisplayDriver(aDeviceNumber, 0, vPckg(), ETrue);
-			Kern::InfoCopy(*(TDes8*)a1,vPckg);
-			}
-		}
-	return KErrNone;
-	}
-
-TInt DMasterIni::DoXYHalFunction(TAny* aThis, TInt aFunction, TAny* a1, TAny* a2)
-	{
-	return static_cast<DMasterIni*>(aThis)->XYHalFunction(aFunction,a1,a2);
-	}
-
-TInt DMasterIni::XYHalFunction(TInt aFunction, TAny* a1, TAny* a2)
-	{
-	TInt r=KErrNone;
-	switch(aFunction)
-		{
-		case EDigitiserHalXYInfo:
-			{
-			if(systemIni->iXYInputType==EXYInputPointer)
-				{
-				TPckgBuf<TDigitiserInfoV01> vPckg;
-				TDigitiserInfoV01& xyinfo=vPckg();
-				xyinfo.iDigitiserSize.iWidth=max(systemIni->iScreens[0]->iXYInputWidth,systemIni->iScreens[0]->iMaxScreenWidth+systemIni->iScreens[0]->iScreenOffsetX);		
-				xyinfo.iDigitiserSize.iHeight=max(systemIni->iScreens[0]->iXYInputHeight,systemIni->iScreens[0]->iMaxScreenHeight+systemIni->iScreens[0]->iScreenOffsetY);
-				xyinfo.iOffsetToDisplay.iX=systemIni->iScreens[0]->iScreenOffsetX;
-				xyinfo.iOffsetToDisplay.iY=systemIni->iScreens[0]->iScreenOffsetY;
-				Kern::InfoCopy(*(TDes8*)a1,vPckg);
-				}
-			else
-				r=KErrNotSupported;
-			}
-			break;
-			
-		// a2 = TBool aSet (ETrue for setting, EFalse for retrieval) 
-		// a1 = TDigitizerOrientation (set)
-		// a1 = &TDigitizerOrientation (get)
-		// Assume screen [0] here as this HAL function is only registered for
-		// screen 0 on the emulator platform. Function only called if display==0
-		case EDigitiserOrientation:	
-			if ((TBool)a2)
-				{
-				// Set the orientation attribute
-				// In case user thread, check it has WDD capability
-				if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDigitiserOrientation")))
-					return KErrPermissionDenied;
-				systemIni->iScreens[0]->iXYOrientation = (TInt)a1;
-				}
-			else
-				{
-				// Get the orientation attribute, safe copy it into user memory
-				kumemput32(a1, &(systemIni->iScreens[0]->iXYOrientation), sizeof(TInt));	
-				}
-			break; 
-			
-		default:
-			r=KErrNotSupported;
-			break;
-		}
-	return r;
-	}
-
-TInt DMasterIni::DoMouseHalFunction(TAny* aThis, TInt aFunction, TAny* a1, TAny* a2)
-	{
-	return static_cast<DMasterIni*>(aThis)->MouseHalFunction(aFunction,a1,a2);
-	}
-
-TInt DMasterIni::MouseHalFunction(TInt aFunction, TAny* a1, TAny* /*a2*/)
-	{
-	TInt r=KErrNone;
-	switch(aFunction)
-		{
-		case EMouseHalMouseInfo:
-			{
-			if(systemIni->iXYInputType==EXYInputMouse || systemIni->iXYInputType==EXYInputDeltaMouse)
-				{
-				TPckgBuf<TMouseInfoV01> vPckg;
-				TMouseInfoV01& xyinfo=vPckg();
-				xyinfo.iMouseButtons=2;
-				xyinfo.iMouseAreaSize.iWidth=max(systemIni->iScreens[0]->iXYInputWidth,systemIni->iScreens[0]->iMaxScreenWidth+systemIni->iScreens[0]->iScreenOffsetX);		
-				xyinfo.iMouseAreaSize.iHeight=max(systemIni->iScreens[0]->iXYInputHeight,systemIni->iScreens[0]->iMaxScreenHeight+systemIni->iScreens[0]->iScreenOffsetY);
-				xyinfo.iOffsetToDisplay.iX=systemIni->iScreens[0]->iScreenOffsetX;
-				xyinfo.iOffsetToDisplay.iY=systemIni->iScreens[0]->iScreenOffsetY;
-				Kern::InfoCopy(*(TDes8*)a1,vPckg);
-				}
-			else
-				r=KErrNotSupported;
-			}
-			break;
-		default:
-			r=KErrNotSupported;
-			break;
-		}
-	return r;
-	}
-
-TInt DMasterIni::DoKbdHalFunction(TAny* /*aThis*/, TInt aFunction, TAny* /*a1*/, TAny* /*a2*/)
-	{
-	// don't actually do anything, just enough to report a Keyboard is present
-	TInt r=KErrNone;
-	if(aFunction!=EKeyboardHalKeyboardInfo)
-		r=KErrNotSupported;
-	return r;
-	}
-
-void Inactive()
-//
-// Window has been minimised.
-//
-    {
-
-	TRawEvent v;
-	v.Set(TRawEvent::EInactive);
-    TheEventQ.Add(v);
-    }
-
-void UpdateModifiers()
-//Updates the modifier key states and sends an event to wserv about the 
-//change in state
-	{
-	TRawEvent v;
-	TInt modifiers=0;
-    if(GetKeyState(VK_SCROLL)&1)
-        modifiers|=EModifierScrollLock;
-    if(GetKeyState(VK_NUMLOCK)&1)
-        modifiers|=EModifierNumLock;
-    if(GetKeyState(VK_CAPITAL)&1)
-        modifiers|=EModifierCapsLock;
-    v.Set(TRawEvent::EUpdateModifiers,modifiers);
-    TheEventQ.Add(v);
-	}
-	
-void Active()
-//
-// Window has been restored.
-// Update the toggling modifiers, reset any others
-//
-    {
-	TRawEvent v;
-    UpdateModifiers();
-    v.Set(TRawEvent::EActive);
-    TheEventQ.Add(v);
-    }
-
-
-void ClearScreen()
-    {
-
-    }
-
-
-TInt DWinsUi::GetVirtualKey(TEmulCommand& aCommand, TInt aX, TInt aY)
-	{
-	//if the point is in the list of shapes, set the key and return true
-	for (TInt keyCount = iVirtualKeys.Count(); --keyCount >= 0; )
-		{
-		const VirtualKey& vk = *iVirtualKeys[keyCount];
-		if (vk.Contains(aX, aY))
-			{
-			aCommand = vk.Command();
-			return vk.Value();
-			}
-		}
-	return -1;
-	}
-
-void DWinsUi::TranslateMouseCoords(const TEmulatorFlip aFlipState, const TInt aX, const TInt aY, const TInt aRegionWidth, const TInt aRegionHeight, TInt& aNewX, TInt& aNewY)
-	{
-	switch (aFlipState)
-		{
-		case EEmulatorFlipRestore:
-			aNewX = aX;
-			aNewY = aY;
-			break;
-		
-		case EEmulatorFlipInvert:
-			aNewX = aRegionWidth - aX;
-			aNewY = aRegionHeight - aY;
-			break;
-		
-		case EEmulatorFlipLeft:
-			aNewX = aRegionWidth - aY;
-			aNewY = aX;
-			break;
-
-		case EEmulatorFlipRight:
-			aNewX = aY;
-			aNewY = aRegionHeight - aX;
-			break;
-		}
-	}
-
-
-TBool DWinsUi::OnScreen(TInt aScreen, TInt ax, TInt ay) const
-//
-// Checks if a point within the Emulator window is on the screen
-//
-	{
-	return (TUint(ax) < TUint(systemIni->iScreens[aScreen]->iScreenWidth) && TUint(ay) < TUint(systemIni->iScreens[aScreen]->iScreenHeight));
-	}
-
-TInt DWinsUi::Create(TInt aId)
-	{
-	TInt r = SetupProperties(aId);
-	if (r != KErrNone)
-		return r;
-	TInt screen;
-	DScreenProperties* currentScreen = NULL;
-	for(screen=0;screen<iScreens.Count();screen++)
-		{
-		BITMAPINFOHEADER bitmapinfo;
-		currentScreen = iScreens[screen];
-		if (readBitmapInfo(&bitmapinfo, currentScreen->iFasciaFileName) == KErrNone)
-			{
-			currentScreen->iXYInputWidth=bitmapinfo.biWidth;
-			currentScreen->iXYInputHeight=bitmapinfo.biHeight;
-			}
-		currentScreen->iXYInputWidth=max(currentScreen->iXYInputWidth,currentScreen->iScreenWidth+currentScreen->iScreenOffsetX);
-		currentScreen->iXYInputHeight=max(currentScreen->iXYInputHeight,currentScreen->iScreenHeight+currentScreen->iScreenOffsetY);
-		}
-
-	currentScreen = iScreens[0];
-	//note digitizer offsets are relative to EPOC screen 0
-	if (-1 == iDigitizerWidth)
-		iDigitizerWidth = currentScreen->iXYInputWidth - 
-			(currentScreen->iScreenOffsetX + iDigitizerOffsetX);
-	else
-		currentScreen->iXYInputWidth=max(currentScreen->iXYInputWidth,iDigitizerWidth);
-
-	if (-1 == iDigitizerHeight)
-		iDigitizerHeight = currentScreen->iXYInputHeight - 
-			(currentScreen->iScreenOffsetY + iDigitizerOffsetY);
-	else
-		currentScreen->iXYInputHeight=max(currentScreen->iXYInputHeight,iDigitizerHeight);
-
-	return r;
-	}
-
-const RDisplayChannel::TPixelFormat DMasterIni::iSupportedPixelFormatTable[] =
-	{
-		EUidPixelFormatXRGB_8888,
-		EUidPixelFormatARGB_8888,
-		EUidPixelFormatARGB_8888_PRE,
-		EUidPixelFormatXRGB_4444,
-		EUidPixelFormatARGB_4444,
-		EUidPixelFormatRGB_565 
-	};
-
-const TInt DMasterIni::iSupportedPixelFormatTableSize = static_cast<TInt>(sizeof(iSupportedPixelFormatTable)/
-		                                                                  sizeof(iSupportedPixelFormatTable[0]));
-
-void DMasterIni::InitBufferFormat(DScreenProperties& aScreenProperties, RDisplayChannel::TBufferFormat& aBufferFormat)
-	{
-	TUint bitsPerPixel = MaximumBitDepthFromMask(aScreenProperties.iColorDepth);
-	
-	aBufferFormat.iSize.iWidth = aScreenProperties.iMaxScreenWidth;
-	aBufferFormat.iSize.iHeight = aScreenProperties.iMaxScreenHeight;
-	switch (bitsPerPixel)
-		{
-	case 12:	// XRGB4444
-		aBufferFormat.iPixelFormat = EUidPixelFormatXRGB_4444;
-		break;
-	case 16:	// RGB565
-		aBufferFormat.iPixelFormat = EUidPixelFormatRGB_565;
-			break;
-	case 24:	// Really 32bpp, but top 8 unused
-	case 32:	// While 32bpp, top 8 will not be used
-	default:
-		aBufferFormat.iPixelFormat = EUidPixelFormatXRGB_8888;
-			break;
-		}
-	}
-
-TInt DMasterIni::Create()
-	{
-	TInt configurations = Property::GetInt("ConfigCount", 0);
-	if (configurations == 0)
-		return KErrGeneral;
-
-	// the pixel formats table is, at present, configuration independent
-	TInt count;
-	TInt r = KErrNone;
-	for (count = 0; count < configurations && r == KErrNone; ++count)
-		{
-		DWinsUi* dwi = new DWinsUi;
-		if (dwi)
-			r = dwi->Create(count);
-
-		if (r == KErrNone)
-			iSystemInis.Append(dwi);
-		}
-	if (r != KErrNone)
-		return r;
-
-	systemIni = masterIni->iSystemInis[0];
-
-	WinsGuiPowerHandler = DWinsGuiPowerHandler::New();
-	if (!WinsGuiPowerHandler)
-		return KErrNoMemory;
-
-	TheWin=new HWND[systemIni->iScreens.Count()];
-	TheChildWin=new HWND[systemIni->iScreens.Count()];
-	TheScreenBitmap=new HBITMAP[systemIni->iScreens.Count()];
-	CurrentFlipState=new TEmulatorFlip[systemIni->iScreens.Count()];
-
-	if(!TheWin || !TheChildWin || !TheScreenBitmap || !CurrentFlipState)
-		return KErrNoMemory;
-	memset(CurrentFlipState,EEmulatorFlipRestore,systemIni->iScreens.Count());
-
-	TBufferSet buffer;
-	buffer.iDisplayDriverCount = 0;
-	buffer.iDisplayState = ENormalResolution;
-	buffer.iDisplayBuffer = 0;
-	buffer.iDisplayChannel = NULL;
-
-
-	TInt i;
-	for(i=0;i<systemIni->iScreens.Count();i++)
-		{
-		DScreenProperties *pScr = systemIni->iScreens[i];
-
-		masterIni->InitBitmapHeader(*pScr, &buffer.iInfo);
-		masterIni->InitBufferFormat(*pScr, buffer.iBufferFormat);
-
-		r = masterIni->iBufferSet.Append(buffer);
-		if (r != KErrNone)
-			return r;
-		}
-
-	if (CreateWin32Thread(EThreadEvent, &KernelWindowThread, NULL, ETrue) == NULL)
-		return KErrGeneral;
-
-	for(i=0;i<systemIni->iScreens.Count();i++)
-		{
-		r = Kern::AddHalEntry(EHalGroupDisplay,&DoHalFunction,(TAny*)i,i);
-		if (r != KErrNone)
-			return r;
-		}
-
-	// should really come from Keyboard driver, but not doing it now...
-	r = Kern::AddHalEntry(EHalGroupKeyboard,&DoKbdHalFunction,this);
-	if (r != KErrNone)
-		return r;
-
-	if(systemIni->iXYInputType==EXYInputPointer)
-		{
-		r = Kern::AddHalEntry(EHalGroupDigitiser,&DoXYHalFunction,this);
-		if (r != KErrNone)
-			return r;
-		}
-	else if(systemIni->iXYInputType==EXYInputMouse || systemIni->iXYInputType==EXYInputDeltaMouse)
-		{
-		r = Kern::AddHalEntry(EHalGroupMouse,&DoMouseHalFunction,this);
-		if (r != KErrNone)
-			return r;
-		}
-
-	return r;
-	}
-
-void DMasterIni::InitBitmapHeader(DScreenProperties& aScreenProperties, LPBITMAPV4HEADER aInfo)
-	{
-	TInt width = aScreenProperties.iMaxScreenWidth; 
-	TInt height = aScreenProperties.iMaxScreenHeight;
-	TUint bitsPerPixel = MaximumBitDepthFromMask(aScreenProperties.iColorDepth);
-
-	memset(aInfo, 0, sizeof(BITMAPV4HEADER));
-
-	switch (bitsPerPixel)
-		{
-	case 12:	// XRGB4444
-			aInfo->bV4BitCount = 16;
-			aInfo->bV4V4Compression = BI_BITFIELDS;
-			aInfo->bV4RedMask   = 0x0F00;
-			aInfo->bV4GreenMask = 0x00F0;
-			aInfo->bV4BlueMask  = 0x000F;
-			break;
-	case 16:	// RGB565
-			aInfo->bV4BitCount = 16;
-			aInfo->bV4V4Compression = BI_BITFIELDS;
-			aInfo->bV4RedMask   = 0xF800;
-			aInfo->bV4GreenMask = 0x07E0;
-			aInfo->bV4BlueMask  = 0x001F;
-			break;
-	case 24:	// Really 32bpp, but top 8 unused
-	case 32:	// While 32bpp, top 8 will not be used
-	default:
-			aInfo->bV4BitCount = 32;
-			aInfo->bV4V4Compression = BI_RGB;
-			// Mask is implicit for BI_RGB compression
-			break;
-		}
-	
-	aInfo->bV4Size = sizeof(BITMAPV4HEADER);
-	aInfo->bV4Width = width;
-	aInfo->bV4Height = -height;	// Bitmap runs top to bottom
-	aInfo->bV4Planes = 1;
-	
-	TInt bpp = _ALIGN_UP(aInfo->bV4BitCount, 16); //12 & 16 --> 16 ; 24 & 32 --> 32
-	TInt widthInPixel = aInfo->bV4Width * bpp;
-	//rounding to 32 bits (4 octets) and converting, then, bits to octets;
-	TInt scanLineInBytes = _ALIGN_UP(widthInPixel, 32) >> 3; 
-	aInfo->bV4SizeImage = -aInfo->bV4Height * scanLineInBytes;
-
-	// Set color space as uncalibrated. All other members are then ignored.
-#if defined(LCS_DEVICE_RGB)
-	aInfo->bV4CSType = LCS_DEVICE_RGB;
-#elif defined(LCS_sRGB)
-	aInfo->bV4CSType = LCS_sRGB;
-#endif
-	}
-
-// Helper function that allocates a single frame buffer. 
-static TInt AllocateOneFrameBuffer(TInt aSize, TScreenBuffer &aScreenBuffer)
-	{
-    // Open shared chunk to the composition framebuffer
-	DChunk* chunk = 0;
-	// round to page size
-	if (aSize <= 0)
-		return KErrArgument;
-	TUint round = Kern::RoundToPageSize(aSize);
-	TLinAddr chunkKernelAddr = 0;
-	TUint32 physicalAddress = 0;
-	TUint32 chunkMapAttr = 0;
-
-	// create shared chunk
-	NKern::ThreadEnterCS();
-
-	TChunkCreateInfo info;
-	info.iType = TChunkCreateInfo::ESharedKernelMultiple;
-	info.iMaxSize = round;
-	info.iMapAttr = 0;
-	info.iOwnsMemory = ETrue;
-	info.iDestroyedDfc = 0;
-
-	TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr);
-	if (r == KErrNone)
-		{
-		// map our chunk to specific 
-		r = Kern::ChunkCommitContiguous(chunk, 0, aSize, physicalAddress);
-		if (r != KErrNone)
-			{
-			Kern::ChunkClose(chunk);
-			}
-		}
-
-	if (r == KErrNone)
-		{
-		TBufferAddressA* bufferAddress = new TBufferAddressA;
-		if (!bufferAddress)
-			{
-			r = KErrNoMemory;
-			}
-		else 
-			{
-			bufferAddress->iAddress = (TAny*)chunkKernelAddr;
-			bufferAddress->iChunk = chunk;
-
-			if ((r = aScreenBuffer.iFrameBuffers.Append(bufferAddress->iAddress)) == KErrNone)
-				{
-				r = aScreenBuffer.iMemChunks.Append(bufferAddress);
-				}
-			}
-		}
-	if (r != KErrNone)
-		{
-		Kern::ChunkClose(chunk);
-		}
-	NKern::ThreadLeaveCS();
-	return KErrNone;
-	}
-
-TInt DMasterIni::AllocateFrameBuffers(TInt aScreenNumber, TInt aCount, TInt aSize)
-	{
-	while (aCount--)
-		{
-		TInt r = AllocateOneFrameBuffer(aSize, masterIni->iBufferSet[aScreenNumber].iScreenBuffer);
-		if (r != KErrNone)
-			{
-			return r;
-			}
-		}
-	return KErrNone;
-	}
-
-void DMasterIni::ReleaseFrameBuffers(TInt aScreenNumber)
-	{
-	RPointerArray<TAny>& frameBuffers = masterIni->iBufferSet[aScreenNumber].iScreenBuffer.iFrameBuffers;
-	RPointerArray<TBufferAddressA>& memChunks = masterIni->iBufferSet[aScreenNumber].iScreenBuffer.iMemChunks;
-	RPointerArray<TBufferAddressA>& dsaChunks = masterIni->iBufferSet[aScreenNumber].iDsaBuffer.iMemChunks;
-
-   	NKern::ThreadEnterCS();
-	TInt index;
-	TInt count = memChunks.Count();
-	for (index = 0; index < count; index++)
-		{
-		Kern::ChunkClose(memChunks[index]->iChunk);
-		}
-	count = dsaChunks.Count();
-	for (index = 0; index < count; index++)
-		{
-		Kern::ChunkClose(dsaChunks[index]->iChunk);
-		}
-	NKern::ThreadLeaveCS();
-	
-	frameBuffers.Reset();
-	memChunks.Reset();
-	dsaChunks.Reset();
-	}
-
-
-TProcessAddrEntry::TProcessAddrEntry(DProcess *aProcess, TUint8* aAddress): 
-	iProcess(aProcess), iAddress(aAddress)
-	{
-	}
-
-
-/**
-Contruct a Shared Chunk cleanup object which will be used to clean up 
-after the process/address table entry. 
-*/
-TChunkCleanup::TChunkCleanup(DProcess* aProcess, TInt aScreenNumber)
-    : TDfc((TDfcFn)TChunkCleanup::ChunkDestroyed,this,Kern::SvMsgQue(),0)
-    , iProcess(aProcess)
-    , iScreenNumber(aScreenNumber)
-    , iIndex(-1)
-    {}
-
-/**
-Cancel the action of the cleanup object.
-*/
-void TChunkCleanup::Cancel()
-    {
-    // Clear iProcess which means that when the DFC gets queued on chunk destruction
-    // our ChunkDestroyed method will do nothing other than cleanup itself.
-    iProcess = NULL;
-    }
-
-/**
-Callback function called when the DFC runs, i.e. when a chunk is destroyed.
-*/
-void TChunkCleanup::ChunkDestroyed(TChunkCleanup* aSelf)
-    {
-    DProcess* process = aSelf->iProcess;
-    TInt screenNumber = aSelf->iScreenNumber;
-    TUint index = aSelf->iIndex;
-    // If we haven't been Cancelled...
-    if(process && index != -1)
-        {
-    	if (masterIni->iBufferSet[screenNumber].iProcAddrTable[index].iProcess == process)
-    		{
-    		masterIni->iBufferSet[screenNumber].iProcAddrTable[index].iProcess = 0;
-    		}
-    	else
-    		{
-    		__KTRACE_OPT(KEXTENSION,Kern::Printf("Oops! Someone has messed up our process index!"));
-    		}
-        }
-
-    // We've finished so now delete ourself
-    delete aSelf;
-    }
-
-
-TInt DMasterIni::DisplayMemoryHandle(TInt aScreenNumber, TInt& aHandle)
-	{
-	if (iBufferSet[aScreenNumber].iDsaBuffer.iMemChunks.Count() == 0)
-		{	
-		int r;
-		r = AllocateOneFrameBuffer(iMaxSizeInBytes, iBufferSet[aScreenNumber].iDsaBuffer);
-		if (KErrNone != r)
-			{
-			return r;
-			}
-		__ASSERT_DEBUG(iBufferSet[aScreenNumber].iDisplayChannel, Fault(EGuiNoDisplayChannel));
-		iBufferSet[aScreenNumber].iDisplayChannel->SetLegacyBuffer(iBufferSet[aScreenNumber].iDsaBuffer.iFrameBuffers[0]);
-		}
-	
-	aHandle = Kern::MakeHandleAndOpen(&Kern::CurrentThread(), 
-			iBufferSet[aScreenNumber].iDsaBuffer.iMemChunks[0]->iChunk);
-	
-	if (aHandle < 0)
-		{
-		return aHandle;
-		}
-	
-	return KErrNone;
-	}
-
-
-
-// Find the address of the display memory. 
-TInt DMasterIni::DisplayMemoryAddress(TInt aScreenNumber, TInt& aAddress)
-	{
-	TBufferSet &bufferSet = iBufferSet[aScreenNumber]; 
-	DProcess *process = &Kern::CurrentProcess();
-	TInt firstFree = -1;
-	NKern::FMWait(&iLock);
-	TUint count = bufferSet.iProcAddrTable.Count();
-	for(TUint i = 0; i < count; ++i)
-		{
-		DProcess *curProcess = bufferSet.iProcAddrTable[i].iProcess;
-		if (curProcess == process)
-			{
-			aAddress = reinterpret_cast<TInt>(bufferSet.iProcAddrTable[i].iAddress);
-			NKern::FMSignal(&iLock);
-			return KErrNone;
-			}
-		if (curProcess == 0 && firstFree == -1)
-			{
-			firstFree = i;
-			}
-		}
-	NKern::FMSignal(&iLock);
-	// If we get here, we couldn't find the process in the iProcAddrTable. 
-	// Create a new Process Address entry. 
-	// Step 1
-	// Create a dummy chunk so that we can detect when the process dies, 
-	// give a handle to the user [but don't actually let the process KNOW what the handle is
-	// so the user process can't do anything silly with the chunk]. Close our side of the
-	// chunk to make sure there is only one reference to it. 
-	DChunk* chunk = 0;
-	// find page size for one page. 
-	TUint round = Kern::RoundToPageSize(1);
-	TLinAddr chunkKernelAddr = 0;
-	TUint32 chunkMapAttr = 0;
-	
-	// create shared chunk
-	NKern::ThreadEnterCS();
-	// Cleanup object, used to issue a DFC when the chunk is closed (and 
-	// as the handle of the chunk is not given to the process, it can only
-	// be closed when the process terminates!)
-	TChunkCleanup *cleanup = new TChunkCleanup(process, aScreenNumber);
-	if (!cleanup)
-		{
-		NKern::ThreadLeaveCS();
-		return KErrNoMemory;
-		}
-
-	TChunkCreateInfo info;
-	info.iType = TChunkCreateInfo::ESharedKernelMultiple;
-	info.iMaxSize = round;
-	info.iMapAttr = 0;
-	info.iOwnsMemory = ETrue;
-	info.iDestroyedDfc = cleanup;
-
-	TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr);
-	
-	if (r != KErrNone)
-		{
-		delete cleanup;
-		NKern::ThreadLeaveCS();
-		return r;
-		}
-	
-	
-	// Create a new handle for the user thread. 
-    r = Kern::MakeHandleAndOpen(&Kern::CurrentThread(), chunk);
-	Kern::ChunkClose(chunk);
-	if (r <= 0)
-		{
-		NKern::ThreadLeaveCS();
-		return r;
-		}
-
-	// Step 2
-	// Create a second handle for the chunk to the DSA buffer.
-	// First part: Make sure there is a DisplayMemoryHandle;
-	TInt handle = 0;
-	r = DisplayMemoryHandle(aScreenNumber, handle); 
-	if (r != KErrNone)
-		{
-		Kern::ChunkClose(chunk);
-		NKern::ThreadLeaveCS();
-		return r;
-		}
-	
-	DChunk *dsaChunk = bufferSet.iDsaBuffer.iMemChunks[0]->iChunk;
-	
-	// Step 3
-	// Get the base addrss and insert into table. 
-	TUint8* baseAddress = Kern::ChunkUserBase(dsaChunk, &Kern::CurrentThread());
-	NKern::FMWait(&iLock);
-	// Optimistically, the place we found earlier in the table is still free.
-	if (firstFree != -1 && bufferSet.iProcAddrTable[firstFree].iProcess != 0)
-		{
-		// If not, we go find another one.
-		firstFree = -1;
-		TUint count = bufferSet.iProcAddrTable.Count();
-		for(TUint i = 0; i < count; ++i)
-			{
-			if (bufferSet.iProcAddrTable[i].iProcess == 0)
-				{
-				firstFree = i;
-				break;
-				}
-			}
-		}
-	// Check if there is a free entry - if so, re-use it. 
-	if (firstFree != -1)
-		{
-		bufferSet.iProcAddrTable[firstFree].iProcess = process;
-		bufferSet.iProcAddrTable[firstFree].iAddress = baseAddress;
-		cleanup->SetIndex(firstFree);
-		NKern::FMSignal(&iLock);
-		}
-	else
-		{
-		// No free entry. Append it to the list. 
-		NKern::FMSignal(&iLock);
-		TProcessAddrEntry entry(process, baseAddress);
-		r = bufferSet.iProcAddrTable.Append(entry);
-		if (r != KErrNone)
-			{
-			Kern::ChunkClose(chunk);
-			NKern::ThreadLeaveCS();
-			return r;
-			}
-		// We added it at the end - so we start from the back and check for the 
-		// process, as some other process COULD have added one after us, so we 
-		// can't just use the count for index!
-		TUint index;
-		for(index = bufferSet.iProcAddrTable.Count()-1; index; --index)
-			{
-			if (bufferSet.iProcAddrTable[index].iProcess == process 
-					&& bufferSet.iProcAddrTable[index].iAddress != baseAddress)
-				{
-				break;
-				}
-			}
-		cleanup->SetIndex(index);
-		}
-	aAddress = reinterpret_cast<TInt>(baseAddress);
-
-	NKern::ThreadLeaveCS();
-	return KErrNone;
-	}
-
-EXPORT_C TInt WinsGui::CurrentConfiguration()
-	{
-	return ::CurrentConfiguration;
-	}
-
-GLDEF_C void Fault(TGuiPanic aPanic)
-	{
-	Kern::Fault("WINS-UI",aPanic);
-	}
-
-DECLARE_STANDARD_EXTENSION()
-	{
-	__KTRACE_OPT(KEXTENSION,Kern::Printf("Starting Emulator GUI"));
-
-	// if NoGui property == true do nothing
-	if (Property::GetBool("NoGui",EFalse))
-		return KErrNone;
-
-	// create keyboard driver
-	TInt r=KErrNoMemory;
-	masterIni = new DMasterIni;
-	if (masterIni)
-		{
-		r = masterIni->Create();
-		if (r!= KErrNone)
-			{
-			return r;
-			}
-		}
-	
-	DMultiTouch::iMultiTouchSupported = DMultiTouch::Init();
-
-	// Create multitouch when necessary
-	if (systemIni->MultiTouchEnabled() && systemIni->GCEEnabled() && DMultiTouch::iMultiTouchSupported)
-		{
-		TheMultiTouch = new DMultiTouch(systemIni->MultiTouchProximityStep(),systemIni->MultiTouchPressureStep());
-		if(!TheMultiTouch)
-			{
-			r = KErrNoMemory;
-			__KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
-			return r;
-			}
-		DMultiTouch::iMultiTouchCreated = TRUE;
-		}
-
-	__KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
-	return r;
-	}
-
-TInt DWinsUi::DoDefineEmulatorControlHotKey(TAny* aPtr, const char* aValue)
-	{
-	return static_cast<DWinsUi*>(aPtr)->DefineEmulatorControlHotKey(aValue);
-	}
-
-
-TInt DWinsUi::DefineEmulatorControlHotKey(const char* aValue)
-	{
-	const char* beg = skipws(aValue);
-	const char* end = skiptok(beg);
-	TInt err = KErrNone;
-	
-	TEmulCommand command = ENoCommand;
-	TInt data = 0;
-	if (_strnicmp(beg, "SelectConfig", end-beg) == 0)
-		{
-		//get the int param which is the config to switch to
-		beg = end;
-		char * e;
-		data = strtol(beg, &e,0);
-		if (beg == e)
-			err = KErrArgument;
-		end = e;
-		command = ESelectConfig;
-		}
-	else if(_strnicmp(beg, "NextConfig", end-beg) == 0)
-		{
-		command = ENextConfig;
-		}
-	else
-		{
-		err = KErrArgument;
-		}
-	if (err != KErrNone)
-		return err;
-	
-	// get the keys	
-	KeyCombination* pCombination = new KeyCombination(data, command);
-	if (!pCombination)
-		return KErrNoMemory;	
-	
-	beg = skipws(end);
-	const char* end2;	
-	for (TInt i=0;i<KMaxHotKeyCombinationLength;i++)
-		{
-		TInt key=KErrNotFound;		
-		end2 = skiptok(beg);
-		TPtrC8 name((const TUint8*)beg, end2-beg);
-		if ((key=iKeyboard.GetScanCode(name))!=KErrNotFound)
-			pCombination->AddKey((TStdScanCode)key);
-		
-		if (beg == end2 || *end2++ != ',') 
-			break;		
-		beg = end2;
-		}
-	return iControlHotKeys.Append(pCombination);
-	}
+	WinsGuiRotateHandler = DWinsGuiRotateHandler::New();
+	if (!WinsGuiRotateHandler)
+		return KErrNoMemory;
+	
+	TheWin=new HWND[systemIni->iScreens.Count()];
+	TheChildWin=new HWND[systemIni->iScreens.Count()];
+	TheScreenBitmap=new HBITMAP[systemIni->iScreens.Count()];
+	CurrentFlipState=new TEmulatorFlip[systemIni->iScreens.Count()];
+
+	if(!TheWin || !TheChildWin || !TheScreenBitmap || !CurrentFlipState)
+		return KErrNoMemory;
+
+	TBufferSet buffer;
+	buffer.iDisplayDriverCount = 0;
+	buffer.iDisplayState = ENormalResolution;
+	buffer.iDisplayBuffer = 0;
+	buffer.iDisplayChannel = NULL;
+
+
+	TInt i;
+	for(i=0;i<systemIni->iScreens.Count();i++)
+		{
+		DScreenProperties *pScr = systemIni->iScreens[i];
+
+		masterIni->InitBitmapHeader(*pScr, &buffer.iInfo);
+		masterIni->InitBufferFormat(*pScr, buffer.iBufferFormat);
+
+		r = masterIni->iBufferSet.Append(buffer);
+		if (r != KErrNone)
+			return r;
+		
+		CurrentFlipState[i] = pScr->iScreenRotation;
+		}
+
+	if (CreateWin32Thread(EThreadEvent, &KernelWindowThread, NULL, ETrue) == NULL)
+		return KErrGeneral;
+
+	for(i=0;i<systemIni->iScreens.Count();i++)
+		{
+		r = Kern::AddHalEntry(EHalGroupDisplay,&DoHalFunction,(TAny*)i,i);
+		if (r != KErrNone)
+			return r;
+		}
+
+	// should really come from Keyboard driver, but not doing it now...
+	r = Kern::AddHalEntry(EHalGroupKeyboard,&DoKbdHalFunction,this);
+	if (r != KErrNone)
+		return r;
+
+	if(systemIni->iXYInputType==EXYInputPointer)
+		{
+		r = Kern::AddHalEntry(EHalGroupDigitiser,&DoXYHalFunction,this);
+		if (r != KErrNone)
+			return r;
+		}
+	else if(systemIni->iXYInputType==EXYInputMouse || systemIni->iXYInputType==EXYInputDeltaMouse)
+		{
+		r = Kern::AddHalEntry(EHalGroupMouse,&DoMouseHalFunction,this);
+		if (r != KErrNone)
+			return r;
+		}
+
+	return r;
+	}
+
+void DMasterIni::InitBitmapHeader(DScreenProperties& aScreenProperties, LPBITMAPV4HEADER aInfo)
+	{
+	TInt width = aScreenProperties.iMaxScreenWidth; 
+	TInt height = aScreenProperties.iMaxScreenHeight;
+	TUint bitsPerPixel = MaximumBitDepthFromMask(aScreenProperties.iColorDepth);
+
+	memset(aInfo, 0, sizeof(BITMAPV4HEADER));
+
+	switch (bitsPerPixel)
+		{
+	case 12:	// XRGB4444
+			aInfo->bV4BitCount = 16;
+			aInfo->bV4V4Compression = BI_BITFIELDS;
+			aInfo->bV4RedMask   = 0x0F00;
+			aInfo->bV4GreenMask = 0x00F0;
+			aInfo->bV4BlueMask  = 0x000F;
+			break;
+	case 16:	// RGB565
+			aInfo->bV4BitCount = 16;
+			aInfo->bV4V4Compression = BI_BITFIELDS;
+			aInfo->bV4RedMask   = 0xF800;
+			aInfo->bV4GreenMask = 0x07E0;
+			aInfo->bV4BlueMask  = 0x001F;
+			break;
+	case 24:	// Really 32bpp, but top 8 unused
+	case 32:	// While 32bpp, top 8 will not be used
+	default:
+			aInfo->bV4BitCount = 32;
+			aInfo->bV4V4Compression = BI_RGB;
+			// Mask is implicit for BI_RGB compression
+			break;
+		}
+	
+	aInfo->bV4Size = sizeof(BITMAPV4HEADER);
+	aInfo->bV4Width = width;
+	aInfo->bV4Height = -height;	// Bitmap runs top to bottom
+	aInfo->bV4Planes = 1;
+	
+	TInt bpp = _ALIGN_UP(aInfo->bV4BitCount, 16); //12 & 16 --> 16 ; 24 & 32 --> 32
+	TInt widthInPixel = aInfo->bV4Width * bpp;
+	//rounding to 32 bits (4 octets) and converting, then, bits to octets;
+	TInt scanLineInBytes = _ALIGN_UP(widthInPixel, 32) >> 3; 
+	aInfo->bV4SizeImage = -aInfo->bV4Height * scanLineInBytes;
+
+	// Set color space as uncalibrated. All other members are then ignored.
+#if defined(LCS_DEVICE_RGB)
+	aInfo->bV4CSType = LCS_DEVICE_RGB;
+#elif defined(LCS_sRGB)
+	aInfo->bV4CSType = LCS_sRGB;
+#endif
+	}
+
+// Helper function that allocates a single frame buffer. 
+static TInt AllocateOneFrameBuffer(TInt aSize, TScreenBuffer &aScreenBuffer)
+	{
+    // Open shared chunk to the composition framebuffer
+	DChunk* chunk = 0;
+	// round to page size
+	if (aSize <= 0)
+		return KErrArgument;
+	TUint round = Kern::RoundToPageSize(aSize);
+	TLinAddr chunkKernelAddr = 0;
+	TUint32 physicalAddress = 0;
+	TUint32 chunkMapAttr = 0;
+
+	// create shared chunk
+	NKern::ThreadEnterCS();
+
+	TChunkCreateInfo info;
+	info.iType = TChunkCreateInfo::ESharedKernelMultiple;
+	info.iMaxSize = round;
+	info.iMapAttr = 0;
+	info.iOwnsMemory = ETrue;
+	info.iDestroyedDfc = 0;
+
+	TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr);
+	if (r == KErrNone)
+		{
+		// map our chunk to specific 
+		r = Kern::ChunkCommitContiguous(chunk, 0, aSize, physicalAddress);
+		if (r != KErrNone)
+			{
+			Kern::ChunkClose(chunk);
+			}
+		}
+
+	if (r == KErrNone)
+		{
+		TBufferAddressA* bufferAddress = new TBufferAddressA;
+		if (!bufferAddress)
+			{
+			r = KErrNoMemory;
+			}
+		else 
+			{
+			bufferAddress->iAddress = (TAny*)chunkKernelAddr;
+			bufferAddress->iChunk = chunk;
+
+			if ((r = aScreenBuffer.iFrameBuffers.Append(bufferAddress->iAddress)) == KErrNone)
+				{
+				r = aScreenBuffer.iMemChunks.Append(bufferAddress);
+				}
+			}
+		}
+	if (r != KErrNone)
+		{
+		Kern::ChunkClose(chunk);
+		}
+	NKern::ThreadLeaveCS();
+	return KErrNone;
+	}
+
+TInt DMasterIni::AllocateFrameBuffers(TInt aScreenNumber, TInt aCount, TInt aSize)
+	{
+	while (aCount--)
+		{
+		TInt r = AllocateOneFrameBuffer(aSize, masterIni->iBufferSet[aScreenNumber].iScreenBuffer);
+		if (r != KErrNone)
+			{
+			return r;
+			}
+		}
+	return KErrNone;
+	}
+
+void DMasterIni::ReleaseFrameBuffers(TInt aScreenNumber)
+	{
+	RPointerArray<TAny>& frameBuffers = masterIni->iBufferSet[aScreenNumber].iScreenBuffer.iFrameBuffers;
+	RPointerArray<TBufferAddressA>& memChunks = masterIni->iBufferSet[aScreenNumber].iScreenBuffer.iMemChunks;
+	RPointerArray<TBufferAddressA>& dsaChunks = masterIni->iBufferSet[aScreenNumber].iDsaBuffer.iMemChunks;
+
+   	NKern::ThreadEnterCS();
+	TInt index;
+	TInt count = memChunks.Count();
+	for (index = 0; index < count; index++)
+		{
+		Kern::ChunkClose(memChunks[index]->iChunk);
+		}
+	count = dsaChunks.Count();
+	for (index = 0; index < count; index++)
+		{
+		Kern::ChunkClose(dsaChunks[index]->iChunk);
+		}
+	NKern::ThreadLeaveCS();
+	
+	frameBuffers.Reset();
+	memChunks.Reset();
+	dsaChunks.Reset();
+	}
+
+
+TProcessAddrEntry::TProcessAddrEntry(DProcess *aProcess, TUint8* aAddress): 
+	iProcess(aProcess), iAddress(aAddress)
+	{
+	}
+
+
+/**
+Contruct a Shared Chunk cleanup object which will be used to clean up 
+after the process/address table entry. 
+*/
+TChunkCleanup::TChunkCleanup(DProcess* aProcess, TInt aScreenNumber)
+    : TDfc((TDfcFn)TChunkCleanup::ChunkDestroyed,this,Kern::SvMsgQue(),0)
+    , iProcess(aProcess)
+    , iScreenNumber(aScreenNumber)
+    , iIndex(-1)
+    {}
+
+/**
+Cancel the action of the cleanup object.
+*/
+void TChunkCleanup::Cancel()
+    {
+    // Clear iProcess which means that when the DFC gets queued on chunk destruction
+    // our ChunkDestroyed method will do nothing other than cleanup itself.
+    iProcess = NULL;
+    }
+
+/**
+Callback function called when the DFC runs, i.e. when a chunk is destroyed.
+*/
+void TChunkCleanup::ChunkDestroyed(TChunkCleanup* aSelf)
+    {
+    DProcess* process = aSelf->iProcess;
+    TInt screenNumber = aSelf->iScreenNumber;
+    TUint index = aSelf->iIndex;
+    // If we haven't been Cancelled...
+    if(process && index != -1)
+        {
+    	if (masterIni->iBufferSet[screenNumber].iProcAddrTable[index].iProcess == process)
+    		{
+    		masterIni->iBufferSet[screenNumber].iProcAddrTable[index].iProcess = 0;
+    		}
+    	else
+    		{
+    		__KTRACE_OPT(KEXTENSION,Kern::Printf("Oops! Someone has messed up our process index!"));
+    		}
+        }
+
+    // We've finished so now delete ourself
+    delete aSelf;
+    }
+
+
+TInt DMasterIni::DisplayMemoryHandle(TInt aScreenNumber, TInt& aHandle)
+	{
+	if (iBufferSet[aScreenNumber].iDsaBuffer.iMemChunks.Count() == 0)
+		{	
+		int r;
+		r = AllocateOneFrameBuffer(iMaxSizeInBytes, iBufferSet[aScreenNumber].iDsaBuffer);
+		if (KErrNone != r)
+			{
+			return r;
+			}
+		__ASSERT_DEBUG(iBufferSet[aScreenNumber].iDisplayChannel, Fault(EGuiNoDisplayChannel));
+		iBufferSet[aScreenNumber].iDisplayChannel->SetLegacyBuffer(iBufferSet[aScreenNumber].iDsaBuffer.iFrameBuffers[0]);
+		}
+	
+	aHandle = Kern::MakeHandleAndOpen(&Kern::CurrentThread(), 
+			iBufferSet[aScreenNumber].iDsaBuffer.iMemChunks[0]->iChunk);
+	
+	if (aHandle < 0)
+		{
+		return aHandle;
+		}
+	
+	return KErrNone;
+	}
+
+
+
+// Find the address of the display memory. 
+TInt DMasterIni::DisplayMemoryAddress(TInt aScreenNumber, TInt& aAddress)
+	{
+	TBufferSet &bufferSet = iBufferSet[aScreenNumber]; 
+	DProcess *process = &Kern::CurrentProcess();
+	TInt firstFree = -1;
+	NKern::FMWait(&iLock);
+	TUint count = bufferSet.iProcAddrTable.Count();
+	for(TUint i = 0; i < count; ++i)
+		{
+		DProcess *curProcess = bufferSet.iProcAddrTable[i].iProcess;
+		if (curProcess == process)
+			{
+			aAddress = reinterpret_cast<TInt>(bufferSet.iProcAddrTable[i].iAddress);
+			NKern::FMSignal(&iLock);
+			return KErrNone;
+			}
+		if (curProcess == 0 && firstFree == -1)
+			{
+			firstFree = i;
+			}
+		}
+	NKern::FMSignal(&iLock);
+	// If we get here, we couldn't find the process in the iProcAddrTable. 
+	// Create a new Process Address entry. 
+	// Step 1
+	// Create a dummy chunk so that we can detect when the process dies, 
+	// give a handle to the user [but don't actually let the process KNOW what the handle is
+	// so the user process can't do anything silly with the chunk]. Close our side of the
+	// chunk to make sure there is only one reference to it. 
+	DChunk* chunk = 0;
+	// find page size for one page. 
+	TUint round = Kern::RoundToPageSize(1);
+	TLinAddr chunkKernelAddr = 0;
+	TUint32 chunkMapAttr = 0;
+	
+	// create shared chunk
+	NKern::ThreadEnterCS();
+	// Cleanup object, used to issue a DFC when the chunk is closed (and 
+	// as the handle of the chunk is not given to the process, it can only
+	// be closed when the process terminates!)
+	TChunkCleanup *cleanup = new TChunkCleanup(process, aScreenNumber);
+	if (!cleanup)
+		{
+		NKern::ThreadLeaveCS();
+		return KErrNoMemory;
+		}
+
+	TChunkCreateInfo info;
+	info.iType = TChunkCreateInfo::ESharedKernelMultiple;
+	info.iMaxSize = round;
+	info.iMapAttr = 0;
+	info.iOwnsMemory = ETrue;
+	info.iDestroyedDfc = cleanup;
+
+	TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr);
+	
+	if (r != KErrNone)
+		{
+		delete cleanup;
+		NKern::ThreadLeaveCS();
+		return r;
+		}
+	
+	
+	// Create a new handle for the user thread. 
+    r = Kern::MakeHandleAndOpen(&Kern::CurrentThread(), chunk);
+	Kern::ChunkClose(chunk);
+	if (r <= 0)
+		{
+		NKern::ThreadLeaveCS();
+		return r;
+		}
+
+	// Step 2
+	// Create a second handle for the chunk to the DSA buffer.
+	// First part: Make sure there is a DisplayMemoryHandle;
+	TInt handle = 0;
+	r = DisplayMemoryHandle(aScreenNumber, handle); 
+	if (r != KErrNone)
+		{
+		Kern::ChunkClose(chunk);
+		NKern::ThreadLeaveCS();
+		return r;
+		}
+	
+	DChunk *dsaChunk = bufferSet.iDsaBuffer.iMemChunks[0]->iChunk;
+	
+	// Step 3
+	// Get the base addrss and insert into table. 
+	TUint8* baseAddress = Kern::ChunkUserBase(dsaChunk, &Kern::CurrentThread());
+	NKern::FMWait(&iLock);
+	// Optimistically, the place we found earlier in the table is still free.
+	if (firstFree != -1 && bufferSet.iProcAddrTable[firstFree].iProcess != 0)
+		{
+		// If not, we go find another one.
+		firstFree = -1;
+		TUint count = bufferSet.iProcAddrTable.Count();
+		for(TUint i = 0; i < count; ++i)
+			{
+			if (bufferSet.iProcAddrTable[i].iProcess == 0)
+				{
+				firstFree = i;
+				break;
+				}
+			}
+		}
+	// Check if there is a free entry - if so, re-use it. 
+	if (firstFree != -1)
+		{
+		bufferSet.iProcAddrTable[firstFree].iProcess = process;
+		bufferSet.iProcAddrTable[firstFree].iAddress = baseAddress;
+		cleanup->SetIndex(firstFree);
+		NKern::FMSignal(&iLock);
+		}
+	else
+		{
+		// No free entry. Append it to the list. 
+		NKern::FMSignal(&iLock);
+		TProcessAddrEntry entry(process, baseAddress);
+		r = bufferSet.iProcAddrTable.Append(entry);
+		if (r != KErrNone)
+			{
+			Kern::ChunkClose(chunk);
+			NKern::ThreadLeaveCS();
+			return r;
+			}
+		// We added it at the end - so we start from the back and check for the 
+		// process, as some other process COULD have added one after us, so we 
+		// can't just use the count for index!
+		TUint index;
+		for(index = bufferSet.iProcAddrTable.Count()-1; index; --index)
+			{
+			if (bufferSet.iProcAddrTable[index].iProcess == process 
+					&& bufferSet.iProcAddrTable[index].iAddress != baseAddress)
+				{
+				break;
+				}
+			}
+		cleanup->SetIndex(index);
+		}
+	aAddress = reinterpret_cast<TInt>(baseAddress);
+
+	NKern::ThreadLeaveCS();
+	return KErrNone;
+	}
+
+EXPORT_C TInt WinsGui::CurrentConfiguration()
+	{
+	return ::CurrentConfiguration;
+	}
+
+GLDEF_C void Fault(TGuiPanic aPanic)
+	{
+	Kern::Fault("WINS-UI",aPanic);
+	}
+
+DECLARE_STANDARD_EXTENSION()
+	{
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("Starting Emulator GUI"));
+
+	// if NoGui property == true do nothing
+	if (Property::GetBool("NoGui",EFalse))
+		return KErrNone;
+
+	// create keyboard driver
+	TInt r=KErrNoMemory;
+	masterIni = new DMasterIni;
+	if (masterIni)
+		{
+		r = masterIni->Create();
+		if (r!= KErrNone)
+			{
+			return r;
+			}
+		}
+	
+	DMultiTouch::iMultiTouchSupported = DMultiTouch::Init();
+
+	// Create multitouch when necessary
+	if (systemIni->MultiTouchEnabled() && systemIni->GCEEnabled() && DMultiTouch::iMultiTouchSupported)
+		{
+		TheMultiTouch = new DMultiTouch(systemIni->MultiTouchProximityStep(),systemIni->MultiTouchPressureStep());
+		if(!TheMultiTouch)
+			{
+			r = KErrNoMemory;
+			__KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
+			return r;
+			}
+		DMultiTouch::iMultiTouchCreated = TRUE;
+		}
+
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
+	return r;
+	}
+
+TInt DWinsUi::DoDefineEmulatorControlHotKey(TAny* aPtr, const char* aValue)
+	{
+	return static_cast<DWinsUi*>(aPtr)->DefineEmulatorControlHotKey(aValue);
+	}
+
+
+TInt DWinsUi::DefineEmulatorControlHotKey(const char* aValue)
+	{
+	const char* beg = skipws(aValue);
+	const char* end = skiptok(beg);
+	TInt err = KErrNone;
+	
+	TEmulCommand command = ENoCommand;
+	TInt data = 0;
+	if (_strnicmp(beg, "SelectConfig", end-beg) == 0)
+		{
+		//get the int param which is the config to switch to
+		beg = end;
+		char * e;
+		data = strtol(beg, &e,0);
+		if (beg == e)
+			err = KErrArgument;
+		end = e;
+		command = ESelectConfig;
+		}
+	else if(_strnicmp(beg, "NextConfig", end-beg) == 0)
+		{
+		command = ENextConfig;
+		}
+	else
+		{
+		err = KErrArgument;
+		}
+	if (err != KErrNone)
+		return err;
+	
+	// get the keys	
+	KeyCombination* pCombination = new KeyCombination(data, command);
+	if (!pCombination)
+		return KErrNoMemory;	
+	
+	beg = skipws(end);
+	const char* end2;	
+	for (TInt i=0;i<KMaxHotKeyCombinationLength;i++)
+		{
+		TInt key=KErrNotFound;		
+		end2 = skiptok(beg);
+		TPtrC8 name((const TUint8*)beg, end2-beg);
+		if ((key=iKeyboard.GetScanCode(name))!=KErrNotFound)
+			pCombination->AddKey((TStdScanCode)key);
+		
+		if (beg == end2 || *end2++ != ',') 
+			break;		
+		beg = end2;
+		}
+	return iControlHotKeys.Append(pCombination);
+	}