--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/nonnga/SERVER/SERVER.CPP Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,900 @@
+// Copyright (c) 1995-2009 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:
+// Window server 'server' class
+//
+//
+
+#include "server.h"
+#include "panics.h"
+#include "wstop.h"
+#include "EVENT.H"
+#include <Graphics/WSGRAPHICDRAWERINTERFACE.H>
+#include <bitdraw.h>
+#include <hal.h>
+#include "inifile.h"
+#include "wspluginmanager.h"
+
+GLREF_D CDebugLogBase *wsDebugLog;
+
+const TUint KRangeCount = 1;
+// We use a lot of 64 bit time calculations, but a periodic can only cope with signed 32 bit times
+// which gives them a limit of about 35 minutes.
+// Fortunately, our animtions are safe if redrawn early. Every half an hour isn't going to hurt.
+const TTimeIntervalMicroSeconds KHalfHour = 30 * 60 * 1000 * 1000;
+
+const TInt KWsServRanges[KRangeCount] =
+ {
+ 0
+ };
+
+const TUint8 KElementsIndex[KRangeCount] =
+ {
+ CPolicyServer::EAlwaysPass,
+ };
+
+const CPolicyServer::TPolicyElement KPolicyElements[] =
+ {
+ {_INIT_SECURITY_POLICY_C1(ECapabilityPowerMgmt), CPolicyServer::EFailClient},
+ {_INIT_SECURITY_POLICY_C1(ECapabilitySwEvent), CPolicyServer::EFailClient},
+ {_INIT_SECURITY_POLICY_C1(ECapabilityWriteDeviceData), CPolicyServer::EFailClient}
+ };
+
+const CPolicyServer::TPolicy KWsServPolicy =
+ {
+ CPolicyServer::EAlwaysPass,
+ KRangeCount,
+ KWsServRanges,
+ KElementsIndex,
+ KPolicyElements
+ };
+
+// CWindowServer::CDefaultAnimationScheduler \\\\\\\\\\\\\\\\\\\\\\\\\\\
+
+class CWindowServer::CDefaultAnimationScheduler: public CBase, public MWsAnimationScheduler
+ {
+public:
+ enum TInactivityBehaviour
+ {
+ EStopAnimation,
+ EStopAllDrawing,
+ EIgnore,
+ };
+ class CKickBack;
+ CDefaultAnimationScheduler(MWsGraphicDrawerEnvironment& aEnv);
+ ~CDefaultAnimationScheduler();
+ void ConstructL(); //LeaveScan: member of nested class declaration
+ // implementing MWsAnimationScheduler
+ void ScheduleAnimation(MWsScreen& aScreen,const TTime& aWhen);
+ void UnscheduleAnimation(MWsScreen& aScreen);
+ void Invalidate(const TGraphicDrawerId& aId);
+ void OnInactive();
+ void OnActive();
+ void ScheduleRedraw(MWsScreen& aScreen,const TTime& aWhen);
+ void DoRedrawNow(MWsScreen& aScreen);
+ TInt RemoveGraphicDrawer(const TGraphicDrawerId &aId);
+
+private:
+ static TBool OnIdleCallBack(TAny* aAny);
+ void OnIdleCallBack(TBool aForceRedraw);
+ static TBool OnTickCallBack(TAny* aAny);
+ void OnTickCallBack();
+ static TBool OnKickBack(TAny* aAny);
+ void OnKickBack();
+private:
+ MWsGraphicDrawerEnvironment& iEnv;
+ static const TInt64 KRedrawGrace;
+ static const TInt64 KAnimationGrace;
+ static const TInt64 KDsaAnimationGrace;
+ CAsyncCallBack* iIdleInitiator;
+ CPeriodic* iTick;
+ CKickBack* iKickBack;
+ struct TSchedule
+ {
+ MWsScreen* iScreen; // used as a unique index, searching with FindInUnsignedKeyOrder
+ TBool iSchedule;
+ TTime iWhen;
+ TInt iGeneration;
+ };
+ RArray<TSchedule> iSchedule;
+ TInt iGeneration;
+ RArray<TGraphicDrawerId> iInvalidated;
+ TBool iInvalidateAll; // if we could not add to iInvalidated, we have to instead redraw everything
+ TTime iWhenDesired;
+ TBool iInactive;
+ TBool iInactiveDraws;
+ TTime iExpectedTime;
+ TBool iRedrawScheduled;
+ TInt64 iRedrawGracePeriod;
+ TInt64 iAnimationGracePeriod;
+ TInt64 iDsaAnimationGracePeriod;
+ TInactivityBehaviour iInactivityBehaviour;
+ };
+
+TInt CWindowServer::CDefaultAnimationScheduler::RemoveGraphicDrawer(const TGraphicDrawerId &aId)
+ {
+ TInt index=iInvalidated.Find(aId);
+ if (index!=KErrNotFound)
+ iInvalidated.Remove(index);
+ return index;
+ }
+
+class CWindowServer::CDefaultAnimationScheduler::CKickBack: public CActive
+ {
+public:
+ CKickBack(const TCallBack& aCallBack);
+ void ConstructL();
+ void RequestKickBack();
+ ~CKickBack();
+private:
+ static TInt IdleThreadFunc(TAny* aAny);
+ void Loop();
+ // from CActive
+ void RunL(); // fires when kicked back by the idle thread
+ void DoCancel();
+private:
+ RThread iWservThread;
+ RThread iIdleThread;
+ TRequestStatus iIdleStatus;
+ TCallBack iCallBack;
+ };
+
+CWindowServer::CDefaultAnimationScheduler::CKickBack::CKickBack(const TCallBack& aCallBack) :
+CActive(EPriorityNormal),
+iCallBack(aCallBack)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::CKickBack::ConstructL()
+ {
+ _LIT(KIdleThreadName,"NearlyIdleKickBack");
+ const TInt KStackSize = 1024;
+ User::LeaveIfError(iWservThread.Open(iWservThread.Id()));
+ User::LeaveIfError(iIdleThread.Create(KIdleThreadName(),IdleThreadFunc,KStackSize,NULL,this));
+ iIdleThread.SetPriority(EPriorityAbsoluteVeryLow);
+ iIdleThread.Resume();
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::CKickBack::RequestKickBack()
+ {
+ if (!IsActive())
+ {
+ iStatus = KRequestPending;
+ SetActive();
+ TRequestStatus * status = &iIdleStatus;
+ iIdleThread.RequestComplete(status, KErrNone);
+ }
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::CKickBack::Loop()
+ {
+ FOREVER
+ {
+ // This is used here for performance reasons.
+ User::WaitForRequest(iIdleStatus);
+ iIdleStatus = KRequestPending;
+ if (IsActive()&& (iStatus == KRequestPending))
+ {
+ TRequestStatus * status = &iStatus;
+ iWservThread.RequestComplete(status,KErrNone);
+ }
+ }
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::CKickBack::RunL()
+ {
+ iCallBack.CallBack();
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::CKickBack::DoCancel()
+ {
+ }
+
+CWindowServer::CDefaultAnimationScheduler::CKickBack::~CKickBack()
+ {
+ Cancel();
+ iWservThread.Close();
+ iIdleThread.Kill(0);
+ iIdleThread.Close();
+ }
+
+TInt CWindowServer::CDefaultAnimationScheduler::CKickBack::IdleThreadFunc(TAny* aAny)
+ {
+ CKickBack* owner = reinterpret_cast<CKickBack*>(aAny);
+ ASSERT(owner);
+ if(owner)
+ {
+ owner->Loop();
+ }
+ return KErrNone;
+ }
+
+// If using the default animation scheduler on a device, these two numbers may be worth tweaking in the inifile
+// However, both are maximum periods - wserv will go faster than either if nothing else is using the system.
+const TInt64 CWindowServer::CDefaultAnimationScheduler::KRedrawGrace = 0; // do redraws immediately
+const TInt64 CWindowServer::CDefaultAnimationScheduler::KAnimationGrace = 35000; // insist upon 35ms grace for other threads to run when animating
+const TInt64 CWindowServer::CDefaultAnimationScheduler::KDsaAnimationGrace = 35000; // insist upon 35ms grace for other threads to run when animating during DSA
+
+CWindowServer::CDefaultAnimationScheduler::CDefaultAnimationScheduler(MWsGraphicDrawerEnvironment& aEnv):
+ iEnv(aEnv), iSchedule(1,_FOFF(TSchedule,iScreen))
+ {
+ }
+
+CWindowServer::CDefaultAnimationScheduler::~CDefaultAnimationScheduler()
+ {
+ iSchedule.Close();
+ iInvalidated.Close();
+ delete iKickBack;
+ delete iIdleInitiator;
+ delete iTick;
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::ConstructL()
+ {
+ _LIT(KOnInactive,"ONINACTIVE");
+ _LIT(KStopAnimation,"STOPANIMATION");
+ _LIT(KStopAllDrawing,"STOPALLDRAWING");
+ _LIT(KIgnore,"IGNORE");
+
+ TPtrC inactivityBehaviourString;
+ WsIniFile->FindVar(KOnInactive,inactivityBehaviourString);
+ if(inactivityBehaviourString.CompareF(KStopAnimation)==0)
+ iInactivityBehaviour = EStopAnimation;
+ else if(inactivityBehaviourString.CompareF(KStopAllDrawing)==0)
+ iInactivityBehaviour = EStopAllDrawing;
+ else if(inactivityBehaviourString.CompareF(KIgnore)==0)
+ iInactivityBehaviour = EIgnore;
+
+ _LIT(KRedrawGracePeriod, "REDRAWGRACEPERIOD");
+ TInt tmp = KRedrawGrace;
+ WsIniFile->FindVar(KRedrawGracePeriod, tmp);
+ iRedrawGracePeriod = tmp;
+
+ _LIT(KAnimationGracePeriod, "ANIMATIONGRACEPERIOD");
+ tmp = KAnimationGrace;
+ WsIniFile->FindVar(KAnimationGracePeriod, tmp);
+ iAnimationGracePeriod = tmp;
+
+ _LIT(KDsaAnimationGracePeriod, "DSAANIMATIONGRACEPERIOD");
+ tmp = KDsaAnimationGrace;
+ WsIniFile->FindVar(KDsaAnimationGracePeriod, tmp);
+ iDsaAnimationGracePeriod = tmp;
+
+ iIdleInitiator = new(ELeave) CAsyncCallBack(TCallBack(OnIdleCallBack,this),EWsGraphicAnimateAwaitIdlePriority);
+ iTick = CPeriodic::NewL(EWsGraphicAnimatePriority);
+
+ _LIT(KDisableIdleAnimation, "DISABLEIDLEANIMATION");
+ if (!WsIniFile->FindVar(KDisableIdleAnimation))
+ {
+ iKickBack = new CKickBack(TCallBack(OnKickBack,this));
+ iKickBack->ConstructL();
+ }
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::Invalidate(const TGraphicDrawerId& aId)
+ {
+ if(!iInvalidateAll)
+ {
+ switch(iInvalidated.InsertInOrder(aId,TLinearOrder<TGraphicDrawerId>(TGraphicDrawerId::Compare)))
+ {
+ case KErrNone:
+ break;
+ case KErrAlreadyExists:
+ break;
+ default:
+ iInvalidateAll = ETrue;
+ iInvalidated.Reset();
+ }
+ }
+ iIdleInitiator->CallBack();
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::OnInactive()
+ {
+ iInactive = ETrue;
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::OnActive()
+ {
+ iInactive = EFalse;
+ if(iInactiveDraws)
+ {
+ iInactiveDraws = EFalse;
+ iIdleInitiator->CallBack();
+ }
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::ScheduleRedraw(MWsScreen& aScreen,const TTime& aWhen)
+ {
+ iRedrawScheduled = ETrue;
+ ScheduleAnimation(aScreen, aWhen);
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::DoRedrawNow(MWsScreen& /*aScreen*/)
+ {
+ OnIdleCallBack(ETrue);
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::ScheduleAnimation(MWsScreen& aScreen,const TTime& aWhen)
+ {
+ TSchedule schedule;
+ schedule.iScreen = &aScreen;
+ schedule.iSchedule = ETrue;
+ schedule.iWhen = aWhen;
+ schedule.iGeneration = iGeneration;
+ TBool ok = EFalse;
+ const TInt idx = iSchedule.FindInUnsignedKeyOrder(schedule);
+ if(0 <= idx)
+ {
+ if(iSchedule[idx].iSchedule)
+ {
+ if(iSchedule[idx].iWhen > aWhen)
+ {
+ iSchedule[idx].iWhen = aWhen;
+ }
+ }
+ else
+ {
+ iSchedule[idx] = schedule;
+ }
+ iSchedule[idx].iGeneration = iGeneration;
+ ok = ETrue;
+ }
+ else
+ {
+ ok = (KErrNone == iSchedule.InsertInUnsignedKeyOrder(schedule));
+ }
+ if(ok)
+ {
+ //If the animation runs at very high rate which exceeds the rate WSERV can
+ //perform the rendering, it is possible that WSERV animation loop will monopolize
+ //processor time.
+ User::After(0); // to yeild from the animation loop
+
+ iIdleInitiator->CallBack();
+ }
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::UnscheduleAnimation(MWsScreen& aScreen)
+ {
+ TSchedule schedule;
+ schedule.iScreen = &aScreen;
+ const TInt idx = iSchedule.FindInUnsignedKeyOrder(schedule);
+ if(0 <= idx)
+ {
+ iSchedule[idx].iSchedule = EFalse;
+ }
+ }
+
+TBool CWindowServer::CDefaultAnimationScheduler::OnIdleCallBack(TAny* aAny)
+ {
+ CDefaultAnimationScheduler* self = reinterpret_cast<CDefaultAnimationScheduler*>(aAny);
+ ASSERT(self);
+ if(self)
+ {
+ self->OnIdleCallBack(EFalse);
+ }
+ return EFalse; //ignored by caller
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::OnIdleCallBack(TBool aForceRedraw)
+ {
+ TBool wasActive = EFalse;
+ if (iTick->IsActive())
+ {
+ wasActive = ETrue;
+ iTick->Cancel(); // stop ticker, as we'll reschedule if necessary
+ }
+ if (aForceRedraw)
+ {
+ // Don't need to update iExpectedTime as we will not schedule a tick.
+ // Don't need to update iWhenDesired as we will not schedule a kick-back.
+ OnTickCallBack();
+ return;
+ }
+ TBool tick = (iInvalidateAll || iInvalidated.Count());
+ TTimeIntervalMicroSeconds next = 0LL;
+ const TInt count = iSchedule.Count();
+ TTime now;
+ now.UniversalTime();
+ if(count)
+ {
+ // work out the next wanted tick
+ TBool animTick = EFalse;
+ for(TInt i=0; i<count; i++)
+ {
+ if(iSchedule[i].iSchedule)
+ {
+ const TTime when = iSchedule[i].iWhen;
+ const TTimeIntervalMicroSeconds fromNow = when.MicroSecondsFrom(now);
+ if(!animTick || (fromNow < next))
+ {
+ animTick = ETrue;
+ tick = ETrue;
+ next = fromNow;
+ iWhenDesired = when;
+ }
+ }
+ }
+ }
+ if(tick)
+ {
+ TInt64 grace;
+ if (iRedrawScheduled)
+ grace = iRedrawGracePeriod;
+ else if (EFalse) // DSA active
+ grace = iDsaAnimationGracePeriod;
+ else
+ grace = iAnimationGracePeriod;
+ if (wasActive)
+ {
+ TInt64 minimum = iExpectedTime.MicroSecondsFrom(now).Int64();
+ if (minimum >= 0 && grace > minimum)
+ grace = minimum;
+ }
+
+ if (next.Int64() <= 0)
+ next = 0LL ; // No kickback/tick is needed. Make sure next == default grace period.
+
+ if(next < grace)
+ {
+ next = grace;
+ if (iKickBack)
+ iKickBack->RequestKickBack();
+ }
+ else if (next > KHalfHour)
+ next = KHalfHour;
+
+ iExpectedTime=now + next;
+ if (next.Int64() > 0)
+ {
+ iTick->Start(next.Int64(),0,TCallBack(OnTickCallBack,this));
+ }
+ else
+ {
+ OnTickCallBack(); // scheduling for 0 doesn't actually execute immediately
+ }
+ }
+ }
+
+TBool CWindowServer::CDefaultAnimationScheduler::OnKickBack(TAny* aAny)
+ {
+ CDefaultAnimationScheduler* self = reinterpret_cast<CDefaultAnimationScheduler*>(aAny);
+ ASSERT(self);
+ if(self)
+ {
+ self->OnKickBack();
+ }
+ return EFalse; //ignored by caller
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::OnKickBack()
+ {
+ if (iTick->IsActive())
+ {
+ iTick->Cancel();
+ TTime now;
+ now.UniversalTime();
+
+ TTimeIntervalMicroSeconds fromNow = iWhenDesired.MicroSecondsFrom(now);
+
+ if (fromNow < 0)
+ {
+ OnTickCallBack();
+ }
+ else
+ {
+ if (fromNow > KHalfHour)
+ fromNow = KHalfHour;
+ iTick->Start(fromNow.Int64(),0,TCallBack(OnTickCallBack, this));
+ }
+ }
+ }
+
+TBool CWindowServer::CDefaultAnimationScheduler::OnTickCallBack(TAny* aAny)
+ {
+ CDefaultAnimationScheduler* self = reinterpret_cast<CDefaultAnimationScheduler*>(aAny);
+ ASSERT(self);
+ if(self)
+ {
+ self->OnTickCallBack();
+ }
+ return EFalse;
+ }
+
+void CWindowServer::CDefaultAnimationScheduler::OnTickCallBack()
+ {
+ iTick->Cancel();
+
+ switch(iInactivityBehaviour)
+ {
+ case EStopAnimation :
+ // only client redraws if inactive. server side drawing stopped.
+ if(iInactive && !iRedrawScheduled)
+ {
+ iInactiveDraws = ETrue;
+ return;
+ }
+ break;
+ case EStopAllDrawing :
+ // if screen off, stop both client and server side drawing.
+ if(iInactive)
+ {
+ iInactiveDraws = ETrue;
+ return;
+ }
+ break;
+ case EIgnore :
+ default :
+ // ignore inactivity and draw as normal
+ break;
+ }
+
+ iRedrawScheduled = EFalse;
+
+ TTime now;
+ now.UniversalTime();
+ CWsActiveScheduler::Static()->AccumReclaimedIdleTime(Max(0LL,now.MicroSecondsFrom(iExpectedTime).Int64()));
+
+ TInt drewCount = 0;
+ TInt scheduledCount = 0;
+ /* first redraw any screens that are affected by invalidated graphic IDs */
+ if(iInvalidateAll || iInvalidated.Count())
+ {
+ // cancel idle callback if it's already scheduled as we're going to redraw all invalidated
+ // request at this point and clear invalidated array
+ if (iIdleInitiator->IsActive())
+ iIdleInitiator->Cancel();
+ const TArray<TGraphicDrawerId> invalidArray = iInvalidated.Array();
+ const TInt screenCount = iEnv.ScreenCount();
+ for(TInt i=0; i<screenCount; i++)
+ {
+ MWsScreen* screen = iEnv.Screen(i);
+ if(screen)
+ {
+ drewCount++;
+ if(iInvalidateAll)
+ {
+ Redraw(*screen);
+ }
+ else
+ {
+ RedrawInvalid(*screen,invalidArray);
+ }
+ }
+ }
+ iInvalidateAll = EFalse;
+ iInvalidated.Reset();
+ }
+ /* iSchedule might resize during this call because an Animate() on a screen might reschedule another animation etc */
+ TInt generation = iGeneration++;
+ TBool drew;
+ do
+ {
+ drew = EFalse;
+ const TInt count = iSchedule.Count();
+ for(TInt i=0; i<count; i++)
+ {
+ if(iSchedule[i].iSchedule)
+ {
+ scheduledCount++;
+ if(iSchedule[i].iGeneration == generation)
+ {
+ iSchedule[i].iSchedule = EFalse; // denote not to tick; it can be rescheduled in the subsequent call to Animate()
+ Animate(*(iSchedule[i].iScreen));
+ drew = ETrue;
+ drewCount++;
+ break; // go back to outer do while(drew)
+ }
+ }
+ }
+ } while(drew);
+ __DEBUG_ONLY(
+ TBool idleIsActive = iIdleInitiator->IsActive();
+ if(scheduledCount || !drewCount)
+ {
+ TBool rescheduled = EFalse;
+ for(TInt i=0; i<iSchedule.Count(); i++)
+ {
+ rescheduled |= iSchedule[i].iSchedule;
+ }
+ if(!rescheduled)
+ {
+ //__DEBUGGER();
+ }
+ })
+ }
+
+// CWindowServer \\\\\\\\\\\\\\\\\\\\\\\\\\\
+
+CWindowServer *CWindowServer::NewL()
+//
+// Create a new CWindowServer.
+//
+ {
+ CWindowServer* self = new(ELeave) CWindowServer();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CWindowServer::CWindowServer()
+//
+// Constructor.
+//
+ : CPolicyServer(EMainServerPriority,KWsServPolicy)
+ {
+ }
+
+CWindowServer::~CWindowServer()
+ {
+ iMemoryReleases.Reset();
+ WS_ASSERT_DEBUG(iDrawerMasterIndex.IsEmpty(), EWsPanicWsGraphic);
+ iDrawerMasterIndex.Close();
+
+ delete iDefaultAnimationScheduler;
+ iDefaultAnimationScheduler = NULL; // might be called from clients during server destruction
+ iCustomAnimationScheduler = NULL; // not owned
+ delete iPluginManager;
+ }
+
+void CWindowServer::ConstructL()
+ {
+ iPluginManager = CWsPluginManager::NewL(*this);
+ iDefaultAnimationScheduler = new(ELeave) CDefaultAnimationScheduler(*this);
+ iDefaultAnimationScheduler->ConstructL();
+ RegisterMemoryRelease(this);
+ }
+
+/** Creates a new client for this server. */
+CSession2* CWindowServer::NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const
+ {
+ TVersion v(KWservMajorVersionNumber,KWservMinorVersionNumber,KWservBuildVersionNumber);
+ if (User::QueryVersionSupported(v,aVersion)==EFalse)
+ User::Leave(KErrNotSupported);
+ RThread thread;
+ User::LeaveIfError(aMessage.Client(thread));
+ return(new(ELeave) CWsClient(thread));
+ }
+
+TInt CWindowServer::SessionCount()
+ {
+ iSessionIter.SetToFirst();
+ TInt count=0;
+ while(iSessionIter++)
+ count++;
+ return(count);
+ }
+
+const CWsGraphicDrawer* CWindowServer::ResolveGraphic(const TGraphicDrawerId& aId) const
+ {
+ return iDrawerMasterIndex.ResolveGraphic(aId);
+ }
+
+void CWindowServer::Invalidate(const TGraphicDrawerId& aId)
+ {
+ AnimationScheduler()->Invalidate(aId);
+ }
+
+TInt CWindowServer::ScreenCount() const
+ {
+ return CWsTop::NumberOfScreens();
+ }
+
+MWsScreen* CWindowServer::Screen(TInt aIndex)
+ {
+ if((aIndex >= 0) && (aIndex < ScreenCount()))
+ {
+ return CWsTop::Screen(aIndex);
+ }
+ return NULL;
+ }
+
+const MWsScreen* CWindowServer::Screen(TInt aIndex) const
+ {
+ if((aIndex >= 0) && (aIndex < ScreenCount()))
+ {
+ return CWsTop::Screen(aIndex);
+ }
+ return NULL;
+ }
+
+/**
+Custom Animation Scheduler
+*/
+TBool CWindowServer::SetCustomAnimationScheduler(MWsAnimationScheduler* aScheduler)
+ {
+ if(!iCustomAnimationScheduler && aScheduler)
+ {
+ iCustomAnimationScheduler = aScheduler;
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+TBool CWindowServer::HasCustomAnimationScheduler() const
+ {
+ return !!iCustomAnimationScheduler;
+ }
+
+TBool CWindowServer::ClearCustomAnimationScheduler(MWsAnimationScheduler* aCurrentScheduler)
+ {
+ if(iCustomAnimationScheduler && (iCustomAnimationScheduler == aCurrentScheduler))
+ {
+ iCustomAnimationScheduler = NULL;
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+MWsAnimationScheduler* CWindowServer::AnimationScheduler()
+ {
+ if(iCustomAnimationScheduler)
+ {
+ return iCustomAnimationScheduler;
+ }
+ return iDefaultAnimationScheduler;
+ }
+
+TInt CWindowServer::RegisterEventHandler(CWsGraphicDrawer* aDrawer, MWsEventHandler* aHandler, TUint32 aEventMask)
+ {
+ if (!aDrawer || !aHandler || aEventMask==0)
+ return KErrArgument;
+ TInt err = TWindowServerEvent::RegisterDrawerHandler(aDrawer, aEventMask);
+ if (err != KErrNone)
+ return err;
+ aDrawer->SetEventHandler(aHandler);
+ return KErrNone;
+ }
+
+TInt CWindowServer::UnregisterEventHandler(CWsGraphicDrawer* aDrawer)
+ {
+ if (!aDrawer || (aDrawer && !aDrawer->HasEventHandler()))
+ return KErrArgument;
+ TInt err = TWindowServerEvent::UnregisterDrawerHandler(aDrawer);
+ if (err != KErrNone)
+ return err;
+ aDrawer->SetEventHandler(NULL);
+ return KErrNone;
+ }
+
+TInt CWindowServer::RegisterWsEventHandler(MWsEventHandler* aHandler, TUint32 aEventMask)
+ {
+ if (!aHandler || aEventMask==0)
+ return KErrArgument;
+ return TWindowServerEvent::RegisterWsEventHandler(aHandler, aEventMask);
+ }
+
+TInt CWindowServer::UnregisterWsEventHandler(MWsEventHandler* aHandler)
+ {
+ return TWindowServerEvent::UnregisterWsEventHandler(aHandler);
+ }
+
+TInt CWindowServer::RegisterRawEventHandler(MEventHandler* aHandler)
+ {
+ if (!aHandler)
+ return KErrArgument;
+ TRAPD(err, TWindowServerEvent::PotentialEventHandlerL(1));
+ if (err != KErrNone)
+ return err;
+ TWindowServerEvent::AddEventHandler(aHandler);
+ return KErrNone;
+ }
+
+void CWindowServer::UnregisterRawEventHandler(MEventHandler* aHandler)
+ {
+ TWindowServerEvent::RemoveEventHandler(aHandler);
+ TWindowServerEvent::PotentialEventHandlerL(-1); // can't leave for -1
+ }
+
+void CWindowServer::PostRawEvent(const TRawEvent & aEvent)
+ {
+ TWindowServerEvent::ProcessRawEvent(aEvent);
+ }
+
+void CWindowServer::PostKeyEvent(const TKeyEvent & aEvent)
+ {
+ TWindowServerEvent::ProcessKeyEvent(aEvent, 0);
+ }
+
+TAny* CWindowServer::ResolveObjectInterface(TUint aTypeId)
+ {
+ switch(aTypeId)
+ {
+ case MWsActiveSchedulerDebug::EWsObjectInterfaceId:
+ return static_cast<MWsActiveSchedulerDebug*>(CWsActiveScheduler::Static());
+ case MWsIniFile::EWsObjectInterfaceId:
+ return static_cast<MWsIniFile*>(WsIniFile);
+ case MWsRawEventServer::EWsObjectInterfaceId:
+ return static_cast<MWsRawEventServer*>(this);
+ }
+
+ if (iPluginManager)
+ return iPluginManager->ResolveObjectInterface(aTypeId);
+
+ return NULL;
+ }
+
+void CWindowServer::Log(TInt aPriority,const TDesC &aFmt,TInt aParam)
+ {
+ if (wsDebugLog)
+ {
+ wsDebugLog->MiscMessage(aPriority, aFmt, aParam);
+ }
+ }
+
+// CWsGraphicDrawer master index
+
+TInt CWindowServer::AddGraphicDrawer(CWsGraphicDrawer* aDrawer)
+ {
+ return iDrawerMasterIndex.Add(aDrawer);
+ }
+
+TInt CWindowServer::SwapGraphicDrawer(CWsGraphicDrawer* aDrawer)
+ {
+ return iDrawerMasterIndex.Swap(aDrawer);
+ }
+
+TInt CWindowServer::RemoveGraphicDrawer(const TGraphicDrawerId& aId)
+ {
+ iDefaultAnimationScheduler->RemoveGraphicDrawer(aId);
+ return iDrawerMasterIndex.Remove(aId);
+ }
+
+TInt CWindowServer::RemoveAllGraphicDrawers(const MWsClient& aOwner)
+ {
+ return iDrawerMasterIndex.RemoveAll(aOwner);
+ }
+
+CWsPluginManager* CWindowServer::PluginManager()
+ {
+ return iPluginManager;
+ }
+
+TInt CWindowServer::RegisterMemoryRelease(MWsMemoryRelease * aMemoryRelease)
+ {
+ return iMemoryReleases.Append(aMemoryRelease);
+ }
+
+void CWindowServer::UnregisterMemoryRelease(MWsMemoryRelease * aMemoryRelease)
+ {
+ for (TInt i = iMemoryReleases.Count() - 1; i >= 0; --i)
+ {
+ if (iMemoryReleases[i] == aMemoryRelease)
+ {
+ iMemoryReleases.Remove(i);
+ break;
+ }
+ }
+ }
+
+TBool CWindowServer::ReleaseMemory(TMemoryReleaseLevel aLevel)
+ {
+ return CWsWindow::ReleaseMemory(aLevel);
+ }
+
+TBool CWindowServer::ReleaseMemory()
+ {
+ TBool released = EFalse;
+ for (TInt level = MWsMemoryRelease::ELow; !released && level <= MWsMemoryRelease::EHigh; ++level)
+ {
+ for (TInt i = iMemoryReleases.Count() - 1; !released && i >= 0; --i)
+ {
+ released = iMemoryReleases[i]->ReleaseMemory(static_cast<TMemoryReleaseLevel>(level));
+ }
+ }
+ return released;
+ }
+