# HG changeset patch # User hgs # Date 1287050300 -19800 # Node ID 5aa1c6a27c95b1eb4978e04cf9b5f6d1c6487d21 # Parent 9b324b5dceff47316001c146388a62692fe4b552 201037_03 diff -r 9b324b5dceff -r 5aa1c6a27c95 emulator/emulatorbsp/inc/gui.h --- 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 */ diff -r 9b324b5dceff -r 5aa1c6a27c95 emulator/emulatorbsp/specific/gui.cpp --- 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 -#include -#include -#include -#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;ixiScreens.Count();ix++) - ScreenOff(ix); - } - -void DWinsGuiPowerHandler::ScreenOn() - { - for(TInt ix=0;ixiScreens.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(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=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 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;modeVideoInfoForDisplayDriver(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(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 +#include +#include +#include +#include "variant.h" +#include "resource.h" +#include "winsgui.h" +#include "display_chan.h" +#include "pixelformats.h" +#include "multitouch.h" + +#include "monitors.h" + +#include + +//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;ixiScreens.Count();ix++) + ScreenOff(ix); + } + +void DWinsGuiPowerHandler::ScreenOn() + { + for(TInt ix=0;ixiScreens.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(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=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 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;modeVideoInfoForDisplayDriver(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(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(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(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;iiBufferSet[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;iiScreens[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;iiControlHotKeys.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;iUnRegister()) + { + 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;ixiScreens.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;iiScreens.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;iiScreens.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;ixiScreens.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(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,¤tWindowRect); + 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;screeniScreens.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;screeniScreens.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], ¤tRect); + //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;screeniScreens.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 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 vPckg; + if (systemIni->VideoInfo(aDeviceNumber, vPckg())) + Kern::InfoCopy(*(TDes8*)a1,vPckg); + else + r=KErrNotSupported; + } + break; + + case EDisplayHalSpecifiedModeInfo: + { + kumemget32(&mode, a1, sizeof(mode)); + TPckgBuf 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;iiScreens[aDeviceNumber]->iModeDepths[i]>maxBpp) + maxBpp=systemIni->iScreens[aDeviceNumber]->iModeDepths[i]; + deepestMode= 1<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 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 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(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 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(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 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;screeniFasciaFileName) == 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(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(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(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;iiBufferSet[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;iiScreens[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;iiControlHotKeys.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;iUnRegister()) - { - 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;ixiScreens.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;iiScreens.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;iiScreens.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;ixiScreens.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(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,¤tWindowRect); - 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;screeniScreens.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;screeniScreens.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], ¤tRect); - //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;screeniScreens.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 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 vPckg; - if (systemIni->VideoInfo(aDeviceNumber, vPckg())) - Kern::InfoCopy(*(TDes8*)a1,vPckg); - else - r=KErrNotSupported; - } - break; - - case EDisplayHalSpecifiedModeInfo: - { - kumemget32(&mode, a1, sizeof(mode)); - TPckgBuf 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;iiScreens[aDeviceNumber]->iModeDepths[i]>maxBpp) - maxBpp=systemIni->iScreens[aDeviceNumber]->iModeDepths[i]; - deepestMode= 1<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 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 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(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 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(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 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;screeniFasciaFileName) == 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(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;iiScreens.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;iiScreens.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& frameBuffers = masterIni->iBufferSet[aScreenNumber].iScreenBuffer.iFrameBuffers; - RPointerArray& memChunks = masterIni->iBufferSet[aScreenNumber].iScreenBuffer.iMemChunks; - RPointerArray& 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(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(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(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;iAddKey((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;iiScreens.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;iiScreens.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& frameBuffers = masterIni->iBufferSet[aScreenNumber].iScreenBuffer.iFrameBuffers; + RPointerArray& memChunks = masterIni->iBufferSet[aScreenNumber].iScreenBuffer.iMemChunks; + RPointerArray& 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(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(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(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;iAddKey((TStdScanCode)key); + + if (beg == end2 || *end2++ != ',') + break; + beg = end2; + } + return iControlHotKeys.Append(pCombination); + }