--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/EikStd/srvuisrc/EIKSRVUI.CPP Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,1971 @@
+/*
+* Copyright (c) 2002-2007 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:
+*
+*/
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <uikon/eiknotifyalert.h>
+#include <viewclipartner.h>
+#include <uiklaf/private/pluginuid.hrh>
+#endif
+#include <hal.h>
+#include <hal_data.h>
+#include <s32file.h>
+#include <basched.h>
+#include <bautils.h>
+#include <eikdll.h>
+#include <eikenv.h>
+#include <eikkeys.h>
+#include "eikkwin.h"
+#include <eikmover.h>
+#include <eikon.rsg>
+
+#include <uikon/eiksrvui.h>
+#include <eiksvdef.h>
+#include <Eikalmct.h>
+
+#define __ASSHDBITFLAGS_H__
+
+#include <uikon/eikalsup.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <uikon/eikenvinterface.h>
+#endif
+#include <eikunder.h>
+#include <uikon/eikalsrv.h>
+#include <uikon/eiknfysv.h>
+#include "EIKNFYUI.H"
+#include <eiksrvui.rsg>
+#include <viewcli.h>
+
+/*
+* Following resources used from Symbian's eikpriv.rss file:
+*
+* r_eik_system_default_view_id
+* r_eik_system_view_server_event_time_out
+* r_eik_system_view_server_client_request_time_out
+*/
+#include <eikpriv.rsg>
+#include "EIKSRV.HRH"
+
+#include <aknPopup.h>
+#include <avkon.rsg>
+#include <eiktxlbx.h>
+#include <eiktxlbm.h>
+#include "eikkeysoundserver.h"
+#include <aknsoundsystem.h>
+#include <eikapp.h>
+#include <aknenv.h>
+
+#include <AknLayout.lag>
+#include <AknUtils.h>
+#include <AknsUtils.h>
+#include <featmgr.h>
+
+#include <e32property.h>
+#include <UikonInternalPSKeys.h> // KUikLayoutState
+
+#include <aknpriv.rsg>
+#include <AknDef.h>
+
+#include <AknIconUtils.h>
+#include <avkon.mbg>
+#include <aknlayout.cdl.h>
+
+#include <asclisession.h>
+#include <asclidefinitions.h>
+#include <ascliclientutils.h>
+#include <c32comm.h>
+
+#include <apasvst.h>
+#include <apgcli.h>
+#include <apgwgnam.h>
+#include <viewcli.h>
+#include <vwsappst.h>
+
+#include "e32uid.h"
+
+#include <eiksrvsp.h>
+#include <eiksrvs.h>
+#include <akneiksrvs.h>
+
+#include <uiklaf/private/lafenv.h>
+#include <uiklaf/private/lafsrv.h>
+
+#include <eikrutil.h>
+#include <AknSgcc.h>
+#include <aknconsts.h>
+
+#include "EikLafShutStarter.h"
+#include "EikLafShutScheduler.h"
+
+#include <AknWsEventObserver.h>
+#include <aknappui.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <AknFontSpecification.h>
+#include <AknTextDecorationMetrics.h>
+#include <e32capability.h>
+
+#include <AknCapServerDefs.h>
+#include <akndialogcontroller.h>
+
+#include "AknNotifierControllerPlugin.h"
+#include <AknCustomCursorSupport.h>
+#include "AknEikSrv.pan"
+
+#if defined(__WINS__)
+const TInt KEikServSideBarWidth = 35;
+const TInt KEikServAppbarHeight = 50;
+#endif
+
+#if defined (__WINS__)
+_LIT(COMMS_PDD_NAME, "ECDRV");
+_LIT(COMMS_LDD_NAME, "ECOMM");
+#else
+_LIT(COMMS_PDD_NAME, "EUART1");
+_LIT(COMMS_LDD_NAME, "ECOMM");
+#endif
+
+const TInt KEikServServerRestartDelay = 500000; // .5 sec
+const TInt KEikServServerRestartInterval = 3000000; // 3 sec
+
+_LIT(KResFileName, "z:\\resource\\eiksrvui.rsc");
+_LIT(KAnimDllFileName, "AknAnimDll.Dll");
+_LIT(KWatcherThreadName, "UikonWatchers");
+
+const TInt KEikServPanicTextBufferSize = 512;
+
+GLDEF_C void Panic(TEikServPanic aPanic)
+ {
+ _LIT(KPanicCat,"EIKON-SERVER");
+ User::Panic(KPanicCat,aPanic);
+ }
+
+#define iAknCapServerClient (*(CAknSgcClient::AknSrv()))
+
+class CFbsBitmap;
+
+// =====================
+// RKeySoundServerCloser
+// =====================
+
+class RKeySoundServerCloser : public RSessionBase
+ {
+public:
+ void CloseServer();
+ };
+
+void RKeySoundServerCloser::CloseServer()
+ {
+ if (CreateSession(__KEYSOUND_SERVER_NAME, TVersion(KKeySoundServMajorVN, KKeySoundServMinorVN,
+ KKeySoundServBuildVN), 0) == KErrNone)
+ {
+ SendReceive(EKeySoundServerCloseServer, TIpcArgs());
+ Close();
+ }
+ }
+
+// ==================
+// CEikServAppStarter
+// ==================
+
+class CEikServAppStarter : public CBase, public MVwsAppStarter
+ {
+public:
+ static CEikServAppStarter* NewL();
+ ~CEikServAppStarter();
+public: // From MVwsAppStarter.
+ void StartAppL(TUid aAppUid, TThreadId& aThreadId);
+private:
+ CEikServAppStarter();
+ void ConstructL();
+private:
+ };
+
+CEikServAppStarter* CEikServAppStarter::NewL()
+ {
+ CEikServAppStarter* self=new(ELeave) CEikServAppStarter;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CEikServAppStarter::~CEikServAppStarter()
+ {
+ }
+
+CEikServAppStarter::CEikServAppStarter()
+ {
+ }
+
+void CEikServAppStarter::ConstructL()
+ {
+ }
+
+void CEikServAppStarter::StartAppL(TUid aAppUid, TThreadId& aThreadId)
+ {
+ RApaLsSession ls;
+ CleanupClosePushL(ls);
+ User::LeaveIfError(ls.Connect());
+ TApaAppInfo info;
+ TInt err = ls.GetAppInfo(info,aAppUid);
+
+ User::LeaveIfError(err);
+
+ // LeaveIfError does not trigger to positive values, but GetAppInfo does not return valid
+ // data unless server returns KErrNone.
+ if ( err > 0 )
+ {
+ User::Leave(KErrNotReady);
+ }
+
+ CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
+ cmdLine->SetExecutableNameL(info.iFullName);
+ cmdLine->SetCommandL(EApaCommandViewActivate);
+
+ // Using apparc client-server to do this "internal" launch.
+ ls.StartApp(*cmdLine, aThreadId);
+ CleanupStack::PopAndDestroy(); // cmdLine
+ CleanupStack::PopAndDestroy(); // ls
+ }
+
+// Thread function for OOD watcher.
+GLDEF_C TInt WatcherThreadFunction(TAny* /*aParameters*/)
+ {
+ TInt err(KErrNone);
+
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ CActiveScheduler* scheduler = new CEikLafShutScheduler();
+ CEikLafShutStarter* lafShut = NULL;
+
+ if (!cleanup || !scheduler)
+ {
+ err = KErrNoMemory;
+ }
+
+ else
+ {
+ CActiveScheduler::Install(scheduler);
+ TRAP(err,
+ {
+ RThread me;
+ me.SetPriority(EPriorityLess);
+ lafShut = CEikLafShutStarter::NewL();
+ })
+
+ if (err == KErrNone)
+ {
+ // start the watchers
+ CActiveScheduler::Start();
+ }
+ }
+
+ delete cleanup;
+ delete scheduler;
+ delete lafShut;
+
+ return err;
+ }
+
+// Creates thread for OOM & OOD watchers.
+GLDEF_C void CreateWatcherThreadL()
+ {
+ RThread thread;
+
+ TInt ret = thread.Create(
+ KWatcherThreadName,
+ WatcherThreadFunction,
+ 0x2000, // stack size
+ NULL, // uses caller thread's heap
+ (TAny*)NULL );
+
+ if (ret == KErrNone)
+ {
+ thread.Resume();
+ thread.Close();
+ }
+
+ User::LeaveIfError(ret);
+ }
+
+// ==================
+// CEikSrvAppShutdown
+// ==================
+
+NONSHARABLE_CLASS(CEikSrvAppShutdown) : public CActive
+ {
+public:
+ static void StartL(
+ const TUid aRequesterUID,
+ const RMessage2& aShutdownMessage,
+ const TInt aTimeoutInMicroseconds);
+private:
+ CEikSrvAppShutdown(const RMessage2& aShutdownMessage);
+ ~CEikSrvAppShutdown();
+ void DoCancel();
+ void RunL();
+private:
+ RMessagePtr2 iMessage;
+ };
+
+void CEikSrvAppShutdown::StartL(const TUid aRequesterUID, const RMessage2& aShutdownMessage,
+ const TInt aTimeoutInMicroseconds)
+ {
+ if (iAknCapServerClient.Handle())
+ {
+ CEikSrvAppShutdown* self = new(ELeave) CEikSrvAppShutdown(aShutdownMessage);
+ iAknCapServerClient.ShutdownApps(aRequesterUID, aTimeoutInMicroseconds, self->iStatus);
+ self->SetActive();
+ }
+ else
+ aShutdownMessage.Complete(KErrNone);
+ }
+
+CEikSrvAppShutdown::CEikSrvAppShutdown(const RMessage2& aShutdownMessage)
+: CActive(CActive::EPriorityStandard), iMessage(aShutdownMessage)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CEikSrvAppShutdown::~CEikSrvAppShutdown()
+ {
+ Cancel();
+ }
+
+void CEikSrvAppShutdown::DoCancel()
+ {
+ }
+
+void CEikSrvAppShutdown::RunL()
+ {
+ iMessage.Complete(KErrNone);
+ delete this;
+ }
+
+// =============
+// CEikServExtra
+// =============
+
+class CEikServExtra : public CBase
+ {
+public:
+ CPeriodic* iServerRestarter;
+ CArrayPtr<RWsPointerCursor>* iPointerCursors;
+ CIdle* iNotifierServerStarter;
+ };
+
+const TInt KEiksrvUiDllValue = 0x100053D0;
+
+
+EXPORT_C CEikServAppUiBase* CEikServAppUiBase::NewLC()
+ {
+ if (CEikonEnv::Static()->WsSession().FindWindowGroupIdentifier(
+ 0, __EIKON_SERVER_NAME, 0) > KErrNotFound)
+ {
+ return NULL; // Already an Eikon server running.
+ }
+
+ // This code duplicates what is in EikSrv.cpp in CEikServAppUiServer::CreateAppUiL().
+ _LIT(KRomPath, "\\System\\Libs\\");
+ _LIT(KEiksrvUiDllName, "EiksrvUi.dll");
+ TFileName path;
+ Dll::FileName(path);
+ const TUint16& drv = path[0];
+ if (drv == 'z' || drv == 'Z')
+ {
+ path.Append(KRomPath);
+ }
+ else
+ {
+ TParse parse;
+ User::LeaveIfError(parse.Set(path, NULL, NULL));
+ path = parse.DriveAndPath();
+ }
+ TUidType uidType(KDynamicLibraryUid, KSharedLibraryUid, TUid::Uid(KEiksrvUiDllValue));
+ RLibrary lib;
+ User::LeaveIfError(lib.Load(KEiksrvUiDllName, path, uidType));
+ CleanupClosePushL(lib);
+ TLibraryFunction appui = lib.Lookup(1);
+ CEikServAppUiBase* self = REINTERPRET_CAST(CEikServAppUiBase*, (*appui)());
+ User::LeaveIfNull(self);
+ STATIC_CAST(CEikServEnv*, CEikonEnv::Static())->SetUiDll(lib);
+ CleanupStack::Pop(); // lib
+ CleanupStack::PushL(self);
+ STATIC_CAST(CEikAppUi*, self)->ConstructL();
+
+ return self;
+ }
+
+EXPORT_C void CEikServAppUiBase::NotifyAlarmServerOfTaskChangeL()
+ {
+ if (iAlarmAlertServer)
+ {
+ iAlarmAlertServer->TaskKeyPressedL();
+ }
+ }
+
+EXPORT_C void CEikServAppUiBase::EnableTaskListL()
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+EXPORT_C void CEikServAppUiBase::LaunchTaskListL()
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+EXPORT_C void CEikServAppUiBase::CycleTasksL(enum TTaskCycleDirection aDirection)
+ {
+ TApaTaskList taskList(iCoeEnv->WsSession());
+ if (aDirection == EBackwards)
+ {
+ TApaTask task = taskList.FindByPos(-1);
+ task.BringToForeground();
+ }
+ else
+ {
+ TApaTask task = taskList.FindByPos(0);
+ task.SendToBackground();
+ }
+
+ // Will also task away from alarm when only 1 task!! Correct?
+ NotifyAlarmServerOfTaskChangeL();
+ }
+
+EXPORT_C CEikServAppUiBase::CEikServAppUiBase()
+ {
+ SetFullScreenApp(EFalse);
+ }
+
+LOCAL_C void ReleaseFactories(TAny* aPtr)
+ {
+ TEikServCtrlFactories& factory = *(TEikServCtrlFactories*)aPtr;
+ if (factory.iAlert)
+ {
+ factory.iAlert->Release();
+ }
+ }
+
+LOCAL_C void PointerCleanup(TAny* aPtr)
+ {
+ RWsPointerCursor* ptr = REINTERPRET_CAST(RWsPointerCursor*, aPtr);
+ ptr->Close();
+ delete ptr;
+ }
+
+EXPORT_C void CEikServAppUiBase::ConstructL()
+ {
+ RWindowGroup& groupWin = iCoeEnv->RootWin();
+ RWsSession& wsSession = iCoeEnv->WsSession();
+ iEikonEnv->SetAutoForwarding(ETrue);
+ iEikonEnv->SetSystem(ETrue);
+ iEikonEnv->FsSession().SetNotifyUser(EFalse);
+
+ // Must call BaseConstructL to get Avkon classes called.
+#ifdef _DEBUG
+ RDebug::Print(_L("CAknAppUiBase::BaseConstructL() in "));
+#endif
+ CAknAppUiBase::BaseConstructL(ENonStandardResourceFile|ENoScreenFurniture|
+ EAknEnableMSK|EAknSingleClickCompatible);
+#ifdef _DEBUG
+ RDebug::Print(_L("CAknAppUiBase::BaseConstructL() out"));
+#endif
+
+ groupWin.SetName(__EIKON_SERVER_NAME);
+ groupWin.EnableErrorMessages(EEventControlAlways);
+ groupWin.EnableOnEvents(EEventControlAlways);
+ wsSession.ComputeMode(RWsSession::EPriorityControlDisabled);
+ iCoeEnv->RootWin().EnableScreenChangeEvents();
+ RThread thread;
+
+#if defined(__EPOC32__)
+ thread.SetProcessPriority(EPriorityHigh);
+#else
+ thread.SetPriority(EPriorityAbsoluteForeground);
+#endif
+
+ // Create a window group for the password and alarm screens.
+ iAlertGroupWin = RWindowGroup(wsSession);
+
+ // EFalse disables key events - they will be enabled again as soon as the ordinal position is
+ // set such that iAlertGroupWin is not the foreground window-group.
+ User::LeaveIfError(iAlertGroupWin.Construct((TUint32)this, EFalse));
+
+ iAlertGroupWin.SetOrdinalPosition(0, ECoeWinPriorityNeverAtFront);
+
+ // Enable key events, now that iAlertGroupWin is not in the foreground.
+ iAlertGroupWin.EnableReceiptOfFocus(ETrue);
+
+ iEikServExtra = new(ELeave) CEikServExtra();
+
+ TInt numCursors = LafServAppUiBase::NumberOfCursorsInSystemCursorList();
+ if(numCursors != 0 && LafServAppUiBase::ClaimPointerCursorListIfNeeded(*iEikonEnv) == KErrNone)
+ {
+ iEikServExtra->iPointerCursors = new(ELeave) CArrayPtrFlat<RWsPointerCursor>(4);
+ TSpriteMember member;
+ for(TInt ii = 0; ii < numCursors; ii++)
+ {
+ RWsPointerCursor* cursor = LafServAppUiBase::ConstructPointerCursorL(ii, member,
+ *iEikonEnv);
+
+ CleanupStack::PushL(TCleanupItem(PointerCleanup, cursor));
+ iEikServExtra->iPointerCursors->AppendL(cursor);
+ CleanupStack::Pop(); // cursor - handle & ptr
+ }
+ }
+ }
+
+EXPORT_C void CEikServAppUiBase::InitializeL(TEikServCtrlFactories& aCtrlFactories)
+ {
+ RWindowGroup& rootWin = iCoeEnv->RootWin();
+
+ CleanupStack::PushL(TCleanupItem(&ReleaseFactories,&aCtrlFactories));
+ RFs& fsSession = iCoeEnv->FsSession();
+ _LIT(KAppDirName, "C:\\System\\Apps\\");
+ fsSession.MkDirAll(KAppDirName); // !! prevent app arch crash
+
+ // Initialize some system settings.
+ SetSystemTime();
+ rootWin.EnableOnEvents(EEventControlAlways);
+
+ TPasswordMode mode = EPasswordNone;
+
+ TRAP_IGNORE(
+ CEikPasswordModeCategory* pcategory = CEikPasswordModeCategory::NewLC(fsSession);
+ if( pcategory )
+ {
+ pcategory->GetPasswordModeL(mode);
+ if (mode == EPasswordNone) // prevent overwriting once per day
+ {
+ mode = EPasswordAlways;
+ }
+ // Initialise (write to system.ini) here so that it won't fail in the future due to OOM.
+ pcategory->SetPasswordModeL(mode);
+ CleanupStack::PopAndDestroy(); // pcategory
+ }
+ );
+
+ // Create separate thread for OOD watchers.
+ CreateWatcherThreadL();
+
+ // Start View Server.
+ iAppStarter = CEikServAppStarter::NewL();
+ User::LeaveIfError(CVwsSessionWrapper::StartViewServer(*iAppStarter));
+ iVwsSession = CVwsSessionWrapper::NewL();
+
+ TResourceReader reader;
+ iEikonEnv->CreateResourceReaderLC(reader, R_EIK_SYSTEM_DEFAULT_VIEW_ID);
+ TVwsViewId viewId;
+ viewId.iAppUid.iUid = reader.ReadInt32();
+ viewId.iViewUid.iUid = reader.ReadInt32();
+ CleanupStack::PopAndDestroy(); // reader
+ iVwsSession->SetSystemDefaultView(viewId);
+
+ TInt serverEventTimeOutDuration = EikResourceUtils::ReadTInt32L(
+ R_EIK_SYSTEM_VIEW_SERVER_EVENT_TIME_OUT, iEikonEnv);
+
+ iVwsSession->SetServerEventTimeOut( TTimeIntervalMicroSeconds32(serverEventTimeOutDuration) );
+
+ TInt clientRequestTimeOutDuration = EikResourceUtils::ReadTInt32L(
+ R_EIK_SYSTEM_VIEW_SERVER_CLIENT_REQUEST_TIME_OUT, iEikonEnv);
+
+ iVwsSession->SetClientRequestTimeOut( TTimeIntervalMicroSeconds32(clientRequestTimeOutDuration) );
+
+ iVwsSession->EnableServerBlankScreen(EFalse);
+
+ // Start Comms
+ TInt err = StartC32();
+ if (err != KErrNone && err != KErrAlreadyExists)
+ {
+ User::Leave(err);
+ }
+
+ err = User::LoadPhysicalDevice(COMMS_PDD_NAME);
+ if (err != KErrNone && err != KErrAlreadyExists && err != KErrNotFound)
+ {
+ User::Leave(err);
+ }
+
+ err = User::LoadLogicalDevice(COMMS_LDD_NAME);
+ if (err != KErrNone && err != KErrAlreadyExists && err != KErrNotFound)
+ {
+ User::Leave(err);
+ }
+
+ // Start notifier server last as these may have plug-ins that rely on the other servers
+ // started here being up and running.
+ iNotifyServer = CEikServNotifyServer::NewL(aCtrlFactories.iAlert);
+
+ CleanupStack::Pop(); // aCtrlFactories
+
+ iEikServExtra->iNotifierServerStarter = CIdle::NewL(CActive::EPriorityLow);
+ iEikServExtra->iNotifierServerStarter->Start(TCallBack(StartNotifierServerCallBackL, this));
+
+ rootWin.EnableGroupListChangeEvents();
+
+ // Create undertaker active object.
+ iUndertaker = CEikUndertaker::NewL(*this);
+
+ // Create an active object to restart servers.
+ iEikServExtra->iServerRestarter = CPeriodic::NewL(CActive::EPriorityStandard);
+ }
+
+EXPORT_C void CEikServAppUiBase::HandleThreadExitL(RThread& aThread)
+ {
+ if (aThread.Name() == ASCliDefinitions::ServerAndThreadName()) // alarm server died
+ {
+ aThread.Close(); // need to Close() before restarting with same name
+ iServerToRestart |= EAlwlSvr; // restarted under active object
+ }
+ else if (aThread.Name()==NameApaServServerThread()) // AppArc server died
+ {
+ aThread.Close();
+ iServerToRestart|=EApaSvr;
+ }
+
+ if (iServerToRestart && !iEikServExtra->iServerRestarter->IsActive())
+ {
+ iEikServExtra->iServerRestarter->Start(
+ KEikServServerRestartDelay,
+ KEikServServerRestartInterval,
+ TCallBack(RestartServerCallback, this));
+ }
+ }
+
+EXPORT_C void CEikServAppUiBase::HandleForegroundEventL(TBool aForeground)
+ {
+ CAknAppUiBase::HandleForegroundEventL(aForeground);
+ }
+
+TInt CEikServAppUiBase::RestartServerCallback(TAny* aObj)
+ {
+ STATIC_CAST(CEikServAppUiBase*, aObj)->RestartServer();
+ return KErrNone;
+ }
+
+TInt CEikServAppUiBase::StartNotifierServerCallBackL(TAny* aPtr)
+ { // static
+ CEikServAppUiBase* self = static_cast<CEikServAppUiBase*>(aPtr);
+ self->iNotifyServer->StartL();
+ delete self->iEikServExtra->iNotifierServerStarter;
+ self->iEikServExtra->iNotifierServerStarter=NULL;
+ return KErrNone;
+ }
+
+// Kick dead servers back to life, if we can connect then stop kicking.
+void CEikServAppUiBase::RestartServer()
+ {
+ if (iServerToRestart & EAlwlSvr)
+ {
+ // Start AlarmServer
+ TInt err = AlarmClientUtils::StartAlarmServer();
+ if (err == KErrNone)
+ {
+ iServerToRestart&=(~EAlwlSvr);
+ }
+ }
+
+ if (iServerToRestart&EApaSvr)
+ {
+ AknStartupApaServerProcess();
+
+ // try to connect to the server
+ RApaLsSession ls;
+ TInt err = ls.Connect();
+ if (err == KErrNone)
+ {
+ ls.Close();
+ iServerToRestart&=(~EApaSvr);
+ }
+ }
+
+ if (!iServerToRestart)
+ {
+ iEikServExtra->iServerRestarter->Cancel();
+ }
+ }
+
+EXPORT_C TKeyResponse CEikServAppUiBase::HandleKeyEventL(const TKeyEvent& aKeyEvent,
+ TEventCode /*aType*/)
+ {
+ if (aKeyEvent.iCode == CTRL('e'))
+ {
+ CBaActiveScheduler::Exit();
+ }
+ return EKeyWasConsumed;
+ }
+
+// Check the battery states and update any alarm snooze time.
+EXPORT_C void CEikServAppUiBase::HandleSwitchOnEventL(CCoeControl* /*aDestination*/)
+ {
+ // Could just expose alarm alert server to UI dll!!
+ if (iAlarmAlertServer)
+ {
+ iAlarmAlertServer->HandleSwitchOnEvent();
+ }
+ }
+
+EXPORT_C void CEikServAppUiBase::HandleSystemEventL(const TWsEvent& aEvent)
+ {
+ TInt event = *((TInt*)aEvent.EventData());
+ switch (event)
+ {
+#ifdef _DEBUG
+ case EEikServExit:
+ CBaActiveScheduler::Exit();
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+
+EXPORT_C void CEikServAppUiBase::HandleApplicationSpecificEventL(TInt aType, const TWsEvent& aEvent)
+ {
+ // Check command/number or whatever first!!
+ CAknAppUiBase::HandleApplicationSpecificEventL(aType, aEvent);
+ }
+
+
+EXPORT_C CEikServAppUiBase::~CEikServAppUiBase()
+ {
+ delete iUndertaker;
+
+ if (iEikServExtra)
+ {
+ delete iEikServExtra->iServerRestarter;
+
+ if (iEikServExtra->iPointerCursors)
+ {
+ const TInt count = iEikServExtra->iPointerCursors->Count();
+
+ for (TInt ii = 0; ii < count; ii++)
+ {
+ (*(iEikServExtra->iPointerCursors))[ii]->Close();
+ }
+
+ iEikServExtra->iPointerCursors->ResetAndDestroy();
+ delete iEikServExtra->iPointerCursors;
+ }
+
+ delete iEikServExtra->iNotifierServerStarter;
+ delete iEikServExtra;
+ }
+
+ LafServAppUiBase::FreePointerCursorListIfNeeded(*iEikonEnv);
+ RWindowGroup& groupWin = iEikonEnv->RootWin();
+ groupWin.DisableErrorMessages();
+ groupWin.DisableOnEvents();
+ iAlertGroupWin.Close();
+ delete iNotifyServer;
+ delete iAlarmAlertServer;
+ delete iAppStarter;
+
+ if (iVwsSession)
+ {
+ iVwsSession->ShutdownViewServer();
+ delete iVwsSession;
+ }
+ }
+
+void CEikServAppUiBase::SetSystemTime() const
+ {
+ // Deprecated, we don't have capability to set system time.
+ }
+
+// Bring to foreground or send to background appropriately.
+EXPORT_C void CEikServAppUiBase::BringAlertGroupWinForwards(TBool aForwards)
+ {
+ if (aForwards)
+ {
+ if (!iAlertGroupForwardsCount++)
+ {
+ iAlertGroupWin.SetOrdinalPosition(0, KMaxTInt);
+ }
+ }
+ else if (--iAlertGroupForwardsCount == 0)
+ {
+ iAlertGroupWin.SetOrdinalPosition(0, ECoeWinPriorityNeverAtFront);
+ }
+ }
+
+EXPORT_C void CEikServAppUiBase::SetStatusPaneFlags(TInt /*aFlags*/)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+EXPORT_C void CEikServAppUiBase::SetStatusPaneLayoutL(TInt /*aLayoutResId*/)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+EXPORT_C void CEikServAppUiBase::BlankScreenL()
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+EXPORT_C void CEikServAppUiBase::UnblankScreen()
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+EXPORT_C void CEikServAppUiBase::ShutdownAppsL(const TUid aRequesterUID,
+ const RMessage2& aShutdownMessage, const TInt aTimeoutInMicroseconds)
+ {
+ CEikSrvAppShutdown::StartL(aRequesterUID, aShutdownMessage, aTimeoutInMicroseconds);
+ }
+
+EXPORT_C void CEikServAppUiBase::HandleResourceChangeL(TInt aType)
+ {
+ CAknAppUiBase::HandleResourceChangeL(aType);
+ }
+
+void CEikServAppUiBase::Extension(TUid /*aExtensionUid*/, const TDesC8& /*aBuffer*/,
+ RMessagePtr2 /*aMessage*/)
+ {
+ // Not implemented
+ }
+
+EXPORT_C void CEikServAppUiBase::HandleWsEventL(const TWsEvent& aEvent,CCoeControl* aDestination)
+ {
+ CAknAppUiBase::HandleWsEventL(aEvent, aDestination);
+ }
+
+void CEikServAppUiBase::SetSgcParamsL(TInt /*aWgId*/, TBitFlags /*aAppFlags*/, TInt /*aSpLayout*/,
+ TInt /*aSpFlags*/)
+ {
+ }
+
+void CEikServAppUiBase::PrepareForAppExitL(TInt /*aWgId*/)
+ {
+ }
+
+
+// =============
+// CEikServAppUi
+// =============
+
+void CEikServAppUi::SetStatusPaneFlags(TInt aFlags)
+ {
+ if (iAknCapServerClient.Handle())
+ {
+ iAknCapServerClient.SetStatusPaneFlags(aFlags);
+ }
+ }
+
+void CEikServAppUi::SetStatusPaneLayoutL(TInt aLayoutResId)
+ {
+ if (iAknCapServerClient.Handle())
+ {
+ iAknCapServerClient.SetStatusPaneLayout(aLayoutResId);
+ }
+ }
+
+void CEikServAppUi::BlankScreenL()
+ {
+ if (iAknCapServerClient.Handle())
+ {
+ iAknCapServerClient.BlankScreen();
+ }
+ }
+
+void CEikServAppUi::UnblankScreen()
+ {
+ if (iAknCapServerClient.Handle())
+ {
+ iAknCapServerClient.UnblankScreen();
+ }
+ }
+
+void CEikServAppUi::EnableTaskListL()
+ {
+ User::LeaveIfError(iAknCapServerClient.EnableTaskList(ETrue));
+ }
+
+void CEikServAppUi::LaunchTaskListL() //const
+ {
+ User::LeaveIfError(iAknCapServerClient.MakeTaskListVisible(ETrue));
+ }
+
+void CEikServAppUi::CloseTaskList() //const
+ {
+ // Ignore possible error.
+ iAknCapServerClient.MakeTaskListVisible(EFalse);
+ }
+
+CEikServAppUi::CEikServAppUi()
+ {
+ }
+
+void CEikServAppUi::ConstructL()
+ {
+ // Create stub to allow device boot up with old notifier controller dependencies.
+ iNotifierDialogController = CNotifierDialogController::NewL(0);
+
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUi::ConstructL() in"));
+#endif
+
+ AknsUtils::InitSkinSupportL();
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUi::ConstructL() init skins ok"));
+#endif
+
+ CEikServAppUiBase::ConstructL();
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUi::ConstructL() CEikServAppUiBase constructed"));
+#endif
+
+ AknsUtils::SetAvkonSkinEnabledL( ETrue );
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUi::ConstructL(), CEikServAppUiBase::ConstructL() succeed"));
+#endif
+
+ AknsUtils::SetAvkonSkinEnabledL( ETrue );
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUiBase::ConstructL(), Skins enabled"));
+#endif
+
+ TFileName fileName(KResFileName);
+ BaflUtils::NearestLanguageFile(iEikonEnv->FsSession(), fileName);
+ iResourceFileOffset = iCoeEnv->AddResourceFileL(fileName);
+
+ // Create notifier controller before Notfier server is started.
+ iNotifierController = CAknNotifierController::NewL();
+
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUi::ConstructL(), initializing Alert"));
+#endif
+
+ CEikServNotifyAlert* alert=new(ELeave) CEikServNotifyAlert;
+ CleanupStack::PushL(alert);
+ alert->ConstructL();
+ TEikServCtrlFactories fctry;
+ fctry.iAlert = alert;
+ fctry.iAlarmAlert = this;
+ CleanupStack::Pop();
+
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUi::ConstructL(), Alert created"));
+#endif
+
+ CEikServAppUiBase::InitializeL(fctry);
+
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUiBase::InitializeL(fctry) succeed"));
+#endif
+
+ RWsSession& wsSession = iCoeEnv->WsSession();
+
+ // Initialize some system settings.
+ TRAP_IGNORE(EnsureExternalKeyHandlerAppStreamExistsL());
+
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUi::ConstructL(), Creating WG for status pane"));
+#endif
+
+ // Create high priority windows for app bar and side bar.
+ iOffScreenGroupWin = RWindowGroup(wsSession);
+ User::LeaveIfError(iOffScreenGroupWin.Construct((TUint32)&iOffScreenGroupWin,
+ EFalse)); // EFalse disables key events
+ iOffScreenGroupWin.SetOrdinalPosition(0,ECoeWinPriorityHigh);
+
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUi::ConstructL(), Starting sound server"));
+#endif
+
+ // Launch the Avkon KeySound Server
+ User::LeaveIfError(CEikKeySoundServer::LaunchServer(iKeySoundThreadId));
+
+ // Start the Avkon Anim Dll - required for keysounds
+ iAknAnimDll = new(ELeave)RAnimDll(wsSession);
+ iAknAnimDll->Load(KAnimDllFileName);
+ iAknAnimKeySound = new(ELeave)RAknAnimKeySound(*iAknAnimDll);
+ iAknAnimKeySound->ConstructL(&iOffScreenGroupWin);
+
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUi::ConstructL(), Keysounds and plugin initialized"));
+#endif
+
+ // Create default keysounds - pass in UID.
+ ReplaceKeySoundsL(0x100053D0);
+
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUi::ConstructL(), Default client and context for keysound created "));
+#endif
+
+ // Window server buffer size.
+ RWsSession &ws = iEikonEnv->WsSession();
+ TInt bufSize = 6400;
+ ws.SetMaxBufferSizeL(bufSize);
+
+ // Load bitmap cursors.
+ LoadBitmapCursorsL();
+
+ STATIC_CAST(CEikServEnv*,CEikonEnv::Static())->SetEikServAppUiSessionFactory( this );
+
+#ifdef _DEBUG
+ RDebug::Print(_L("CEikServAppUi::ConstructL(), over and out"));
+#endif
+ }
+
+
+void CEikServAppUi::RestartKeySoundThreadL()
+ {
+ // Restart keysound server.
+ TInt err = CEikKeySoundServer::LaunchServer(iKeySoundThreadId);
+ if (err != KErrNone)
+ {
+ // Server cannot be restarted, so leave existing animation dll.
+ // No sounds will be played, but machine will still operate.
+ return;
+ }
+
+ // Restart the animation dll
+ if (iAknAnimKeySound)
+ {
+ iAknAnimKeySound->Close();
+ delete iAknAnimKeySound;
+ iAknAnimKeySound = NULL;
+ }
+
+ if (iAknAnimDll)
+ {
+ iAknAnimDll->Close();
+ delete iAknAnimDll;
+ iAknAnimDll = NULL;
+ }
+
+ // Restart the animation dll.
+ iAknAnimDll = new(ELeave)RAnimDll(iCoeEnv->WsSession());
+ iAknAnimDll->Load(KAnimDllFileName);
+ iAknAnimKeySound = new(ELeave)RAknAnimKeySound(*iAknAnimDll);
+ iAknAnimKeySound->ConstructL(&iOffScreenGroupWin);
+
+ // Invented new API.
+ ReplaceKeySoundsL(0x100053D0);
+ KeySounds()->BringToForeground();
+ }
+
+
+void CEikServAppUi::HandleThreadExitL(RThread& aThread)
+ {
+ if(aThread.Name().CompareF(_L("aknnfysrv")) == 0)
+ {
+ StartNewServerApplicationL(KCommonNotifierAppSrvUid);
+ return;
+ }
+
+ TThreadId id = aThread.Id();
+ TExitType exitType = aThread.ExitType();
+ if (id == iExternalKeyHandlerThreadId)
+ {
+ iExternalKeyHandlerRunning = EFalse;
+ }
+ else if (id == iHelpAppThreadId)
+ {
+ iHelpAppRunning = EFalse;
+ }
+ else if (id == iKeySoundThreadId)
+ {
+ RestartKeySoundThreadL();
+ // Don't tell the user about it.
+ return;
+ }
+
+ TBool rdSupport = BaflUtils::FileExists( iEikonEnv->FsSession(), KRDSupport );
+
+ // Show panic notes only if that feature is enabled.
+ if ( exitType == EExitPanic && ( rdSupport || FeatureManager::FeatureSupported(
+ KFeatureIdShowPanics )) )
+ {
+ // Construct text for a panic note.
+ HBufC* panicText = ConstructPanicTextLC( aThread, rdSupport );
+
+ iAknCapServerClient.ShowGlobalNoteL(panicText->Des(), EAknGlobalErrorNote);
+ CleanupStack::PopAndDestroy(); // panicText
+ }
+
+ CEikServAppUiBase::HandleThreadExitL(aThread);
+ }
+
+void CEikServAppUi::UpdateTaskListL()
+ {
+ iAknCapServerClient.UpdateTaskList();
+ }
+
+TKeyResponse CEikServAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode /*aType*/)
+ {
+ if (aKeyEvent.iCode == CTRL('e')) // Exit
+ {
+ CBaActiveScheduler::Exit();
+ }
+ return EKeyWasConsumed;
+ }
+
+void CEikServAppUi::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination)
+ {
+ switch (aEvent.Type())
+ {
+ case EEventPassword:
+ {
+ // No action in Avkon.
+ break;
+ }
+ case EEventErrorMessage:
+ HandleErrorMessageEvent(*(aEvent.ErrorMessage()));
+ break;
+ case KUidValueAknsSkinChangeEvent:
+ {
+ HandleResourceChangeL(KAknsMessageSkinChange);
+ HandleStackedControlsResourceChange(KAknsMessageSkinChange);
+ break;
+ }
+ default:
+ CEikServAppUiBase::HandleWsEventL(aEvent, aDestination);
+ break;
+ }
+ }
+
+// Handle an error message from the window server.
+void CEikServAppUi::HandleErrorMessageEvent(const TWsErrorMessage& aErrorMessage)
+ {
+ TUint err = aErrorMessage.iError;
+
+ switch (aErrorMessage.iErrorCategory)
+ {
+ case TWsErrorMessage::EDrawingRegion:
+ HandleOomEvent();
+ break;
+ case TWsErrorMessage::EBackLight:
+ HandleBacklightError(err);
+ break;
+ case TWsErrorMessage::ELogging:
+ HandleWservLoggingError(err);
+ break;
+ default:
+ break; // intentionally ignored
+ }
+ }
+
+void CEikServAppUi::HandleResourceChangeL(TInt aType)
+ {
+ CEikServAppUiBase::HandleResourceChangeL(aType);
+ if ( aType == KEikDynamicLayoutVariantSwitch )
+ {
+ UpdateCursorsL();
+ }
+ }
+
+// Check the battery states and update any alarm snooze time.
+void CEikServAppUi::HandleSwitchOnEventL(CCoeControl* /*aDestination*/)
+ {
+ if (iAlarmAlertServer)
+ {
+ iAlarmAlertServer->HandleSwitchOnEvent();
+ }
+ }
+
+void CEikServAppUi::HandleSystemEventL(const TWsEvent& aEvent)
+ {
+ TInt event = *((TInt*)aEvent.EventData());
+ switch (event)
+ {
+#ifdef _DEBUG
+ case EEikServExit:
+ CBaActiveScheduler::Exit();
+ break;
+#endif
+ case EEikServChangePasswordMode:
+ // No action in Avkon
+ break;
+ case EEikServShowTaskList:
+ LaunchTaskListL();
+ break;
+ case EEikServHideTaskList:
+ CloseTaskList();
+ break;
+ default:
+ break;
+ }
+ }
+
+CEikServAppUi::~CEikServAppUi()
+ {
+ if (iAknAnimKeySound)
+ {
+ iAknAnimKeySound->Close();
+ }
+ delete iAknAnimKeySound;
+
+ if (iAknAnimDll)
+ {
+ iAknAnimDll->Close();
+ }
+ delete iAknAnimDll;
+
+ // Shut down the key sound server.
+ RKeySoundServerCloser ksCloserSession;
+ ksCloserSession.CloseServer();
+
+ iOffScreenGroupWin.Close();
+ delete iAppbarWindow;
+ delete iSidebarWindow;
+
+ if (iCoeEnv)
+ {
+ iCoeEnv->DeleteResourceFile(iResourceFileOffset);
+ }
+
+ delete iIdler;
+ iNotifServerAppQueue.Close();
+
+ delete iNotifierController;
+ delete iNotifierDialogController;
+ }
+
+MEikServAlarm* CEikServAppUi::NewAlarmL(CEikAlmControlSupervisor& aSupervisor)
+ {
+ CEikAlarmControl* alarm = new(ELeave) CEikAlarmControl(&aSupervisor,this);
+ CleanupStack::PushL(alarm);
+ alarm->ConstructL();
+ CleanupStack::Pop(); // alarm
+ return alarm;
+ }
+
+void CEikServAppUi::EnsureExternalKeyHandlerAppStreamExistsL()
+ {
+ }
+
+// Respond to an out of memory event from the window server.
+void CEikServAppUi::HandleOomEvent()
+ {
+ TBuf<80> msg1;
+ TBuf<80> msg2;
+ iEikonEnv->ReadResource(msg1, R_EIKSRV_OOM_EVENT_TOP);
+ iEikonEnv->ReadResource(msg2, R_EIKSRV_OOM_EVENT_BOT);
+ MEikAlertWin* mAlert = CONST_CAST(MEikAlertWin*, iEikonEnv->Alert());
+ CEikDialog* alert = mAlert->AsEikDialog();
+
+ CEikMover* title = NULL;
+ if ( alert )
+ {
+ title = &( alert->Title() );
+ alert->SetGloballyCapturing(ETrue);
+ title->SetActive(EFalse);
+ }
+ iEikonEnv->AlertWin(msg1, msg2);
+ if ( alert )
+ {
+ title->SetActive(ETrue);
+ alert->SetGloballyCapturing(EFalse);
+ }
+ }
+
+// Respond to an error from the backlight (battery too low).
+void CEikServAppUi::HandleBacklightError(TInt /*aError*/)
+ {
+ }
+
+// Respond to a logging error from wserv (for use by developers)
+void CEikServAppUi::HandleWservLoggingError(TInt aError)
+ {
+ TBuf<80> temp;
+ iEikonEnv->ReadResource(temp, R_EIKSRV_WSERV_LOGGING_ERROR);
+ TBuf<80> msg;
+ msg.Format(temp, aError);
+ iEikonEnv->AlertWin(msg);
+ }
+
+EXPORT_C void CEikServAppUi::SuppressAppSwitching(TBool aSuppress)
+ {
+ // Ignore error as there is nothing to do if failing.
+ iAknCapServerClient.ConnectAndSendAppsKeySuppress(aSuppress);
+ }
+
+HBufC* CEikServAppUi::ConstructPanicTextLC( RThread& aThread, TBool aRDSupport ) const
+ {
+ HBufC* panicText = HBufC::NewLC( KEikServPanicTextBufferSize );
+ TPtr ptr = panicText->Des();
+
+ iEikonEnv->ReadResource( ptr, R_PROGRAM_CLOSED );
+
+ ptr.Append( '\n' );
+
+ HBufC* buffer = aThread.Name().AllocL();
+ TPtr name = buffer->Des();
+
+ // Here we truncate the thread name to fit in the second and third lines of the note.
+
+ TRect mainPane;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EPopupParent, mainPane );
+ TAknLayoutRect popupNoteWindow;
+
+ AknLayoutUtils::TAknCbaLocation cbaLocation( AknLayoutUtils::CbaLocation() );
+ TInt variety( 0 );
+ if ( cbaLocation == AknLayoutUtils::EAknCbaLocationRight )
+ {
+ variety = 3;
+ }
+ else if ( cbaLocation == AknLayoutUtils::EAknCbaLocationLeft )
+ {
+ variety = 6;
+ }
+ else
+ {
+ variety = 0;
+ }
+
+ popupNoteWindow.LayoutRect(mainPane, AknLayoutScalable_Avkon::popup_note_window( variety ) );
+
+ TAknLayoutText textRectTwoLines;
+
+ textRectTwoLines.LayoutText(
+ popupNoteWindow.Rect(),
+ AKN_LAYOUT_TEXT_Note_pop_up_window_texts_Line_1(1));
+
+ // First determine how much fits in the 2. line of the note this can't return NULL.
+ const CFont* font = textRectTwoLines.Font();
+
+ TInt characters( font->TextCount( name, textRectTwoLines.TextRect().Width() ) );
+
+ // 'characters' is now the amount of characters that fit in the second line.
+
+ ptr.Append( name.Left( characters ) );
+ ptr.Append( '\n' );
+
+ // If the name was cut, clip the rest in the third line.
+ TInt charactersLeft( name.Length() - characters );
+
+ if ( charactersLeft > 0 )
+ {
+ TPtr line3(
+ (TText*)&name[characters],
+ charactersLeft,
+ charactersLeft );
+
+ popupNoteWindow.LayoutRect(
+ mainPane,
+ AknLayoutScalable_Avkon::popup_note_window( variety + 1) );
+
+ TAknLayoutText textRectThreeLines;
+
+ textRectThreeLines.LayoutText(
+ popupNoteWindow.Rect(),
+ AKN_LAYOUT_TEXT_Note_pop_up_window_texts_Line_1(2));
+
+ // No bidirectional text support for rendering the thread name. This is intentional.
+
+ AknTextUtils::ClipToFit(
+ line3,
+ *font,
+ textRectThreeLines.TextRect().Width() );
+
+ ptr.Append( line3 );
+ ptr.Append( '\n' );
+ }
+
+ delete buffer;
+
+ // Append panic category and reason only if RD-support file exists.
+
+ if ( aRDSupport )
+ {
+ ptr.Append( aThread.ExitCategory() );
+ ptr.Append( ' ' );
+ ptr.AppendNum( aThread.ExitReason() );
+ }
+
+ return panicText;
+ }
+
+void CEikServAppUi::LoadBitmapCursorsL()
+ {
+ RWsSession& ws = iEikonEnv->WsSession();
+
+ // Create the array containing one sprite member.
+ TFixedArray<TSpriteMember, 1> spriteMemberArray;
+ TSpriteMember& spriteMember = spriteMemberArray[0];
+ spriteMember.iInterval = TTimeIntervalMicroSeconds32(0);
+
+ // This resource is of type AVKON_CUSTOM_TEXT_CURSORS defined in eiksrvui.rss.
+ TResourceReader reader;
+ iEikonEnv->CreateResourceReaderLC(reader, R_AKN_CUSTOM_TEXT_CURSORS);
+
+ HBufC* bmpFile = reader.ReadHBufCL();
+ CleanupStack::PushL(bmpFile);
+
+
+ TInt count = reader.ReadInt16();
+ for (TInt ii = 0; ii < count; ii++)
+ {
+ // id
+ TInt id = reader.ReadInt32();
+
+ // bmpId and maskId
+ TInt bmpId = reader.ReadInt32();
+ TInt maskId = reader.ReadInt32();
+ spriteMember.iBitmap = NULL;
+ spriteMember.iMaskBitmap = NULL;
+
+ if (maskId != -1)
+ {
+ AknIconUtils::CreateIconLC(
+ spriteMember.iBitmap,
+ spriteMember.iMaskBitmap,
+ *bmpFile,
+ bmpId,
+ maskId );
+ }
+ else
+ {
+ spriteMember.iBitmap = AknIconUtils::CreateIconL( *bmpFile, bmpId );
+ CleanupStack::PushL( spriteMember.iBitmap );
+ }
+
+ TAknWindowLineLayout l;
+
+ switch( id )
+ {
+ case KAknCustomTextCursorIdLeftToRight:
+ case KAknCustomTextCursorIdRightToLeft:
+ l = AknLayoutScalable_Avkon::cursor_primary_pane().LayoutLine();
+ break;
+ case KAknCustomTextCursorIdLeftToRightThin:
+ case KAknCustomTextCursorIdRightToLeftThin:
+ default:
+ l = AknLayoutScalable_Avkon::cursor_primary_small_pane().LayoutLine();
+ break;
+ }
+
+ TRect rectParent = ApplicationRect();
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( rectParent, l );
+ TRect rectCursorBitmap( layoutRect.Rect() );
+ TSize scaledSize(rectCursorBitmap.Width(), rectCursorBitmap.Height() );
+
+ // Perform the scaling
+ AknIconUtils::SetSize(
+ spriteMember.iBitmap,
+ scaledSize,
+ EAspectRatioPreservedAndUnusedSpaceRemoved);
+
+ if ( spriteMember.iMaskBitmap )
+ {
+ AknIconUtils::SetSize(
+ spriteMember.iMaskBitmap,
+ scaledSize,
+ EAspectRatioPreservedAndUnusedSpaceRemoved);
+ }
+
+ // Flags.
+ TUint flags = reader.ReadUint16();
+ spriteMember.iInvertMask = flags|EAknCustomTextCursorFlagInvertMask;
+
+ // Draw mode.
+ spriteMember.iDrawMode = (CGraphicsContext::TDrawMode)reader.ReadInt16();
+
+ // Offset. Use actual scalings used. Do not read inside TPoint constructor for compiler
+ // independence.
+ TInt offsetX = reader.ReadInt16();
+ TInt offsetY = reader.ReadInt16();
+ spriteMember.iOffset = TPoint(offsetX, offsetY);
+
+ // Alignment.
+ TInt align = reader.ReadInt16();
+
+ // Decode the "vehicle ids" into features:
+ TAknFontCategory category(EAknFontCategoryPrimary);
+ TBool isRightToLeft(EFalse);
+
+ switch( id )
+ {
+ case KAknCustomTextCursorIdLeftToRight:
+ break;
+ case KAknCustomTextCursorIdRightToLeft:
+ isRightToLeft = ETrue;
+ break;
+ case KAknCustomTextCursorIdLeftToRightThin:
+ category = EAknFontCategoryPrimarySmall;
+ break;
+ case KAknCustomTextCursorIdRightToLeftThin:
+ category = EAknFontCategoryPrimarySmall;
+ isRightToLeft = ETrue;
+ break;
+ default:
+ // Should not get here if the resource is correct. Already initialized defaults
+ // get used.
+ break;
+ }
+
+ id = AknCustomCursorSupport::CustomBidiTextCursorId(
+ category,
+ rectCursorBitmap,
+ isRightToLeft );
+
+ // Return code is ignored since we will regularly be setting a bitmap twice
+ (void)ws.SetCustomTextCursor(
+ id,
+ spriteMemberArray.Array(),
+ ESpriteFlash,
+ (RWsSession::TCustomTextCursorAlignment)align);
+
+ if (maskId != -1)
+ {
+ CleanupStack::PopAndDestroy(spriteMember.iMaskBitmap);
+ }
+ CleanupStack::PopAndDestroy(spriteMember.iBitmap);
+ }
+
+ CleanupStack::PopAndDestroy(bmpFile);
+ CleanupStack::PopAndDestroy(); // reader
+ }
+
+//
+// First export
+//
+
+EXPORT_C CEikServAppUi* CreateAppUi()
+ {
+ return new CEikServAppUi;
+ }
+
+EXPORT_C void CEikServAppUi::ActivateDisplayIfNeeded()
+ {
+#ifndef __WINS__
+
+ // Check if screen saver active.
+ TApaTaskList list(iCoeEnv->WsSession());
+ TApaTask task = list.FindByPos(0); // topmost application
+ CApaWindowGroupName* name = 0;
+ TRAPD( err, name = CApaWindowGroupName::NewL(iCoeEnv->WsSession(), task.WgId()));
+ if ( !err && name->AppUid() == TUid::Uid(0x100056CF) ) // Screen saver Uid
+ {
+ User::ResetInactivityTime();
+ }
+ delete name;
+#endif
+ }
+
+EXPORT_C CEikServAppUiSession* CEikServAppUi::CreateSessionL( /*RThread aClient*/ )
+ {
+ return CAknEikServAppUiSession::NewL( /*aClient,*/ this, *this);
+ }
+
+void CEikServAppUi::Extension(TUid aExtensionUid, const TDesC8& aBuffer, RMessagePtr2 aMessage)
+ {
+ TBool hasCap = aMessage.HasCapability(ECapabilityWriteDeviceData); // Write Dev D required here
+
+ if (!hasCap)
+ {
+ aMessage.Complete(KErrPermissionDenied);
+ return;
+ }
+
+ switch(aExtensionUid.iUid)
+ {
+ case EAknCommonNotifierServerRunning:
+ {
+ aMessage.Complete(KErrNone);
+ TRAP_IGNORE(
+ // Do not clear the list, it can be used when common notifier server is being
+ // restarted due crash.
+ for (TInt i = iNotifierController->iPreloadList.Count() - 1; i >= 0; i--)
+ {
+ iNotifierController->iPreloadList[i]->PreLoadLibraryL();
+ }
+ );
+ break;
+ }
+ case EAknNotifierControllerCmd:
+ {
+ TInt cmd = static_cast<TInt>(*(aBuffer.Ptr()));
+#ifdef _DEBUG
+ RThread thread;
+ aMessage.ClientL(thread); // ok to leave in debug mode
+ TName threadName( thread.Name() );
+#endif
+ if(cmd == CAknNotifierControllerUtility::EDoAllow)
+ {
+#ifdef _DEBUG
+
+ RDebug::Print(_L("Allow all notifications: thread %S"), &threadName);
+#endif
+ NotifierController()->DoAllowNotifications();
+ }
+ else if(cmd == CAknNotifierControllerUtility::EDoStop)
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("Stop all notifications: thread %S"), &threadName);
+#endif
+ NotifierController()->DoStopNotifications();
+ }
+ else if(cmd == CAknNotifierControllerUtility::DoCancelAll)
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("Cancel all notifications: thread %S"), &threadName);
+#endif
+ CloseTaskList();
+ NotifierController()->DoCancelAllNotificatons();
+ }
+ else
+ {
+ if (!aMessage.IsNull())
+ {
+ aMessage.Complete(KErrNotSupported);
+ }
+ return;
+ }
+
+ if (!aMessage.IsNull())
+ {
+ // Release caller before forwarding to app servers.
+ aMessage.Complete(KErrNone);
+ }
+
+ NotifierController()->NotifyAppServers(cmd);
+ break;
+ }
+ case EAknCapServerStartupComplete:
+ {
+ aMessage.Complete(KErrNone); // No one is listening this return value.
+ TRAP_IGNORE(DoAknCapServerStartupCompleteL());
+ break;
+ }
+ case EAknSignalAknCapServerReady:
+ {
+ DoSignalWhenAknServerReady(aMessage); // Completes message when akncapserver is ready.
+ break;
+ }
+ default:
+ aMessage.Complete(KErrNotSupported);
+ }
+ }
+
+/// Session within avkon code:
+
+CAknEikServAppUiSession::CAknEikServAppUiSession(
+ /* RThread aClient, */
+ MEikServAppUiSessionHandler* aHandler,
+ CEikServAppUi& aAppUi )
+: CEikServAppUiSession( aHandler), iAppUi(aAppUi)
+ {
+ }
+
+CAknEikServAppUiSession* CAknEikServAppUiSession::NewL(
+ /*RThread aClient, */
+ MEikServAppUiSessionHandler* aHandler,
+ CEikServAppUi& aAppUi )
+ {
+ CAknEikServAppUiSession* session = new(ELeave) CAknEikServAppUiSession(
+ /*aClient,*/
+ aHandler,
+ aAppUi);
+
+ CleanupStack::PushL(session);
+ session->ConstructL();
+ CleanupStack::Pop();
+ return session;
+ }
+
+CAknEikServAppUiSession::~CAknEikServAppUiSession()
+ {
+ }
+
+void CAknEikServAppUiSession::ConstructL()
+ {
+ }
+
+void CAknEikServAppUiSession::ServiceL(const RMessage2 &aMessage)
+ {
+ switch (aMessage.Function())
+ {
+ case EEikAppUiNotifyAlarmServerOfTaskChange:
+ SessionHandler()->NotifyAlarmServerOfTaskChangeL();
+ aMessage.Complete(KErrNone);
+ break;
+ case EEikAppUiEnableTaskList:
+ SessionHandler()->EnableTaskListL();
+ aMessage.Complete(KErrNone);
+ break;
+ case EEikAppUiLaunchTaskList:
+ SessionHandler()->LaunchTaskListL();
+ aMessage.Complete(KErrNone);
+ break;
+ case EEikAppUiCycleTasks:
+ {
+ aMessage.Complete(KErrNone);
+ }
+ break;
+ case EAknEikAppUiAddToStack:
+ {
+ CCoeControl*temp = REINTERPRET_CAST(CCoeControl*, CONST_CAST(TAny*, aMessage.Ptr0()) );
+ iAppUi.AddToStackL(temp, aMessage.Int1(), aMessage.Int2());
+ aMessage.Complete(KErrNone);
+ }
+ break;
+ case EAknEikAppUiRemoveFromStack:
+ {
+ CCoeControl*temp = REINTERPRET_CAST(CCoeControl*, CONST_CAST(TAny*, aMessage.Ptr0()) );
+ iAppUi.RemoveFromStack(temp);
+ aMessage.Complete(KErrNone);
+ }
+ break;
+ case EAknEikAppUiShutdownApps:
+ {
+ aMessage.HasCapabilityL(ECapabilityPowerMgmt); // PowerMgmt required here
+ TUid uid;
+ uid.iUid = (REINTERPRET_CAST(TInt, CONST_CAST(TAny*, aMessage.Ptr0()) ));
+ TInt timeout = REINTERPRET_CAST(TInt, CONST_CAST(TAny*, aMessage.Ptr1()) );
+
+ //ShutdownAppsL must complete message.
+ TRAPD(err, iAppUi.ShutdownAppsL(uid, aMessage, timeout));
+ if (err != KErrNone)
+ {
+ // Message wasn't completed.
+ aMessage.Complete(err);
+ }
+ }
+ break;
+
+ default:
+ {
+ // It is the base class' responsibility to complete.
+ // This will pick up any new opcodes added by Symbian that are
+ // not yet handled here.
+ CEikServAppUiSession::ServiceL(aMessage);
+ break;
+ }
+ }
+ }
+void CAknEikServAppUiSession::Write(const RMessage2& aMessage, const TAny* aPtr, const TDesC8& aDes,
+ TInt anOffset)
+ {
+ TRAPD(ret, aMessage.WriteL( (TInt)aPtr, aDes, anOffset);)
+ if (ret != KErrNone)
+ {
+ RThread clientThread;
+ (void)aMessage.Client( clientThread);
+ clientThread.Panic(_L("CEikServAppUi server"), KErrGeneral);
+ }
+ }
+
+//
+// Main
+//
+
+GLDEF_C TInt PanicNoteThreadFunction( TAny* /*aParameters*/ )
+ {
+ return KErrNone;
+ }
+
+// Probably obsolete, but just in case, Fix Me !!
+EXPORT_C void CEikServAppUi::HideApplicationFromFswL(TInt aUid,TBool aDisable)
+ {
+ iAknCapServerClient.HideApplicationFromFsw(aDisable, aUid);
+ }
+
+// Start new notifier server plugin using fixed server differentiator.
+void StartNotifierAppServerL(TUid aAppServerUid)
+ {
+ RApaLsSession apa;
+ User::LeaveIfError(apa.Connect());
+ CleanupClosePushL(apa);
+
+ TApaAppInfo info;
+
+ TInt err(0);
+ for(TInt i = 20;
+ ((err = apa.GetAppInfo(info, aAppServerUid)) == RApaLsSession::EAppListInvalid) && i > 0;
+ i--)
+ {
+ User::After(500000);
+ }
+
+ User::LeaveIfError(err);
+
+ CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
+ cmdLine->SetExecutableNameL(info.iFullName);
+ cmdLine->SetServerRequiredL(KUikonUidPluginInterfaceNotifiers);
+ cmdLine->SetCommandL(EApaCommandBackground);
+ TThreadId dummy;
+ User::LeaveIfError(apa.StartApp(*cmdLine, dummy));
+
+ CleanupStack::PopAndDestroy(2, &apa); // cmdLine and apa
+ }
+
+TBool StartNotifierAppServer(TAny* aAny)
+ {
+ // Resolve uid.
+ CEikServAppUi* appUI = (CEikServAppUi*)aAny;
+ TUid serverUid = appUI->NextNotifierServerUid();
+
+ // Check if the aknnfysrv.exe is running, perventing for dropping into
+ // an infinite loop of launching aknnfysrv.exe
+ if (serverUid == KCommonNotifierAppSrvUid)
+ {
+ TFullName serverName;
+ serverName.Format(_L("%08x_%08x_AppServer"), KUikonUidPluginInterfaceNotifiers, KCommonNotifierAppSrvUid);
+ TFindServer find(serverName);
+ TFullName fullName;
+ if (find.Next(fullName) == KErrNone)
+ {
+ // Aknnfysrv.exe is already running, so just return.
+ return EFalse;
+ }
+ }
+
+ if (serverUid != KNullUid)
+ {
+ TRAP_IGNORE(StartNotifierAppServerL(serverUid))
+ }
+
+ return EFalse; // do not call back again
+ }
+
+EXPORT_C void CEikServAppUi::StartNewServerApplicationL(TUid aAppServerUid)
+ {
+ // Add to queue.
+ if (iNotifServerAppQueue.Find(aAppServerUid.iUid) == KErrNotFound)
+ {
+ iNotifServerAppQueue.AppendL(aAppServerUid.iUid);
+ }
+
+ // Start idler if does not exist (if only akncapserver is already running).
+ if (!iIdler && iAknCapServerClient.Handle() != 0)
+ {
+ iIdler = CIdle::NewL(CActive::EPriorityHigh);
+ iIdler->Start(TCallBack(StartNotifierAppServer, this));
+ }
+ }
+
+TUid CEikServAppUi::NextNotifierServerUid()
+ {
+ TInt uid = 0;
+
+ delete iIdler;
+ iIdler = 0;
+
+ if (iNotifServerAppQueue.Count())
+ {
+ uid = iNotifServerAppQueue[0];
+ iNotifServerAppQueue.Remove(0);
+ }
+
+ // Activate idler for next uid.
+ if (iNotifServerAppQueue.Count())
+ {
+ // We must trap this call, if creating a new CIdle fails, no applications will be started
+ // from queue until new request comes.
+ TRAPD(err, iIdler = CIdle::NewL(CActive::EPriorityHigh))
+ if (!err)
+ {
+ iIdler->Start(TCallBack(StartNotifierAppServer, this));
+ }
+ }
+ else
+ {
+ // Last notifier app server is being launched, free starter.
+ if (!iAknCapServerMessage.IsNull())
+ {
+ iAknCapServerMessage.Complete(KErrNone);
+ }
+ }
+
+ // Return uid of topmost.
+ return TUid::Uid(uid);
+ }
+
+void CEikServAppUi::UpdateCursorsL()
+ {
+ LoadBitmapCursorsL();
+ }
+
+TInt DoPollCapServer(TAny* appui)
+ {
+ _LIT(KServerNameFormat, "%08x_%08x_AppServer");
+ TFullName serverName;
+ serverName.Format(KServerNameFormat, KUikonUidPluginInterfaceNotifiers, KAknCapServerUid.iUid);
+ TFindServer find(serverName);
+ TFullName fullName;
+ ((CEikServAppUi*)appui)->AknCapServerStartupComplete(find.Next(fullName) == KErrNone);
+ return KErrNone;
+ }
+
+// We are doing this on startup when there is always enough memory, so methods with L really
+// can't leave.
+void CEikServAppUi::AknCapServerStartupComplete(TBool aComplete)
+ {
+ delete iIdler;
+ iIdler = 0;
+
+ if (aComplete)
+ {
+ // In this phase of boot, create real connection to akncapserver.
+ iAknCapServerClient.DoEikonServerConnect();
+
+ // Create alarm server as we have capserver running.
+ TRAPD(err, DoAlarmServerStartupL());
+
+ // No use to startup phone if this fails.
+ __ASSERT_ALWAYS(!err, User::Invariant());
+
+ iIdler = CIdle::NewL(CActive::EPriorityHigh);
+ iIdler->Start(TCallBack(StartNotifierAppServer, this));
+ }
+ else
+ {
+ const TInt waitDelay = 200000; // 0.2 seconds
+ User::After(waitDelay);
+ DoAknCapServerStartupCompleteL();
+ }
+ }
+
+void CEikServAppUi::DoAknCapServerStartupCompleteL()
+ {
+ __ASSERT_DEBUG(iIdler == 0, User::Invariant());
+
+ iIdler = CIdle::NewL(CActive::EPriorityIdle);
+ iIdler->Start(TCallBack(DoPollCapServer, this));
+ }
+
+void CEikServAppUi::DoSignalWhenAknServerReady(const RMessagePtr2& aMessage)
+ {
+ if (iAknCapServerClient.Handle() != 0)
+ {
+ aMessage.Complete(KErrNone);
+ }
+
+ // This should be used as single shot.
+ __ASSERT_DEBUG(iAknCapServerMessage.IsNull(), User::Invariant());
+ iAknCapServerMessage = aMessage;
+ }
+
+void CEikServAppUi::DoAlarmServerStartupL()
+ {
+ // Stupid naming, perhaps.
+ iAlarmAlertServer = CEikServAlarmAlertServer::NewL(this);
+
+ // Start AlarmServer.
+ TInt err = AlarmClientUtils::StartAlarmServer();
+ if (err != KErrNone && err != KErrAlreadyExists)
+ {
+ User::Leave(err);
+ }
+
+ HandleSwitchOnEventL( NULL );
+ }
+
+// End of file