sl@0: // Copyright (c) 1995-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 the License "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: // e32\ewsrv\ws_main.cpp sl@0: // sl@0: // sl@0: sl@0: #include "ws_std.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #ifdef __WINS__ sl@0: #include sl@0: #endif sl@0: sl@0: GLREF_D CKeyTranslator *KeyTranslator; sl@0: GLREF_D CKeyRepeat* KeyRepeat; sl@0: sl@0: // password notifier support functions sl@0: LOCAL_C void RenderPassword(RConsole *aCon, TInt aPWLeft, const TDesC& aPW); sl@0: sl@0: _LIT(KShellProcessName, "ESHELL"); sl@0: _LIT(KShellCommandLine, "/p"); sl@0: sl@0: // sl@0: // class CKeyRepeat sl@0: // sl@0: sl@0: CKeyRepeat::CKeyRepeat(TInt aPriority) : CTimer(aPriority) sl@0: // sl@0: // Constructor. Set default repeat delay and rate sl@0: // sl@0: { sl@0: iDelay=EDefaultKeyRepeatDelay; sl@0: iRate=EDefaultKeyRepeatRate; sl@0: } sl@0: sl@0: void CKeyRepeat::ConstructL() sl@0: { sl@0: sl@0: CTimer::ConstructL(); sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: void CKeyRepeat::RunL() sl@0: // sl@0: // Send a repeat keypress to the window sl@0: // sl@0: { sl@0: sl@0: After(iRate); sl@0: CWsWindow::KeyPress(iKeyData); sl@0: } sl@0: sl@0: void CKeyRepeat::Request(TKeyData& aKeyData) sl@0: // sl@0: // Request a repeat event sl@0: // sl@0: { sl@0: sl@0: iKeyData=aKeyData; sl@0: Cancel(); sl@0: After(iDelay); sl@0: } sl@0: sl@0: void CKeyRepeat::SetRepeatTime(TInt aDelay,TInt aRate) sl@0: { sl@0: sl@0: iDelay=aDelay; sl@0: iRate=aRate; sl@0: } sl@0: sl@0: void CKeyRepeat::RepeatTime(TInt& aDelay,TInt& aRate) sl@0: { sl@0: sl@0: aDelay=iDelay; sl@0: aRate=iRate; sl@0: } sl@0: sl@0: // sl@0: // class CWsSession sl@0: // sl@0: sl@0: CWsSession::CWsSession() sl@0: { sl@0: iTestFast = (UserSvr::DebugMask(2)&0x00000002) ? 1 : 0; sl@0: } sl@0: sl@0: CWsSession::~CWsSession() sl@0: // sl@0: // Destructor sl@0: // sl@0: { sl@0: sl@0: delete iWindow; sl@0: } sl@0: sl@0: // sl@0: // class CWsServer sl@0: // sl@0: sl@0: void CWsServer::New() sl@0: // sl@0: // Create a new CWsServer. sl@0: // sl@0: { sl@0: sl@0: CWsServer *pS=new CWsServer(EPriority); sl@0: __ASSERT_ALWAYS(pS!=NULL,Fault(ECreateServer)); sl@0: pS->SetPinClientDescriptors(EFalse); // don't pin because client interface can't cope with errors if pin fails under real or simulated OOM sl@0: TInt r=pS->Start(KE32WindowServer); sl@0: __ASSERT_ALWAYS(r==KErrNone,Fault(EStartServer)); sl@0: RProcess::Rendezvous(KErrNone); sl@0: sl@0: } sl@0: sl@0: CWsServer::CWsServer(TInt aPriority) sl@0: // sl@0: // Constructor. sl@0: // sl@0: : CServer2(aPriority) sl@0: { sl@0: } sl@0: sl@0: CSession2* CWsServer::NewSessionL(const TVersion& aVersion,const RMessage2&) const sl@0: // sl@0: // Create a new client for this server. sl@0: // sl@0: { sl@0: sl@0: TVersion v(KW32MajorVersionNumber,KW32MinorVersionNumber,KE32BuildVersionNumber); sl@0: TBool r=User::QueryVersionSupported(v,aVersion); sl@0: if (!r) sl@0: User::Leave(KErrNotSupported); sl@0: return new(ELeave) CWsSession; sl@0: } sl@0: sl@0: void CWsSession::ServiceL(const RMessage2& aMessage) sl@0: // sl@0: // Handle messages for this session. sl@0: // sl@0: { sl@0: sl@0: iCurMsg = aMessage; sl@0: CWsWindow::WaitOnService(); sl@0: CWsWindow* pW=iWindow; sl@0: TInt r=EPrematureOperation; sl@0: TBool delayCompletion=EFalse; sl@0: switch (aMessage.Function()) sl@0: { sl@0: case EConsoleCreate: sl@0: { sl@0: if (pW) sl@0: { sl@0: delete pW; sl@0: iWindow=NULL; sl@0: } sl@0: pW=new CWsWindow; sl@0: if (!pW) sl@0: { sl@0: r=EWindowOutOfMemory; sl@0: break; sl@0: } sl@0: iWindow=pW; sl@0: pW->iAllowResize=ETrue; sl@0: pW->iIsVisible=ETrue; sl@0: pW->iOnTop=EFalse; sl@0: pW->SetCursorHeight(50); sl@0: pW->iKQueue.SetOffset(_FOFF(SWsKey,iLink)); sl@0: break; sl@0: } sl@0: case EConsoleSet: sl@0: { sl@0: if (!pW) sl@0: { sl@0: pW=new(ELeave) CWsWindow; sl@0: iWindow=pW; sl@0: pW->iAllowResize=ETrue; sl@0: pW->iIsVisible=ETrue; sl@0: pW->iOnTop=EFalse; sl@0: pW->SetCursorHeight(50); sl@0: pW->iKQueue.SetOffset(_FOFF(SWsKey,iLink)); sl@0: } sl@0: pW->iAllowSlide=ETrue; sl@0: TFileName name; sl@0: iCurMsg.ReadL(0, name); sl@0: pW->iTitle=name; sl@0: TPckgBuf size; sl@0: iCurMsg.ReadL(1, size); sl@0: TRAP(r,pW->CreateL(size())); sl@0: if (r != KErrNone) sl@0: { sl@0: delete pW; sl@0: iWindow=NULL; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleClearScreen: sl@0: { sl@0: if (pW) sl@0: { sl@0: pW->Clear(); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleClearToEndOfLine: sl@0: { sl@0: if (pW) sl@0: { sl@0: pW->ClearToEndOfLine(); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleSetTitle: sl@0: { sl@0: if (pW) sl@0: { sl@0: TFileName name; sl@0: iCurMsg.ReadL(0, name); sl@0: pW->SetTitle(name); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleSetSize: sl@0: { sl@0: if (pW) sl@0: { sl@0: TPckgBuf size; sl@0: iCurMsg.ReadL(0, size); sl@0: // pW->SetSize(size()); sl@0: // r=KErrNone; sl@0: r=KErrNotSupported; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleSetWindowPosAbs: sl@0: { sl@0: if (pW) sl@0: { sl@0: TPckgBuf point; sl@0: iCurMsg.ReadL(0, point); sl@0: pW->SetWindowPosAbs(point()); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleSetCursorHeight: sl@0: { sl@0: if (pW) sl@0: { sl@0: pW->SetCursorHeight(aMessage.Int0()); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleSetCursorPosAbs: sl@0: { sl@0: if (pW) sl@0: { sl@0: TPckgBuf point; sl@0: iCurMsg.ReadL(0, point); sl@0: pW->SetCursorPosAbs(point()); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleSetCursorPosRel: sl@0: { sl@0: if (pW) sl@0: { sl@0: TPckgBuf point; sl@0: iCurMsg.ReadL(0, point); sl@0: pW->SetCursorPosRel(point()); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleCursorPos: sl@0: { sl@0: if (pW) sl@0: { sl@0: TPckgBuf point; sl@0: point()=pW->CursorPosition(); sl@0: aMessage.WriteL(0,point); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleSize: sl@0: { sl@0: if (pW) sl@0: { sl@0: TPckgBuf size; sl@0: size()=pW->Size(); sl@0: aMessage.WriteL(0,size); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleScreenSize: sl@0: { sl@0: if (pW) sl@0: { sl@0: TPckgBuf size; sl@0: size()=CWsWindow::ScreenSize; sl@0: aMessage.WriteL(0,size); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleControl: sl@0: { sl@0: if (pW) sl@0: { sl@0: TBool indicator=ETrue; sl@0: TInt offset=0; sl@0: TBuf<0x100> b; sl@0: do sl@0: { sl@0: iCurMsg.ReadL(0,b,offset); sl@0: for (const TText* pB=b.Ptr();pBControlScrollBars(indicator); sl@0: break; sl@0: case 'W': sl@0: pW->ControlWrapLock(indicator); sl@0: break; sl@0: case 'P': sl@0: pW->ControlPointerEvents(indicator); sl@0: break; sl@0: case 'L': sl@0: pW->ControlScrollLock(indicator); sl@0: break; sl@0: case 'V': sl@0: pW->ControlVisibility(indicator); sl@0: break; sl@0: case 'C': sl@0: pW->ControlCursorRequired(indicator); sl@0: break; sl@0: case 'M': sl@0: pW->ControlMaximised(indicator); sl@0: break; sl@0: case 'N': sl@0: pW->ControlNewLineMode(indicator); sl@0: break; sl@0: case 'O': sl@0: pW->ControlOnTop(indicator); sl@0: break; sl@0: case 'I': sl@0: pW->ControlInformAllMouse(indicator); sl@0: break; sl@0: case 'R': sl@0: pW->ControlRawEventMode(indicator); sl@0: break; sl@0: case 'A': sl@0: pW->ControlAllowResize(indicator); sl@0: } sl@0: } sl@0: offset+=b.Length(); sl@0: } sl@0: while (b.Length()==b.MaxLength()); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleWrite: sl@0: { sl@0: if (pW) sl@0: { sl@0: switch(iTestFast) sl@0: { sl@0: case 0: sl@0: { sl@0: TInt offset=0; sl@0: TBuf<0x100> b; sl@0: do sl@0: { sl@0: iCurMsg.ReadL(0,b,offset); sl@0: pW->Write(b); sl@0: offset+=b.Length(); sl@0: } sl@0: while (b.Length()==b.MaxLength()); sl@0: pW->WriteDone(); sl@0: } sl@0: r=KErrNone; sl@0: break; sl@0: sl@0: case 1: sl@0: { sl@0: pW->Write(_L("Output suppressed because TESTFAST mode is set...")); sl@0: pW->WriteDone(); sl@0: ++iTestFast; sl@0: } sl@0: r=KErrNone; sl@0: break; sl@0: sl@0: default: sl@0: r=KErrNone; sl@0: break; sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleRead: sl@0: { sl@0: if (pW) sl@0: { sl@0: if (pW->EnqueReadRequest(aMessage)) sl@0: { sl@0: delayCompletion=ETrue; sl@0: r=KErrNone; sl@0: } sl@0: else sl@0: r=EDoubleReadRequest; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleReadCancel: sl@0: { sl@0: if (pW) sl@0: { sl@0: pW->DequeReadRequest(); sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleDestroy: sl@0: { sl@0: if (pW) sl@0: { sl@0: delete pW; sl@0: iWindow=NULL; sl@0: r=KErrNone; sl@0: } sl@0: break; sl@0: } sl@0: case EConsoleSetMode: sl@0: { sl@0: r=CWsWindow::SetMode((TVideoMode)aMessage.Int0()); sl@0: break; sl@0: } sl@0: case EConsoleSetPaletteEntry: sl@0: { sl@0: CWsWindow::ScreenDriver->SetPaletteEntry((TColorIndex)aMessage.Int0(),(TUint8)aMessage.Int1(),(TUint8)aMessage.Int2(),(TUint8)aMessage.Int3()); sl@0: pW->Redraw(); sl@0: r=KErrNone; sl@0: break; sl@0: } sl@0: case EConsoleGetPaletteEntry: sl@0: { sl@0: TUint8 r,g,b; sl@0: TPckgBuf red,green,blue; sl@0: CWsWindow::ScreenDriver->GetPaletteEntry((TColorIndex)aMessage.Int0(),r,g,b); sl@0: red()=r; green()=g; blue()=b; sl@0: aMessage.WriteL(1,red); sl@0: aMessage.WriteL(2,green); sl@0: aMessage.WriteL(3,blue); sl@0: } sl@0: r=KErrNone; sl@0: break; sl@0: case EConsoleSetTextColors: sl@0: { sl@0: if(pW) sl@0: { sl@0: pW->iFgColor=(TColorIndex)aMessage.Int0(); sl@0: pW->iBgColor=(TColorIndex)aMessage.Int1(); sl@0: } sl@0: r=KErrNone; sl@0: break; sl@0: } sl@0: case EConsoleSetUIColors: sl@0: { sl@0: CWsWindow::WindowBgColor=(TColorIndex)aMessage.Int0(); sl@0: CWsWindow::BorderColor=(TColorIndex)aMessage.Int1(); sl@0: CWsWindow::ScreenColor=(TColorIndex)aMessage.Int2(); sl@0: CWsWindow::ChangeUIColors(); sl@0: r=KErrNone; sl@0: break; sl@0: } sl@0: case EConsoleSetTextAttribute: sl@0: { sl@0: if(pW) sl@0: pW->SetTextAttribute((TTextAttribute)aMessage.Int0()); sl@0: r=KErrNone; sl@0: break; sl@0: } sl@0: default: sl@0: r=KErrNotSupported; sl@0: } sl@0: if (!delayCompletion) sl@0: aMessage.Complete(r); sl@0: CWsWindow::SignalService(); sl@0: } sl@0: sl@0: void CWsSession::ServiceError(const RMessage2& aMessage,TInt aError) sl@0: { sl@0: if (!aMessage.IsNull()) sl@0: { sl@0: if (aError>0) sl@0: { sl@0: aMessage.Panic(_L("WServ panic"),aError); sl@0: } sl@0: else sl@0: { sl@0: aMessage.Complete(aError); sl@0: } sl@0: } sl@0: } sl@0: sl@0: CWsServer::~CWsServer() sl@0: // sl@0: // Destructor sl@0: // sl@0: { sl@0: } sl@0: sl@0: // sl@0: // class CEvent sl@0: // sl@0: sl@0: void CEvent::New() sl@0: // sl@0: // Create the CEvent active object. sl@0: // sl@0: { sl@0: sl@0: CEvent *pE=new CEvent(EPriority); sl@0: __ASSERT_ALWAYS(pE!=NULL,Fault(ECreateEvent)); sl@0: pE->CaptureKeys=new CCaptureKeys(); sl@0: __ASSERT_ALWAYS(pE->CaptureKeys!=NULL,Fault(ECreateEvent)); sl@0: sl@0: pE->CaptureKeys->Construct(); sl@0: sl@0: CActiveScheduler::Add(pE); sl@0: UserSvr::CaptureEventHook(); sl@0: pE->Request(); sl@0: } sl@0: sl@0: CEvent::~CEvent() sl@0: // sl@0: // Destroy the CEvent active object sl@0: // sl@0: { sl@0: sl@0: Cancel(); sl@0: } sl@0: sl@0: #pragma warning( disable : 4705 ) // statement has no effect sl@0: CEvent::CEvent(TInt aPriority) sl@0: // sl@0: // Constructor sl@0: // sl@0: : CActive(aPriority) sl@0: { sl@0: } sl@0: #pragma warning( default : 4705 ) sl@0: sl@0: void CEvent::Request() sl@0: // sl@0: // Issue a request for the next event. sl@0: // sl@0: { sl@0: sl@0: UserSvr::RequestEvent(iEvent,iStatus); sl@0: SetActive(); sl@0: } sl@0: sl@0: void CEvent::DoCancel() sl@0: // sl@0: // Cancel a pending event. sl@0: // sl@0: { sl@0: sl@0: UserSvr::RequestEventCancel(); sl@0: } sl@0: sl@0: void CEvent::RunL() sl@0: // sl@0: // Event has completed. sl@0: // sl@0: { sl@0: sl@0: if (CWsWindow::RawEventMode()) sl@0: { sl@0: KeyRepeat->Cancel(); sl@0: CWsWindow::QueueRawEvent(iEvent.Event()); sl@0: Request(); sl@0: return; sl@0: } sl@0: switch(iEvent.Event().Type()) sl@0: { sl@0: case TRawEvent::ERedraw: sl@0: CWsWindow::Redraw(); sl@0: break; sl@0: case TRawEvent::EButton1Down: sl@0: if(!CWsWindow::MouseIsCaptured) sl@0: { sl@0: CWsWindow::MouseMove(iEvent.Event().Pos()); sl@0: CWsWindow::MouseLeftButton(); sl@0: } sl@0: else sl@0: CWsWindow::InformTopMouse(iEvent.Event().Pos()); sl@0: break; sl@0: case TRawEvent::EButton1Up: sl@0: if(!CWsWindow::MouseIsCaptured) sl@0: { sl@0: CWsWindow::MouseMove(iEvent.Event().Pos()); sl@0: CWsWindow::MouseLeftButtonUp(); sl@0: } sl@0: break; sl@0: case TRawEvent::EButton2Down: sl@0: break; sl@0: case TRawEvent::EButton2Up: sl@0: break; sl@0: case TRawEvent::EButton3Down: sl@0: break; sl@0: case TRawEvent::EButton3Up: sl@0: break; sl@0: case TRawEvent::EPointerMove: sl@0: CWsWindow::MouseMove(iEvent.Event().Pos()); sl@0: break; sl@0: case TRawEvent::EInactive: sl@0: KeyRepeat->Cancel(); sl@0: break; sl@0: case TRawEvent::EActive: sl@0: break; sl@0: case TRawEvent::EUpdateModifiers: sl@0: KeyTranslator->UpdateModifiers(iEvent.Event().Modifiers()); sl@0: break; sl@0: case TRawEvent::EKeyDown: sl@0: { sl@0: TKeyData keyData; sl@0: if (KeyTranslator->TranslateKey(iEvent.Event().ScanCode(), EFalse,*CaptureKeys,keyData)) sl@0: CWsWindow::KeyPress(keyData); sl@0: if (keyData.iModifiers&EModifierAutorepeatable) sl@0: KeyRepeat->Request(keyData); sl@0: break; sl@0: } sl@0: case TRawEvent::EKeyUp: sl@0: { sl@0: TKeyData keyData; sl@0: KeyRepeat->Cancel(); sl@0: if (KeyTranslator->TranslateKey(iEvent.Event().ScanCode(), ETrue,*CaptureKeys,keyData)) sl@0: CWsWindow::KeyPress(keyData); sl@0: break; sl@0: } sl@0: case TRawEvent::ESwitchOn: sl@0: case TRawEvent::ECaseOpen: sl@0: HAL::Set(HAL::EDisplayState, 1); sl@0: { sl@0: RDmDomainManager mgr; sl@0: TInt r = mgr.Connect(); sl@0: if (r != KErrNone) sl@0: User::Panic(_L("EWSRV SwitchOn0"), r); sl@0: TRequestStatus status; sl@0: mgr.RequestDomainTransition(KDmIdUiApps, EPwActive, status); sl@0: User::WaitForRequest(status); sl@0: if (status.Int() != KErrNone) sl@0: User::Panic(_L("EWSRV SwitchOn1"), status.Int()); sl@0: mgr.Close(); sl@0: } sl@0: break; sl@0: case TRawEvent::EPointerSwitchOn: sl@0: #if defined(_DEBUG) sl@0: User::Beep(440,250000); sl@0: #endif sl@0: break; sl@0: case TRawEvent::ESwitchOff: sl@0: { sl@0: RDmDomainManager mgr; sl@0: TInt r = mgr.Connect(); sl@0: if (r != KErrNone) sl@0: User::Panic(_L("EWSRV SwitchOff0"), r); sl@0: TRequestStatus status; sl@0: mgr.RequestSystemTransition(EPwStandby, status); sl@0: User::WaitForRequest(status); sl@0: if (status.Int() != KErrNone) sl@0: User::Panic(_L("EWSRV SwitchOff1"), status.Int()); sl@0: mgr.Close(); sl@0: } sl@0: break; sl@0: case TRawEvent::ECaseClose: sl@0: { sl@0: RDmDomainManager mgr; sl@0: TInt r = mgr.Connect(); sl@0: if (r != KErrNone) sl@0: User::Panic(_L("EWSRV CaseClosed"), r); sl@0: TRequestStatus status; sl@0: mgr.RequestDomainTransition(KDmIdUiApps, EPwStandby, status); sl@0: User::WaitForRequest(status); sl@0: if (status.Int() != KErrNone) sl@0: User::Panic(_L("EWSRV CaseClosed1"), status.Int()); sl@0: mgr.Close(); sl@0: } sl@0: HAL::Set(HAL::EDisplayState, 0); sl@0: break; sl@0: case TRawEvent::ENone: sl@0: break; sl@0: default: sl@0: break; sl@0: } sl@0: Request(); sl@0: } sl@0: sl@0: LOCAL_C void RenderPassword(RConsole *aCon, TInt aPWLeft, const TDesC& aPW) sl@0: // pre: aCon points to a console being used to read a password. sl@0: // aPWLeft is the column number from which the left brace should be drawn. sl@0: // aPasswd is a valid password. sl@0: // post: the password is rendered onto the console and followed by a '#' and sl@0: // padding spaces. Everything is enclosed in a pair of square brackets. sl@0: { sl@0: aCon->SetCursorPosAbs(TPoint(aPWLeft, 3)); sl@0: aCon->Write(_L("[")); sl@0: aCon->Write(aPW); sl@0: aCon->Write(_L("#")); sl@0: sl@0: TInt i; sl@0: for (i = 0; i < KMaxMediaPassword - aPW.Length(); i++) sl@0: { sl@0: aCon->Write(_L(" ")); sl@0: } sl@0: sl@0: aCon->Write(_L("]")); sl@0: } sl@0: sl@0: sl@0: void CNotifierSession::RunPasswordWindowL(const RMessage2 &aMsg) sl@0: // sl@0: // Eight unicode chars are mapped to (up to) sixteen bytes. Remainder of array is sl@0: // zeroed. Message is completed in CNotifierSession::ServiceL(). sl@0: // sl@0: { sl@0: // local copies of dialog data, 5 * (8 + 32 * 2) bytes sl@0: TBuf<0x20> line1, line2, unlockBtn, storeBtn, cancelBtn; sl@0: line1.Copy(_L("Password notifier")); sl@0: line2.Copy(_L("Enter password")); sl@0: unlockBtn.Copy(_L("Unlock")); sl@0: storeBtn.Copy(_L("Store")); sl@0: cancelBtn.Copy(_L("Cancel")); sl@0: sl@0: TPckgBuf reply; sl@0: sl@0: // Format the console window. sl@0: sl@0: const TInt KPasswordBarLen(1 + KMaxMediaPassword + 1 + 1); sl@0: const TInt KButtonBarLen( sl@0: 1 + unlockBtn.Length() + 1 sl@0: + 1 + 1 + cancelBtn.Length() + 1 sl@0: + 1 + 1 + storeBtn.Length() + 1); sl@0: sl@0: // Work out width of window. sl@0: // (Buttons are enclosed by angle brackets and separted by a space.) sl@0: // (Password is followed by '#' and delimited by square brackets.) sl@0: // If KButtonBarLen is at least as long as any other line then it will write sl@0: // to the bottom right corner and cause the console to scroll. To counter sl@0: // this, an extra padding character is added if necessary. sl@0: sl@0: TInt width; sl@0: width = Max(line1.Length(), line2.Length()); sl@0: width = Max(width, KPasswordBarLen); sl@0: width = KButtonBarLen >= width ? KButtonBarLen + 1: width; sl@0: sl@0: // Create the window and render its contents. sl@0: sl@0: RConsole con; sl@0: con.Create(); sl@0: con.Control(_L("-Visible")); sl@0: TInt r = con.Init(_L(""), TSize(width, 2 + 1 + 1 + 1 + 1)); sl@0: if (KErrNone != r) sl@0: { sl@0: PanicClient(aMsg, ENotifierPanicPasswordWindow); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: con.Control(_L("+Max -Cursor -AllowResize +OnTop")); sl@0: sl@0: con.SetCursorPosAbs(TPoint(0, 0)); sl@0: con.Write(line1); sl@0: con.SetCursorPosAbs(TPoint(0, 1)); sl@0: con.Write(line2); sl@0: const TInt KPasswordLeft((width - KPasswordBarLen) / 2); sl@0: con.SetCursorPosAbs(TPoint(KPasswordLeft, 3)); sl@0: con.Write(_L("[# ]")); sl@0: con.SetCursorPosAbs(TPoint((width - KButtonBarLen) / 2, 5)); sl@0: con.Write(_L("<")); sl@0: con.Write(unlockBtn); sl@0: con.Write(_L("> <")); sl@0: con.Write(storeBtn); sl@0: con.Write(_L("> <")); sl@0: con.Write(cancelBtn); sl@0: con.Write(_L(">")); sl@0: sl@0: // Allow the user to edit the password until they either press enter or escape. sl@0: sl@0: TBool done(EFalse); sl@0: TBuf pw; sl@0: pw.Zero(); sl@0: TMediaPswdNotifyExitMode em(EMPEMUnlock); // avoid VC warning C4701 (used w/o init). sl@0: sl@0: const TInt sendInfoLen = User::LeaveIfError(aMsg.GetDesLength(1)); sl@0: sl@0: if (sendInfoLen == sizeof(TMediaPswdSendNotifyInfoV1Debug)) sl@0: { sl@0: // debug mode - wait for specified period and close notifier sl@0: sl@0: TPckgBuf sendDbg; sl@0: aMsg.ReadL(1, sendDbg); sl@0: if (sendDbg().iSleepPeriod >= 0) sl@0: User::After(sendDbg().iSleepPeriod); sl@0: else sl@0: { sl@0: TTime now; sl@0: now.HomeTime(); sl@0: TInt64 seed = now.Int64(); sl@0: User::After(Math::Rand(seed) % -(sendDbg().iSleepPeriod)); sl@0: } sl@0: sl@0: reply().iEM = sendDbg().iEM; sl@0: Mem::Copy(reply().iPW, sendDbg().iPW, KMaxMediaPassword); sl@0: } sl@0: else sl@0: { sl@0: RenderPassword(&con, KPasswordLeft, pw); sl@0: do sl@0: { sl@0: TConsoleKey key; sl@0: sl@0: con.Read(key); sl@0: TInt keyCode = key.Code(); sl@0: sl@0: switch (keyCode) sl@0: { sl@0: case EKeyEscape: sl@0: em = EMPEMCancel; sl@0: done = ETrue; sl@0: break; sl@0: sl@0: case EKeyEnter: sl@0: em = EMPEMUnlock; sl@0: done = ETrue; sl@0: break; sl@0: sl@0: case EKeySpace: sl@0: em = EMPEMUnlockAndStore; sl@0: done = ETrue; sl@0: break; sl@0: sl@0: case EKeyBackspace: sl@0: if (pw.Length() > 0) sl@0: { sl@0: pw.SetLength(pw.Length() - 1); sl@0: RenderPassword(&con, KPasswordLeft, pw); sl@0: } sl@0: break; sl@0: sl@0: default: // interpret other keys as pw contents sl@0: TChar ch(keyCode); sl@0: // unicode encoding, so number of password characters is half byte length sl@0: if (ch.IsPrint() && pw.Length() < KMaxMediaPassword / 2) sl@0: { sl@0: pw.Append(ch); sl@0: RenderPassword(&con, KPasswordLeft, pw); sl@0: } sl@0: break; sl@0: } sl@0: } while (! done); sl@0: sl@0: // Fill the TMediaPswdReplyNotifyInfoV1 structure. sl@0: sl@0: if (em == EMPEMUnlock || em == EMPEMUnlockAndStore) sl@0: { sl@0: const TInt byteLen = pw.Length() * 2; sl@0: sl@0: // zero entire array; and then copy in valid section of TMediaPassword, sl@0: // not converting Unicode to ASCII. sl@0: TPtr8 pt8(reply().iPW, KMaxMediaPassword); // length = 0 sl@0: pt8.FillZ(KMaxMediaPassword); // length = KMaxMediaPassword sl@0: pt8.Zero(); // length = 0 sl@0: // length = byteLen sl@0: pt8.Copy(reinterpret_cast(pw.Ptr()), byteLen); sl@0: } sl@0: sl@0: // Set exit mode to tell user how dialog handled. sl@0: sl@0: reply().iEM = em; sl@0: } // else (sendInfoLen == sizeof(TMediaPswdSendNotifyInfoV1Debug)) sl@0: sl@0: con.Destroy(); sl@0: sl@0: aMsg.WriteL(2, reply); sl@0: } sl@0: sl@0: // sl@0: // class MNotifierBase2 sl@0: // sl@0: sl@0: void MNotifierBase2::SetManager(MNotifierManager* aManager) sl@0: { sl@0: iManager=aManager; sl@0: } sl@0: sl@0: // sl@0: // class CNotifierServer sl@0: // sl@0: sl@0: _LIT(__NOTIFIER_SERVER,"TextNotifierSrvr"); sl@0: sl@0: CNotifierServer* CNotifierServer::NewL() sl@0: { sl@0: CNotifierServer* server=new(ELeave) CNotifierServer(200); sl@0: CleanupStack::PushL(server); sl@0: server->ConstructL(); sl@0: server->StartL(__NOTIFIER_NAME); sl@0: CleanupStack::Pop(); // server sl@0: return server; sl@0: } sl@0: sl@0: CNotifierServer::~CNotifierServer() sl@0: { sl@0: SetIsExiting(); sl@0: delete iManager; sl@0: } sl@0: sl@0: void CNotifierServer::SetIsExiting() sl@0: { sl@0: iExiting=ETrue; sl@0: } sl@0: sl@0: TBool CNotifierServer::IsExiting() const sl@0: { sl@0: return iExiting; sl@0: } sl@0: sl@0: CNotifierServer::CNotifierServer(TInt aPriority) sl@0: : CServer2(aPriority) sl@0: {} sl@0: sl@0: void CNotifierServer::ConstructL() sl@0: { sl@0: iManager=CNotifierManager::NewL(); sl@0: RFs fs; sl@0: User::LeaveIfError(fs.Connect()); sl@0: CleanupClosePushL(fs); sl@0: iManager->RegisterL(fs); sl@0: CleanupStack::PopAndDestroy(); // fs.Close() sl@0: } sl@0: sl@0: CSession2* CNotifierServer::NewSessionL(const TVersion &aVersion,const RMessage2&) const sl@0: { sl@0: TVersion v(1,0,0); // !! liaise with E32 sl@0: if (!User::QueryVersionSupported(v,aVersion)) sl@0: User::Leave(KErrNotSupported); sl@0: return new(ELeave) CNotifierSession(*this); sl@0: } sl@0: sl@0: // sl@0: // class CNotifierSession sl@0: // sl@0: sl@0: CNotifierSession::CNotifierSession(const CNotifierServer& aServer) sl@0: { sl@0: iServer=&aServer; sl@0: iClientId=(TInt)this; sl@0: } sl@0: sl@0: CNotifierSession::~CNotifierSession() sl@0: { sl@0: const CNotifierServer* server=static_cast(Server()); sl@0: if (!server->IsExiting()) sl@0: { sl@0: server->Manager()->HandleClientExit(iClientId); sl@0: } sl@0: } sl@0: sl@0: void CNotifierSession::ServiceL(const RMessage2 &aMessage) sl@0: { sl@0: TBool completeMessage=ETrue; sl@0: switch (aMessage.Function()) sl@0: { sl@0: case ENotifierNotify: sl@0: DisplayAlertL(aMessage); sl@0: break; sl@0: case ENotifierNotifyCancel: sl@0: // do nothing - this server doesn't support cancelling RNotifier::Notify - the client will just have to wait sl@0: break; sl@0: case ENotifierInfoPrint: sl@0: DisplayInfoMsgL(aMessage); sl@0: break; sl@0: case EStartNotifier: sl@0: DoStartNotifierL(aMessage); sl@0: break; sl@0: case ECancelNotifier: sl@0: iServer->Manager()->NotifierCancel(TUid::Uid(aMessage.Int0())); sl@0: break; sl@0: case EUpdateNotifierAndGetResponse: sl@0: case EUpdateNotifier: sl@0: DoUpdateNotifierL(aMessage); sl@0: break; sl@0: case EStartNotifierAndGetResponse: sl@0: { sl@0: if (aMessage.Int0()==KMediaPasswordNotifyUid) sl@0: { sl@0: RunPasswordWindowL(aMessage); sl@0: } sl@0: else sl@0: { sl@0: TBool cleanupComplete=ETrue; sl@0: StartNotifierAndGetResponseL(aMessage,cleanupComplete); sl@0: // if the plug-in starts successfully, it has sl@0: // responsibility for completing the message (either sl@0: // synchronously or asynchronously) sl@0: completeMessage=EFalse; sl@0: } sl@0: } sl@0: break; sl@0: default: sl@0: aMessage.Complete(KErrNotSupported); sl@0: break; sl@0: } sl@0: if (completeMessage && !aMessage.IsNull()) sl@0: { sl@0: aMessage.Complete(KErrNone); sl@0: } sl@0: } sl@0: sl@0: void CNotifierSession::DisplayAlertL(const RMessage2& aMessage) sl@0: { sl@0: const TInt lengthOfCombinedBuffer=User::LeaveIfError(aMessage.GetDesLength(1)); sl@0: const TInt lengthOfLine1=(STATIC_CAST(TUint,aMessage.Int2())>>16); sl@0: const TInt lengthOfLine2=(aMessage.Int2()&KMaxTUint16); sl@0: const TInt lengthOfBut1=(STATIC_CAST(TUint,aMessage.Int3())>>16); sl@0: const TInt lengthOfBut2=(aMessage.Int3()&KMaxTUint16); sl@0: if (lengthOfCombinedBuffer!=lengthOfLine1+lengthOfLine2+lengthOfBut1+lengthOfBut2) sl@0: { sl@0: PanicClient(aMessage,ENotifierPanicInconsistentDescriptorLengths); sl@0: return; sl@0: } sl@0: HBufC* const combinedBuffer=HBufC::NewLC(lengthOfCombinedBuffer); sl@0: {TPtr combinedBuffer_asWritable(combinedBuffer->Des()); sl@0: aMessage.ReadL(1,combinedBuffer_asWritable);} sl@0: const TPtrC line1(combinedBuffer->Left(lengthOfLine1)); sl@0: const TPtrC line2(combinedBuffer->Mid(lengthOfLine1,lengthOfLine2)); sl@0: const TPtrC but1(combinedBuffer->Mid(lengthOfLine1+lengthOfLine2,lengthOfBut1)); sl@0: const TPtrC but2(combinedBuffer->Mid(lengthOfLine1+lengthOfLine2+lengthOfBut1,lengthOfBut2)); sl@0: TInt buttons, len, offset; sl@0: if (lengthOfBut2==0) sl@0: { sl@0: buttons=1; sl@0: len=lengthOfBut1+2; sl@0: } sl@0: else sl@0: { sl@0: buttons=2; sl@0: len=lengthOfBut1+lengthOfBut2+5; sl@0: } sl@0: if (lengthOfLine1>len) sl@0: len=lengthOfLine1; sl@0: if (lengthOfLine2>len) sl@0: len=lengthOfLine2; sl@0: RConsole con; sl@0: con.Create(); sl@0: TSize scsz; sl@0: con.ScreenSize(scsz); sl@0: con.Control(_L("-Visible")); sl@0: TInt ww=Min(len,scsz.iWidth-4); sl@0: TInt wh=3; sl@0: if ((lengthOfBut1+lengthOfBut2+5)>ww) sl@0: wh++; sl@0: if (lengthOfLine1>ww) sl@0: wh++; sl@0: if (lengthOfLine2>ww) sl@0: wh++; sl@0: con.Init(_L(""),TSize(ww,wh)); sl@0: con.Control(_L("+Max -Cursor -Allowresize +Ontop +Wrap")); sl@0: con.Write(line1); sl@0: con.SetCursorPosAbs(TPoint(0,1)); sl@0: con.Write(line2); sl@0: if (buttons==2) sl@0: offset=(len-lengthOfBut1-lengthOfBut2-5)/2; sl@0: else sl@0: offset=(len-lengthOfBut1-2)/2; sl@0: con.SetCursorPosAbs(TPoint(offset,2)); sl@0: con.Write(_L("<")); sl@0: con.Write(but1); sl@0: con.Write(_L(">")); sl@0: if(buttons==2) sl@0: { sl@0: con.Write(_L(" <")); sl@0: con.Write(but2); sl@0: con.Write(_L(">")); sl@0: } sl@0: sl@0: TConsoleKey key; sl@0: TInt keycode; sl@0: do sl@0: { sl@0: con.Read(key); sl@0: keycode=key.Code(); sl@0: } sl@0: while((keycode!=EKeyEscape&&keycode!=EKeyEnter&&buttons==2)||(keycode!=EKeyEnter&&buttons==1)); sl@0: if(keycode==EKeyEscape) sl@0: keycode=0; sl@0: else sl@0: keycode=1; sl@0: con.Destroy(); sl@0: aMessage.WriteL(0,TPckgC(keycode)); sl@0: CleanupStack::PopAndDestroy(combinedBuffer); sl@0: } sl@0: sl@0: TInt CNotifierSession::InfoPrintThread(TAny* aMessage) sl@0: { sl@0: TBuf<0x50> des; // 0x50 max size of message sl@0: RConsole con; sl@0: des=*(TBuf<0x50> *)aMessage; sl@0: TInt l=des.Length(); sl@0: NotifierSemaphore.Signal(); sl@0: con.Create(); sl@0: con.Control(_L("-Visible")); sl@0: TSize size; sl@0: con.ScreenSize(size); sl@0: TInt ww=Min(size.iWidth-6,l); sl@0: TInt wh=(l+ww-1)/ww; sl@0: if (wh==0) sl@0: wh=1; sl@0: con.Init(_L(""),TSize(ww,wh)); sl@0: con.Control(_L("+Maximise")); sl@0: con.SetWindowPosAbs(TPoint(size.iWidth-ww-4,1)); sl@0: con.Control(_L("+Wrap +Ontop")); sl@0: con.Write(des); sl@0: sl@0: User::After(1300000); sl@0: con.Destroy(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void CNotifierSession::DisplayInfoMsgL(const RMessage2& aMessage) sl@0: { sl@0: TInt r; sl@0: TBuf<0x50> des; // 0x50 max size of message lines sl@0: aMessage.ReadL(0,des); sl@0: RThread thread; sl@0: do sl@0: { sl@0: r=thread.Create(_L("Info Window"),InfoPrintThread,KDefaultStackSize,&User::Allocator(),(TAny*)&des); sl@0: if(r==KErrAlreadyExists) sl@0: User::After(200000); sl@0: } while(r==KErrAlreadyExists); sl@0: User::LeaveIfError(r); sl@0: thread.Resume(); sl@0: NotifierSemaphore.Wait(); sl@0: thread.Close(); sl@0: } sl@0: sl@0: void CNotifierSession::DoStartNotifierL(const RMessage2& aMessage) sl@0: { sl@0: const TUid targetUid={aMessage.Int0()}; sl@0: HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1))); sl@0: {TPtr8 input(inputBuffer->Des()); sl@0: aMessage.ReadL(1,input);} sl@0: TPtrC8 output(0,0); sl@0: iServer->Manager()->NotifierStartL(targetUid,*inputBuffer,&output,iClientId); sl@0: if(aMessage.Int2()) sl@0: aMessage.WriteL(2,output); sl@0: CleanupStack::PopAndDestroy(inputBuffer); sl@0: } sl@0: sl@0: void CNotifierSession::DoUpdateNotifierL(const RMessage2& aMessage) sl@0: { sl@0: const TUid targetUid={aMessage.Int0()}; sl@0: HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1))); sl@0: {TPtr8 input(inputBuffer->Des()); sl@0: aMessage.ReadL(1, input);} sl@0: HBufC8* const outputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesMaxLength(2))); sl@0: {TPtr8 output(outputBuffer->Des()); sl@0: iServer->Manager()->NotifierUpdateL(targetUid,*inputBuffer,&output,iClientId);} sl@0: aMessage.WriteL(2,*outputBuffer); sl@0: CleanupStack::PopAndDestroy(2,inputBuffer); sl@0: } sl@0: sl@0: void CNotifierSession::StartNotifierAndGetResponseL(const RMessage2& aMessage,TBool& aCleanupComplete) sl@0: { sl@0: const TUid targetUid={aMessage.Int0()}; sl@0: HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1))); sl@0: {TPtr8 input(inputBuffer->Des()); sl@0: aMessage.ReadL(1,input);} sl@0: iServer->Manager()->NotifierStartAndGetResponseL(targetUid,*inputBuffer,2,aMessage,iClientId,aCleanupComplete); sl@0: CleanupStack::PopAndDestroy(inputBuffer); sl@0: } sl@0: sl@0: void CNotifierSession::PanicClient(const RMessage2& aMessage,TNotifierPanic aCode) sl@0: { sl@0: aMessage.Panic(__NOTIFIER_SERVER,aCode); sl@0: } sl@0: sl@0: // sl@0: // class CNotifierManager sl@0: // sl@0: sl@0: const TInt KNullClientId=0; sl@0: sl@0: CNotifierManager* CNotifierManager::NewL() sl@0: { sl@0: CNotifierManager* self=new(ELeave) CNotifierManager; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CNotifierManager::~CNotifierManager() sl@0: { sl@0: if (iObservedList) sl@0: { sl@0: const TInt count=iObservedList->Count(); sl@0: for (TInt ii=0;iiRelease(); sl@0: } sl@0: delete iObservedList; sl@0: } sl@0: if (iLibraries) sl@0: { sl@0: const TInt count=iLibraries->Count(); sl@0: for (TInt ii=0;iiFindWildByDir(KNotifierPlugInExt, KNotifierPlugInOldSearchPath, directory); sl@0: else sl@0: #endif sl@0: error=findFile->FindWildByDir(KNotifierPlugInExt, KNotifierPlugInSearchPath, directory); sl@0: for (; error!=KErrNotFound; error=findFile->FindWild(directory)) sl@0: { sl@0: CleanupStack::PushL(directory); sl@0: User::LeaveIfError(error); sl@0: const TInt numberOfEntries=directory->Count(); sl@0: for (TInt i=0; iSetNoWild(entry.iName, &findFile->File(), NULL); // findFile->File() returns a reference rather than an object, therefore taking the address of it is fine sl@0: sl@0: if (entry.iType[0].iUid==0x10000079) sl@0: { sl@0: // It's a DLL sl@0: if( (entry.iType[1]==KUidTextNotifierPlugInV2)) sl@0: { sl@0: // Its a notifier... sl@0: TPtrC path(fileNameParser->DriveAndPath()); sl@0: TPtrC name(fileNameParser->NameAndExt()); sl@0: DoAddPlugInL(path,name,entry.iType); sl@0: } sl@0: } sl@0: } sl@0: CleanupStack::PopAndDestroy(); // directory sl@0: directory=NULL; sl@0: } sl@0: delete directory; sl@0: CleanupStack::PopAndDestroy(2); // fileNameParser and findFile sl@0: #ifdef SUPPORT_OLD_PLUGIN_PATH sl@0: } sl@0: #endif sl@0: } sl@0: sl@0: LOCAL_C void DeleteTemp(TAny* aPtr) sl@0: { sl@0: CArrayPtr* array=REINTERPRET_CAST(CArrayPtr*,aPtr); sl@0: const TInt count=array->Count(); sl@0: for (TInt ii=0;iiRelease(); sl@0: } sl@0: delete array; sl@0: } sl@0: sl@0: sl@0: sl@0: void CNotifierManager::DoAddPlugInL(const TDesC& aPath,const TDesC& aFileName,const TUidType& aUidType) sl@0: { sl@0: RLibrary lib; sl@0: User::LeaveIfError(lib.Load(aFileName,aPath,aUidType)); sl@0: CleanupClosePushL(lib); sl@0: iLibraries->AppendL(lib); sl@0: CleanupStack::Pop(); // lib sl@0: TLibraryFunction libEntry=lib.Lookup(1); sl@0: CArrayPtr* array=REINTERPRET_CAST(CArrayPtr*,(libEntry)()); sl@0: User::LeaveIfNull(array); sl@0: CleanupStack::PushL(TCleanupItem(DeleteTemp,array)); sl@0: while (array->Count()>0) sl@0: { sl@0: MNotifierBase2* notif=(*array)[0]; sl@0: { sl@0: iObservedList->AppendL(notif); sl@0: array->Delete(0); sl@0: notif->SetManager(this); sl@0: } sl@0: MNotifierBase2::TNotifierInfo info=notif->RegisterL(); sl@0: if (!iChannelMonitor->AlreadyHasChannel(info.iChannel)) sl@0: iChannelMonitor->AddNewChannelL(info.iChannel); sl@0: } sl@0: CleanupStack::PopAndDestroy(); // array sl@0: } sl@0: sl@0: CNotifierManager::CNotifierManager() sl@0: {} sl@0: sl@0: void CNotifierManager::ConstructL() sl@0: { sl@0: iObservedList=new(ELeave) CArrayPtrSeg(6); sl@0: iLibraries=new(ELeave) CArrayFixFlat(2); sl@0: iChannelMonitor=CChannelMonitor::NewL(); sl@0: iActivityMonitor=CActivityMonitor::NewL(); sl@0: iQueue=CNotifierQueue::NewL(); sl@0: } sl@0: sl@0: struct SActivityCleanup sl@0: { sl@0: CActivityMonitor* iMonitor; sl@0: TUid iNotifier; sl@0: TInt iClientId; sl@0: }; sl@0: sl@0: LOCAL_C void CleanupActivityMonitor(TAny* aPtr) sl@0: { sl@0: SActivityCleanup& cleanup=*REINTERPRET_CAST(SActivityCleanup*,aPtr); sl@0: cleanup.iMonitor->Remove(cleanup.iNotifier,cleanup.iClientId); sl@0: } sl@0: sl@0: void CNotifierManager::NotifierStartL(TUid aNotifierUid,const TDesC8& aBuffer,TPtrC8* aResponse,TInt aClientId) sl@0: { sl@0: TInt result=KErrNotFound; sl@0: const TInt count=iObservedList->Count(); sl@0: for (TInt ii=0;iiInfo(); sl@0: if (info.iUid==aNotifierUid) sl@0: { sl@0: if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel)) sl@0: { sl@0: result=KErrAlreadyExists; sl@0: } sl@0: else if (info.iPriority>iChannelMonitor->ActivityLevel(info.iChannel)) sl@0: { sl@0: TUid notifier; sl@0: MNotifierBase2::TNotifierPriority priority; sl@0: const TBool channelWasActive=iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority); sl@0: iActivityMonitor->AddL(info,aClientId); sl@0: SActivityCleanup cleanup; sl@0: cleanup.iMonitor=iActivityMonitor; sl@0: cleanup.iNotifier=aNotifierUid; sl@0: cleanup.iClientId=aClientId; sl@0: CleanupStack::PushL(TCleanupItem(CleanupActivityMonitor,&cleanup)); sl@0: TPtrC8 response(notif->StartL(aBuffer)); sl@0: if(aResponse) sl@0: aResponse->Set(response); sl@0: CleanupStack::Pop(); // cleanup; sl@0: if (channelWasActive) sl@0: { sl@0: for (TInt jj=0;jjInfo(); sl@0: if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel) sl@0: { sl@0: TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused)); sl@0: } sl@0: } sl@0: } sl@0: iChannelMonitor->UpdateChannel(info.iChannel,info.iPriority); sl@0: if (result!=ENotExtRequestQueued) sl@0: { sl@0: result=ENotExtRequestCompleted; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if (iQueue->IsAlreadyQueued(info.iUid,info.iChannel)) sl@0: { sl@0: result=KErrAlreadyExists; sl@0: } sl@0: else sl@0: { sl@0: CQueueItem* queueCopy=CQueueItem::NewL(info,aBuffer,aClientId); sl@0: CleanupStack::PushL(queueCopy); sl@0: iQueue->QueueItemL(queueCopy); sl@0: CleanupStack::Pop(); // queueCopy sl@0: result=ENotExtRequestQueued; sl@0: } sl@0: } sl@0: } sl@0: } sl@0: User::LeaveIfError(result); sl@0: } sl@0: sl@0: TInt CNotifierManager::NotifierUpdateL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8* aResponse,TInt aClientId) sl@0: { sl@0: TInt result=KErrNotFound; sl@0: const TInt count=iObservedList->Count(); sl@0: for (TInt ii=0;iiInfo(); sl@0: if (info.iUid==aNotifierUid) sl@0: { sl@0: if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel)) sl@0: { sl@0: if (!iActivityMonitor->IsClientPresent(aNotifierUid,info.iChannel,aClientId)) sl@0: { sl@0: iActivityMonitor->AddL(info,aClientId); sl@0: } sl@0: if (aResponse==NULL) sl@0: { sl@0: notif->UpdateL(aBuffer); sl@0: } sl@0: else sl@0: { sl@0: aResponse->Copy(notif->UpdateL(aBuffer)); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: ; // not all channels have been started yet so update the queue sl@0: } sl@0: result=KErrNone; sl@0: } sl@0: } sl@0: return result; sl@0: } sl@0: sl@0: void CNotifierManager::NotifierStartAndGetResponseL(TUid aNotifierUid,const TDesC8& aBuffer,TInt aReplySlot, sl@0: const RMessage2& aMessage,TInt aClientId,TBool& aCleanupComplete) sl@0: { sl@0: NotifierStartAndGetResponseL(aNotifierUid,TUid::Null(),aBuffer,aReplySlot,aMessage,aClientId,aCleanupComplete); sl@0: } sl@0: sl@0: void CNotifierManager::NotifierStartAndGetResponseL(TUid aNotifierUid,TUid aChannelUid,const TDesC8& aBuffer,TInt aReplySlot, sl@0: const RMessage2& aMessage,TInt aClientId,TBool& aCleanupComplete) sl@0: { sl@0: TInt result=KErrNotFound; sl@0: const TInt count=iObservedList->Count(); sl@0: for (TInt ii=0;iiInfo(); sl@0: if (info.iUid==aNotifierUid && (aChannelUid==TUid::Null() || info.iChannel==aChannelUid)) sl@0: { sl@0: if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel)) sl@0: { sl@0: notif->StartL(aBuffer,aReplySlot,aMessage); // asynch notifier can decide whether to support multiple clients sl@0: result=KErrNone; sl@0: } sl@0: else if (info.iPriority>iChannelMonitor->ActivityLevel(info.iChannel)) sl@0: { sl@0: TUid notifier; sl@0: MNotifierBase2::TNotifierPriority priority; sl@0: const TBool channelWasActive=iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority); sl@0: iActivityMonitor->AddL(info,aClientId); sl@0: SActivityCleanup activityCleanup; sl@0: activityCleanup.iMonitor=iActivityMonitor; sl@0: activityCleanup.iNotifier=aNotifierUid; sl@0: activityCleanup.iClientId=aClientId; sl@0: CleanupStack::PushL(TCleanupItem(CleanupActivityMonitor,&activityCleanup)); sl@0: aCleanupComplete=EFalse; sl@0: // IMPORTANT, aMessage needs to be a full RMessage object until suport for V1 notifiers is removed sl@0: // I.e. until CNotifierBaseAdaptor is removed sl@0: notif->StartL(aBuffer,aReplySlot,aMessage); sl@0: CleanupStack::Pop(&activityCleanup); sl@0: if (channelWasActive) sl@0: { sl@0: for (TInt jj=0;jjInfo(); sl@0: if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel) sl@0: { sl@0: TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused)); sl@0: } sl@0: } sl@0: } sl@0: iChannelMonitor->UpdateChannel(info.iChannel,info.iPriority); sl@0: result=KErrNone; sl@0: } sl@0: else sl@0: { sl@0: if (iQueue->IsAlreadyQueued(info.iUid,info.iChannel)) sl@0: { sl@0: result=KErrAlreadyExists; sl@0: } sl@0: else sl@0: { sl@0: CQueueItem* queueCopy=CQueueItem::NewL(info,aBuffer,aReplySlot,aMessage,aClientId); sl@0: CleanupStack::PushL(queueCopy); sl@0: iQueue->QueueItemL(queueCopy); sl@0: CleanupStack::Pop(queueCopy); sl@0: result=ENotExtRequestQueued; sl@0: } sl@0: } sl@0: } sl@0: } sl@0: User::LeaveIfError(result); sl@0: } sl@0: sl@0: TInt CNotifierManager::NotifierCancel(TUid aNotifierUid) sl@0: { sl@0: TInt result=KErrNotFound; sl@0: const TInt count=iObservedList->Count(); sl@0: for (TInt ii=0;iiInfo(); sl@0: if (info.iUid==aNotifierUid) sl@0: { sl@0: notif->Cancel(); sl@0: iActivityMonitor->RemoveNotifier(aNotifierUid,info.iChannel); sl@0: MNotifierBase2::TNotifierPriority priority=MNotifierBase2::ENotifierPriorityLowest; sl@0: TUid notifier; sl@0: //check channel activity and get highest priority on channnel sl@0: if (iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority)) sl@0: { sl@0: sl@0: //check if priority of a queued item on the same channel is sl@0: //greater sl@0: MNotifierBase2::TNotifierPriority queuePriority= sl@0: (MNotifierBase2::TNotifierPriority)iQueue->GetHighestQueuePriority(info.iChannel); sl@0: if (queuePriority>priority) sl@0: { sl@0: iChannelMonitor->UpdateChannel(info.iChannel,MNotifierBase2::ENotifierPriorityLowest); sl@0: CQueueItem* next=iQueue->FetchItem(info.iChannel); sl@0: if (next) sl@0: { sl@0: TUid notif=next->iInfo.iUid; sl@0: TRAPD(err,StartFromQueueL(next)); sl@0: if (err!=KErrNone) sl@0: { sl@0: NotifierCancel(notif); sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: for (TInt jj=0;jjInfo(); sl@0: if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel) sl@0: { sl@0: TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused)); sl@0: } sl@0: } sl@0: iChannelMonitor->UpdateChannel(info.iChannel,priority); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: iChannelMonitor->UpdateChannel(info.iChannel,MNotifierBase2::ENotifierPriorityLowest); sl@0: CQueueItem* next=iQueue->FetchItem(info.iChannel); sl@0: if (next) sl@0: { sl@0: TUid notif=next->iInfo.iUid; sl@0: TRAPD(err,StartFromQueueL(next)); sl@0: if (err!=KErrNone) sl@0: { sl@0: NotifierCancel(notif); sl@0: } sl@0: } sl@0: } sl@0: result=KErrNone; sl@0: } sl@0: } sl@0: return result; sl@0: } sl@0: sl@0: struct SCleanupMessage sl@0: { sl@0: TBool* iDoCleanup; sl@0: RMessage2* iMessage; sl@0: }; sl@0: sl@0: LOCAL_C void CleanupStartAndGetResponse(TAny* aPtr) sl@0: { sl@0: SCleanupMessage& cleanup=*REINTERPRET_CAST(SCleanupMessage*,aPtr); sl@0: if (cleanup.iDoCleanup) sl@0: { sl@0: cleanup.iMessage->Complete(KErrNoMemory); sl@0: } sl@0: } sl@0: sl@0: void CNotifierManager::StartFromQueueL(CQueueItem* aItem) sl@0: { sl@0: CleanupStack::PushL(aItem); sl@0: TPtr8 buffer=aItem->iBuffer->Des(); sl@0: if (aItem->iAsynchronous) sl@0: { sl@0: SCleanupMessage cleanup; sl@0: TBool doCleanup=ETrue; sl@0: cleanup.iDoCleanup=&doCleanup; sl@0: cleanup.iMessage=&aItem->iMessage; sl@0: CleanupStack::PushL(TCleanupItem(CleanupStartAndGetResponse,&cleanup)); sl@0: // IMPORTANT, aItem->iMessage needs to be a full RMessage object until suport for V1 notifiers is removed sl@0: // I.e. until CNotifierBaseAdaptor is removed sl@0: NotifierStartAndGetResponseL(aItem->iInfo.iUid,aItem->iInfo.iChannel,buffer,aItem->iReplySlot,aItem->iMessage,aItem->iClientId,doCleanup); sl@0: CleanupStack::Pop(&cleanup); sl@0: } sl@0: else sl@0: { sl@0: NotifierStartL(aItem->iInfo.iUid,buffer,NULL,aItem->iClientId); sl@0: } sl@0: CleanupStack::PopAndDestroy(); // aItem sl@0: CQueueItem* update=iQueue->FetchItem(aItem->iInfo.iChannel); sl@0: while (update) sl@0: { sl@0: CleanupStack::PushL(update); sl@0: NotifierUpdateL(update->iInfo.iUid,*update->iBuffer,NULL,update->iClientId); sl@0: CleanupStack::PopAndDestroy(); // update sl@0: update=iQueue->FetchItem(aItem->iInfo.iChannel); sl@0: } sl@0: } sl@0: sl@0: void CNotifierManager::HandleClientExit(TInt aClientId) sl@0: { sl@0: TUid notifier=KNullUid; sl@0: while (iActivityMonitor->NotifierForClient(notifier,aClientId)) sl@0: { sl@0: const TInt count=iObservedList->Count(); sl@0: for (TInt ii=0;iiInfo().iUid==notifier) sl@0: { sl@0: NotifierCancel(notifier); sl@0: } sl@0: } sl@0: iActivityMonitor->Remove(notifier,aClientId); sl@0: } sl@0: iActivityMonitor->RemoveClient(aClientId); sl@0: iQueue->RemoveClient(aClientId); sl@0: } sl@0: sl@0: void CNotifierManager::StartNotifierL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse) sl@0: { sl@0: TPtrC8 response(0,0); sl@0: NotifierStartL(aNotifierUid,aBuffer, &response,KNullClientId); sl@0: aResponse.Copy(response); sl@0: } sl@0: sl@0: void CNotifierManager::CancelNotifier(TUid aNotifierUid) sl@0: { sl@0: NotifierCancel(aNotifierUid); sl@0: } sl@0: sl@0: void CNotifierManager::UpdateNotifierL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse) sl@0: { sl@0: NotifierUpdateL(aNotifierUid,aBuffer,&aResponse,KNullClientId); sl@0: } sl@0: sl@0: // sl@0: // class CChannelMonitor sl@0: // sl@0: sl@0: CChannelMonitor* CChannelMonitor::NewL() sl@0: { sl@0: CChannelMonitor* self=new(ELeave) CChannelMonitor; sl@0: return self; sl@0: } sl@0: sl@0: TBool CChannelMonitor::AlreadyHasChannel(TUid aChannel)const sl@0: { sl@0: const TInt count=iMonitor.Count(); sl@0: for (TInt ii=0;iiConstructL(aClientId); sl@0: return self; sl@0: } sl@0: sl@0: CNotifierActivity::~CNotifierActivity() sl@0: { sl@0: iClientArray.Reset(); sl@0: } sl@0: sl@0: TInt CNotifierActivity::Find(TInt aClientId) const sl@0: { sl@0: TInt index=KErrNotFound; sl@0: const TInt count=iClientArray.Count(); sl@0: for (TInt ii=0;iiiClientArray.AppendL(aClientId); sl@0: } sl@0: } sl@0: sl@0: void CActivityMonitor::Remove(TUid aNotifierUid,TInt aClientId) sl@0: { sl@0: const TInt index=Find(aNotifierUid); sl@0: if (index!=KErrNotFound) sl@0: { sl@0: CNotifierActivity* activity=iMonitor[index]; sl@0: const TInt clientIndex=activity->Find(aClientId); sl@0: if (clientIndex!=KErrNotFound) sl@0: { sl@0: if (activity->iClientArray.Count()==1) sl@0: { sl@0: delete activity; sl@0: iMonitor.Delete(index); sl@0: } sl@0: else sl@0: { sl@0: activity->iClientArray.Delete(index); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CActivityMonitor::RemoveNotifier(TUid aNotifierUid,TUid aChannel) sl@0: { sl@0: const TInt index=Find(aNotifierUid,aChannel); sl@0: if (index!=KErrNotFound) sl@0: { sl@0: delete iMonitor[index]; sl@0: iMonitor.Delete(index); sl@0: } sl@0: } sl@0: sl@0: void CActivityMonitor::RemoveClient(TInt aClientId) sl@0: { sl@0: TInt ii=0; sl@0: while (iiFind(aClientId); sl@0: if (index!=KErrNotFound) sl@0: { sl@0: ptr->iClientArray.Delete(index); sl@0: } sl@0: if (ptr->iClientArray.Count()==0) sl@0: { sl@0: iMonitor.Delete(ii); sl@0: } sl@0: else sl@0: { sl@0: ++ii; sl@0: } sl@0: } sl@0: } sl@0: sl@0: TBool CActivityMonitor::IsNotifierActive(TUid aNotifierUid,TUid aChannel) const sl@0: { sl@0: const TInt index=Find(aNotifierUid,aChannel); sl@0: return (index!=KErrNotFound); sl@0: } sl@0: sl@0: TBool CActivityMonitor::IsClientPresent(TUid aNotifierUid,TUid aChannel,TInt aClientId) const sl@0: { sl@0: TBool found=EFalse; sl@0: const TInt index=Find(aNotifierUid,aChannel); sl@0: if (index!=KErrNotFound) sl@0: { sl@0: found=(iMonitor[index]->Find(aClientId)!=KErrNotFound); sl@0: } sl@0: return found; sl@0: } sl@0: sl@0: TBool CActivityMonitor::IsChannelActive(TUid aChannel,TUid& aNotifier,MNotifierBase2::TNotifierPriority& aHighestPriority) const sl@0: { sl@0: TBool ret=EFalse; sl@0: const TInt count=iMonitor.Count(); sl@0: for (TInt ii=0;iiiInfo; sl@0: if (info.iChannel==aChannel) sl@0: { sl@0: ret=ETrue; sl@0: if ((MNotifierBase2::TNotifierPriority)info.iPriority>aHighestPriority) sl@0: { sl@0: aNotifier=info.iUid; sl@0: aHighestPriority=(MNotifierBase2::TNotifierPriority)info.iPriority; sl@0: } sl@0: } sl@0: } sl@0: return ret; sl@0: } sl@0: sl@0: TBool CActivityMonitor::NotifierForClient(TUid& aNotifierUid,TInt aClientId) const sl@0: { sl@0: TBool isOnlyClient=EFalse; sl@0: aNotifierUid=KNullUid; sl@0: const TInt count=iMonitor.Count(); sl@0: for (TInt ii=0;iiFind(aClientId)!=KErrNotFound) sl@0: { sl@0: aNotifierUid=ptr->iInfo.iUid; sl@0: isOnlyClient=ptr->iClientArray.Count()==1; sl@0: break; sl@0: } sl@0: } sl@0: return isOnlyClient; sl@0: } sl@0: sl@0: CActivityMonitor::CActivityMonitor() sl@0: : iMonitor(1) sl@0: {} sl@0: sl@0: TInt CActivityMonitor::Find(TUid aNotifierUid) const sl@0: { sl@0: TInt index=KErrNotFound; sl@0: const TInt count=iMonitor.Count(); sl@0: for (TInt ii=0;iiiInfo.iUid==aNotifierUid) sl@0: { sl@0: index=ii; sl@0: break; sl@0: } sl@0: } sl@0: return index; sl@0: } sl@0: sl@0: TInt CActivityMonitor::Find(TUid aNotifierUid,TUid aChannel) const sl@0: { sl@0: TInt index=KErrNotFound; sl@0: const TInt count=iMonitor.Count(); sl@0: for (TInt ii=0;iiiInfo.iUid==aNotifierUid && ptr->iInfo.iChannel==aChannel) sl@0: { sl@0: index=ii; sl@0: break; sl@0: } sl@0: } sl@0: return index; sl@0: } sl@0: sl@0: // sl@0: // class CQueueItem sl@0: // sl@0: sl@0: CQueueItem* CQueueItem::NewL(const MNotifierBase2::TNotifierInfo& aInfo,const TDesC8& aBuffer, sl@0: TInt aReplySlot,const RMessage2& aMessage,TInt aClientId) //Asynchronous sl@0: { sl@0: CQueueItem* self=new(ELeave) CQueueItem(aInfo); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aBuffer,aMessage,aClientId,aReplySlot); sl@0: CleanupStack::Pop(); // self sl@0: return self; sl@0: } sl@0: sl@0: CQueueItem* CQueueItem::NewL(const MNotifierBase2::TNotifierInfo& aInfo,const TDesC8& aBuffer,TInt aClientId) //synchronous sl@0: { sl@0: CQueueItem* self=new(ELeave) CQueueItem(aInfo); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aBuffer,aClientId); sl@0: CleanupStack::Pop(); // self sl@0: return self; sl@0: } sl@0: sl@0: CQueueItem::~CQueueItem() sl@0: { sl@0: delete iBuffer; sl@0: } sl@0: sl@0: CQueueItem::CQueueItem(const MNotifierBase2::TNotifierInfo& aInfo) sl@0: : iInfo(aInfo) sl@0: {} sl@0: sl@0: void CQueueItem::ConstructL(const TDesC8& aBuffer,TInt aClientId) sl@0: { sl@0: iBuffer=aBuffer.AllocL(); sl@0: iClientId=aClientId; sl@0: iAsynchronous=EFalse; sl@0: } sl@0: sl@0: void CQueueItem::ConstructL(const TDesC8& aBuffer,const RMessage2& aMessage,TInt aClientId,TInt aReplySlot) sl@0: { sl@0: iBuffer=aBuffer.AllocL(); sl@0: iAsynchronous=ETrue; sl@0: iMessage=aMessage; sl@0: iClientId=aClientId; sl@0: iReplySlot=aReplySlot; sl@0: } sl@0: sl@0: // sl@0: // class CNotifierQueue sl@0: // sl@0: sl@0: CNotifierQueue* CNotifierQueue::NewL() sl@0: { sl@0: CNotifierQueue* self=new(ELeave) CNotifierQueue; sl@0: return self; sl@0: } sl@0: sl@0: CQueueItem* CNotifierQueue::FetchItem(TUid aChannel) sl@0: { sl@0: CQueueItem* result=NULL; sl@0: const TInt count=iQueue.Count(); sl@0: TInt priority=MNotifierBase2::ENotifierPriorityLowest-1; sl@0: TInt index=KErrNotFound; sl@0: for (TInt ii=0;iiiInfo.iChannel==aChannel && item->iInfo.iPriority>priority) sl@0: { sl@0: index=ii; sl@0: priority=item->iInfo.iPriority; sl@0: result=item; sl@0: } sl@0: } sl@0: if (index!=KErrNotFound) sl@0: { sl@0: iQueue.Delete(index); sl@0: } sl@0: return result; sl@0: } sl@0: sl@0: TBool CNotifierQueue::IsAlreadyQueued(TUid aNotifier,TUid aChannel) const sl@0: { sl@0: TBool ret=EFalse; sl@0: const TInt count=iQueue.Count(); sl@0: for (TInt ii=0;iiiInfo.iUid==aNotifier && item->iInfo.iChannel==aChannel) sl@0: { sl@0: ret=ETrue; sl@0: break; sl@0: } sl@0: } sl@0: return ret; sl@0: } sl@0: sl@0: void CNotifierQueue::RemoveClient(TInt aClientId) sl@0: { sl@0: const TInt count=iQueue.Count(); sl@0: for (TInt ii=count-1;ii>=0;ii--) sl@0: { sl@0: CQueueItem* item=iQueue[ii]; sl@0: TInt clientId=item->iClientId; sl@0: if (clientId==aClientId) sl@0: { sl@0: iQueue.Delete(ii); sl@0: } sl@0: } sl@0: } sl@0: sl@0: sl@0: TInt CNotifierQueue::GetHighestQueuePriority(TUid aChannel) sl@0: { sl@0: const TInt count=iQueue.Count(); sl@0: TInt priority=MNotifierBase2::ENotifierPriorityLowest-1; sl@0: sl@0: for (TInt ii=0;iiiInfo.iChannel==aChannel && item->iInfo.iPriority>priority) sl@0: { sl@0: priority=item->iInfo.iPriority; sl@0: } sl@0: } sl@0: sl@0: return priority; sl@0: } sl@0: sl@0: sl@0: void CWsActiveScheduler::New() sl@0: // sl@0: // Create and install the active scheduler. sl@0: // sl@0: { sl@0: sl@0: CWsActiveScheduler *pA=new CWsActiveScheduler; sl@0: __ASSERT_ALWAYS(pA!=NULL,Fault(ECreateScheduler)); sl@0: CActiveScheduler::Install(pA); sl@0: } sl@0: sl@0: void CWsActiveScheduler::Error(TInt) const sl@0: // sl@0: // Called if any Run() method leaves. sl@0: // sl@0: { sl@0: } sl@0: sl@0: sl@0: TInt NotifierServerThread(TAny*) sl@0: { sl@0: CTrapCleanup* CleanUpStack=CTrapCleanup::New(); sl@0: CWsActiveScheduler::New(); sl@0: TRAP_IGNORE(CNotifierServer::NewL()); sl@0: CNotifierSession::NotifierSemaphore.Signal(); sl@0: CWsActiveScheduler::Start(); sl@0: delete CleanUpStack; sl@0: return(0); sl@0: } sl@0: sl@0: sl@0: _LIT(KLitKeyDataDllNameBase, "EKDATA"); sl@0: _LIT(TwoDigExt,".%02d"); sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: UserSvr::WsRegisterThread(); sl@0: UserSvr::WsRegisterSwitchOnScreenHandling(ETrue); sl@0: User::SetProcessCritical(User::ESystemPermanent); sl@0: User::SetCritical(User::ESystemPermanent); sl@0: sl@0: CWsActiveScheduler::New(); sl@0: CWsServer::New(); sl@0: CWsWindow::New(); sl@0: CEvent::New(); sl@0: sl@0: KeyTranslator=CKeyTranslator::New(); sl@0: if (!KeyTranslator) sl@0: Fault(ENoKeyboardTranslator); sl@0: sl@0: // Change keyboard mapping according to information in the HAL sl@0: // This code is the same as WSERV sl@0: TInt keyboardIndex; sl@0: if (HAL::Get(HALData::EKeyboardIndex,keyboardIndex)==KErrNone) sl@0: { sl@0: TBuf<16> keyDataDllName(KLitKeyDataDllNameBase); sl@0: keyDataDllName.AppendFormat(TwoDigExt, keyboardIndex); sl@0: KeyTranslator->ChangeKeyData(keyDataDllName); sl@0: } sl@0: sl@0: KeyRepeat=new(ELeave) CKeyRepeat(CKeyRepeat::EKeyRepeatPriority); sl@0: TRAPD(r,KeyRepeat->ConstructL()); sl@0: if (r!=KErrNone) sl@0: User::Panic(_L("KEYREPEAT"),r); sl@0: sl@0: #ifndef __WINS__ sl@0: if (UserSvr::TestBootSequence()) sl@0: { sl@0: RDebug::Print(_L("WS_MAIN: TestBootSequence=TRUE, not loading ESHELL.EXE")); sl@0: } sl@0: #else sl@0: if (EmulatorAutoRun()) sl@0: { // don't start ESHELL if we used a self-bootstrapping EXE sl@0: } sl@0: #endif sl@0: else sl@0: { sl@0: RProcess shell; sl@0: r=shell.Create(KShellProcessName, KShellCommandLine); sl@0: __ASSERT_ALWAYS(r==KErrNone,Fault(ECreateShell)); sl@0: shell.Resume(); sl@0: shell.Close(); sl@0: } sl@0: sl@0: RThread t; sl@0: r=CNotifierSession::NotifierSemaphore.CreateLocal(0); sl@0: if (r!=KErrNone) sl@0: Fault(ECreateNotifierSemaphore); sl@0: r=t.Create(_L("NotifierServer"),NotifierServerThread,KDefaultStackSize,0x2000,0x100000,NULL); sl@0: if (r!=KErrNone) sl@0: Fault(ECreateNotifierThread); sl@0: t.Resume(); sl@0: CNotifierSession::NotifierSemaphore.Wait(); sl@0: sl@0: CWsActiveScheduler::Start(); sl@0: UserSvr::ReleaseEventHook(); sl@0: return(KErrNone); sl@0: } sl@0: