os/kernelhwsrv/kernel/eka/ewsrv/ws_main.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/ewsrv/ws_main.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,2198 @@
     1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32\ewsrv\ws_main.cpp
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include "ws_std.h"
    1.22 +#include <e32hal.h>
    1.23 +#include <hal.h>
    1.24 +#include <e32math.h>
    1.25 +#include <domainmanager.h>
    1.26 +#ifdef __WINS__
    1.27 +#include <e32wins.h>
    1.28 +#endif
    1.29 +
    1.30 +GLREF_D CKeyTranslator *KeyTranslator;
    1.31 +GLREF_D CKeyRepeat* KeyRepeat;
    1.32 +
    1.33 +// password notifier support functions
    1.34 +LOCAL_C void RenderPassword(RConsole *aCon, TInt aPWLeft, const TDesC& aPW);
    1.35 +
    1.36 +_LIT(KShellProcessName, "ESHELL");
    1.37 +_LIT(KShellCommandLine, "/p");
    1.38 +
    1.39 +//
    1.40 +// class CKeyRepeat
    1.41 +//
    1.42 +
    1.43 +CKeyRepeat::CKeyRepeat(TInt aPriority) : CTimer(aPriority)
    1.44 +//
    1.45 +// Constructor. Set default repeat delay and rate
    1.46 +//
    1.47 +    {
    1.48 +    iDelay=EDefaultKeyRepeatDelay;
    1.49 +    iRate=EDefaultKeyRepeatRate;
    1.50 +    }
    1.51 +
    1.52 +void CKeyRepeat::ConstructL()
    1.53 +    {
    1.54 +
    1.55 +    CTimer::ConstructL();
    1.56 +    CActiveScheduler::Add(this);
    1.57 +    }
    1.58 +
    1.59 +void CKeyRepeat::RunL()
    1.60 +//
    1.61 +// Send a repeat keypress to the window
    1.62 +//
    1.63 +    {
    1.64 +
    1.65 +    After(iRate);
    1.66 +	CWsWindow::KeyPress(iKeyData);
    1.67 +    }
    1.68 +
    1.69 +void CKeyRepeat::Request(TKeyData& aKeyData)
    1.70 +//
    1.71 +// Request a repeat event
    1.72 +//
    1.73 +    {
    1.74 +
    1.75 +    iKeyData=aKeyData;
    1.76 +	Cancel();
    1.77 +    After(iDelay);
    1.78 +    }
    1.79 +
    1.80 +void CKeyRepeat::SetRepeatTime(TInt aDelay,TInt aRate)
    1.81 +    {
    1.82 +
    1.83 +    iDelay=aDelay;
    1.84 +    iRate=aRate;
    1.85 +    }
    1.86 +
    1.87 +void CKeyRepeat::RepeatTime(TInt& aDelay,TInt& aRate)
    1.88 +    {
    1.89 +
    1.90 +    aDelay=iDelay;
    1.91 +    aRate=iRate;
    1.92 +    }
    1.93 +
    1.94 +//
    1.95 +// class CWsSession
    1.96 +//
    1.97 +
    1.98 +CWsSession::CWsSession()
    1.99 +	{
   1.100 +	iTestFast = (UserSvr::DebugMask(2)&0x00000002) ? 1 : 0;
   1.101 +	}
   1.102 +
   1.103 +CWsSession::~CWsSession()
   1.104 +//
   1.105 +// Destructor
   1.106 +//
   1.107 +	{
   1.108 +
   1.109 +	delete iWindow;
   1.110 +	}
   1.111 +
   1.112 +//
   1.113 +// class CWsServer
   1.114 +//
   1.115 +
   1.116 +void CWsServer::New()
   1.117 +//
   1.118 +// Create a new CWsServer.
   1.119 +//
   1.120 +	{
   1.121 +
   1.122 +	CWsServer *pS=new CWsServer(EPriority);
   1.123 +	__ASSERT_ALWAYS(pS!=NULL,Fault(ECreateServer));
   1.124 +	pS->SetPinClientDescriptors(EFalse); // don't pin because client interface can't cope with errors if pin fails under real or simulated OOM
   1.125 +	TInt r=pS->Start(KE32WindowServer);
   1.126 +	__ASSERT_ALWAYS(r==KErrNone,Fault(EStartServer));
   1.127 +	RProcess::Rendezvous(KErrNone);
   1.128 +
   1.129 +	}
   1.130 +
   1.131 +CWsServer::CWsServer(TInt aPriority)
   1.132 +//
   1.133 +// Constructor.
   1.134 +//
   1.135 +	: CServer2(aPriority)
   1.136 +	{
   1.137 +	}
   1.138 +
   1.139 +CSession2* CWsServer::NewSessionL(const TVersion& aVersion,const RMessage2&) const
   1.140 +//
   1.141 +// Create a new client for this server.
   1.142 +//
   1.143 +	{
   1.144 +
   1.145 +	TVersion v(KW32MajorVersionNumber,KW32MinorVersionNumber,KE32BuildVersionNumber);
   1.146 +	TBool r=User::QueryVersionSupported(v,aVersion);
   1.147 +	if (!r)
   1.148 +		User::Leave(KErrNotSupported);
   1.149 +	return new(ELeave) CWsSession;
   1.150 +	}
   1.151 +
   1.152 +void CWsSession::ServiceL(const RMessage2& aMessage)
   1.153 +//									    
   1.154 +// Handle messages for this session.
   1.155 +//
   1.156 +	{
   1.157 +
   1.158 +	iCurMsg = aMessage;
   1.159 +	CWsWindow::WaitOnService();
   1.160 +	CWsWindow* pW=iWindow;
   1.161 +	TInt r=EPrematureOperation;
   1.162 +	TBool delayCompletion=EFalse;
   1.163 +	switch (aMessage.Function())
   1.164 +		{
   1.165 +	case EConsoleCreate:
   1.166 +		{
   1.167 +		if (pW)
   1.168 +			{
   1.169 +			delete pW;
   1.170 +			iWindow=NULL;
   1.171 +			}
   1.172 +		pW=new CWsWindow;
   1.173 +		if (!pW)
   1.174 +			{ 
   1.175 +			r=EWindowOutOfMemory;
   1.176 +			break;
   1.177 +			}
   1.178 +		iWindow=pW;
   1.179 +		pW->iAllowResize=ETrue;
   1.180 +		pW->iIsVisible=ETrue;
   1.181 +		pW->iOnTop=EFalse;
   1.182 +		pW->SetCursorHeight(50);
   1.183 +		pW->iKQueue.SetOffset(_FOFF(SWsKey,iLink));
   1.184 +		break;
   1.185 +		}
   1.186 +	case EConsoleSet:
   1.187 +		{
   1.188 +		if (!pW)
   1.189 +			{
   1.190 +			pW=new(ELeave) CWsWindow;
   1.191 +			iWindow=pW;
   1.192 +			pW->iAllowResize=ETrue;
   1.193 +			pW->iIsVisible=ETrue;
   1.194 +			pW->iOnTop=EFalse;
   1.195 +			pW->SetCursorHeight(50);
   1.196 +			pW->iKQueue.SetOffset(_FOFF(SWsKey,iLink));
   1.197 +			}
   1.198 +		pW->iAllowSlide=ETrue;
   1.199 +		TFileName name;
   1.200 +		iCurMsg.ReadL(0, name);
   1.201 +		pW->iTitle=name;
   1.202 +		TPckgBuf<TSize> size;
   1.203 +		iCurMsg.ReadL(1, size);
   1.204 +		TRAP(r,pW->CreateL(size()));
   1.205 +		if (r != KErrNone)
   1.206 +			{
   1.207 +			delete pW;
   1.208 +			iWindow=NULL;			
   1.209 +			}
   1.210 +		break;
   1.211 +		}
   1.212 +	case EConsoleClearScreen:
   1.213 +		{
   1.214 +		if (pW)
   1.215 +			{
   1.216 +			pW->Clear();
   1.217 +			r=KErrNone;
   1.218 +			}
   1.219 +		break;
   1.220 +		}
   1.221 +	case EConsoleClearToEndOfLine:
   1.222 +		{
   1.223 +		if (pW)
   1.224 +			{
   1.225 +			pW->ClearToEndOfLine();
   1.226 +			r=KErrNone;
   1.227 +			}
   1.228 +		break;
   1.229 +		}
   1.230 +	case EConsoleSetTitle:
   1.231 +		{
   1.232 +		if (pW)
   1.233 +			{
   1.234 +			TFileName name;
   1.235 +			iCurMsg.ReadL(0, name);
   1.236 +			pW->SetTitle(name);
   1.237 +			r=KErrNone;
   1.238 +			}
   1.239 +		break;
   1.240 +		}
   1.241 +	case EConsoleSetSize:
   1.242 +		{
   1.243 +		if (pW)
   1.244 +			{
   1.245 +			TPckgBuf<TSize> size;
   1.246 +			iCurMsg.ReadL(0, size);
   1.247 +//			pW->SetSize(size());
   1.248 +//			r=KErrNone;
   1.249 +			r=KErrNotSupported;
   1.250 +			}
   1.251 +		break;
   1.252 +		}
   1.253 +	case EConsoleSetWindowPosAbs:
   1.254 +		{
   1.255 +		if (pW)
   1.256 +			{
   1.257 +			TPckgBuf<TPoint> point;
   1.258 +			iCurMsg.ReadL(0, point);
   1.259 +			pW->SetWindowPosAbs(point());
   1.260 +			r=KErrNone;
   1.261 +			}
   1.262 +		break;
   1.263 +		}
   1.264 +	case EConsoleSetCursorHeight:
   1.265 +		{
   1.266 +		if (pW)
   1.267 +			{
   1.268 +			pW->SetCursorHeight(aMessage.Int0());
   1.269 +			r=KErrNone;
   1.270 +			}
   1.271 +		break;
   1.272 +		}
   1.273 +	case EConsoleSetCursorPosAbs:
   1.274 +		{
   1.275 +		if (pW)
   1.276 +			{
   1.277 +			TPckgBuf<TPoint> point;
   1.278 +			iCurMsg.ReadL(0, point);
   1.279 +			pW->SetCursorPosAbs(point());
   1.280 +			r=KErrNone;
   1.281 +			}
   1.282 +		break;
   1.283 +		}
   1.284 +	case EConsoleSetCursorPosRel:
   1.285 +		{
   1.286 +		if (pW)
   1.287 +			{
   1.288 +			TPckgBuf<TPoint> point;
   1.289 +			iCurMsg.ReadL(0, point);
   1.290 +			pW->SetCursorPosRel(point());
   1.291 +			r=KErrNone;
   1.292 +			}
   1.293 +		break;
   1.294 +		}
   1.295 +	case EConsoleCursorPos:
   1.296 +		{
   1.297 +		if (pW)
   1.298 +			{
   1.299 +			TPckgBuf<TPoint> point;
   1.300 +			point()=pW->CursorPosition();
   1.301 +			aMessage.WriteL(0,point);
   1.302 +			r=KErrNone;
   1.303 +			}
   1.304 +		break;
   1.305 +		}
   1.306 +	case EConsoleSize:
   1.307 +		{
   1.308 +		if (pW)
   1.309 +			{
   1.310 +			TPckgBuf<TSize> size;
   1.311 +			size()=pW->Size();
   1.312 +			aMessage.WriteL(0,size);
   1.313 +			r=KErrNone;
   1.314 +			}
   1.315 +		break;
   1.316 +		}
   1.317 +	case EConsoleScreenSize:
   1.318 +		{
   1.319 +		if (pW)
   1.320 +			{
   1.321 +			TPckgBuf<TSize> size;
   1.322 +			size()=CWsWindow::ScreenSize;
   1.323 +			aMessage.WriteL(0,size);
   1.324 +			r=KErrNone;
   1.325 +			}
   1.326 +		break;
   1.327 +		}
   1.328 +	case EConsoleControl:
   1.329 +		{
   1.330 +		if (pW)
   1.331 +			{
   1.332 +			TBool indicator=ETrue;
   1.333 +			TInt offset=0;
   1.334 +			TBuf<0x100> b;
   1.335 +			do
   1.336 +				{
   1.337 +				iCurMsg.ReadL(0,b,offset);
   1.338 +				for (const TText* pB=b.Ptr();pB<b.Ptr()+b.Length();pB++)
   1.339 +					{
   1.340 +					switch(*pB)
   1.341 +						{
   1.342 +					case '+':
   1.343 +
   1.344 +						indicator=ETrue;
   1.345 +						break;
   1.346 +					case '-':
   1.347 +						indicator=EFalse;
   1.348 +						break;
   1.349 +					case 'S':
   1.350 +						pW->ControlScrollBars(indicator);
   1.351 +						break;
   1.352 +					case 'W':
   1.353 +						pW->ControlWrapLock(indicator);
   1.354 +						break;
   1.355 +                    case 'P':
   1.356 +                        pW->ControlPointerEvents(indicator);
   1.357 +                        break;
   1.358 +					case 'L':
   1.359 +						pW->ControlScrollLock(indicator);
   1.360 +						break;
   1.361 +					case 'V':
   1.362 +						pW->ControlVisibility(indicator);
   1.363 +						break;
   1.364 +					case 'C':
   1.365 +						pW->ControlCursorRequired(indicator);
   1.366 +						break;
   1.367 +					case 'M':
   1.368 +						pW->ControlMaximised(indicator);
   1.369 +						break;
   1.370 +					case 'N':
   1.371 +						pW->ControlNewLineMode(indicator);
   1.372 +						break;
   1.373 +                    case 'O':
   1.374 +						pW->ControlOnTop(indicator);
   1.375 +						break;
   1.376 +					case 'I':
   1.377 +                        pW->ControlInformAllMouse(indicator);
   1.378 +                        break;
   1.379 +                    case 'R':
   1.380 +                        pW->ControlRawEventMode(indicator);
   1.381 +                        break;
   1.382 +					case 'A':
   1.383 +						pW->ControlAllowResize(indicator);
   1.384 +						}
   1.385 +					}
   1.386 +				offset+=b.Length();
   1.387 +				}
   1.388 +			while (b.Length()==b.MaxLength());
   1.389 +			r=KErrNone;
   1.390 +			}
   1.391 +		break;
   1.392 +		}
   1.393 +	case EConsoleWrite:
   1.394 +		{
   1.395 +		if (pW)
   1.396 +			{
   1.397 +			switch(iTestFast)
   1.398 +				{
   1.399 +			case 0:
   1.400 +				{
   1.401 +				TInt offset=0;
   1.402 +				TBuf<0x100> b;
   1.403 +				do
   1.404 +					{
   1.405 +					iCurMsg.ReadL(0,b,offset);
   1.406 +					pW->Write(b);
   1.407 +					offset+=b.Length();
   1.408 +					}
   1.409 +				while (b.Length()==b.MaxLength());
   1.410 +				pW->WriteDone();
   1.411 +				}
   1.412 +				r=KErrNone;
   1.413 +				break;
   1.414 +
   1.415 +			case 1:
   1.416 +				{
   1.417 +				pW->Write(_L("Output suppressed because TESTFAST mode is set..."));
   1.418 +				pW->WriteDone();
   1.419 +				++iTestFast;
   1.420 +				}
   1.421 +				r=KErrNone;
   1.422 +				break;
   1.423 +
   1.424 +			default:
   1.425 +				r=KErrNone;
   1.426 +				break;
   1.427 +				}
   1.428 +			}
   1.429 +		break;
   1.430 +		}
   1.431 +	case EConsoleRead:
   1.432 +		{
   1.433 +		if (pW)
   1.434 +			{
   1.435 +			if (pW->EnqueReadRequest(aMessage))
   1.436 +				{
   1.437 +				delayCompletion=ETrue;
   1.438 +				r=KErrNone;
   1.439 +				}
   1.440 +			else
   1.441 +				r=EDoubleReadRequest;
   1.442 +			}
   1.443 +		break;
   1.444 +		}
   1.445 +	case EConsoleReadCancel:
   1.446 +		{
   1.447 +		if (pW)
   1.448 +			{
   1.449 +			pW->DequeReadRequest();
   1.450 +			r=KErrNone;
   1.451 +			}
   1.452 +		break;
   1.453 +		}
   1.454 +	case EConsoleDestroy:
   1.455 +		{
   1.456 +		if (pW)
   1.457 +			{
   1.458 +			delete pW;
   1.459 +			iWindow=NULL;
   1.460 +			r=KErrNone;
   1.461 +			}
   1.462 +		break;
   1.463 +		}
   1.464 +	case EConsoleSetMode:
   1.465 +		{
   1.466 +		r=CWsWindow::SetMode((TVideoMode)aMessage.Int0());		
   1.467 +		break;
   1.468 +		}
   1.469 +	case EConsoleSetPaletteEntry:
   1.470 +		{
   1.471 +		CWsWindow::ScreenDriver->SetPaletteEntry((TColorIndex)aMessage.Int0(),(TUint8)aMessage.Int1(),(TUint8)aMessage.Int2(),(TUint8)aMessage.Int3());
   1.472 +		pW->Redraw();
   1.473 +		r=KErrNone;
   1.474 +		break;
   1.475 +		}
   1.476 +	case EConsoleGetPaletteEntry:
   1.477 +		{
   1.478 +		TUint8 r,g,b;
   1.479 +		TPckgBuf<TUint8> red,green,blue;
   1.480 +		CWsWindow::ScreenDriver->GetPaletteEntry((TColorIndex)aMessage.Int0(),r,g,b);
   1.481 +		red()=r; green()=g; blue()=b;
   1.482 +		aMessage.WriteL(1,red);
   1.483 +		aMessage.WriteL(2,green);
   1.484 +		aMessage.WriteL(3,blue);
   1.485 +		}
   1.486 +		r=KErrNone;
   1.487 +		break;
   1.488 +	case EConsoleSetTextColors:
   1.489 +		{
   1.490 +		if(pW)
   1.491 +			{
   1.492 +			pW->iFgColor=(TColorIndex)aMessage.Int0();
   1.493 +			pW->iBgColor=(TColorIndex)aMessage.Int1();
   1.494 +			}		
   1.495 +		r=KErrNone;
   1.496 +		break;
   1.497 +		}
   1.498 +	case EConsoleSetUIColors:
   1.499 +		{
   1.500 +		CWsWindow::WindowBgColor=(TColorIndex)aMessage.Int0();
   1.501 +		CWsWindow::BorderColor=(TColorIndex)aMessage.Int1();
   1.502 +		CWsWindow::ScreenColor=(TColorIndex)aMessage.Int2();
   1.503 +		CWsWindow::ChangeUIColors();
   1.504 +		r=KErrNone;
   1.505 +		break;
   1.506 +		}
   1.507 +	case EConsoleSetTextAttribute:
   1.508 +		{
   1.509 +		if(pW)
   1.510 +			pW->SetTextAttribute((TTextAttribute)aMessage.Int0());		
   1.511 +		r=KErrNone;
   1.512 +		break;
   1.513 +		}
   1.514 +	default:
   1.515 +		r=KErrNotSupported;
   1.516 +		}
   1.517 +	if (!delayCompletion)
   1.518 +		aMessage.Complete(r);
   1.519 +	CWsWindow::SignalService();
   1.520 +	}
   1.521 +
   1.522 +void CWsSession::ServiceError(const RMessage2& aMessage,TInt aError)
   1.523 +	{
   1.524 +	if (!aMessage.IsNull())
   1.525 +		{
   1.526 +		if (aError>0)
   1.527 +			{
   1.528 +			aMessage.Panic(_L("WServ panic"),aError);
   1.529 +			}
   1.530 +		else
   1.531 +			{
   1.532 +			aMessage.Complete(aError);
   1.533 +			}
   1.534 +		}
   1.535 +	}
   1.536 +
   1.537 +CWsServer::~CWsServer()
   1.538 +//
   1.539 +// Destructor
   1.540 +//
   1.541 +	{
   1.542 +	}
   1.543 +
   1.544 +//
   1.545 +// class CEvent
   1.546 +//
   1.547 +
   1.548 +void CEvent::New()
   1.549 +//
   1.550 +// Create the CEvent active object.
   1.551 +//
   1.552 +	{
   1.553 +
   1.554 +	CEvent *pE=new CEvent(EPriority);
   1.555 +	__ASSERT_ALWAYS(pE!=NULL,Fault(ECreateEvent));
   1.556 +	pE->CaptureKeys=new CCaptureKeys();
   1.557 +	__ASSERT_ALWAYS(pE->CaptureKeys!=NULL,Fault(ECreateEvent));
   1.558 +
   1.559 +	pE->CaptureKeys->Construct();
   1.560 +
   1.561 +	CActiveScheduler::Add(pE);
   1.562 +	UserSvr::CaptureEventHook();
   1.563 +	pE->Request();
   1.564 +	}
   1.565 +
   1.566 +CEvent::~CEvent()
   1.567 +//
   1.568 +// Destroy the CEvent active object
   1.569 +//
   1.570 +	{
   1.571 +
   1.572 +	Cancel();
   1.573 +	}
   1.574 +
   1.575 +#pragma warning( disable : 4705 )	// statement has no effect
   1.576 +CEvent::CEvent(TInt aPriority)
   1.577 +//
   1.578 +// Constructor
   1.579 +//
   1.580 +	: CActive(aPriority)
   1.581 +	{
   1.582 +	}
   1.583 +#pragma warning( default : 4705 )
   1.584 +
   1.585 +void CEvent::Request()
   1.586 +//
   1.587 +// Issue a request for the next event.
   1.588 +//
   1.589 +	{
   1.590 +
   1.591 +	UserSvr::RequestEvent(iEvent,iStatus);
   1.592 +	SetActive();
   1.593 +	}
   1.594 +
   1.595 +void CEvent::DoCancel()
   1.596 +//
   1.597 +// Cancel a pending event.
   1.598 +//
   1.599 +	{
   1.600 +
   1.601 +	UserSvr::RequestEventCancel();
   1.602 +	}
   1.603 +
   1.604 +void CEvent::RunL()
   1.605 +//
   1.606 +// Event has completed.
   1.607 +//
   1.608 +	{
   1.609 +
   1.610 +    if (CWsWindow::RawEventMode())
   1.611 +        {
   1.612 +        KeyRepeat->Cancel();
   1.613 +        CWsWindow::QueueRawEvent(iEvent.Event());
   1.614 +        Request();
   1.615 +        return;
   1.616 +        }
   1.617 +	switch(iEvent.Event().Type())
   1.618 +		{
   1.619 +	case TRawEvent::ERedraw:
   1.620 +		CWsWindow::Redraw();
   1.621 +		break;
   1.622 +	case TRawEvent::EButton1Down:
   1.623 +        if(!CWsWindow::MouseIsCaptured)
   1.624 +            {
   1.625 +      		CWsWindow::MouseMove(iEvent.Event().Pos());
   1.626 +  	    	CWsWindow::MouseLeftButton();
   1.627 +            }
   1.628 +        else
   1.629 +            CWsWindow::InformTopMouse(iEvent.Event().Pos());
   1.630 +		break;
   1.631 +	case TRawEvent::EButton1Up:
   1.632 +		if(!CWsWindow::MouseIsCaptured)
   1.633 +			{
   1.634 +			CWsWindow::MouseMove(iEvent.Event().Pos());
   1.635 +			CWsWindow::MouseLeftButtonUp();
   1.636 +			}
   1.637 +		break;
   1.638 +	case TRawEvent::EButton2Down:
   1.639 +		break;
   1.640 +	case TRawEvent::EButton2Up:
   1.641 +		break;
   1.642 +	case TRawEvent::EButton3Down:
   1.643 +		break;
   1.644 +	case TRawEvent::EButton3Up:
   1.645 +		break;
   1.646 +	case TRawEvent::EPointerMove:
   1.647 +		CWsWindow::MouseMove(iEvent.Event().Pos());
   1.648 +		break;
   1.649 +	case TRawEvent::EInactive:
   1.650 +        KeyRepeat->Cancel();
   1.651 +        break;
   1.652 +    case TRawEvent::EActive:
   1.653 +        break;
   1.654 +    case TRawEvent::EUpdateModifiers:
   1.655 +        KeyTranslator->UpdateModifiers(iEvent.Event().Modifiers());
   1.656 +        break;
   1.657 +	case TRawEvent::EKeyDown:
   1.658 +		{
   1.659 +		TKeyData keyData;
   1.660 +		if (KeyTranslator->TranslateKey(iEvent.Event().ScanCode(), EFalse,*CaptureKeys,keyData))
   1.661 +			CWsWindow::KeyPress(keyData);
   1.662 +		if (keyData.iModifiers&EModifierAutorepeatable)
   1.663 +			KeyRepeat->Request(keyData);
   1.664 +		break;
   1.665 +		}
   1.666 +	case TRawEvent::EKeyUp:
   1.667 +		{
   1.668 +		TKeyData keyData;
   1.669 +		KeyRepeat->Cancel();
   1.670 +		if (KeyTranslator->TranslateKey(iEvent.Event().ScanCode(), ETrue,*CaptureKeys,keyData))
   1.671 +			CWsWindow::KeyPress(keyData);
   1.672 +		break;
   1.673 +		}
   1.674 +	case TRawEvent::ESwitchOn:
   1.675 +	case TRawEvent::ECaseOpen:
   1.676 +		HAL::Set(HAL::EDisplayState, 1);
   1.677 +			{
   1.678 +			RDmDomainManager mgr; 
   1.679 +			TInt r = mgr.Connect();
   1.680 +			if (r != KErrNone)
   1.681 +				User::Panic(_L("EWSRV SwitchOn0"), r);
   1.682 +			TRequestStatus status;
   1.683 +			mgr.RequestDomainTransition(KDmIdUiApps, EPwActive, status);
   1.684 +			User::WaitForRequest(status);
   1.685 +			if (status.Int() != KErrNone)
   1.686 +				User::Panic(_L("EWSRV SwitchOn1"), status.Int());
   1.687 +			mgr.Close();
   1.688 +			}
   1.689 +		break;
   1.690 +	case TRawEvent::EPointerSwitchOn:
   1.691 +#if defined(_DEBUG)
   1.692 +    	User::Beep(440,250000);
   1.693 +#endif
   1.694 +		break;
   1.695 +	case TRawEvent::ESwitchOff:
   1.696 +			{
   1.697 +			RDmDomainManager mgr; 
   1.698 +			TInt r = mgr.Connect();
   1.699 +			if (r != KErrNone)
   1.700 +				User::Panic(_L("EWSRV SwitchOff0"), r);
   1.701 +			TRequestStatus status;
   1.702 +			mgr.RequestSystemTransition(EPwStandby, status);
   1.703 +			User::WaitForRequest(status);
   1.704 +			if (status.Int() != KErrNone)
   1.705 +				User::Panic(_L("EWSRV SwitchOff1"), status.Int());
   1.706 +			mgr.Close();
   1.707 +			}
   1.708 +		break;
   1.709 +	case TRawEvent::ECaseClose:
   1.710 +			{
   1.711 +			RDmDomainManager mgr; 
   1.712 +			TInt r = mgr.Connect();
   1.713 +			if (r != KErrNone)
   1.714 +				User::Panic(_L("EWSRV CaseClosed"), r);
   1.715 +			TRequestStatus status;
   1.716 +			mgr.RequestDomainTransition(KDmIdUiApps, EPwStandby, status);
   1.717 +			User::WaitForRequest(status);
   1.718 +			if (status.Int() != KErrNone)
   1.719 +				User::Panic(_L("EWSRV CaseClosed1"), status.Int());
   1.720 +			mgr.Close();
   1.721 +			}
   1.722 +		HAL::Set(HAL::EDisplayState, 0);
   1.723 +		break;
   1.724 +	case TRawEvent::ENone:
   1.725 +		break;
   1.726 +	default:
   1.727 +		break;
   1.728 +		}                                       
   1.729 +	Request();
   1.730 +	}
   1.731 +
   1.732 +LOCAL_C void RenderPassword(RConsole *aCon, TInt aPWLeft, const TDesC& aPW)
   1.733 +// pre:		aCon points to a console being used to read a password.
   1.734 +//			aPWLeft is the column number from which the left brace should be drawn.
   1.735 +//			aPasswd is a valid password.
   1.736 +// post:	the password is rendered onto the console and followed by a '#' and
   1.737 +//			padding spaces.  Everything is enclosed in a pair of square brackets.
   1.738 +	{
   1.739 +	aCon->SetCursorPosAbs(TPoint(aPWLeft, 3));
   1.740 +	aCon->Write(_L("["));
   1.741 +	aCon->Write(aPW);
   1.742 +	aCon->Write(_L("#"));
   1.743 +
   1.744 +	TInt i;
   1.745 +	for (i = 0; i < KMaxMediaPassword - aPW.Length(); i++)
   1.746 +		{
   1.747 +		aCon->Write(_L(" "));
   1.748 +		}
   1.749 +
   1.750 +	aCon->Write(_L("]"));
   1.751 +	}
   1.752 +
   1.753 +
   1.754 +void CNotifierSession::RunPasswordWindowL(const RMessage2 &aMsg)
   1.755 +//
   1.756 +// Eight unicode chars are mapped to (up to) sixteen bytes.  Remainder of array is
   1.757 +// zeroed.  Message is completed in CNotifierSession::ServiceL().
   1.758 +// 
   1.759 +	{
   1.760 +	// local copies of dialog data, 5 * (8 + 32 * 2) bytes
   1.761 +	TBuf<0x20> line1, line2, unlockBtn, storeBtn, cancelBtn;
   1.762 +	line1.Copy(_L("Password notifier"));
   1.763 +	line2.Copy(_L("Enter password"));
   1.764 +	unlockBtn.Copy(_L("Unlock"));
   1.765 +	storeBtn.Copy(_L("Store"));
   1.766 +	cancelBtn.Copy(_L("Cancel"));
   1.767 +
   1.768 +	TPckgBuf<TMediaPswdReplyNotifyInfoV1> reply;
   1.769 +
   1.770 +	// Format the console window.
   1.771 +
   1.772 +	const TInt KPasswordBarLen(1 + KMaxMediaPassword + 1 + 1);
   1.773 +	const TInt KButtonBarLen(
   1.774 +				1 + unlockBtn.Length() + 1
   1.775 +		+ 1 +	1 + cancelBtn.Length() + 1
   1.776 +		+ 1 +	1 + storeBtn.Length() + 1);
   1.777 +
   1.778 +	// Work out width of window.
   1.779 +	// (Buttons are enclosed by angle brackets and separted by a space.)
   1.780 +	// (Password is followed by '#' and delimited by square brackets.)
   1.781 +	// If KButtonBarLen is at least as long as any other line then it will write
   1.782 +	// to the bottom right corner and cause the console to scroll.  To counter
   1.783 +	// this, an extra padding character is added if necessary.
   1.784 +
   1.785 +	TInt width;
   1.786 +	width = Max(line1.Length(), line2.Length());
   1.787 +	width = Max(width, KPasswordBarLen);
   1.788 +	width = KButtonBarLen >= width ? KButtonBarLen + 1: width;
   1.789 +
   1.790 +	// Create the window and render its contents.
   1.791 +
   1.792 +	RConsole con;
   1.793 +	con.Create();
   1.794 +	con.Control(_L("-Visible"));
   1.795 +	TInt r = con.Init(_L(""), TSize(width, 2 + 1 + 1 + 1 + 1));
   1.796 +	if (KErrNone != r)
   1.797 +		{
   1.798 +		PanicClient(aMsg, ENotifierPanicPasswordWindow);
   1.799 +		User::Leave(KErrGeneral);
   1.800 +		}
   1.801 +	con.Control(_L("+Max -Cursor -AllowResize +OnTop"));
   1.802 +
   1.803 +	con.SetCursorPosAbs(TPoint(0, 0));
   1.804 +	con.Write(line1);
   1.805 +	con.SetCursorPosAbs(TPoint(0, 1));
   1.806 +	con.Write(line2);
   1.807 +	const TInt KPasswordLeft((width - KPasswordBarLen) / 2);
   1.808 +	con.SetCursorPosAbs(TPoint(KPasswordLeft, 3));
   1.809 +	con.Write(_L("[#                ]"));
   1.810 +	con.SetCursorPosAbs(TPoint((width - KButtonBarLen) / 2, 5));
   1.811 +	con.Write(_L("<"));
   1.812 +	con.Write(unlockBtn);
   1.813 +	con.Write(_L("> <"));
   1.814 +	con.Write(storeBtn);
   1.815 +	con.Write(_L("> <"));
   1.816 +	con.Write(cancelBtn);
   1.817 +	con.Write(_L(">"));
   1.818 +
   1.819 +	// Allow the user to edit the password until they either press enter or escape.
   1.820 +
   1.821 +	TBool done(EFalse);
   1.822 +	TBuf<KMaxMediaPassword> pw;
   1.823 +	pw.Zero();
   1.824 +	TMediaPswdNotifyExitMode em(EMPEMUnlock);	// avoid VC warning C4701 (used w/o init).
   1.825 +
   1.826 +	const TInt sendInfoLen = User::LeaveIfError(aMsg.GetDesLength(1));
   1.827 +
   1.828 +	if (sendInfoLen == sizeof(TMediaPswdSendNotifyInfoV1Debug))
   1.829 +		{
   1.830 +		// debug mode - wait for specified period and close notifier
   1.831 +
   1.832 +		TPckgBuf<TMediaPswdSendNotifyInfoV1Debug> sendDbg;
   1.833 +		aMsg.ReadL(1, sendDbg);
   1.834 +		if (sendDbg().iSleepPeriod >= 0)
   1.835 +			User::After(sendDbg().iSleepPeriod);
   1.836 +		else
   1.837 +			{
   1.838 +			TTime now;
   1.839 +			now.HomeTime();
   1.840 +			TInt64 seed = now.Int64();
   1.841 +			User::After(Math::Rand(seed) % -(sendDbg().iSleepPeriod));
   1.842 +			}
   1.843 +
   1.844 +		reply().iEM = sendDbg().iEM;
   1.845 +		Mem::Copy(reply().iPW, sendDbg().iPW, KMaxMediaPassword);
   1.846 +		}
   1.847 +	else
   1.848 +		{
   1.849 +		RenderPassword(&con, KPasswordLeft, pw);
   1.850 +		do
   1.851 +			{
   1.852 +			TConsoleKey key;
   1.853 +
   1.854 +			con.Read(key);
   1.855 +			TInt keyCode = key.Code();
   1.856 +
   1.857 +			switch (keyCode)
   1.858 +				{
   1.859 +				case EKeyEscape:
   1.860 +					em = EMPEMCancel;
   1.861 +					done = ETrue;
   1.862 +					break;
   1.863 +
   1.864 +				case EKeyEnter:
   1.865 +					em = EMPEMUnlock;
   1.866 +					done = ETrue;
   1.867 +					break;
   1.868 +				
   1.869 +				case EKeySpace:
   1.870 +					em = EMPEMUnlockAndStore;
   1.871 +					done = ETrue;
   1.872 +					break;
   1.873 +				
   1.874 +				case EKeyBackspace:
   1.875 +					if (pw.Length() > 0)
   1.876 +						{
   1.877 +						pw.SetLength(pw.Length() - 1);
   1.878 +						RenderPassword(&con, KPasswordLeft, pw);
   1.879 +						}
   1.880 +					break;
   1.881 +
   1.882 +				default:							// interpret other keys as pw contents
   1.883 +					TChar ch(keyCode);
   1.884 +					// unicode encoding, so number of password characters is half byte length
   1.885 +					if (ch.IsPrint() && pw.Length() < KMaxMediaPassword / 2)
   1.886 +						{
   1.887 +						pw.Append(ch);
   1.888 +						RenderPassword(&con, KPasswordLeft, pw);
   1.889 +						}
   1.890 +					break;
   1.891 +				}
   1.892 +			} while (! done);
   1.893 +
   1.894 +		// Fill the TMediaPswdReplyNotifyInfoV1 structure.
   1.895 +
   1.896 +		if (em == EMPEMUnlock || em == EMPEMUnlockAndStore)
   1.897 +			{
   1.898 +			const TInt byteLen = pw.Length() * 2;
   1.899 +
   1.900 +			// zero entire array; and then copy in valid section of TMediaPassword,
   1.901 +			// not converting Unicode to ASCII.
   1.902 +			TPtr8 pt8(reply().iPW, KMaxMediaPassword);	// length = 0
   1.903 +			pt8.FillZ(KMaxMediaPassword);				// length = KMaxMediaPassword
   1.904 +			pt8.Zero();									// length = 0
   1.905 +														// length = byteLen
   1.906 +			pt8.Copy(reinterpret_cast<const TUint8 *>(pw.Ptr()), byteLen);
   1.907 +			}
   1.908 +		
   1.909 +		// Set exit mode to tell user how dialog handled.
   1.910 +
   1.911 +		reply().iEM = em;
   1.912 +		}	// else (sendInfoLen == sizeof(TMediaPswdSendNotifyInfoV1Debug))
   1.913 +	
   1.914 +	con.Destroy();
   1.915 +
   1.916 +	aMsg.WriteL(2, reply);
   1.917 +	}
   1.918 +
   1.919 +//
   1.920 +// class MNotifierBase2
   1.921 +//
   1.922 +
   1.923 +void MNotifierBase2::SetManager(MNotifierManager* aManager)
   1.924 +	{
   1.925 +	iManager=aManager;
   1.926 +	}
   1.927 +
   1.928 +//
   1.929 +// class CNotifierServer
   1.930 +//
   1.931 +
   1.932 +_LIT(__NOTIFIER_SERVER,"TextNotifierSrvr");
   1.933 +
   1.934 +CNotifierServer* CNotifierServer::NewL()
   1.935 +	{
   1.936 +	CNotifierServer* server=new(ELeave) CNotifierServer(200);
   1.937 +	CleanupStack::PushL(server);
   1.938 +	server->ConstructL();
   1.939 +	server->StartL(__NOTIFIER_NAME);
   1.940 +	CleanupStack::Pop(); // server
   1.941 +	return server;
   1.942 +	}
   1.943 +
   1.944 +CNotifierServer::~CNotifierServer()
   1.945 +	{
   1.946 +	SetIsExiting();
   1.947 +	delete iManager;
   1.948 +	}
   1.949 +
   1.950 +void CNotifierServer::SetIsExiting()
   1.951 +	{
   1.952 +	iExiting=ETrue;
   1.953 +	}
   1.954 +
   1.955 +TBool CNotifierServer::IsExiting() const
   1.956 +	{
   1.957 +	return iExiting;
   1.958 +	}
   1.959 +
   1.960 +CNotifierServer::CNotifierServer(TInt aPriority)
   1.961 +	: CServer2(aPriority)
   1.962 +	{}
   1.963 +
   1.964 +void CNotifierServer::ConstructL()
   1.965 +	{
   1.966 +	iManager=CNotifierManager::NewL();
   1.967 +	RFs fs;
   1.968 +	User::LeaveIfError(fs.Connect());
   1.969 +	CleanupClosePushL(fs);
   1.970 +	iManager->RegisterL(fs);
   1.971 +	CleanupStack::PopAndDestroy(); // fs.Close()
   1.972 +	}
   1.973 +
   1.974 +CSession2* CNotifierServer::NewSessionL(const TVersion &aVersion,const RMessage2&) const
   1.975 +	{
   1.976 +	TVersion v(1,0,0); // !! liaise with E32
   1.977 +	if (!User::QueryVersionSupported(v,aVersion))
   1.978 +		User::Leave(KErrNotSupported);
   1.979 +	return new(ELeave) CNotifierSession(*this);
   1.980 +	}
   1.981 +
   1.982 +//
   1.983 +// class CNotifierSession
   1.984 +//
   1.985 +
   1.986 +CNotifierSession::CNotifierSession(const CNotifierServer& aServer)
   1.987 +	{
   1.988 +	iServer=&aServer;
   1.989 +	iClientId=(TInt)this;
   1.990 +	}
   1.991 +
   1.992 +CNotifierSession::~CNotifierSession()
   1.993 +	{
   1.994 +	const CNotifierServer* server=static_cast<const CNotifierServer*>(Server());
   1.995 +	if (!server->IsExiting())
   1.996 +		{
   1.997 +		server->Manager()->HandleClientExit(iClientId);
   1.998 +		}
   1.999 +	}
  1.1000 +
  1.1001 +void CNotifierSession::ServiceL(const RMessage2 &aMessage)
  1.1002 +	{
  1.1003 +	TBool completeMessage=ETrue;
  1.1004 +	switch (aMessage.Function())
  1.1005 +		{
  1.1006 +	case ENotifierNotify:
  1.1007 +		DisplayAlertL(aMessage);
  1.1008 +		break;
  1.1009 +	case ENotifierNotifyCancel:
  1.1010 +		// do nothing - this server doesn't support cancelling RNotifier::Notify - the client will just have to wait
  1.1011 +		break;
  1.1012 +	case ENotifierInfoPrint:
  1.1013 +		DisplayInfoMsgL(aMessage);
  1.1014 +		break;
  1.1015 +	case EStartNotifier:
  1.1016 +		DoStartNotifierL(aMessage);
  1.1017 +		break;
  1.1018 +	case ECancelNotifier:
  1.1019 +		iServer->Manager()->NotifierCancel(TUid::Uid(aMessage.Int0()));
  1.1020 +		break;
  1.1021 +	case EUpdateNotifierAndGetResponse:
  1.1022 +	case EUpdateNotifier:
  1.1023 +		DoUpdateNotifierL(aMessage);
  1.1024 +		break;
  1.1025 +	case EStartNotifierAndGetResponse:
  1.1026 +		{
  1.1027 +		if (aMessage.Int0()==KMediaPasswordNotifyUid)
  1.1028 +			{
  1.1029 +			RunPasswordWindowL(aMessage);
  1.1030 +			}
  1.1031 +		else
  1.1032 +			{
  1.1033 +			TBool cleanupComplete=ETrue;
  1.1034 +			StartNotifierAndGetResponseL(aMessage,cleanupComplete);
  1.1035 +			 // if the plug-in starts successfully, it has
  1.1036 +			 // responsibility for completing the message (either
  1.1037 +			 // synchronously or asynchronously)
  1.1038 +			completeMessage=EFalse;
  1.1039 +			}
  1.1040 +		}
  1.1041 +		break;
  1.1042 +	default:
  1.1043 +		aMessage.Complete(KErrNotSupported);
  1.1044 +		break;
  1.1045 +		}
  1.1046 +	if (completeMessage && !aMessage.IsNull())
  1.1047 +		{
  1.1048 +		aMessage.Complete(KErrNone);
  1.1049 +		}
  1.1050 +	}
  1.1051 +
  1.1052 +void CNotifierSession::DisplayAlertL(const RMessage2& aMessage)
  1.1053 +	{
  1.1054 +	const TInt lengthOfCombinedBuffer=User::LeaveIfError(aMessage.GetDesLength(1));
  1.1055 +	const TInt lengthOfLine1=(STATIC_CAST(TUint,aMessage.Int2())>>16);
  1.1056 +	const TInt lengthOfLine2=(aMessage.Int2()&KMaxTUint16);
  1.1057 +	const TInt lengthOfBut1=(STATIC_CAST(TUint,aMessage.Int3())>>16);
  1.1058 +	const TInt lengthOfBut2=(aMessage.Int3()&KMaxTUint16);
  1.1059 +	if (lengthOfCombinedBuffer!=lengthOfLine1+lengthOfLine2+lengthOfBut1+lengthOfBut2)
  1.1060 +		{
  1.1061 +		PanicClient(aMessage,ENotifierPanicInconsistentDescriptorLengths);
  1.1062 +		return;
  1.1063 +		}
  1.1064 +	HBufC* const combinedBuffer=HBufC::NewLC(lengthOfCombinedBuffer);
  1.1065 +	{TPtr combinedBuffer_asWritable(combinedBuffer->Des());
  1.1066 +	aMessage.ReadL(1,combinedBuffer_asWritable);}
  1.1067 +	const TPtrC line1(combinedBuffer->Left(lengthOfLine1));
  1.1068 +	const TPtrC line2(combinedBuffer->Mid(lengthOfLine1,lengthOfLine2));
  1.1069 +	const TPtrC but1(combinedBuffer->Mid(lengthOfLine1+lengthOfLine2,lengthOfBut1));
  1.1070 +	const TPtrC but2(combinedBuffer->Mid(lengthOfLine1+lengthOfLine2+lengthOfBut1,lengthOfBut2));
  1.1071 +	TInt buttons, len, offset;
  1.1072 +	if (lengthOfBut2==0)
  1.1073 +		{
  1.1074 +		buttons=1;
  1.1075 +		len=lengthOfBut1+2;
  1.1076 +		}
  1.1077 +	else
  1.1078 +		{
  1.1079 +		buttons=2;
  1.1080 +		len=lengthOfBut1+lengthOfBut2+5;
  1.1081 +		}
  1.1082 +	if (lengthOfLine1>len)
  1.1083 +		len=lengthOfLine1;
  1.1084 +	if (lengthOfLine2>len)
  1.1085 +		len=lengthOfLine2;
  1.1086 +	RConsole con;
  1.1087 +	con.Create();
  1.1088 +	TSize scsz;
  1.1089 +	con.ScreenSize(scsz);
  1.1090 +	con.Control(_L("-Visible"));
  1.1091 +	TInt ww=Min(len,scsz.iWidth-4);
  1.1092 +	TInt wh=3;
  1.1093 +	if ((lengthOfBut1+lengthOfBut2+5)>ww)
  1.1094 +		wh++;
  1.1095 +	if (lengthOfLine1>ww)
  1.1096 +		wh++;
  1.1097 +	if (lengthOfLine2>ww)
  1.1098 +		wh++;
  1.1099 +	con.Init(_L(""),TSize(ww,wh));
  1.1100 +	con.Control(_L("+Max -Cursor -Allowresize +Ontop +Wrap"));
  1.1101 +	con.Write(line1);
  1.1102 +	con.SetCursorPosAbs(TPoint(0,1));
  1.1103 +	con.Write(line2);
  1.1104 +	if (buttons==2)
  1.1105 +		offset=(len-lengthOfBut1-lengthOfBut2-5)/2;
  1.1106 +	else
  1.1107 +		offset=(len-lengthOfBut1-2)/2;
  1.1108 +	con.SetCursorPosAbs(TPoint(offset,2));
  1.1109 +	con.Write(_L("<"));
  1.1110 +	con.Write(but1);
  1.1111 +	con.Write(_L(">"));
  1.1112 +	if(buttons==2)
  1.1113 +		{
  1.1114 +		con.Write(_L(" <"));
  1.1115 +		con.Write(but2);
  1.1116 +		con.Write(_L(">"));
  1.1117 +		}
  1.1118 +	
  1.1119 +	TConsoleKey key;
  1.1120 +	TInt keycode;
  1.1121 +	do
  1.1122 +		{
  1.1123 +		con.Read(key);
  1.1124 +		keycode=key.Code();
  1.1125 +		}
  1.1126 +	while((keycode!=EKeyEscape&&keycode!=EKeyEnter&&buttons==2)||(keycode!=EKeyEnter&&buttons==1));
  1.1127 +	if(keycode==EKeyEscape)
  1.1128 +		keycode=0;
  1.1129 +	else
  1.1130 +		keycode=1;
  1.1131 +	con.Destroy();
  1.1132 +	aMessage.WriteL(0,TPckgC<TInt>(keycode));
  1.1133 +	CleanupStack::PopAndDestroy(combinedBuffer);
  1.1134 +	}
  1.1135 +
  1.1136 +TInt CNotifierSession::InfoPrintThread(TAny* aMessage)
  1.1137 +	{
  1.1138 +	TBuf<0x50> des; // 0x50 max size of message
  1.1139 +	RConsole con;
  1.1140 +	des=*(TBuf<0x50> *)aMessage;
  1.1141 +	TInt l=des.Length();
  1.1142 +	NotifierSemaphore.Signal();
  1.1143 +	con.Create();
  1.1144 +	con.Control(_L("-Visible"));
  1.1145 +	TSize size;
  1.1146 +	con.ScreenSize(size);
  1.1147 +	TInt ww=Min(size.iWidth-6,l);
  1.1148 +	TInt wh=(l+ww-1)/ww;
  1.1149 +	if (wh==0)
  1.1150 +		wh=1;
  1.1151 +	con.Init(_L(""),TSize(ww,wh));
  1.1152 +	con.Control(_L("+Maximise"));
  1.1153 +	con.SetWindowPosAbs(TPoint(size.iWidth-ww-4,1));
  1.1154 +	con.Control(_L("+Wrap +Ontop"));
  1.1155 +	con.Write(des);
  1.1156 +
  1.1157 +	User::After(1300000);
  1.1158 +	con.Destroy();
  1.1159 +	return KErrNone;
  1.1160 +	}
  1.1161 +
  1.1162 +void CNotifierSession::DisplayInfoMsgL(const RMessage2& aMessage)
  1.1163 +	{
  1.1164 +	TInt r;
  1.1165 +	TBuf<0x50> des; // 0x50 max size of message lines
  1.1166 +	aMessage.ReadL(0,des);
  1.1167 +	RThread thread;
  1.1168 +	do
  1.1169 +		{
  1.1170 +		r=thread.Create(_L("Info Window"),InfoPrintThread,KDefaultStackSize,&User::Allocator(),(TAny*)&des);
  1.1171 +		if(r==KErrAlreadyExists)
  1.1172 +			User::After(200000);
  1.1173 +		} while(r==KErrAlreadyExists);
  1.1174 +		User::LeaveIfError(r);
  1.1175 +	thread.Resume();
  1.1176 +	NotifierSemaphore.Wait();
  1.1177 +	thread.Close();
  1.1178 +	}
  1.1179 +
  1.1180 +void CNotifierSession::DoStartNotifierL(const RMessage2& aMessage)
  1.1181 +	{
  1.1182 +	const TUid targetUid={aMessage.Int0()};
  1.1183 +	HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1)));
  1.1184 +	{TPtr8 input(inputBuffer->Des());
  1.1185 +	aMessage.ReadL(1,input);}
  1.1186 +	TPtrC8 output(0,0);
  1.1187 +	iServer->Manager()->NotifierStartL(targetUid,*inputBuffer,&output,iClientId);
  1.1188 +	if(aMessage.Int2())
  1.1189 +		aMessage.WriteL(2,output);
  1.1190 +	CleanupStack::PopAndDestroy(inputBuffer);
  1.1191 +	}
  1.1192 +
  1.1193 +void CNotifierSession::DoUpdateNotifierL(const RMessage2& aMessage)
  1.1194 +	{
  1.1195 +	const TUid targetUid={aMessage.Int0()};
  1.1196 +	HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1)));
  1.1197 +	{TPtr8 input(inputBuffer->Des());
  1.1198 +	aMessage.ReadL(1, input);}
  1.1199 +	HBufC8* const outputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesMaxLength(2)));
  1.1200 +	{TPtr8 output(outputBuffer->Des());
  1.1201 +	iServer->Manager()->NotifierUpdateL(targetUid,*inputBuffer,&output,iClientId);}
  1.1202 +	aMessage.WriteL(2,*outputBuffer);
  1.1203 +	CleanupStack::PopAndDestroy(2,inputBuffer);
  1.1204 +	}
  1.1205 +
  1.1206 +void CNotifierSession::StartNotifierAndGetResponseL(const RMessage2& aMessage,TBool& aCleanupComplete)
  1.1207 +	{
  1.1208 +	const TUid targetUid={aMessage.Int0()};
  1.1209 +	HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1)));
  1.1210 +	{TPtr8 input(inputBuffer->Des());
  1.1211 +	aMessage.ReadL(1,input);}
  1.1212 +	iServer->Manager()->NotifierStartAndGetResponseL(targetUid,*inputBuffer,2,aMessage,iClientId,aCleanupComplete);
  1.1213 +	CleanupStack::PopAndDestroy(inputBuffer);
  1.1214 +	}
  1.1215 +
  1.1216 +void CNotifierSession::PanicClient(const RMessage2& aMessage,TNotifierPanic aCode)
  1.1217 +	{
  1.1218 +	aMessage.Panic(__NOTIFIER_SERVER,aCode);
  1.1219 +	}
  1.1220 +
  1.1221 +//
  1.1222 +// class CNotifierManager
  1.1223 +//
  1.1224 +
  1.1225 +const TInt KNullClientId=0;
  1.1226 +
  1.1227 +CNotifierManager* CNotifierManager::NewL()
  1.1228 +	{
  1.1229 +	CNotifierManager* self=new(ELeave) CNotifierManager;
  1.1230 +	CleanupStack::PushL(self);
  1.1231 +	self->ConstructL();
  1.1232 +	CleanupStack::Pop(self);
  1.1233 +	return self;
  1.1234 +	}
  1.1235 +
  1.1236 +CNotifierManager::~CNotifierManager()
  1.1237 +	{
  1.1238 +	if (iObservedList)
  1.1239 +		{
  1.1240 +		const TInt count=iObservedList->Count();
  1.1241 +		for (TInt ii=0;ii<count;ii++)
  1.1242 +			{
  1.1243 +			(*iObservedList)[ii]->Release();
  1.1244 +			}
  1.1245 +		delete iObservedList;
  1.1246 +		}
  1.1247 +	if (iLibraries)
  1.1248 +		{
  1.1249 +		const TInt count=iLibraries->Count();
  1.1250 +		for (TInt ii=0;ii<count;ii++)
  1.1251 +			{
  1.1252 +			(*iLibraries)[ii].Close();
  1.1253 +			}
  1.1254 +		delete iLibraries;
  1.1255 +		}
  1.1256 +	delete iChannelMonitor;
  1.1257 +	delete iActivityMonitor;
  1.1258 +	delete iQueue;
  1.1259 +	}
  1.1260 +
  1.1261 +
  1.1262 +void CNotifierManager::RegisterL(RFs& aFs)
  1.1263 +	{
  1.1264 +#ifdef SUPPORT_OLD_PLUGIN_PATH
  1.1265 +	TBool old;
  1.1266 +	for(old=0; old<2; old++)
  1.1267 +	{
  1.1268 +#endif
  1.1269 +	TFindFile* findFile=new(ELeave) TFindFile(aFs);
  1.1270 +	CleanupStack::PushL(findFile);
  1.1271 +	TParse* fileNameParser=new(ELeave) TParse;
  1.1272 +	CleanupStack::PushL(fileNameParser);
  1.1273 +	CDir* directory=NULL;
  1.1274 +	TInt error;
  1.1275 +#ifdef SUPPORT_OLD_PLUGIN_PATH
  1.1276 +	_LIT(KNotifierPlugInOldSearchPath,"\\system\\tnotifiers\\");
  1.1277 +	if(old)
  1.1278 +		error=findFile->FindWildByDir(KNotifierPlugInExt, KNotifierPlugInOldSearchPath, directory);
  1.1279 +	else
  1.1280 +#endif
  1.1281 +	error=findFile->FindWildByDir(KNotifierPlugInExt, KNotifierPlugInSearchPath, directory);
  1.1282 +	for (; error!=KErrNotFound; error=findFile->FindWild(directory))
  1.1283 +		{
  1.1284 +		CleanupStack::PushL(directory);
  1.1285 +		User::LeaveIfError(error);
  1.1286 +		const TInt numberOfEntries=directory->Count();
  1.1287 +		for (TInt i=0; i<numberOfEntries; ++i)
  1.1288 +			{
  1.1289 +			const TEntry& entry=(*directory)[i];
  1.1290 +			fileNameParser->SetNoWild(entry.iName, &findFile->File(), NULL); // findFile->File() returns a reference rather than an object, therefore taking the address of it is fine
  1.1291 +
  1.1292 +			if (entry.iType[0].iUid==0x10000079)
  1.1293 +				{
  1.1294 +				 // It's a DLL
  1.1295 +				if( (entry.iType[1]==KUidTextNotifierPlugInV2))
  1.1296 +					{
  1.1297 +					// Its a notifier...
  1.1298 +					TPtrC path(fileNameParser->DriveAndPath());
  1.1299 +					TPtrC name(fileNameParser->NameAndExt());
  1.1300 +					DoAddPlugInL(path,name,entry.iType);
  1.1301 +					}
  1.1302 +				}
  1.1303 +			}
  1.1304 +		CleanupStack::PopAndDestroy(); // directory
  1.1305 +		directory=NULL;
  1.1306 +		}
  1.1307 +	delete directory;
  1.1308 +	CleanupStack::PopAndDestroy(2); // fileNameParser and findFile
  1.1309 +#ifdef SUPPORT_OLD_PLUGIN_PATH
  1.1310 +	}
  1.1311 +#endif
  1.1312 +	}
  1.1313 +
  1.1314 +LOCAL_C void DeleteTemp(TAny* aPtr)
  1.1315 +	{
  1.1316 +	CArrayPtr<MNotifierBase2>* array=REINTERPRET_CAST(CArrayPtr<MNotifierBase2>*,aPtr);
  1.1317 +	const TInt count=array->Count();
  1.1318 +	for (TInt ii=0;ii<count;ii++)
  1.1319 +		{
  1.1320 +		(*array)[ii]->Release();
  1.1321 +		}
  1.1322 +	delete array;
  1.1323 +	}
  1.1324 +
  1.1325 +
  1.1326 +
  1.1327 +void CNotifierManager::DoAddPlugInL(const TDesC& aPath,const TDesC& aFileName,const TUidType& aUidType)
  1.1328 +	{
  1.1329 +	RLibrary lib;
  1.1330 +	User::LeaveIfError(lib.Load(aFileName,aPath,aUidType));
  1.1331 +	CleanupClosePushL(lib);
  1.1332 +	iLibraries->AppendL(lib);
  1.1333 +	CleanupStack::Pop(); // lib
  1.1334 +	TLibraryFunction libEntry=lib.Lookup(1);
  1.1335 +	CArrayPtr<MNotifierBase2>* array=REINTERPRET_CAST(CArrayPtr<MNotifierBase2>*,(libEntry)());
  1.1336 +	User::LeaveIfNull(array);
  1.1337 +	CleanupStack::PushL(TCleanupItem(DeleteTemp,array));
  1.1338 +	while (array->Count()>0)
  1.1339 +		{
  1.1340 +		MNotifierBase2* notif=(*array)[0];
  1.1341 +			{
  1.1342 +			iObservedList->AppendL(notif);
  1.1343 +			array->Delete(0);
  1.1344 +			notif->SetManager(this);
  1.1345 +			}
  1.1346 +		MNotifierBase2::TNotifierInfo info=notif->RegisterL();
  1.1347 +		if (!iChannelMonitor->AlreadyHasChannel(info.iChannel))
  1.1348 +			iChannelMonitor->AddNewChannelL(info.iChannel);
  1.1349 +		}
  1.1350 +	CleanupStack::PopAndDestroy(); // array
  1.1351 +	}
  1.1352 +
  1.1353 +CNotifierManager::CNotifierManager()
  1.1354 +	{}
  1.1355 +
  1.1356 +void CNotifierManager::ConstructL()
  1.1357 +	{
  1.1358 +	iObservedList=new(ELeave) CArrayPtrSeg<MNotifierBase2>(6);
  1.1359 +	iLibraries=new(ELeave) CArrayFixFlat<RLibrary>(2);
  1.1360 +	iChannelMonitor=CChannelMonitor::NewL();
  1.1361 +	iActivityMonitor=CActivityMonitor::NewL();
  1.1362 +	iQueue=CNotifierQueue::NewL();
  1.1363 +	}
  1.1364 +
  1.1365 +struct SActivityCleanup
  1.1366 +	{
  1.1367 +	CActivityMonitor* iMonitor;
  1.1368 +	TUid iNotifier;
  1.1369 +	TInt iClientId;
  1.1370 +	};
  1.1371 +
  1.1372 +LOCAL_C void CleanupActivityMonitor(TAny* aPtr)
  1.1373 +	{
  1.1374 +	SActivityCleanup& cleanup=*REINTERPRET_CAST(SActivityCleanup*,aPtr);
  1.1375 +	cleanup.iMonitor->Remove(cleanup.iNotifier,cleanup.iClientId);
  1.1376 +	}
  1.1377 +
  1.1378 +void CNotifierManager::NotifierStartL(TUid aNotifierUid,const TDesC8& aBuffer,TPtrC8* aResponse,TInt aClientId)
  1.1379 +	{
  1.1380 +	TInt result=KErrNotFound;
  1.1381 +	const TInt count=iObservedList->Count();
  1.1382 +	for (TInt ii=0;ii<count;ii++)
  1.1383 +		{
  1.1384 +		MNotifierBase2* notif=(*iObservedList)[ii];
  1.1385 +		MNotifierBase2::TNotifierInfo info=notif->Info();
  1.1386 +		if (info.iUid==aNotifierUid)
  1.1387 +			{
  1.1388 +			if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel))
  1.1389 +				{
  1.1390 +				result=KErrAlreadyExists;
  1.1391 +				}
  1.1392 +			else if (info.iPriority>iChannelMonitor->ActivityLevel(info.iChannel))
  1.1393 +				{
  1.1394 +				TUid notifier;
  1.1395 +				MNotifierBase2::TNotifierPriority priority;
  1.1396 +				const TBool channelWasActive=iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority);
  1.1397 +				iActivityMonitor->AddL(info,aClientId);
  1.1398 +				SActivityCleanup cleanup;
  1.1399 +				cleanup.iMonitor=iActivityMonitor;
  1.1400 +				cleanup.iNotifier=aNotifierUid;
  1.1401 +				cleanup.iClientId=aClientId;
  1.1402 +				CleanupStack::PushL(TCleanupItem(CleanupActivityMonitor,&cleanup));
  1.1403 +				TPtrC8 response(notif->StartL(aBuffer));
  1.1404 +				if(aResponse)
  1.1405 +					aResponse->Set(response);
  1.1406 +				CleanupStack::Pop(); // cleanup;
  1.1407 +				if (channelWasActive)
  1.1408 +					{
  1.1409 +					for (TInt jj=0;jj<count;jj++)
  1.1410 +						{
  1.1411 +						MNotifierBase2* notifForUpdate=(*iObservedList)[ii];
  1.1412 +						MNotifierBase2::TNotifierInfo infoForUpdate=notifForUpdate->Info();
  1.1413 +						if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel)
  1.1414 +							{
  1.1415 +							TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused));
  1.1416 +							}
  1.1417 +						}
  1.1418 +					}
  1.1419 +				iChannelMonitor->UpdateChannel(info.iChannel,info.iPriority);
  1.1420 +				if (result!=ENotExtRequestQueued)
  1.1421 +					{
  1.1422 +					result=ENotExtRequestCompleted;
  1.1423 +					}
  1.1424 +				}
  1.1425 +			else
  1.1426 +				{
  1.1427 +				if (iQueue->IsAlreadyQueued(info.iUid,info.iChannel))
  1.1428 +					{
  1.1429 +					result=KErrAlreadyExists;
  1.1430 +					}
  1.1431 +				else
  1.1432 +					{
  1.1433 +					CQueueItem* queueCopy=CQueueItem::NewL(info,aBuffer,aClientId);
  1.1434 +					CleanupStack::PushL(queueCopy);
  1.1435 +					iQueue->QueueItemL(queueCopy);
  1.1436 +					CleanupStack::Pop(); // queueCopy
  1.1437 +					result=ENotExtRequestQueued;
  1.1438 +					}
  1.1439 +				}
  1.1440 +			}
  1.1441 +		}
  1.1442 +	User::LeaveIfError(result);
  1.1443 +	}
  1.1444 +
  1.1445 +TInt CNotifierManager::NotifierUpdateL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8* aResponse,TInt aClientId)
  1.1446 +	{
  1.1447 +	TInt result=KErrNotFound;
  1.1448 +	const TInt count=iObservedList->Count();
  1.1449 +	for (TInt ii=0;ii<count;ii++)
  1.1450 +		{
  1.1451 +		MNotifierBase2* notif=(*iObservedList)[ii];
  1.1452 +		MNotifierBase2::TNotifierInfo info=notif->Info();
  1.1453 +		if (info.iUid==aNotifierUid)
  1.1454 +			{
  1.1455 +			if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel))
  1.1456 +				{
  1.1457 +				if (!iActivityMonitor->IsClientPresent(aNotifierUid,info.iChannel,aClientId))
  1.1458 +					{
  1.1459 +					iActivityMonitor->AddL(info,aClientId);
  1.1460 +					}
  1.1461 +				if (aResponse==NULL)
  1.1462 +					{
  1.1463 +					notif->UpdateL(aBuffer);
  1.1464 +					}
  1.1465 +				else
  1.1466 +					{
  1.1467 +					aResponse->Copy(notif->UpdateL(aBuffer));
  1.1468 +					}
  1.1469 +				}
  1.1470 +			else
  1.1471 +				{
  1.1472 +				; // not all channels have been started yet so update the queue
  1.1473 +				}
  1.1474 +			result=KErrNone;
  1.1475 +			}
  1.1476 +		}
  1.1477 +	return result;
  1.1478 +	}
  1.1479 +
  1.1480 +void CNotifierManager::NotifierStartAndGetResponseL(TUid aNotifierUid,const TDesC8& aBuffer,TInt aReplySlot,
  1.1481 +														  const RMessage2& aMessage,TInt aClientId,TBool& aCleanupComplete)
  1.1482 +	{
  1.1483 +	NotifierStartAndGetResponseL(aNotifierUid,TUid::Null(),aBuffer,aReplySlot,aMessage,aClientId,aCleanupComplete);
  1.1484 +	}
  1.1485 +
  1.1486 +void CNotifierManager::NotifierStartAndGetResponseL(TUid aNotifierUid,TUid aChannelUid,const TDesC8& aBuffer,TInt aReplySlot,
  1.1487 +														  const RMessage2& aMessage,TInt aClientId,TBool& aCleanupComplete)
  1.1488 +	{
  1.1489 +	TInt result=KErrNotFound;
  1.1490 +	const TInt count=iObservedList->Count();
  1.1491 +	for (TInt ii=0;ii<count;ii++)
  1.1492 +		{
  1.1493 +		MNotifierBase2* notif=(*iObservedList)[ii];
  1.1494 +		MNotifierBase2::TNotifierInfo info=notif->Info();
  1.1495 +		if (info.iUid==aNotifierUid && (aChannelUid==TUid::Null() || info.iChannel==aChannelUid))
  1.1496 +			{
  1.1497 +			if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel))
  1.1498 +				{
  1.1499 +				notif->StartL(aBuffer,aReplySlot,aMessage); // asynch notifier can decide whether to support multiple clients
  1.1500 +				result=KErrNone;
  1.1501 +				}
  1.1502 +			else if (info.iPriority>iChannelMonitor->ActivityLevel(info.iChannel))
  1.1503 +				{
  1.1504 +				TUid notifier;
  1.1505 +				MNotifierBase2::TNotifierPriority priority;
  1.1506 +				const TBool channelWasActive=iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority);
  1.1507 +				iActivityMonitor->AddL(info,aClientId);
  1.1508 +				SActivityCleanup activityCleanup;
  1.1509 +				activityCleanup.iMonitor=iActivityMonitor;
  1.1510 +				activityCleanup.iNotifier=aNotifierUid;
  1.1511 +				activityCleanup.iClientId=aClientId;
  1.1512 +				CleanupStack::PushL(TCleanupItem(CleanupActivityMonitor,&activityCleanup));
  1.1513 +				aCleanupComplete=EFalse;
  1.1514 +				// IMPORTANT, aMessage needs to be a full RMessage object until suport for V1 notifiers is removed
  1.1515 +				// I.e. until CNotifierBaseAdaptor is removed
  1.1516 +				notif->StartL(aBuffer,aReplySlot,aMessage);
  1.1517 +				CleanupStack::Pop(&activityCleanup);
  1.1518 +				if (channelWasActive)
  1.1519 +					{
  1.1520 +					for (TInt jj=0;jj<count;jj++)
  1.1521 +						{
  1.1522 +						MNotifierBase2* notifForUpdate=(*iObservedList)[ii];
  1.1523 +						MNotifierBase2::TNotifierInfo infoForUpdate=notifForUpdate->Info();
  1.1524 +						if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel)
  1.1525 +							{
  1.1526 +							TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused));
  1.1527 +							}
  1.1528 +						}
  1.1529 +					}
  1.1530 +				iChannelMonitor->UpdateChannel(info.iChannel,info.iPriority);
  1.1531 +				result=KErrNone;
  1.1532 +				}
  1.1533 +			else
  1.1534 +				{
  1.1535 +				if (iQueue->IsAlreadyQueued(info.iUid,info.iChannel))
  1.1536 +					{
  1.1537 +					result=KErrAlreadyExists;
  1.1538 +					}
  1.1539 +				else
  1.1540 +					{
  1.1541 +					CQueueItem* queueCopy=CQueueItem::NewL(info,aBuffer,aReplySlot,aMessage,aClientId);
  1.1542 +					CleanupStack::PushL(queueCopy);
  1.1543 +					iQueue->QueueItemL(queueCopy);
  1.1544 +					CleanupStack::Pop(queueCopy);
  1.1545 +					result=ENotExtRequestQueued;
  1.1546 +					}
  1.1547 +				}
  1.1548 +			}
  1.1549 +		}
  1.1550 +	User::LeaveIfError(result);
  1.1551 +	}
  1.1552 +
  1.1553 +TInt CNotifierManager::NotifierCancel(TUid aNotifierUid)
  1.1554 +	{
  1.1555 +	TInt result=KErrNotFound;
  1.1556 +	const TInt count=iObservedList->Count();
  1.1557 +	for (TInt ii=0;ii<count;ii++)
  1.1558 +		{
  1.1559 +		MNotifierBase2* notif=(*iObservedList)[ii];
  1.1560 +		MNotifierBase2::TNotifierInfo info=notif->Info();
  1.1561 +		if (info.iUid==aNotifierUid)
  1.1562 +			{
  1.1563 +			notif->Cancel();
  1.1564 +			iActivityMonitor->RemoveNotifier(aNotifierUid,info.iChannel);
  1.1565 +			MNotifierBase2::TNotifierPriority priority=MNotifierBase2::ENotifierPriorityLowest;
  1.1566 +			TUid notifier;
  1.1567 +			//check channel activity and get highest priority on channnel
  1.1568 +			if (iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority))
  1.1569 +				{
  1.1570 +
  1.1571 +				//check if priority of a queued item on the same channel is
  1.1572 +				//greater 
  1.1573 +				MNotifierBase2::TNotifierPriority queuePriority=
  1.1574 +				(MNotifierBase2::TNotifierPriority)iQueue->GetHighestQueuePriority(info.iChannel);
  1.1575 +				if (queuePriority>priority)
  1.1576 +					{
  1.1577 +					iChannelMonitor->UpdateChannel(info.iChannel,MNotifierBase2::ENotifierPriorityLowest);
  1.1578 +					CQueueItem* next=iQueue->FetchItem(info.iChannel);
  1.1579 +					if (next)
  1.1580 +						{
  1.1581 +						TUid notif=next->iInfo.iUid;
  1.1582 +						TRAPD(err,StartFromQueueL(next));
  1.1583 +						if (err!=KErrNone)
  1.1584 +							{
  1.1585 +							NotifierCancel(notif);
  1.1586 +							}
  1.1587 +						}
  1.1588 +					 }
  1.1589 +					else
  1.1590 +					{
  1.1591 +					for (TInt jj=0;jj<count;jj++)
  1.1592 +						{
  1.1593 +						MNotifierBase2* notifForUpdate=(*iObservedList)[ii];
  1.1594 +						MNotifierBase2::TNotifierInfo infoForUpdate=notifForUpdate->Info();
  1.1595 +						if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel)
  1.1596 +							{
  1.1597 +							TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused));
  1.1598 +							}
  1.1599 +						}
  1.1600 +					iChannelMonitor->UpdateChannel(info.iChannel,priority);
  1.1601 +					}
  1.1602 +				}
  1.1603 +			else
  1.1604 +				{
  1.1605 +				iChannelMonitor->UpdateChannel(info.iChannel,MNotifierBase2::ENotifierPriorityLowest);
  1.1606 +				CQueueItem* next=iQueue->FetchItem(info.iChannel);
  1.1607 +				if (next)
  1.1608 +					{
  1.1609 +					TUid notif=next->iInfo.iUid;
  1.1610 +					TRAPD(err,StartFromQueueL(next));
  1.1611 +					if (err!=KErrNone)
  1.1612 +						{
  1.1613 +						NotifierCancel(notif);
  1.1614 +						}
  1.1615 +					}
  1.1616 +				}
  1.1617 +			result=KErrNone;
  1.1618 +			}
  1.1619 +		}
  1.1620 +	return result;
  1.1621 +	}
  1.1622 +
  1.1623 +struct SCleanupMessage
  1.1624 +	{
  1.1625 +	TBool* iDoCleanup;
  1.1626 +	RMessage2* iMessage;
  1.1627 +	};
  1.1628 +
  1.1629 +LOCAL_C void CleanupStartAndGetResponse(TAny* aPtr)
  1.1630 +	{
  1.1631 +	SCleanupMessage& cleanup=*REINTERPRET_CAST(SCleanupMessage*,aPtr);
  1.1632 +	if (cleanup.iDoCleanup)
  1.1633 +		{
  1.1634 +		cleanup.iMessage->Complete(KErrNoMemory);
  1.1635 +		}
  1.1636 +	}
  1.1637 +
  1.1638 +void CNotifierManager::StartFromQueueL(CQueueItem* aItem)
  1.1639 +	{
  1.1640 +	CleanupStack::PushL(aItem);
  1.1641 +	TPtr8 buffer=aItem->iBuffer->Des();
  1.1642 +	if (aItem->iAsynchronous)
  1.1643 +		{
  1.1644 +		SCleanupMessage cleanup;
  1.1645 +		TBool doCleanup=ETrue;
  1.1646 +		cleanup.iDoCleanup=&doCleanup;
  1.1647 +		cleanup.iMessage=&aItem->iMessage;
  1.1648 +		CleanupStack::PushL(TCleanupItem(CleanupStartAndGetResponse,&cleanup));
  1.1649 +		// IMPORTANT, aItem->iMessage needs to be a full RMessage object until suport for V1 notifiers is removed
  1.1650 +		// I.e. until CNotifierBaseAdaptor is removed
  1.1651 +		NotifierStartAndGetResponseL(aItem->iInfo.iUid,aItem->iInfo.iChannel,buffer,aItem->iReplySlot,aItem->iMessage,aItem->iClientId,doCleanup);
  1.1652 +		CleanupStack::Pop(&cleanup);
  1.1653 +		}
  1.1654 +	else
  1.1655 +		{
  1.1656 +		NotifierStartL(aItem->iInfo.iUid,buffer,NULL,aItem->iClientId);
  1.1657 +		}
  1.1658 +	CleanupStack::PopAndDestroy(); // aItem
  1.1659 +	CQueueItem* update=iQueue->FetchItem(aItem->iInfo.iChannel);
  1.1660 +	while (update)
  1.1661 +		{
  1.1662 +		CleanupStack::PushL(update);
  1.1663 +		NotifierUpdateL(update->iInfo.iUid,*update->iBuffer,NULL,update->iClientId);
  1.1664 +		CleanupStack::PopAndDestroy(); // update
  1.1665 +		update=iQueue->FetchItem(aItem->iInfo.iChannel);
  1.1666 +		}
  1.1667 +	}
  1.1668 +
  1.1669 +void CNotifierManager::HandleClientExit(TInt aClientId)
  1.1670 +	{
  1.1671 +	TUid notifier=KNullUid;
  1.1672 +	while (iActivityMonitor->NotifierForClient(notifier,aClientId))
  1.1673 +		{
  1.1674 +		const TInt count=iObservedList->Count();
  1.1675 +		for (TInt ii=0;ii<count;ii++)
  1.1676 +			{
  1.1677 +			MNotifierBase2* notif=(*iObservedList)[ii];
  1.1678 +			if (notif->Info().iUid==notifier)
  1.1679 +				{
  1.1680 +				NotifierCancel(notifier);
  1.1681 +				}
  1.1682 +			}
  1.1683 +		iActivityMonitor->Remove(notifier,aClientId);
  1.1684 +		}
  1.1685 +	iActivityMonitor->RemoveClient(aClientId);
  1.1686 +	iQueue->RemoveClient(aClientId);
  1.1687 +	}
  1.1688 +
  1.1689 +void CNotifierManager::StartNotifierL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
  1.1690 +	{
  1.1691 +	TPtrC8 response(0,0);
  1.1692 +	NotifierStartL(aNotifierUid,aBuffer, &response,KNullClientId);
  1.1693 +	aResponse.Copy(response);
  1.1694 +	}
  1.1695 +
  1.1696 +void CNotifierManager::CancelNotifier(TUid aNotifierUid)
  1.1697 +	{
  1.1698 +	NotifierCancel(aNotifierUid);
  1.1699 +	}
  1.1700 +
  1.1701 +void CNotifierManager::UpdateNotifierL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
  1.1702 +	{
  1.1703 +	NotifierUpdateL(aNotifierUid,aBuffer,&aResponse,KNullClientId);
  1.1704 +	}
  1.1705 +
  1.1706 +//
  1.1707 +// class CChannelMonitor
  1.1708 +//
  1.1709 +
  1.1710 +CChannelMonitor* CChannelMonitor::NewL()
  1.1711 +	{
  1.1712 +	CChannelMonitor* self=new(ELeave) CChannelMonitor;
  1.1713 +	return self;
  1.1714 +	}
  1.1715 +
  1.1716 +TBool CChannelMonitor::AlreadyHasChannel(TUid aChannel)const
  1.1717 +	{
  1.1718 +	const TInt count=iMonitor.Count();
  1.1719 +	for (TInt ii=0;ii<count;ii++)
  1.1720 +		{
  1.1721 +		if (iMonitor[ii].iChannel==aChannel)
  1.1722 +			return ETrue;
  1.1723 +		}
  1.1724 +	return EFalse;
  1.1725 +	}
  1.1726 +
  1.1727 +TInt CChannelMonitor::ActivityLevel(TUid aChannel) const
  1.1728 +	{
  1.1729 +	const TInt count=iMonitor.Count();
  1.1730 +	for (TInt ii=0;ii<count;ii++)
  1.1731 +		{
  1.1732 +		TChannelActivity activity=iMonitor[ii];
  1.1733 +		if (activity.iChannel==aChannel)
  1.1734 +			return activity.iHighestPriorityRunning;
  1.1735 +		}
  1.1736 +	return 0;
  1.1737 +	}
  1.1738 +
  1.1739 +void CChannelMonitor::UpdateChannel(TUid aChannel,TInt aLevel)
  1.1740 +	{
  1.1741 +	const TInt count=iMonitor.Count();
  1.1742 +	for (TInt ii=0;ii<count;ii++)
  1.1743 +		{
  1.1744 +		TChannelActivity& activity=iMonitor[ii];
  1.1745 +		if (activity.iChannel==aChannel)
  1.1746 +			{
  1.1747 +			activity.iHighestPriorityRunning=aLevel;
  1.1748 +			break;
  1.1749 +			}
  1.1750 +		}
  1.1751 +	}
  1.1752 +
  1.1753 +CChannelMonitor::CChannelMonitor()
  1.1754 +	:iMonitor(3)
  1.1755 +	{}
  1.1756 +
  1.1757 +//
  1.1758 +// class CNotifierActivity
  1.1759 +//
  1.1760 +
  1.1761 +CNotifierActivity* CNotifierActivity::NewLC(const MNotifierBase2::TNotifierInfo& aInfo,TInt aClientId)
  1.1762 +	{ // static
  1.1763 +	CNotifierActivity* self=new(ELeave) CNotifierActivity(aInfo);
  1.1764 +	CleanupStack::PushL(self);
  1.1765 +	self->ConstructL(aClientId);
  1.1766 +	return self;
  1.1767 +	}
  1.1768 +
  1.1769 +CNotifierActivity::~CNotifierActivity()
  1.1770 +	{
  1.1771 +	iClientArray.Reset();
  1.1772 +	}
  1.1773 +
  1.1774 +TInt CNotifierActivity::Find(TInt aClientId) const
  1.1775 +	{
  1.1776 +	TInt index=KErrNotFound;
  1.1777 +	const TInt count=iClientArray.Count();
  1.1778 +	for (TInt ii=0;ii<count;ii++)
  1.1779 +		{
  1.1780 +		TInt clientId=iClientArray[ii];
  1.1781 +		if (clientId==aClientId)
  1.1782 +			{
  1.1783 +			index=ii;
  1.1784 +			break;
  1.1785 +			}
  1.1786 +		}
  1.1787 +	return index;
  1.1788 +	}
  1.1789 +
  1.1790 +CNotifierActivity::CNotifierActivity(const MNotifierBase2::TNotifierInfo& aInfo)
  1.1791 +	: iInfo(aInfo), iClientArray(1)
  1.1792 +	{}
  1.1793 +
  1.1794 +void CNotifierActivity::ConstructL(TInt aClientId)
  1.1795 +	{
  1.1796 +	iClientArray.AppendL(aClientId);
  1.1797 +	}
  1.1798 +
  1.1799 +//
  1.1800 +// class CActivityMonitor
  1.1801 +//
  1.1802 +
  1.1803 +CActivityMonitor* CActivityMonitor::NewL()
  1.1804 +	{ // static
  1.1805 +	CActivityMonitor* self=new(ELeave) CActivityMonitor();
  1.1806 +	return self;
  1.1807 +	}
  1.1808 +
  1.1809 +CActivityMonitor::~CActivityMonitor()
  1.1810 +	{
  1.1811 +	iMonitor.ResetAndDestroy();
  1.1812 +	}
  1.1813 +
  1.1814 +void CActivityMonitor::AddL(const MNotifierBase2::TNotifierInfo& aInfo,TInt aClientId)
  1.1815 +	{
  1.1816 +	const TInt index=Find(aInfo.iUid,aInfo.iChannel);
  1.1817 +	if (index==KErrNotFound)
  1.1818 +		{
  1.1819 +		CNotifierActivity* activity=CNotifierActivity::NewLC(aInfo,aClientId);
  1.1820 +		iMonitor.AppendL(activity);
  1.1821 +		CleanupStack::Pop(); // activity
  1.1822 +		}
  1.1823 +	else
  1.1824 +		{
  1.1825 +		iMonitor[index]->iClientArray.AppendL(aClientId);
  1.1826 +		}
  1.1827 +	}
  1.1828 +
  1.1829 +void CActivityMonitor::Remove(TUid aNotifierUid,TInt aClientId)
  1.1830 +	{
  1.1831 +	const TInt index=Find(aNotifierUid);
  1.1832 +	if (index!=KErrNotFound)
  1.1833 +		{
  1.1834 +		CNotifierActivity* activity=iMonitor[index];
  1.1835 +		const TInt clientIndex=activity->Find(aClientId);
  1.1836 +		if (clientIndex!=KErrNotFound)
  1.1837 +			{
  1.1838 +			if (activity->iClientArray.Count()==1)
  1.1839 +				{
  1.1840 +				delete activity;
  1.1841 +				iMonitor.Delete(index);
  1.1842 +				}
  1.1843 +			else
  1.1844 +				{
  1.1845 +				activity->iClientArray.Delete(index);
  1.1846 +				}
  1.1847 +			}
  1.1848 +		}
  1.1849 +	}
  1.1850 +
  1.1851 +void CActivityMonitor::RemoveNotifier(TUid aNotifierUid,TUid aChannel)
  1.1852 +	{
  1.1853 +	const TInt index=Find(aNotifierUid,aChannel);
  1.1854 +	if (index!=KErrNotFound)
  1.1855 +		{
  1.1856 +		delete iMonitor[index];
  1.1857 +		iMonitor.Delete(index);
  1.1858 +		}
  1.1859 +	}
  1.1860 +
  1.1861 +void CActivityMonitor::RemoveClient(TInt aClientId)
  1.1862 +	{
  1.1863 +	TInt ii=0;
  1.1864 +	while (ii<iMonitor.Count())
  1.1865 +		{
  1.1866 +		CNotifierActivity* ptr=iMonitor[ii];
  1.1867 +		TInt index=ptr->Find(aClientId);
  1.1868 +		if (index!=KErrNotFound)
  1.1869 +			{
  1.1870 +			ptr->iClientArray.Delete(index);
  1.1871 +			}
  1.1872 +		if (ptr->iClientArray.Count()==0)
  1.1873 +			{
  1.1874 +			iMonitor.Delete(ii);
  1.1875 +			}
  1.1876 +		else
  1.1877 +			{
  1.1878 +			++ii;
  1.1879 +			}
  1.1880 +		}
  1.1881 +	}
  1.1882 +
  1.1883 +TBool CActivityMonitor::IsNotifierActive(TUid aNotifierUid,TUid aChannel) const
  1.1884 +	{
  1.1885 +	const TInt index=Find(aNotifierUid,aChannel);
  1.1886 +	return (index!=KErrNotFound);
  1.1887 +	}
  1.1888 +
  1.1889 +TBool CActivityMonitor::IsClientPresent(TUid aNotifierUid,TUid aChannel,TInt aClientId) const
  1.1890 +	{
  1.1891 +	TBool found=EFalse;
  1.1892 +	const TInt index=Find(aNotifierUid,aChannel);
  1.1893 +	if (index!=KErrNotFound)
  1.1894 +		{
  1.1895 +		found=(iMonitor[index]->Find(aClientId)!=KErrNotFound);
  1.1896 +		}
  1.1897 +	return found;
  1.1898 +	}
  1.1899 +
  1.1900 +TBool CActivityMonitor::IsChannelActive(TUid aChannel,TUid& aNotifier,MNotifierBase2::TNotifierPriority& aHighestPriority) const
  1.1901 +	{
  1.1902 +	TBool ret=EFalse;
  1.1903 +	const TInt count=iMonitor.Count();
  1.1904 +	for (TInt ii=0;ii<count;ii++)
  1.1905 +		{
  1.1906 +		MNotifierBase2::TNotifierInfo info=iMonitor[ii]->iInfo;
  1.1907 +		if (info.iChannel==aChannel)
  1.1908 +			{
  1.1909 +			ret=ETrue;
  1.1910 +			if ((MNotifierBase2::TNotifierPriority)info.iPriority>aHighestPriority)
  1.1911 +				{
  1.1912 +				aNotifier=info.iUid;
  1.1913 +				aHighestPriority=(MNotifierBase2::TNotifierPriority)info.iPriority;
  1.1914 +				}
  1.1915 +			}
  1.1916 +		}
  1.1917 +	return ret;
  1.1918 +	}
  1.1919 +
  1.1920 +TBool CActivityMonitor::NotifierForClient(TUid& aNotifierUid,TInt aClientId) const
  1.1921 +	{
  1.1922 +	TBool isOnlyClient=EFalse;
  1.1923 +	aNotifierUid=KNullUid;
  1.1924 +	const TInt count=iMonitor.Count();
  1.1925 +	for (TInt ii=0;ii<count;ii++)
  1.1926 +		{
  1.1927 +		CNotifierActivity* ptr=iMonitor[ii];
  1.1928 +		if (ptr->Find(aClientId)!=KErrNotFound)
  1.1929 +			{
  1.1930 +			aNotifierUid=ptr->iInfo.iUid;
  1.1931 +			isOnlyClient=ptr->iClientArray.Count()==1;
  1.1932 +			break;
  1.1933 +			}
  1.1934 +		}
  1.1935 +	return isOnlyClient;
  1.1936 +	}
  1.1937 +
  1.1938 +CActivityMonitor::CActivityMonitor()
  1.1939 +	: iMonitor(1)
  1.1940 +	{}
  1.1941 +
  1.1942 +TInt CActivityMonitor::Find(TUid aNotifierUid) const
  1.1943 +	{
  1.1944 +	TInt index=KErrNotFound;
  1.1945 +	const TInt count=iMonitor.Count();
  1.1946 +	for (TInt ii=0;ii<count;ii++)
  1.1947 +		{
  1.1948 +		if (iMonitor[ii]->iInfo.iUid==aNotifierUid)
  1.1949 +			{
  1.1950 +			index=ii;
  1.1951 +			break;
  1.1952 +			}
  1.1953 +		}
  1.1954 +	return index;
  1.1955 +	}
  1.1956 +
  1.1957 +TInt CActivityMonitor::Find(TUid aNotifierUid,TUid aChannel) const
  1.1958 +	{
  1.1959 +	TInt index=KErrNotFound;
  1.1960 +	const TInt count=iMonitor.Count();
  1.1961 +	for (TInt ii=0;ii<count;ii++)
  1.1962 +		{
  1.1963 +		CNotifierActivity* ptr=iMonitor[ii];
  1.1964 +		if (ptr->iInfo.iUid==aNotifierUid && ptr->iInfo.iChannel==aChannel)
  1.1965 +			{
  1.1966 +			index=ii;
  1.1967 +			break;
  1.1968 +			}
  1.1969 +		}
  1.1970 +	return index;
  1.1971 +	}
  1.1972 +
  1.1973 +//
  1.1974 +// class CQueueItem
  1.1975 +//
  1.1976 +
  1.1977 +CQueueItem* CQueueItem::NewL(const MNotifierBase2::TNotifierInfo& aInfo,const TDesC8& aBuffer,
  1.1978 +									TInt aReplySlot,const RMessage2& aMessage,TInt aClientId) //Asynchronous
  1.1979 +	{
  1.1980 +	CQueueItem* self=new(ELeave) CQueueItem(aInfo);
  1.1981 +	CleanupStack::PushL(self);
  1.1982 +	self->ConstructL(aBuffer,aMessage,aClientId,aReplySlot);
  1.1983 +	CleanupStack::Pop(); // self
  1.1984 +	return self;
  1.1985 +	}
  1.1986 +
  1.1987 +CQueueItem* CQueueItem::NewL(const MNotifierBase2::TNotifierInfo& aInfo,const TDesC8& aBuffer,TInt aClientId) //synchronous
  1.1988 +	{
  1.1989 +	CQueueItem* self=new(ELeave) CQueueItem(aInfo);
  1.1990 +	CleanupStack::PushL(self);
  1.1991 +	self->ConstructL(aBuffer,aClientId);
  1.1992 +	CleanupStack::Pop(); // self
  1.1993 +	return self;
  1.1994 +	}
  1.1995 +
  1.1996 +CQueueItem::~CQueueItem()
  1.1997 +	{
  1.1998 +	delete iBuffer;
  1.1999 +	}
  1.2000 +
  1.2001 +CQueueItem::CQueueItem(const MNotifierBase2::TNotifierInfo& aInfo)
  1.2002 +	: iInfo(aInfo)
  1.2003 +	{}
  1.2004 +
  1.2005 +void CQueueItem::ConstructL(const TDesC8& aBuffer,TInt aClientId)
  1.2006 +	{
  1.2007 +	iBuffer=aBuffer.AllocL();
  1.2008 +	iClientId=aClientId;
  1.2009 +	iAsynchronous=EFalse;
  1.2010 +	}
  1.2011 +
  1.2012 +void CQueueItem::ConstructL(const TDesC8& aBuffer,const RMessage2& aMessage,TInt aClientId,TInt aReplySlot)
  1.2013 +	{
  1.2014 +	iBuffer=aBuffer.AllocL();
  1.2015 +	iAsynchronous=ETrue;
  1.2016 +	iMessage=aMessage;
  1.2017 +	iClientId=aClientId;
  1.2018 +	iReplySlot=aReplySlot;
  1.2019 +	}
  1.2020 +
  1.2021 +//
  1.2022 +// class CNotifierQueue
  1.2023 +//
  1.2024 +
  1.2025 +CNotifierQueue* CNotifierQueue::NewL()
  1.2026 +	{
  1.2027 +	CNotifierQueue* self=new(ELeave) CNotifierQueue;
  1.2028 +	return self;
  1.2029 +	}
  1.2030 +
  1.2031 +CQueueItem* CNotifierQueue::FetchItem(TUid aChannel)
  1.2032 +	{
  1.2033 +	CQueueItem* result=NULL;
  1.2034 +	const TInt count=iQueue.Count();
  1.2035 +	TInt priority=MNotifierBase2::ENotifierPriorityLowest-1;
  1.2036 +	TInt index=KErrNotFound;
  1.2037 +	for (TInt ii=0;ii<count;ii++)
  1.2038 +		{
  1.2039 +		CQueueItem* item=iQueue[ii];
  1.2040 +		if (item->iInfo.iChannel==aChannel && item->iInfo.iPriority>priority)
  1.2041 +			{
  1.2042 +			index=ii;
  1.2043 +			priority=item->iInfo.iPriority;
  1.2044 +			result=item;
  1.2045 +			}
  1.2046 +		}
  1.2047 +	if (index!=KErrNotFound)
  1.2048 +		{
  1.2049 +		iQueue.Delete(index);
  1.2050 +		}
  1.2051 +	return result;
  1.2052 +	}
  1.2053 +
  1.2054 +TBool CNotifierQueue::IsAlreadyQueued(TUid aNotifier,TUid aChannel) const
  1.2055 +	{
  1.2056 +	TBool ret=EFalse;
  1.2057 +	const TInt count=iQueue.Count();
  1.2058 +	for (TInt ii=0;ii<count;ii++)
  1.2059 +		{
  1.2060 +		CQueueItem* item=iQueue[ii];
  1.2061 +		if (item->iInfo.iUid==aNotifier && item->iInfo.iChannel==aChannel)
  1.2062 +			{
  1.2063 +			ret=ETrue;
  1.2064 +			break;
  1.2065 +			}
  1.2066 +		}
  1.2067 +	return ret;
  1.2068 +	}
  1.2069 +
  1.2070 +void CNotifierQueue::RemoveClient(TInt aClientId)
  1.2071 +	{
  1.2072 +	const TInt count=iQueue.Count();
  1.2073 +	for (TInt ii=count-1;ii>=0;ii--)
  1.2074 +		{
  1.2075 +		CQueueItem* item=iQueue[ii];
  1.2076 +		TInt clientId=item->iClientId;
  1.2077 +		if (clientId==aClientId)
  1.2078 +			{
  1.2079 +			iQueue.Delete(ii);
  1.2080 +			}
  1.2081 +		}
  1.2082 +	}
  1.2083 +
  1.2084 +
  1.2085 +TInt CNotifierQueue::GetHighestQueuePriority(TUid aChannel)
  1.2086 +	{
  1.2087 +	const TInt count=iQueue.Count();
  1.2088 +	TInt priority=MNotifierBase2::ENotifierPriorityLowest-1;
  1.2089 +
  1.2090 +	for (TInt ii=0;ii<count;ii++)
  1.2091 +		{
  1.2092 +		CQueueItem* item=iQueue[ii];
  1.2093 +		if (item->iInfo.iChannel==aChannel && item->iInfo.iPriority>priority)
  1.2094 +			{
  1.2095 +			priority=item->iInfo.iPriority;
  1.2096 +			}
  1.2097 +		}
  1.2098 +
  1.2099 +	return priority;
  1.2100 +	}
  1.2101 +
  1.2102 +
  1.2103 +void CWsActiveScheduler::New()
  1.2104 +//
  1.2105 +// Create and install the active scheduler.
  1.2106 +//
  1.2107 +	{
  1.2108 +
  1.2109 +	CWsActiveScheduler *pA=new CWsActiveScheduler;
  1.2110 +	__ASSERT_ALWAYS(pA!=NULL,Fault(ECreateScheduler));
  1.2111 +	CActiveScheduler::Install(pA);
  1.2112 +	}
  1.2113 +
  1.2114 +void CWsActiveScheduler::Error(TInt) const
  1.2115 +//
  1.2116 +// Called if any Run() method leaves.
  1.2117 +//
  1.2118 +	{
  1.2119 +	}
  1.2120 +
  1.2121 +
  1.2122 +TInt NotifierServerThread(TAny*)
  1.2123 +	{
  1.2124 +	CTrapCleanup* CleanUpStack=CTrapCleanup::New();
  1.2125 +	CWsActiveScheduler::New();
  1.2126 +	TRAP_IGNORE(CNotifierServer::NewL());
  1.2127 +	CNotifierSession::NotifierSemaphore.Signal();
  1.2128 +	CWsActiveScheduler::Start();
  1.2129 +	delete CleanUpStack;
  1.2130 +	return(0);
  1.2131 +	}
  1.2132 +
  1.2133 +
  1.2134 +_LIT(KLitKeyDataDllNameBase, "EKDATA");
  1.2135 +_LIT(TwoDigExt,".%02d");
  1.2136 +
  1.2137 +GLDEF_C TInt E32Main()
  1.2138 +	{
  1.2139 +	UserSvr::WsRegisterThread();
  1.2140 +	UserSvr::WsRegisterSwitchOnScreenHandling(ETrue);
  1.2141 +	User::SetProcessCritical(User::ESystemPermanent);
  1.2142 +	User::SetCritical(User::ESystemPermanent);
  1.2143 +
  1.2144 +	CWsActiveScheduler::New();
  1.2145 +	CWsServer::New();
  1.2146 +	CWsWindow::New();
  1.2147 +	CEvent::New();
  1.2148 +    
  1.2149 +	KeyTranslator=CKeyTranslator::New();
  1.2150 +	if (!KeyTranslator)
  1.2151 +		Fault(ENoKeyboardTranslator);
  1.2152 +
  1.2153 +//  Change keyboard mapping according to information in the HAL
  1.2154 +//	This code is the same as WSERV
  1.2155 +	TInt keyboardIndex;
  1.2156 +	if (HAL::Get(HALData::EKeyboardIndex,keyboardIndex)==KErrNone)
  1.2157 +		{
  1.2158 +		TBuf<16> keyDataDllName(KLitKeyDataDllNameBase);
  1.2159 +		keyDataDllName.AppendFormat(TwoDigExt, keyboardIndex);
  1.2160 +		KeyTranslator->ChangeKeyData(keyDataDllName);
  1.2161 +		}
  1.2162 +
  1.2163 +    KeyRepeat=new(ELeave) CKeyRepeat(CKeyRepeat::EKeyRepeatPriority);
  1.2164 +	TRAPD(r,KeyRepeat->ConstructL());
  1.2165 +	if (r!=KErrNone)
  1.2166 +		User::Panic(_L("KEYREPEAT"),r);
  1.2167 +
  1.2168 +#ifndef __WINS__
  1.2169 +    if (UserSvr::TestBootSequence())
  1.2170 +		{
  1.2171 +		RDebug::Print(_L("WS_MAIN: TestBootSequence=TRUE, not loading ESHELL.EXE"));
  1.2172 +		}
  1.2173 +#else
  1.2174 +    if (EmulatorAutoRun())
  1.2175 +    	{	// don't start ESHELL if we used a self-bootstrapping EXE
  1.2176 +    	}
  1.2177 +#endif
  1.2178 +	else
  1.2179 +		{
  1.2180 +		RProcess shell;
  1.2181 +		r=shell.Create(KShellProcessName, KShellCommandLine);
  1.2182 +		__ASSERT_ALWAYS(r==KErrNone,Fault(ECreateShell));
  1.2183 +		shell.Resume();
  1.2184 +		shell.Close();
  1.2185 +		}
  1.2186 +
  1.2187 +	RThread t;
  1.2188 +	r=CNotifierSession::NotifierSemaphore.CreateLocal(0);
  1.2189 +	if (r!=KErrNone)
  1.2190 +		Fault(ECreateNotifierSemaphore);
  1.2191 +	r=t.Create(_L("NotifierServer"),NotifierServerThread,KDefaultStackSize,0x2000,0x100000,NULL);
  1.2192 +	if (r!=KErrNone)
  1.2193 +		Fault(ECreateNotifierThread);
  1.2194 +	t.Resume();
  1.2195 +	CNotifierSession::NotifierSemaphore.Wait();
  1.2196 +
  1.2197 +	CWsActiveScheduler::Start();
  1.2198 +	UserSvr::ReleaseEventHook();
  1.2199 +	return(KErrNone);
  1.2200 +	}
  1.2201 +