libraries/clogger/inc/SensibleServer.h
author Tom Sutcliffe <thomas.sutcliffe@accenture.com>
Thu, 26 Aug 2010 00:49:35 +0100
changeset 37 534b01198c2d
parent 0 7f656887cf89
permissions -rw-r--r--
Added ENotifyKeypresses and ECaptureCtrlC flags to CCommandBase. Commands can now get keypresses and handle ctrl-C via callbacks instead of having to implement custom active objects. As part of this extended the CCommandBase extension interface to MCommandExtensionsV2 for the new virtual functions KeyPressed(TUint aKeyCode, TUint aModifiers) and CtrlCPressed(). sudo now cleans up correctly by using ECaptureCtrlC.

// SensibleServer.h
// 
// Copyright (c) 2006 - 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
// 
// Initial Contributors:
// Accenture - Initial contribution
//

#ifndef SENSIBLESERVER_H
#define SENSIBLESERVER_H

#include <e32base.h>
#include "cliserv.h"
#include <f32file.h>
#include <gdi.h>
#include <basched.h>

#include "SensibleCompat.h"

class CCallbackContext;
class CSensibleSession;
class CFilteringScheduler;

void PanicClient(const RMessage& aMessage, TInt TMyPanic);
extern void CleanupPanicPushL();

class CShutdown : public CTimer
	{
public:
	inline CShutdown();
	inline void ConstructL();
	inline void Start(TInt aDelay);
private:
	void RunL();
	};

class CSensibleServer : public CServerBase
	{
public:
	void AddSession();
	void DropSession();
	inline CFilteringScheduler* Scheduler();
	CSensibleServer();
	~CSensibleServer();
	virtual void ConstructL();

	// Some functions that call into the filtering scheduler
	// NOTE: These functions cannot be used at the same time as queuing a callback that requires a result, nor can they be nested (you'll get a panic)
	//void BlockAllAOsExceptServerRequests();
	void BlockRequestsFrom(CActive* aActive1, CActive* aActive2=NULL);
	void StopBlocking();

protected:
	#ifdef __HIDE_IPC_V1__
	CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
	#else
	CSessionBase* NewSessionL(const TVersion& aVersion) const;
	#endif
	TInt RunError(TInt aError);
	virtual TInt TransientServerShutdownTime() const; // Return 0 to never shutdown

private:
	TInt iSessionCount;
	CShutdown iShutdown;
	CFilteringScheduler* iScheduler;
	CActiveScheduler* iOldScheduler;
	};

class CSensibleSession : public CSessionBase
	{
public:
	CSensibleSession();
	#ifndef __HIDE_IPC_V1__
	void CreateL(const CServer& aServer);
	#endif
	void CreateL();
	void QueueCallbackL(CCallbackContext* aContext); // This completes a callback immediately if possible, otherwise queues it. Used for callbacks that MUST be delivered.
	TBool DispatchCallback(TServerCallback& aCallback); // This completes a callback immediately if possible, otherwise returns EFalse. Used for notify-style callbacks. The callback cannot have a context.
	void CompleteNextCallback();

protected:
	virtual TBool DoServiceL(const RMessage& aMessage); // return EFalse if aMessage wasn't handled
	~CSensibleSession();

private:
	inline CSensibleServer& Server();
	void ServiceL(const RMessage& aMessage);
//	inline TBool ReceivePending() const;
private:
	TSglQue<CCallbackContext> iCallbackQ;
	RMessage iCallbackNotifier;
	TBool iCallbackPending;
	TBool iWaitingForCallbackResult;
	};

enum TCallbackContextFlags
	{
	EResultHBufC8 = 2,
	EResultHBufC16 = 4,
	EResultIsLeaveCode = 8,
	EActive = 16,
	EBlockServer = 32,
	};

class TCallbackWriter
	{
public:
	TCallbackWriter(TServerCallback& aCallback, HBufC8** aContext);

	// If any of the AddLs leave, they will delete aContext if it has been created
	void AddL(TInt aInt);
	void AddL(TUint aInt);
	void AddL(TPoint aPoint);
	void AddL(TSize aSize);
	void AddL(TRgb aRgb);
	void AddL(TRect aRect);
	void AddL(const TDesC16& aDesc);
	void AddL(const TDesC8& aDesc);

private:
	void AddL(const TDesC8& aData, char* aType);

private:
	TServerCallback& iCallback;
	HBufC8** iContext;
	TPtr8 iBuf;
	TBool iInContext;
	};

class CCallbackContext : public CBase
	{
public:
	union TResult
		{
		HBufC8** s;
		HBufC16** l;
		TDes8* pkg;
		TInt integer;
		};
		
public:
	CCallbackContext(TCallbackCode aCode);
	~CCallbackContext();
	void SetFlags(TInt aFlags);
	TBool Flag(TInt aFlags) const; // All bits of aFlags must be set to return true
	void ClearFlags(TInt aFlags);
	TBool CallbackRequiresResult() const;
	TBool CallbackHasContext() const;
	//void SetContext(HBufC8* aContext); // Takes ownership and clears flag EContextHBufC16
	//void SetContext(HBufC16* aContext); // Takes ownership and sets flag EContextHBufC16
	TCallbackWriter Writer();

	void SetResult(TDes8& aPkg); // Sets appropriate flags
	void SetResult(HBufC8*& aResult); // Sets appropriate flags
	void SetResult(HBufC16*& aResult); // Sets appropriate flags
	//void SetResult(TInt& aResult); // Sets appropriate flags
	HBufC8* Context();
	TResult& Result();
	TServerCallback& Callback();
	
private:
	void AddContext(const TUint8* aPtr, TInt aSize, char* aType);
private:
	TInt iFlags; // bitwise OR of TCallbackContextFlags
	TServerCallback iCallback;
	HBufC8* iContext;
	TResult iResult;

public:
	TSglQueLink iLink;
	};

#endif