sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "screen.h" sl@0: sl@0: #include sl@0: sl@0: #include "server.h" sl@0: #include "wstop.h" sl@0: #include "rootwin.h" sl@0: #include "walkwindowtree.h" sl@0: #include "offscreenbitmap.h" sl@0: #include "EVENT.H" sl@0: #include "windowgroup.h" sl@0: #include "gc.h" sl@0: #include "inifile.h" sl@0: #include "pointer.h" sl@0: sl@0: #include "debugbar.h" sl@0: #include "ScreenRedraw.h" sl@0: #include "wspluginmanager.h" sl@0: sl@0: GLREF_D CDebugLogBase *wsDebugLog; sl@0: GLREF_D TDisplayMode ParseDisplayMode(const TDesC& aModeName); sl@0: sl@0: LOCAL_D TBool FindNextValue(TLex& aLex, TInt& aValue) // assumes the list cannot contain *negative* integers sl@0: { sl@0: while (!aLex.Eos()) sl@0: { sl@0: const TUint character=aLex.Peek(); sl@0: if (Rng(TUint('0'), character, TUint('9')) || (character=='-')) sl@0: { sl@0: break; sl@0: } sl@0: aLex.Inc(); sl@0: } sl@0: sl@0: return (aLex.Val(aValue)==KErrNone); sl@0: } sl@0: sl@0: CScreen::CFallbackMap * CScreen::CFallbackMap::NewL(CScreen* aScreen) sl@0: { sl@0: CFallbackMap * self = new (ELeave) CFallbackMap(aScreen); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CScreen::CFallbackMap::CFallbackMap(CScreen* aScreen) : sl@0: iScreen(aScreen), sl@0: iRegion(TRect(TPoint(0,0), TSize(1,1))), sl@0: iCount(0) sl@0: { sl@0: } sl@0: sl@0: CScreen::CFallbackMap::~CFallbackMap() sl@0: { sl@0: delete iMap; sl@0: } sl@0: sl@0: void CScreen::CFallbackMap::ConstructL() sl@0: { sl@0: iMapSize = 0; sl@0: sl@0: for (TInt num = 0; num < iScreen->NumScreenSizeModes(); ++num) sl@0: { sl@0: if (iScreen->IsValidScreenSizeMode(num)) sl@0: { sl@0: const TSizeMode & mode = iScreen->ScreenSizeModeData(num); sl@0: TInt width = mode.iScreenSize.iWidth / 32; sl@0: if (mode.iScreenSize.iWidth & (32 - 1)) sl@0: ++width; sl@0: TInt size = width * mode.iScreenSize.iHeight; sl@0: if (size > iMapSize) sl@0: iMapSize = size; sl@0: } sl@0: } sl@0: sl@0: iMap = new (ELeave) TInt [iMapSize]; sl@0: } sl@0: sl@0: void CScreen::CFallbackMap::Prepare() sl@0: { sl@0: const TSizeMode & mode = iScreen->ScreenSizeModeData(); sl@0: Mem::FillZ(iMap, iMapSize * sizeof(TInt)); sl@0: iCount = mode.iScreenSize.iHeight * mode.iScreenSize.iWidth; sl@0: WS_ASSERT_DEBUG(iRegion.Count() == 1, EWsPanicScreenFallback); sl@0: iRegion.Clear(); sl@0: iRegion.AddRect(TRect(mode.iOrigin, mode.iScreenSize)); sl@0: } sl@0: sl@0: TBool CScreen::CFallbackMap::FillRegion(const TRegion& aRegion) sl@0: { sl@0: WS_ASSERT_DEBUG(!aRegion.CheckError(), EWsPanicScreenFallback); sl@0: if (aRegion.Count() > 20 || aRegion.CheckError()) sl@0: return ETrue; sl@0: TBool hit = EFalse; sl@0: if (iCount > 0) sl@0: { sl@0: const TRect * rect = aRegion.RectangleList(); sl@0: for (TInt num = 0; num < aRegion.Count(); ++num) sl@0: { sl@0: hit = FillRect(*rect) || hit; sl@0: if (iCount < 1) sl@0: break; sl@0: ++rect; sl@0: } sl@0: } sl@0: return hit; sl@0: } sl@0: sl@0: // x >> 5 is equivalent to x / 32 sl@0: // 0x1F is the rounding error when dividing by 32 sl@0: // 0x20 is 32. sl@0: // The compiler might do all the optimizations for us - not checked. sl@0: TBool CScreen::CFallbackMap::FillRect(const TRect& aRect) sl@0: { sl@0: TBool hit = EFalse; sl@0: const TSizeMode & mode = iScreen->ScreenSizeModeData(); sl@0: TRect scrrect(mode.iOrigin, mode.iScreenSize); sl@0: TRect rect = aRect; sl@0: rect.Intersection(scrrect); sl@0: TInt rowWidthInInts = mode.iScreenSize.iWidth; sl@0: if (rowWidthInInts & 0x1F) sl@0: rowWidthInInts += 0x20; sl@0: rowWidthInInts >>= 5; sl@0: sl@0: TInt colStartInInts = rect.iTl.iX >> 5; sl@0: TInt firstOffsetInBits = rect.iTl.iX & 0x1F; sl@0: sl@0: for(TInt row = rect.iTl.iY; row < rect.iBr.iY; ++row) sl@0: { sl@0: TInt * map = iMap + row * rowWidthInInts + colStartInInts; sl@0: TInt offsetShift = 31 - firstOffsetInBits; sl@0: for (TInt col = rect.iTl.iX; col < rect.iBr.iX; ++col) sl@0: { sl@0: WS_ASSERT_DEBUG(map - iMap < iMapSize, EWsPanicScreenFallback); sl@0: if (!(*map & 1 << offsetShift)) sl@0: { sl@0: --iCount; sl@0: hit = ETrue; sl@0: if (iCount < 1) sl@0: break; sl@0: (*map) |= (1 << offsetShift); sl@0: } sl@0: --offsetShift; sl@0: if (offsetShift < 0) sl@0: { sl@0: offsetShift = 31; sl@0: ++map; sl@0: } sl@0: } sl@0: } sl@0: return hit; sl@0: } sl@0: sl@0: TInt CScreen::CFallbackMap::Count() const sl@0: { sl@0: return iCount; sl@0: } sl@0: sl@0: const TRect * CScreen::CFallbackMap::Rect() const sl@0: { sl@0: return iRegion.RectangleList(); sl@0: } sl@0: sl@0: const RRegion * CScreen::CFallbackMap::Region() const sl@0: { sl@0: return &iRegion; sl@0: } sl@0: sl@0: // sl@0: // CScreen sl@0: // sl@0: CScreen::CScreen(): iDirects(_FOFF(CWsDirectScreenAccess,iLink)), iMaxContrast(-1), iMaxBrightness(-1) sl@0: { sl@0: } sl@0: sl@0: CScreen::~CScreen() sl@0: { sl@0: delete iDebugBar; sl@0: delete iOffScreenBitmap; sl@0: delete iScreenGdi; sl@0: TInt ii; sl@0: if(iModes) sl@0: { sl@0: for(ii=iNumScreenSizeModes-1;ii>=0;--ii) sl@0: { sl@0: delete (*iModes)[ii]; sl@0: } sl@0: iModes->Close(); sl@0: delete iModes; sl@0: } sl@0: delete iRootWindow; sl@0: delete iScreenDevice; sl@0: delete iFallbackMap; sl@0: delete iSpriteManager; sl@0: delete iRedraw; sl@0: } sl@0: sl@0: void CScreen::ConstructL(const TRect& aDigitiserArea, TInt aScreenNumber ) sl@0: { sl@0: iScreenNumber = aScreenNumber ; sl@0: sl@0: if (wsDebugLog) sl@0: { sl@0: _LIT(KWSERVInitScreen,"Initialising for Screen %d"); sl@0: wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant, KWSERVInitScreen, aScreenNumber); sl@0: } sl@0: sl@0: CreateScreenDeviceL(); sl@0: iScreenDevice->SetAutoUpdate(EFalse); sl@0: iPhysicalScreenSize=iScreenDevice->SizeInPixels(); sl@0: LoadScreenSizesL(iPhysicalScreenSize); sl@0: // mode 0 might not be available, get the first/lowest valid mode sl@0: SetInitialScreenSizeMode(); sl@0: sl@0: iFallbackMap = CFallbackMap::NewL(this); sl@0: // sl@0: iScreenGdi=CFbsBitGc::NewL(); sl@0: iScreenGdi->Activate(iScreenDevice); sl@0: LoadScreenSizeProperties(); sl@0: SetDigitiserAreas(iScreenDevice->SizeInPixels(),aDigitiserArea); sl@0: // sl@0: iScreenGdi->SetOrientation(Orientation()); sl@0: const TSizeMode& sizeMode=ScreenSizeModeData(ScreenSizeMode()); sl@0: iScreenDevice->SetScalingFactor(sizeMode.iOrigin,sizeMode.iScreenScale.iWidth,sizeMode.iScreenScale.iHeight,1,1); sl@0: iScreenDevice->ChangeScreenDevice(NULL); //This is necessary to initialise the screen sl@0: // sl@0: // Off Screen Bitmaps sl@0: iOffScreenBitmap=CWsOffScreenBitmap::NewL(this); sl@0: TSize osbSize(iOffScreenBitmap->Bitmap()->SizeInPixels()); sl@0: TSize osbTwips(sizeMode.iScreenTwipsSize); sl@0: if (osbSize!=sizeMode.iScreenSize) sl@0: { sl@0: // The specified screen twips size is for the specified screen pixel size, however the OSB sl@0: // is potentially larger as it needs to hold the maximum possible screen size, so we need sl@0: // to scale the twips size up correspondingly. sl@0: osbTwips.iWidth=sizeMode.iScreenTwipsSize.iWidth*osbSize.iWidth/sizeMode.iScreenSize.iWidth; sl@0: osbTwips.iHeight=sizeMode.iScreenTwipsSize.iHeight*osbSize.iHeight/sizeMode.iScreenSize.iHeight; sl@0: } sl@0: iOffScreenBitmap->Bitmap()->SetSizeInTwips(osbTwips); sl@0: sl@0: TInt autoClear = 1; sl@0: _LIT(KWSERVIniFileVarAutoClear,"AUTOCLEAR"); sl@0: WsIniFile->FindVar(iScreenNumber,KWSERVIniFileVarAutoClear,autoClear); sl@0: if (autoClear != 0) sl@0: { sl@0: iFlags|=EAutoClear; sl@0: } sl@0: sl@0: _LIT(KBackLight,"BACKLIGHTCONTROL"); sl@0: iBackLightFlag=WsIniFile->FindVar( iScreenNumber, KBackLight); sl@0: sl@0: _LIT(KWSERVIniFileVarBlankScreen, "BLANKSCREENONROTATION"); sl@0: if (WsIniFile->FindVar(iScreenNumber, KWSERVIniFileVarBlankScreen)) sl@0: { sl@0: iFlags|=EBlankScreenOnRotation; sl@0: } sl@0: sl@0: SetShadowVector(TPoint(EDefaultShadowX,EDefaultShadowY)); sl@0: sl@0: iRedraw = CScreenRedraw::NewL(*this); sl@0: sl@0: iRootWindow = new (ELeave) CWsRootWindow(NULL, this); sl@0: iRootWindow->ConstructL(); sl@0: sl@0: TInt refreshRate = 1000000; sl@0: _LIT(KDebugBar, "DEBUGBAR"); sl@0: if (WsIniFile->FindVar(refreshRate, KDebugBar)) sl@0: { sl@0: if (refreshRate < 100000) sl@0: refreshRate = 50000; sl@0: const TPoint origin = CurrentScreenModeOrigin(); sl@0: iDebugBar = CDebugBar::NewL(this, TRect(origin.iX,origin.iY,origin.iX+CurrentScreenSize().iWidth,origin.iY+16), refreshRate); sl@0: } sl@0: // Default fading parameters sl@0: iBlackMap=128; sl@0: iWhiteMap=255; sl@0: sl@0: iSpriteManager = CWsSpriteManager::NewL(); sl@0: //Look for fading plugins here. sl@0: _LIT(KDefaultFaderPluginName, "wsfader"); sl@0: _LIT(KFaderPluginIni,"FADER"); sl@0: CWsPluginManager* mgr = CWsTop::WindowServer()->PluginManager(); sl@0: if (mgr) sl@0: { sl@0: TPtrC faderName; sl@0: if (WsIniFile->FindVar(iScreenNumber, KFaderPluginIni, faderName)) sl@0: iFader = mgr->FindNamedImplementation(faderName); sl@0: else sl@0: iFader = mgr->FindNamedImplementation(KDefaultFaderPluginName); sl@0: } sl@0: sl@0: _LIT(KBltOffScreenBitmap,"BLTOFFSCREENBITMAP"); sl@0: if (WsIniFile->FindVar(iScreenNumber, KBltOffScreenBitmap)) sl@0: { sl@0: iFlags|=EBltOffScreenBitmap; sl@0: } sl@0: } sl@0: sl@0: void CScreen::CreateScreenDeviceL() sl@0: { sl@0: _LIT(KScreenMode,"SCREENMODE"); sl@0: _LIT(KWindowMode,"WINDOWMODE"); sl@0: TPtrC screenModeName; sl@0: TDisplayMode screenMode = ENone; sl@0: if (WsIniFile->FindVar(iScreenNumber, KScreenMode, screenModeName)) sl@0: { sl@0: screenMode = ParseDisplayMode(screenModeName); sl@0: } sl@0: else if (WsIniFile->FindVar(iScreenNumber, KWindowMode, screenModeName)) sl@0: { sl@0: screenMode = ParseDisplayMode(screenModeName); sl@0: } sl@0: sl@0: if (screenMode != ENone) sl@0: { sl@0: if(DoCreateScreenDevice(screenMode)) sl@0: return; sl@0: } sl@0: sl@0: // No screen mode was specified, or we failed creating the specified screen sl@0: // mode. Default to as high display mode as possible. sl@0: sl@0: // Check if the screen device supports 16M colors (it can only support one of sl@0: // 16M, 16MU, 16MA, 16MAP, or none of them) sl@0: screenMode = CFbsDevice::DisplayMode16M(); sl@0: if(screenMode != ENone) sl@0: { sl@0: if(DoCreateScreenDevice(screenMode)) sl@0: return; sl@0: } sl@0: sl@0: // Try creating the screen device with all available display modes, going from best to worst sl@0: __ASSERT_COMPILE(EColorLast == 14); // if any display mode is added to TDisplayMode we must update the list below sl@0: // (the list below contains all enums in TDisplayMode except ENone, ERgb, EColorLast) sl@0: if(DoCreateScreenDevice(EColor16MAP)) sl@0: return; sl@0: if(DoCreateScreenDevice(EColor16MA)) sl@0: return; sl@0: if(DoCreateScreenDevice(EColor16MU)) sl@0: return; sl@0: if(DoCreateScreenDevice(EColor16M)) sl@0: return; sl@0: if(DoCreateScreenDevice(EColor64K)) sl@0: return; sl@0: if(DoCreateScreenDevice(EColor4K)) sl@0: return; sl@0: if(DoCreateScreenDevice(EColor256)) sl@0: return; sl@0: if(DoCreateScreenDevice(EColor16)) sl@0: return; sl@0: if(DoCreateScreenDevice(EGray256)) sl@0: return; sl@0: if(DoCreateScreenDevice(EGray16)) sl@0: return; sl@0: if(DoCreateScreenDevice(EGray4)) sl@0: return; sl@0: if(DoCreateScreenDevice(EGray2)) sl@0: return; sl@0: sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: sl@0: TBool CScreen::DoCreateScreenDevice(TDisplayMode aScreenMode) sl@0: { sl@0: TRAPD(err, iScreenDevice = CFbsScreenDevice::NewL(iScreenNumber, aScreenMode)); sl@0: return (err == KErrNone); sl@0: } sl@0: sl@0: void CScreen::AbortDSAs(RDirectScreenAccess::TTerminationReasons aReason,TSglQue& aDirects) sl@0: { sl@0: if (aDirects.IsEmpty()) sl@0: return; sl@0: TInt nofDSAs = 0; sl@0: TSglQueIter iter(aDirects); sl@0: CWsDirectScreenAccess* direct; sl@0: while (( direct=iter++)!=NULL ) sl@0: { sl@0: nofDSAs++; sl@0: direct->SignalAbort( aReason ); sl@0: } sl@0: sl@0: TRequestStatus timerStatus; sl@0: RTimer& timer=CWsTop::Timer(); sl@0: timer.Cancel(); sl@0: sl@0: TRequestStatus** cancelReqList = (TRequestStatus**) User::AllocZ( sizeof( TRequestStatus* ) * (nofDSAs + 1) ); sl@0: if ( NULL != cancelReqList ) sl@0: { sl@0: TInt dsaNo = 1; sl@0: sl@0: timer.After( timerStatus, KDSAAbortingImmediateRespAwaitFrameMicrosec ); sl@0: sl@0: iter.SetToFirst(); sl@0: while (( direct=iter++)!=NULL ) sl@0: { sl@0: cancelReqList[ dsaNo ] = &direct->AbortStatus(); sl@0: dsaNo++; sl@0: } sl@0: cancelReqList[ 0 ] = &timerStatus; sl@0: sl@0: User::WaitForNRequest( cancelReqList, nofDSAs + 1 ); sl@0: sl@0: iter.SetToFirst(); sl@0: while (( direct=iter++)!=NULL ) sl@0: { sl@0: if ( direct->AbortStatus() != KRequestPending ) sl@0: direct->CancelAbortObject(); // responded sl@0: else sl@0: direct->Abort(); sl@0: } sl@0: sl@0: if (timerStatus == KRequestPending) sl@0: { sl@0: timer.Cancel(); sl@0: User::WaitForRequest( timerStatus ); sl@0: } sl@0: sl@0: User::Free( cancelReqList ); sl@0: } sl@0: else sl@0: { sl@0: iter.SetToFirst(); sl@0: while ((direct=iter++) != NULL) sl@0: { sl@0: sl@0: TRequestStatus timerStatus; sl@0: RTimer& timer=CWsTop::Timer(); sl@0: timer.Cancel(); sl@0: timer.After(timerStatus, KDSAAbortingImmediateRespAwaitFrameMicrosec); sl@0: //wait for response or timeout sl@0: User::WaitForRequest(direct->AbortStatus(), timerStatus); sl@0: sl@0: if (direct->AbortStatus() != KRequestPending) sl@0: direct->CancelAbortObject(); //responded sl@0: else sl@0: direct->Abort(); //timed out sl@0: sl@0: if (timerStatus == KRequestPending) sl@0: { sl@0: timer.Cancel(); sl@0: User::WaitForRequest(timerStatus); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CScreen::AbortAllDirectDrawing(RDirectScreenAccess::TTerminationReasons aReason) sl@0: { sl@0: AbortDSAs(aReason,iDirects); sl@0: } sl@0: sl@0: void CScreen::AddDirect(CWsDirectScreenAccess& aDirect) sl@0: { sl@0: TBool emptyBefore = iDirects.IsEmpty(); sl@0: iDirects.AddLast(aDirect); sl@0: TBool emptyAfter = iDirects.IsEmpty(); sl@0: if (emptyBefore && ! emptyAfter) sl@0: { sl@0: TWsEvent wsevent; sl@0: wsevent.SetType(EEventDirectScreenAccessBegin); sl@0: *(wsevent.Int()) = iScreenNumber; sl@0: TWindowServerEvent::PublishNotification(wsevent); sl@0: } sl@0: sl@0: if (iDsaDrawState==EDsaDrawStateIdle && aDirect.IsVisible()) sl@0: { sl@0: iDsaDrawState = EDsaDrawStateDrawing; sl@0: TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EDsaDrawingBegin, iScreenNumber)); sl@0: } sl@0: } sl@0: sl@0: void CScreen::RemoveDirect(CWsDirectScreenAccess& aDirect) sl@0: { sl@0: TBool emptyBefore = iDirects.IsEmpty(); sl@0: iDirects.Remove(aDirect); sl@0: TBool emptyAfter = iDirects.IsEmpty(); sl@0: if (emptyAfter && ! emptyBefore) sl@0: { sl@0: TWsEvent wsevent; sl@0: wsevent.SetType(EEventDirectScreenAccessEnd); sl@0: *(wsevent.Int()) = iScreenNumber; sl@0: TWindowServerEvent::PublishNotification(wsevent); sl@0: } sl@0: sl@0: if (iDsaDrawState==EDsaDrawStateDrawing && aDirect.IsVisible() && !HasVisibleDirectOnQueue()) sl@0: { sl@0: iDsaDrawState = EDsaDrawStateIdle; sl@0: TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EDsaDrawingEnd, iScreenNumber)); sl@0: } sl@0: } sl@0: sl@0: TBool CScreen::HasVisibleDirectOnQueue() sl@0: { sl@0: if (iDirects.IsEmpty()) sl@0: return EFalse; sl@0: sl@0: TSglQueIter iter(iDirects); sl@0: CWsDirectScreenAccess* dsa; sl@0: while ((dsa=iter++)!=NULL) sl@0: { sl@0: if (dsa->IsVisible()) sl@0: return ETrue; sl@0: } sl@0: sl@0: return EFalse; sl@0: } sl@0: sl@0: #if defined(_DEBUG) sl@0: TBool CScreen::IsDirectOnQueue(const CWsDirectScreenAccess* aDirect) sl@0: { sl@0: TSglQueIter iter(iDirects); sl@0: CWsDirectScreenAccess* direct; sl@0: while ((direct=iter++)!=NULL) sl@0: { sl@0: if (direct==aDirect) sl@0: return ETrue; sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: #if defined(__WINS__) sl@0: void CScreen::UpdateOffScreenBitmap() sl@0: { sl@0: if (iOffScreenBitmap) sl@0: iOffScreenBitmap->Update(); sl@0: } sl@0: #endif sl@0: #endif sl@0: sl@0: void CScreen::KillForegroundSession() sl@0: { sl@0: if (iCurrentFocus) sl@0: { sl@0: _LIT(KWSERVKillWinGp,"Killing Session owning Window Group with Id=%d"); sl@0: if (wsDebugLog) sl@0: wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVKillWinGp,iCurrentFocus->Identifier()); sl@0: iCurrentFocus->WsOwner()->SessionTerminate(); sl@0: } sl@0: } sl@0: sl@0: CWsWindowGroup* CScreen::FindNewFocus(CWsRootWindow* aRootWindow) sl@0: { sl@0: CWsWindowGroup* newFocus; sl@0: for(newFocus=aRootWindow->Child();newFocus && newFocus->CanReceiveFocus()==EFalse;newFocus=newFocus->NextSibling()) {} sl@0: sl@0: return newFocus; sl@0: } sl@0: sl@0: void CScreen::ResetFocus(CWsWindowGroup* aClosingWindow) sl@0: { sl@0: CWsWindowGroup* oldFocus=iCurrentFocus; sl@0: CWsWindowGroup* newFocus=NULL; sl@0: CScreen* newFocusedScreen=NULL; sl@0: iCurrentFocus=FindNewFocus(iRootWindow); sl@0: TBool focusedScreen= EFalse; sl@0: /*Focus policy is specified in the wsini.ini file using the keyword 'MULTIFOCUSPOLICY'. sl@0: If the keyword is not specified, then the default policy is run. sl@0: */ sl@0: if(!CWsTop::MultiFocusPolicy()) sl@0: { sl@0: focusedScreen=(this==CWsTop::CurrentFocusScreen()); //check if this screen is the focus screen sl@0: if (!iCurrentFocus && focusedScreen) sl@0: { sl@0: /*If this screen is the focused screen but does not have a focusable window group, then search for the sl@0: next screen that has a focusable window group and set that screen as the focused screen. sl@0: */ sl@0: CScreen* screen=NULL; sl@0: TInt screenNo; sl@0: for (screenNo=0; screenNoRootWindow()); sl@0: } sl@0: } sl@0: if (newFocus) sl@0: newFocusedScreen=screen; sl@0: } sl@0: } sl@0: /*Scenario A: multi-focus policy sl@0: newFocusedScreen is NULL sl@0: focusedScreen is EFalse sl@0: CWsTop::MultiFocusPolicy() returns ETrue sl@0: Check if the new focusable window group is not the same, send focus lost message to window group sl@0: that has just lost focus and send focus gain message to window group that can receive focus. sl@0: Scenario B: single-focus policy (default) sl@0: CWsTop::MultiFocusPolicy() returns EFalse sl@0: Check if the new focusable window group is not the same or if there is a new focused screen, send focus lost sl@0: message to window group that has just lost focus and send focus gain message to window group that can receive focus. sl@0: */ sl@0: if (iCurrentFocus!=oldFocus || newFocusedScreen) sl@0: { sl@0: if (oldFocus && (focusedScreen||CWsTop::MultiFocusPolicy()) && oldFocus!=aClosingWindow) sl@0: { sl@0: oldFocus->LostFocus(); sl@0: } sl@0: if (newFocusedScreen) sl@0: { sl@0: CWsTop::SetCurrentFocusScreen(newFocusedScreen); sl@0: newFocus->ReceivedFocus(); sl@0: } sl@0: else if (iCurrentFocus && (focusedScreen||CWsTop::MultiFocusPolicy())) sl@0: { sl@0: iCurrentFocus->ReceivedFocus(); sl@0: } sl@0: WsPointer::UpdatePointerCursor(); sl@0: TWindowServerEvent::SendFocusChangedEvents(); sl@0: } sl@0: TWindowServerEvent::SendGroupListChangedEvents(); sl@0: } sl@0: sl@0: void CScreen::SetShadowVector(const TPoint &aShadowShift) sl@0: { sl@0: iShadowShift=aShadowShift; sl@0: } sl@0: sl@0: void CScreen::RemoveFromDefaultOwningList(CWsWindowGroup *aDestroyedGroup) sl@0: { sl@0: for (CWsWindowGroup **group=&iDefaultOwningWindow;*group;group=(*group)->NextDefaultOwningWindowPtr()) sl@0: { sl@0: if (*group==aDestroyedGroup) sl@0: { sl@0: *group=*aDestroyedGroup->NextDefaultOwningWindowPtr(); sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CScreen::SetDefaultOwningWindow(CWsWindowGroup *aGroup) sl@0: { sl@0: RemoveFromDefaultOwningList(aGroup); sl@0: aGroup->SetNextDefaultOwningWindow(iDefaultOwningWindow); sl@0: iDefaultOwningWindow=aGroup; sl@0: } sl@0: sl@0: void CScreen::GetScanLine(const TWsSdCmdGetScanLine *aGetScanLine) sl@0: { sl@0: TRgb buf[EGetScanLineBufLen]; sl@0: TPtr8 des((TUint8 *)&buf[0],EGetScanLineBufLen*sizeof(TRgb)); sl@0: TPoint pos(aGetScanLine->pos); sl@0: TInt read=0; sl@0: TInt len=(des.MaxLength()*EGetScanLineBufLen)/CFbsBitmap::ScanLineLength(EGetScanLineBufLen,aGetScanLine->dispMode); sl@0: if (aGetScanLine->len < 0 || (CFbsBitmap::ScanLineLength(aGetScanLine->len, aGetScanLine->dispMode) > sl@0: CWsClient::CurrentClient()->ClientMessage().GetDesMaxLength(1))) sl@0: { sl@0: CWsClient::PanicCurrentClient(EWservPanicInvalidParameter); sl@0: } sl@0: FOREVER sl@0: { sl@0: if ((aGetScanLine->len-read)len-read; sl@0: iScreenDevice->GetScanLine(des,pos,len,aGetScanLine->dispMode); sl@0: CWsClient::ReplyBuf(des); sl@0: read+=len; sl@0: if (read==aGetScanLine->len) sl@0: break; sl@0: pos.iX+=len; sl@0: } sl@0: } sl@0: sl@0: void CScreen::MaxNumColors(TInt& aColors,TInt& aGrays) sl@0: { sl@0: aGrays=0; sl@0: aColors=TDisplayModeUtils::NumDisplayModeColors(DisplayMode()); sl@0: if (!TDisplayModeUtils::IsDisplayModeColor(DisplayMode())) sl@0: { sl@0: aGrays=aColors; sl@0: aColors=0; sl@0: } sl@0: } sl@0: sl@0: #define MODE_TO_FLAG(x) 1<<(x-1) sl@0: #define ROTATION_TO_FLAG(x) 1<Update(); sl@0: #endif sl@0: sl@0: if (iRedirectGc) sl@0: TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EScreenUpdated, iScreenNumber)); sl@0: else sl@0: iScreenDevice->Update(); sl@0: } sl@0: sl@0: void CScreen::UpdateGcs() sl@0: { sl@0: iScreenGdi->Activate(iScreenDevice); sl@0: } sl@0: sl@0: void CScreen::ChangeDisplayModeForAllOffScreenBitmap(TBool aSwapWidthAndHeight/*=EFalse*/) sl@0: { sl@0: TInt err; sl@0: if (iOffScreenBitmap) sl@0: { sl@0: err=iOffScreenBitmap->DisplayModeChanged(aSwapWidthAndHeight); sl@0: if(err!=KErrNone) sl@0: { sl@0: delete iOffScreenBitmap; sl@0: iOffScreenBitmap=NULL; sl@0: } sl@0: } sl@0: } sl@0: sl@0: CFbsScreenDevice *CScreen::ScreenDevice() sl@0: { sl@0: return(iScreenDevice); sl@0: } sl@0: sl@0: void CScreen::UpdateOrientation() sl@0: { sl@0: CFbsBitGc::TGraphicsOrientation orientation=Orientation(); sl@0: iScreenGdi->SetOrientation(orientation); sl@0: TWservCrEvent crEvent(TWservCrEvent::EScreenOrientationChanged,iScreenNumber,&orientation); sl@0: TWindowServerEvent::NotifyDrawer(crEvent); sl@0: } sl@0: sl@0: void CScreen::SetPointerCursorArea(TInt aMode,const TRect& aRect) sl@0: { sl@0: (*iModes)[aMode]->iPointerCursorArea=aRect; sl@0: WsPointer::SetPointerCursorPos(WsPointer::PointerCursorPos()); sl@0: } sl@0: sl@0: CFbsBitGc::TGraphicsOrientation CScreen::Orientation() sl@0: { sl@0: WS_ASSERT_DEBUG(IsValidScreenSizeMode(iScreenSizeMode),EWsPanicInvalidScreenSizeMode); sl@0: return (*iModes)[iScreenSizeMode]->iRotation; sl@0: } sl@0: sl@0: TRect CScreen::DrawableArea() const sl@0: { sl@0: TRect drawRect; sl@0: iScreenDevice->GetDrawRect(drawRect); sl@0: return drawRect; sl@0: } sl@0: sl@0: TClientPanic CScreen::SetModeRotation(TInt aMode,CFbsBitGc::TGraphicsOrientation aRotation) sl@0: { sl@0: if (!IsValidScreenSizeMode(aMode)) sl@0: return EWservPanicScreenModeNumber; sl@0: TSizeMode& mode=*(*iModes)[aMode]; sl@0: if (!(ROTATION_TO_FLAG(aRotation)&mode.iAlternativeRotations)) sl@0: return EWservPanicRotation; sl@0: TInt oldRotation=mode.iRotation; sl@0: mode.iRotation=aRotation; sl@0: CWsWindowGroup::NewOrientation(aMode,aRotation, iRootWindow); sl@0: if (aMode==ScreenSizeMode()) sl@0: { sl@0: UpdateOrientation(); sl@0: TBool shouldSwapWidthAndHeight=ShouldSwapWidthAndHeightOffScBitmap(oldRotation); sl@0: ChangeDisplayModeForAllOffScreenBitmap(shouldSwapWidthAndHeight); sl@0: iRootWindow->OrientationChanged(); sl@0: } sl@0: return EWservNoPanic; sl@0: } sl@0: sl@0: void CScreen::CycleDisplaySize() sl@0: { sl@0: TInt newMode = iScreenSizeMode; sl@0: TSizeMode* sizeMode = NULL; sl@0: do sl@0: { sl@0: newMode = (newMode+1)%iModes->Count(); sl@0: sizeMode = (*iModes)[newMode]; sl@0: } sl@0: while (sizeMode==NULL); sl@0: doSetScreenMode(newMode); sl@0: } sl@0: sl@0: inline TBool CScreen::ShouldSwapWidthAndHeightOffScBitmap(TInt aOldRotation) sl@0: { sl@0: TInt rot=Abs((*iModes)[iScreenSizeMode]->iRotation-aOldRotation); sl@0: return (rot==1||rot==3); sl@0: } sl@0: sl@0: void CScreen::doSetScreenMode(TInt aMode) sl@0: { sl@0: WS_ASSERT_DEBUG(IsValidScreenSizeMode(aMode),EWsPanicInvalidScreenSizeMode); sl@0: sl@0: TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EScreenSizeModeAboutToChange, aMode)); sl@0: sl@0: TInt oldRotation=(*iModes)[iScreenSizeMode]->iRotation; sl@0: iScreenSizeMode=aMode; sl@0: TBool shouldSwapWidthAndHeight=ShouldSwapWidthAndHeightOffScBitmap(oldRotation); sl@0: CWsWindowGroup::SetScreenDeviceValidStates(ETrue,shouldSwapWidthAndHeight,this); sl@0: if (shouldSwapWidthAndHeight) sl@0: { sl@0: SetPhysicalScreenSize(); sl@0: } sl@0: TWindowServerEvent::SendScreenDeviceChangedEvents(this); sl@0: ResetFocus(NULL); sl@0: } sl@0: sl@0: void CScreen::UpdateOffScreenBitmapGc(const TBool aSwapWidthAndHeight) sl@0: { sl@0: if (iOffScreenBitmap) sl@0: { sl@0: iOffScreenBitmap->UpdateGc(aSwapWidthAndHeight); sl@0: } sl@0: } sl@0: sl@0: void CScreen::CycleOrientation() sl@0: { sl@0: WS_ASSERT_DEBUG(IsValidScreenSizeMode(iScreenSizeMode),EWsPanicInvalidScreenSizeMode); sl@0: TSizeMode& currentSizeMode=*(*iModes)[iScreenSizeMode]; sl@0: TUint rotations=currentSizeMode.iAlternativeRotations; sl@0: TInt currentRotation=currentSizeMode.iRotation; sl@0: TInt rotation=currentRotation+1; sl@0: while (rotation!=currentRotation) sl@0: { sl@0: if (rotation>CFbsBitGc::EGraphicsOrientationRotated270) sl@0: rotation=CFbsBitGc::EGraphicsOrientationNormal; sl@0: if (ROTATION_TO_FLAG(rotation)&rotations) sl@0: break; sl@0: ++rotation; sl@0: } sl@0: if (rotation==currentRotation) sl@0: { sl@0: if (rotation>CFbsBitGc::EGraphicsOrientationRotated90) sl@0: rotation-=2; sl@0: else sl@0: rotation+=2; sl@0: } sl@0: currentSizeMode.iRotation=REINTERPRET_CAST(CFbsBitGc::TGraphicsOrientation&,rotation); sl@0: CWsWindowGroup::NewOrientation(iScreenSizeMode,currentSizeMode.iRotation, iRootWindow); sl@0: sl@0: UpdateOrientation(); sl@0: TBool shouldSwapWidthAndHeight=ShouldSwapWidthAndHeightOffScBitmap(currentRotation); sl@0: ChangeDisplayModeForAllOffScreenBitmap(shouldSwapWidthAndHeight); sl@0: if (shouldSwapWidthAndHeight) sl@0: { sl@0: SetPhysicalScreenSize(); sl@0: } sl@0: iRootWindow->OrientationChanged(); sl@0: } sl@0: sl@0: TPoint CScreen::PhysicalToLogical(TPoint aPhysicalPt) sl@0: { sl@0: const TSizeMode& mode=ScreenSizeModeData(); sl@0: TPoint logicalPt; sl@0: logicalPt=aPhysicalPt-mode.iOrigin; sl@0: if (mode.iScreenScale.iWidth!=1) sl@0: logicalPt.iX=(logicalPt.iX>=0 ? logicalPt.iX/mode.iScreenScale.iWidth : (logicalPt.iX-(mode.iScreenScale.iWidth-1))/mode.iScreenScale.iWidth); sl@0: if (mode.iScreenScale.iHeight!=1) sl@0: logicalPt.iY=(logicalPt.iY>=0 ? logicalPt.iY/mode.iScreenScale.iHeight : (logicalPt.iY-(mode.iScreenScale.iHeight-1))/mode.iScreenScale.iHeight); sl@0: return logicalPt; sl@0: } sl@0: sl@0: void CScreen::LoadScreenSizesL(TSize aScreenSize) sl@0: { sl@0: _LIT(KWSERVNumScrSizeMode, "NUMSCREENMODES"); sl@0: TBool allowScrGap=WsIniFile->FindVar(iScreenNumber, KWSERVNumScrSizeMode, iNumScreenSizeModes); sl@0: iModes=new(ELeave) RPointerArray(1); sl@0: WS_ASSERT_DEBUG(!allowScrGap || (allowScrGap && iNumScreenSizeModes>0), EWsPanicInvalidScreenSizeMode); sl@0: TInt screenNum=0; sl@0: FOREVER sl@0: { sl@0: ++screenNum; sl@0: TBuf<32> varNameWidth; sl@0: TBuf<32> varNameHeight; sl@0: _LIT(KWSERVScreenWidthPattern,"SCR_WIDTH%d"); sl@0: varNameWidth.Format(KWSERVScreenWidthPattern,screenNum); sl@0: _LIT(KWSERVScreenHeightPattern,"SCR_HEIGHT%d"); sl@0: varNameHeight.Format(KWSERVScreenHeightPattern,screenNum); sl@0: TSize screenSize; sl@0: if (!WsIniFile->FindVar(iScreenNumber, varNameWidth, screenSize.iWidth) || sl@0: !WsIniFile->FindVar(iScreenNumber, varNameHeight, screenSize.iHeight)) sl@0: { sl@0: if (allowScrGap && screenNum<=iNumScreenSizeModes) sl@0: { sl@0: iModes->AppendL(NULL); sl@0: continue; sl@0: } sl@0: else sl@0: break; sl@0: } sl@0: if (screenSize.iWidth==0 && screenSize.iHeight==0) sl@0: screenSize=aScreenSize; sl@0: TSizeMode* newSizeMode=new(ELeave) TSizeMode(screenSize); sl@0: CleanupStack::PushL(newSizeMode); sl@0: iModes->AppendL(newSizeMode); sl@0: CleanupStack::Pop(newSizeMode); sl@0: ++iNumSupportedScreenSizeModes; sl@0: } sl@0: // If sparse index is enabled and no screen size mode defined, all iModes entries will be NULL sl@0: // Otherwise iModes will be empty sl@0: if (iModes->Count()==0 || iNumSupportedScreenSizeModes==0) sl@0: { sl@0: TSizeMode* defaultSizeMode=new(ELeave) TSizeMode(aScreenSize); sl@0: if (iModes->Count()>0) sl@0: (*iModes)[0]=defaultSizeMode; sl@0: else sl@0: { sl@0: CleanupStack::PushL(defaultSizeMode); sl@0: iModes->AppendL(defaultSizeMode); sl@0: CleanupStack::Pop(defaultSizeMode); sl@0: } sl@0: ++iNumSupportedScreenSizeModes; sl@0: } sl@0: if (!allowScrGap) sl@0: iNumScreenSizeModes=iNumSupportedScreenSizeModes; sl@0: } sl@0: sl@0: void CScreen::LoadScreenSizeProperties() sl@0: { sl@0: TBool orientations[4]; sl@0: TUint allowableRotations=0; sl@0: TInt ii; sl@0: iScreenGdi->OrientationsAvailable(orientations); sl@0: for (ii=0;ii<4;++ii) sl@0: { sl@0: if (orientations[ii]) sl@0: allowableRotations|=ROTATION_TO_FLAG(ii); sl@0: } sl@0: TBuf<32> xScale; sl@0: TBuf<32> yScale; sl@0: _LIT(KWSERVScreenXScale,"SCR_XSCALE%d"); sl@0: _LIT(KWSERVScreenYScale,"SCR_YSCALE%d"); sl@0: for(TInt sizeLoop=0;sizeLoopCount();sizeLoop++) sl@0: { sl@0: TSizeMode* modePtr=(*iModes)[sizeLoop]; sl@0: if (!modePtr) sl@0: continue; sl@0: TSizeMode& mode=*modePtr; sl@0: TBuf<32> varLeft; sl@0: TBuf<32> varTop; sl@0: TBuf<32> varRotation; sl@0: TBuf<32> varNameWidth; sl@0: TBuf<32> varNameHeight; sl@0: TBuf<32> varDisplayMode; sl@0: _LIT(KWSERVScreenLeftPattern,"SCR_LEFT%d"); sl@0: varLeft.Format(KWSERVScreenLeftPattern,sizeLoop+1); sl@0: _LIT(KWSERVScreenTopPattern,"SCR_TOP%d"); sl@0: varTop.Format(KWSERVScreenTopPattern,sizeLoop+1); sl@0: _LIT(KWSERVScreenRotationPattern,"SCR_ROTATION%d"); sl@0: varRotation.Format(KWSERVScreenRotationPattern,sizeLoop+1); sl@0: _LIT(KWSERVScreenTwipWidthPattern,"SCR_TWIP_WIDTH%d"); sl@0: varNameWidth.Format(KWSERVScreenTwipWidthPattern,sizeLoop+1); sl@0: _LIT(KWSERVScreenTwipHeightPattern,"SCR_TWIP_HEIGHT%d"); sl@0: varNameHeight.Format(KWSERVScreenTwipHeightPattern,sizeLoop+1); sl@0: _LIT(KWSERVScreenDisplayModePattern,"SCR_WINDOWMODE%d"); sl@0: varDisplayMode.Format(KWSERVScreenDisplayModePattern,sizeLoop+1); sl@0: xScale.Format(KWSERVScreenXScale,sizeLoop+1); sl@0: yScale.Format(KWSERVScreenYScale,sizeLoop+1); sl@0: if (!WsIniFile->FindVar(iScreenNumber,xScale,mode.iScreenScale.iWidth)) sl@0: { sl@0: mode.iScreenScale.iWidth=1; sl@0: } sl@0: if (!WsIniFile->FindVar(iScreenNumber,yScale,mode.iScreenScale.iHeight)) sl@0: { sl@0: mode.iScreenScale.iHeight=1; sl@0: } sl@0: if (!WsIniFile->FindVar( iScreenNumber, varLeft,mode.iOrigin.iX)) sl@0: { sl@0: mode.iOrigin.iX=0; sl@0: } sl@0: if (!WsIniFile->FindVar( iScreenNumber, varTop,mode.iOrigin.iY)) sl@0: { sl@0: mode.iOrigin.iY=0; sl@0: } sl@0: TPtrC displayModeName(NULL,0); sl@0: mode.iDefaultDisplayMode = iScreenDevice->DisplayMode(); sl@0: TInt rotation=CFbsBitGc::EGraphicsOrientationNormal; sl@0: TUint allRotations=0; sl@0: TPtrC rotList(NULL,0); sl@0: if (WsIniFile->FindVar( iScreenNumber, varRotation,rotList)) sl@0: { sl@0: TLex lex(rotList); sl@0: TBool foundOne=EFalse; sl@0: TInt rot; sl@0: sl@0: while (!lex.Eos()) sl@0: { sl@0: if (!FindNextValue(lex, rot)) sl@0: { sl@0: break; sl@0: } sl@0: if (rot<0 || rot>360) sl@0: { sl@0: continue; sl@0: } sl@0: if (rot>4) sl@0: { sl@0: rot/=90; sl@0: } sl@0: if (!foundOne) sl@0: { sl@0: rotation=rot; sl@0: foundOne=ETrue; sl@0: } sl@0: if (rot<=CFbsBitGc::EGraphicsOrientationRotated270) sl@0: { sl@0: allRotations|=ROTATION_TO_FLAG(rot); sl@0: } sl@0: } sl@0: } sl@0: if (allRotations==0) sl@0: allRotations=ROTATION_TO_FLAG(rotation); sl@0: WS_ASSERT_ALWAYS((ROTATION_TO_FLAG(rotation)&allowableRotations)>0, EWsPanicFailedToInitialise); sl@0: mode.iRotation=(CFbsBitGc::TGraphicsOrientation&)rotation; sl@0: mode.iAlternativeRotations=allRotations & allowableRotations; sl@0: sl@0: TSize twipsSize; sl@0: TSize pixels(mode.iScreenSize); sl@0: sl@0: switch(mode.iRotation) sl@0: { sl@0: // CFbsBitGc::TGraphicsOrientation sl@0: case CFbsBitGc::EGraphicsOrientationRotated90: sl@0: case CFbsBitGc::EGraphicsOrientationRotated270: sl@0: { sl@0: //swap the axes in order to use the correct twips per pixel ratio, as CFbsScreenDevice sl@0: //does not take into consideration rotation, when converting pixels to twips sl@0: if (!WsIniFile->FindVar( iScreenNumber, varNameWidth,twipsSize.iWidth)) sl@0: twipsSize.iWidth=iScreenDevice->VerticalPixelsToTwips(pixels.iWidth); sl@0: if (!WsIniFile->FindVar( iScreenNumber, varNameHeight,twipsSize.iHeight)) sl@0: twipsSize.iHeight=iScreenDevice->HorizontalPixelsToTwips(pixels.iHeight); sl@0: break; sl@0: } sl@0: case CFbsBitGc::EGraphicsOrientationNormal: sl@0: case CFbsBitGc::EGraphicsOrientationRotated180: sl@0: { sl@0: if (!WsIniFile->FindVar( iScreenNumber, varNameWidth,twipsSize.iWidth)) sl@0: twipsSize.iWidth=iScreenDevice->HorizontalPixelsToTwips(pixels.iWidth); sl@0: if (!WsIniFile->FindVar( iScreenNumber, varNameHeight,twipsSize.iHeight)) sl@0: twipsSize.iHeight=iScreenDevice->VerticalPixelsToTwips(pixels.iHeight); sl@0: break; sl@0: } sl@0: default: sl@0: WS_PANIC_ALWAYS(EWsPanicFailedToInitialise); sl@0: break; sl@0: } sl@0: mode.iScreenTwipsSize=twipsSize; sl@0: } sl@0: // sl@0: TInt intForFindVar=0; sl@0: _LIT(KWSERVIniFileVarSizeMode,"SIZE_MODE"); sl@0: WsIniFile->FindVar( iScreenNumber, KWSERVIniFileVarSizeMode,intForFindVar); sl@0: iSizeEnforcementMode=(TScreenModeEnforcement)intForFindVar; sl@0: } sl@0: sl@0: void CScreen::SetDigitiserAreas(const TSize& aScreenSize,const TRect& aDigitiserArea) sl@0: { sl@0: for(TInt sizeLoop=0;sizeLoopCount();sizeLoop++) sl@0: { sl@0: TSizeMode* modePtr=(*iModes)[sizeLoop]; sl@0: if (!modePtr) sl@0: continue; sl@0: TSizeMode& mode=*modePtr; sl@0: switch (mode.iRotation) sl@0: { sl@0: case CFbsBitGc::EGraphicsOrientationNormal: sl@0: mode.iPointerCursorArea=aDigitiserArea; sl@0: continue; sl@0: case CFbsBitGc::EGraphicsOrientationRotated90: sl@0: mode.iPointerCursorArea.SetRect(aDigitiserArea.iTl.iY,aScreenSize.iWidth-aDigitiserArea.iBr.iX, sl@0: aDigitiserArea.iBr.iY,aScreenSize.iWidth-aDigitiserArea.iTl.iX); sl@0: break; sl@0: case CFbsBitGc::EGraphicsOrientationRotated180: sl@0: mode.iPointerCursorArea.SetRect(-(aDigitiserArea.iBr-aScreenSize),-(aDigitiserArea.iTl-aScreenSize)); sl@0: break; sl@0: case CFbsBitGc::EGraphicsOrientationRotated270: sl@0: mode.iPointerCursorArea.SetRect(aScreenSize.iHeight-aDigitiserArea.iBr.iY,aDigitiserArea.iTl.iX, sl@0: aScreenSize.iHeight-aDigitiserArea.iTl.iY,aDigitiserArea.iBr.iX); sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CScreen::GetScreenSizeAndRotation(TPixelsTwipsAndRotation &aSar, TInt aScreenMode) sl@0: { sl@0: TSizeMode& mode=*(*iModes)[aScreenMode]; sl@0: aSar.iRotation=mode.iRotation; sl@0: aSar.iPixelSize=mode.iScreenSize; sl@0: aSar.iTwipsSize=mode.iScreenTwipsSize; sl@0: if (aSar.iTwipsSize.iWidth==0) sl@0: { sl@0: aSar.iTwipsSize.iWidth=iScreenDevice->HorizontalPixelsToTwips(aSar.iPixelSize.iWidth); sl@0: aSar.iTwipsSize.iHeight=iScreenDevice->VerticalPixelsToTwips(aSar.iPixelSize.iHeight); sl@0: } sl@0: } sl@0: sl@0: void CScreen::GetScreenSizeAndRotation(TPixelsAndRotation &aSar, TInt aScreenMode) sl@0: { sl@0: TSizeMode& mode=*(*iModes)[aScreenMode]; sl@0: aSar.iRotation=mode.iRotation; sl@0: aSar.iPixelSize=mode.iScreenSize; sl@0: } sl@0: sl@0: TBool CScreen::SetScreenModeEnforcement(TInt aMode) sl@0: { sl@0: if (aMode<0 || aMode>ESizeEnforcementPixelsTwipsAndRotation) sl@0: return EFalse; sl@0: TScreenModeEnforcement newMode=(TScreenModeEnforcement)aMode; sl@0: if (newMode!=iSizeEnforcementMode) sl@0: { sl@0: iSizeEnforcementMode=newMode; sl@0: CWsWindowGroup::SetScreenDeviceValidStates(EFalse,EFalse,this); sl@0: ResetFocus(NULL); sl@0: } sl@0: return ETrue; sl@0: } sl@0: sl@0: CWsOffScreenBitmap* CScreen::OffScreenBitmap() sl@0: { sl@0: return iOffScreenBitmap; sl@0: } sl@0: sl@0: CFbsDevice * CScreen::DrawDevice() sl@0: { sl@0: if (iOffScreenBitmap) sl@0: return iOffScreenBitmap->BitmapDevice(); sl@0: else sl@0: return ScreenDevice(); sl@0: } sl@0: sl@0: void CScreen::FreeOffScreenBitmap() sl@0: { sl@0: // for Flicker Free test sl@0: /** Andy - this either needs to talk to render stages or simply be removed. sl@0: Deleting the OSB when CRPs already know it exists is one thing - we dont do it while sl@0: testing ones that can't cope - deleting it when render stages use it is something else. sl@0: Fortunately we never actually use it. sl@0: if (iOffScreenBitmap) sl@0: { sl@0: delete iOffScreenBitmap; sl@0: iOffScreenBitmap = NULL; sl@0: } sl@0: */ sl@0: } sl@0: sl@0: void CScreen::IncContrast() sl@0: { sl@0: TInt contrast; sl@0: if (iMaxContrast<0) //If failed to get it sofar get it again sl@0: TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Get(iScreenNumber,HALData::EDisplayContrastMax,iMaxContrast)); sl@0: if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Get(iScreenNumber,HALData::EDisplayContrast,contrast))) sl@0: return; sl@0: if (contrast==iMaxContrast) sl@0: contrast=-1; sl@0: TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Set(iScreenNumber,HALData::EDisplayContrast,++contrast)); sl@0: } sl@0: sl@0: void CScreen::DecContrast() sl@0: { sl@0: TInt contrast; sl@0: if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Get(iScreenNumber,HALData::EDisplayContrast,contrast))) sl@0: return; sl@0: if (contrast==0) sl@0: { sl@0: if (iMaxContrast<0 && TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, sl@0: HAL::Get(iScreenNumber,HALData::EDisplayContrastMax,iMaxContrast))) sl@0: return; sl@0: contrast=iMaxContrast+1; sl@0: } sl@0: TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EContrast, HAL::Set(iScreenNumber,HALData::EDisplayContrast,--contrast)); sl@0: } sl@0: sl@0: void CScreen::IncBrightness() sl@0: { sl@0: TInt brightness; sl@0: if (iMaxBrightness<0) //If failed to get it sofar get it again sl@0: TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(iScreenNumber,HALData::EDisplayBrightnessMax,iMaxBrightness)); sl@0: if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(iScreenNumber,HALData::EDisplayBrightness,brightness))) sl@0: return; sl@0: if (brightness==iMaxBrightness) sl@0: brightness=-1; sl@0: TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(iScreenNumber,HALData::EDisplayBrightness,++brightness)); sl@0: } sl@0: sl@0: void CScreen::DecBrightness() sl@0: { sl@0: TInt brightness; sl@0: if (TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(iScreenNumber,HALData::EDisplayBrightness,brightness))) sl@0: return; sl@0: if (brightness==0) sl@0: { sl@0: if (iMaxBrightness<0 && TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, sl@0: HAL::Get(iScreenNumber,HALData::EDisplayBrightnessMax,iMaxBrightness))) sl@0: return; sl@0: brightness=iMaxBrightness+1; sl@0: } sl@0: TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(iScreenNumber,HALData::EDisplayBrightness,--brightness)); sl@0: } sl@0: sl@0: TInt CScreen::GetScreenSizeModeListL() sl@0: { sl@0: RArray list(iNumScreenSizeModes); sl@0: CleanupClosePushL(list); sl@0: TInt index; sl@0: for (index=0; indexCount(); ++index) sl@0: { sl@0: TSizeMode* modePtr=(*iModes)[index]; sl@0: if (modePtr) sl@0: list.AppendL(index); sl@0: } sl@0: TInt count=list.Count(); sl@0: CWsClient::ReplyBuf(&list[0], count*sizeof(TInt)); sl@0: CleanupStack::PopAndDestroy(&list); sl@0: return count; sl@0: } sl@0: sl@0: void CScreen::SetInitialScreenSizeMode() sl@0: { sl@0: // get first/lowest valid screen size mode, if mode 0 not available sl@0: TInt index; sl@0: for (index=0; indexCount(); ++index) sl@0: { sl@0: TSizeMode* modePtr=(*iModes)[index]; sl@0: if (modePtr) sl@0: { sl@0: iScreenSizeMode=index; sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: TDisplayMode CScreen::FirstDefaultDisplayMode() const sl@0: { sl@0: TInt mode=-1; sl@0: while ((*iModes)[++mode]==NULL) sl@0: { sl@0: WS_ASSERT_DEBUG(modeCount()-1,EWsPanicInvalidScreenSizeMode); sl@0: } sl@0: return((*iModes)[mode]->iDefaultDisplayMode); sl@0: } sl@0: sl@0: CFbsDevice* CScreen::GetFbsDevice() sl@0: { sl@0: if (iRedirectGc) sl@0: { sl@0: WS_ASSERT_DEBUG(iRedirectGc->Device(), EWsPanicNullDeviceHandle); sl@0: return static_cast(iRedirectGc->Device()); sl@0: } sl@0: else sl@0: { sl@0: return iScreenDevice; sl@0: } sl@0: } sl@0: sl@0: void CScreen::AddRedrawRegion(const TRegion& aRegion, TBool aSchedule, TRedrawDepth aDepth) sl@0: { sl@0: iRedraw->AddRedrawRegion(aRegion, aSchedule, aDepth); sl@0: } sl@0: sl@0: void CScreen::DoRedrawNow() sl@0: { sl@0: iRedraw->DoRedrawNow(); sl@0: } sl@0: sl@0: // implementing MWsScreen sl@0: sl@0: const TTime& CScreen::Now() const sl@0: { sl@0: return iRedraw->Now(); sl@0: } sl@0: sl@0: void CScreen::ScheduleAnimation(const TRect& aRect,const TTimeIntervalMicroSeconds& aFromNow,const TTimeIntervalMicroSeconds& aFreq,const TTimeIntervalMicroSeconds& aStop) sl@0: { sl@0: iRedraw->ScheduleAnimation(aRect,aFromNow,aFreq,aStop); sl@0: } sl@0: sl@0: void CScreen::OnAnimation() sl@0: { sl@0: iRedraw->OnAnimation(); sl@0: } sl@0: sl@0: void CScreen::Redraw() sl@0: { sl@0: STACK_REGION bounds; sl@0: bounds.AddRect(DrawableArea()); sl@0: AddRedrawRegion(bounds); sl@0: bounds.Close(); sl@0: } sl@0: sl@0: TBool CScreen::RedrawInvalid(const TArray& aInvalid) sl@0: { sl@0: TBool wasDirty = EFalse; sl@0: STACK_REGION bounds; sl@0: bounds.AddRect(DrawableArea()); sl@0: STACK_REGION dirty; sl@0: TWalkWindowTreeCalcInvalidGraphics calc(&bounds,dirty,aInvalid); sl@0: if(calc.CreateSubRegion()) sl@0: { sl@0: calc.CalcInvalid(*this); sl@0: if(dirty.CheckError() || dirty.Count()) sl@0: { sl@0: Redraw(); sl@0: wasDirty = ETrue; sl@0: } sl@0: calc.DestroyRegions(); sl@0: } sl@0: dirty.Close(); sl@0: bounds.Close(); sl@0: return wasDirty; sl@0: } sl@0: sl@0: /** sl@0: Overidding MWsObjectProvider sl@0: */ sl@0: TAny* CScreen::ResolveObjectInterface(TUint aTypeId) sl@0: { sl@0: TAny* interface = NULL; sl@0: sl@0: switch (aTypeId) sl@0: { sl@0: case MWsScreenConfig::EWsObjectInterfaceId: sl@0: interface = static_cast(this); sl@0: break; sl@0: case MWsFrontBuffer::EWsObjectInterfaceId: sl@0: interface = static_cast(this); sl@0: break; sl@0: case MWsWindow::EWsObjectInterfaceId: sl@0: interface = static_cast(RootWindow()); sl@0: break; sl@0: } sl@0: sl@0: if (!interface && iOffScreenBitmap) sl@0: interface = iOffScreenBitmap->ResolveObjectInterface(aTypeId); sl@0: sl@0: if (!interface) sl@0: interface = iRedraw->ResolveObjectInterface(aTypeId); sl@0: sl@0: return interface; sl@0: } sl@0: sl@0: /** sl@0: Implementing MWsScreenConfig sl@0: */ sl@0: TDisplayMode CScreen::DisplayMode() const sl@0: { sl@0: return iScreenDevice->DisplayMode(); sl@0: } sl@0: sl@0: TSize CScreen::SizeInPixels() const sl@0: { sl@0: return iScreenDevice->SizeInPixels(); sl@0: } sl@0: sl@0: TSize CScreen::ScreenModeSizeInPixels() const sl@0: { sl@0: return (*iModes)[iScreenSizeMode]->iScreenSize; sl@0: } sl@0: sl@0: TInt CScreen::Stride() const sl@0: { sl@0: return iScreenDevice->Stride(); sl@0: } sl@0: sl@0: CFbsBitGc::TGraphicsOrientation CScreen::Orientation() const sl@0: { sl@0: return iScreenDevice->Orientation(); sl@0: } sl@0: sl@0: TInt CScreen::SizeMode() const sl@0: { sl@0: return iScreenSizeMode; sl@0: } sl@0: sl@0: TSize CScreen::ScalingFactor() const sl@0: { sl@0: return (*iModes)[iScreenSizeMode]->iScreenScale; sl@0: } sl@0: sl@0: TPoint CScreen::Origin() const sl@0: { sl@0: return (*iModes)[iScreenSizeMode]->iOrigin; sl@0: } sl@0: sl@0: TPoint CScreen::ScaledOrigin() const sl@0: { sl@0: return (*iModes)[iScreenSizeMode]->ScaledOrigin(); sl@0: } sl@0: sl@0: /** sl@0: Implementing MWsFrontBuffer sl@0: */ sl@0: const TAny* CScreen::GetBits() sl@0: { sl@0: return iScreenDevice->Bits(); sl@0: } sl@0: sl@0: CFbsBitGc* CScreen::GetBitGc() sl@0: { sl@0: return iScreenGdi; sl@0: } sl@0: sl@0: CFbsBitGc* CScreen::GetBitGcCurrent() sl@0: { sl@0: if (iRedirectGc) sl@0: return iRedirectGc; sl@0: else sl@0: return iScreenGdi; sl@0: } sl@0: sl@0: /** sl@0: Redirect screen drawing to specified gc. Passing NULL will stop redirection. sl@0: */ sl@0: TInt CScreen::SetBitGc(CFbsBitGc* aBitGc) sl@0: { sl@0: if (aBitGc && (aBitGc==iScreenGdi || aBitGc==iRedirectGc)) sl@0: return KErrAlreadyExists; sl@0: sl@0: if (aBitGc && !aBitGc->Device()) sl@0: return KErrArgument; sl@0: sl@0: // screen shall not be redirected when there is at least one DSA client is actively drawing sl@0: if (aBitGc && iDsaDrawState==EDsaDrawStateDrawing) sl@0: return KErrInUse; sl@0: sl@0: iRedirectGc = aBitGc; sl@0: sl@0: // Redraw window CWindowGC objects have CFbsBitGcs active on the screen device and need reactivating: sl@0: TWalkWindowTreeReactivateGcs wwt; sl@0: RootWindow()->WalkWindowTree(wwt, EWalkChildren); sl@0: sl@0: // Andy - should we do something with the CPlaybackGc here? Can they be active at this point? sl@0: // if so, do they care, or should it already be handled for them? sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CScreen::SetBitGc(CFbsBitGc* aBitGc, TBool aInvalidateScreen) sl@0: { sl@0: const TInt err = SetBitGc(aBitGc); sl@0: sl@0: if (err==KErrNone && aInvalidateScreen) sl@0: iRootWindow->InvalidateWholeScreen(); sl@0: sl@0: return err; sl@0: } sl@0: sl@0: void CScreen::DiscardAllSchedules() sl@0: { sl@0: iRedraw->DiscardAllSchedules(); sl@0: } sl@0: sl@0: void CScreen::ScheduleRegionUpdate(const TRegion* aDefinitelyDirty) sl@0: { sl@0: iRedraw->ScheduleRegionUpdate(aDefinitelyDirty); sl@0: } sl@0: void CScreen::DSARegionSyncStart( CWsDirectScreenAccess& aDSA ) sl@0: { sl@0: iRedraw->BanThisRegionUpdate( aDSA.RegionUnderSync() ); sl@0: } sl@0: sl@0: void CScreen::DSARegionSyncOver( CWsDirectScreenAccess& aDSA ) sl@0: { sl@0: iRedraw->LiftRegionUpdateBan( aDSA.RegionUnderSync() ); sl@0: } sl@0: sl@0: TBool CScreen::IsUpdatePending() sl@0: { sl@0: return iRedraw->IsUpdatePending(); sl@0: } sl@0: sl@0: TBool CScreen::IsDSAClientWindow( const CWsClientWindow* aWin ) const sl@0: { sl@0: TBool res = EFalse; sl@0: if ( ! iDirects.IsEmpty() ) sl@0: { sl@0: TSglQueIter iter( (TSglQueBase&)iDirects ); sl@0: iter.SetToFirst(); sl@0: CWsDirectScreenAccess* dsa; sl@0: while ( (dsa = iter++) != NULL && !res ) sl@0: { sl@0: res = (dsa->ClientWindow() == aWin ) && ( dsa->IsVisible() || dsa->IsSyncTimeoutPending() ); sl@0: } sl@0: } sl@0: return res; sl@0: } sl@0: sl@0: void CScreen::AcceptFadeRequest( CWsWindow* aWin, TBool aIsFaded, TBool aIsBehind, TBool aIncludeChildren ) sl@0: { sl@0: iRedraw->AcceptFadeRequest( aWin, aIsFaded, aIsBehind, aIncludeChildren ); sl@0: }