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.
// dobject.h
//
// Copyright (c) 1998 - 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
//
/**
@file
@internalTechnology
*/
#ifndef __DOBJECT_H__
#define __DOBJECT_H__
#ifdef _DEBUG
// In DEBUG builds use linear growth by 1 to aid kernel heap checking
#else
const TInt KObjectConMinSize=8;
#endif
const TInt KObjectIxGranularity=8;
const TInt KObjectIndexMask=0x7fff;
const TInt KObjectMaxIndex=0x7fff;
const TInt KObjectInstanceShift=16;
const TInt KObjectInstanceMask=0x3fff;
const TInt KObjectIxMaxHandles=0x8000;
inline TInt index(TInt aHandle)
{return(aHandle&KObjectIndexMask);}
inline TInt instance(TInt aHandle)
{return((aHandle>>KObjectInstanceShift)&KObjectInstanceMask);}
inline TInt instanceLimit(TInt& aCount)
{return ((aCount&KObjectInstanceMask)==0) ? ((++aCount)&KObjectInstanceMask) : aCount&KObjectInstanceMask;}
inline TInt makeHandle(TInt aIndex, TInt aInstance)
{return((TInt)((aInstance<<KObjectInstanceShift)|aIndex));}
enum TDObjectPanic
{
EObjObjectStillReferenced,
EObjNegativeAccessCount,
EObjRemoveObjectNotFound,
EObjRemoveContainerNotFound,
EObjRemoveBadHandle,
EObjFindBadHandle,
EObjFindIndexOutOfRange,
EDObjectConDestroyed,
EArrayIndexOutOfRange,
EObjInconsistent,
};
inline void Panic(TDObjectPanic aPanic)
{ Kern::Fault("DOBJECT",aPanic); }
//BEGIN TOMSCI
// This is needed because on 9.1 the DObjectIx header is defined as IMPORT_C
#undef IMPORT_C
#define IMPORT_C
#define DObjectIx DObjectIxNinePointTwoHack // So that we're not redefining DObjectIx
NONSHARABLE_CLASS(DObjectIx) : public DBase
{
public:
enum {ENoClose=KHandleNoClose,ELocalHandle=0x40000000};
public:
IMPORT_C static DObjectIx* New(TAny* aPtr);
IMPORT_C ~DObjectIx();
IMPORT_C TInt Add(DObject* aObj, TInt& aHandle);
IMPORT_C TInt Remove(TInt aHandle, DObject*& aObject, TAny*& aPtr);
IMPORT_C DObject* At(TInt aHandle,TInt aUniqueID);
IMPORT_C DObject* At(TInt aHandle);
IMPORT_C TInt At(DObject* aObject);
IMPORT_C TInt Count(DObject* aObject);
IMPORT_C DObject* operator[](TInt aIndex);
TInt LastHandle();
static void Wait();
static void Signal();
inline TInt Count();
inline TInt ActiveCount();
protected:
IMPORT_C DObjectIx(TAny* aPtr);
private:
void UpdateState();
private:
TInt iNextInstance;
TInt iAllocated; // Max entries before realloc needed
TInt iCount; // Points to at least 1 above the highest active index
TInt iActiveCount; // Number of actual entries in the index
SDObjectIxRec* iObjects;
TAny* iPtr;
TInt iFree; // The index of the first free slot or -1.
TInt iUpdateDisabled; // If >0, disables: iCount update, reorder of the free list and memory shrinking.
public:
static DMutex* HandleMutex;
public:
friend void PreprocessHandler();
friend class DThread;
friend class K;
friend class Monitor;
};
inline TInt DObjectIx::Count()
{return iCount;}
inline TInt DObjectIx::ActiveCount()
{return iActiveCount;}
#undef DObjectIx
//
// Include these in a header file
//
__ASSERT_COMPILE(sizeof(DObject) == 6*4 || sizeof(DObject) == 8*4); // We can't cope if the size changes again!
#define DOBJECT_PADDING TUint64 _padding
const TBool KCompiledUsingOldDefinition = sizeof(DObject) == 6*4;
#define ADD_PADDING(type, variablePtr) (*reinterpret_cast<type*>((TUint8*)variablePtr + sizeof(TUint64)))
#define SUBTRACT_PADDING(type, variablePtr) (*reinterpret_cast<type*>((TUint8*)variablePtr - sizeof(TUint64)))
template <class T>
class TemplatedPadder
{
public:
inline static T& AddPadding(T* aPtr)
{
return ADD_PADDING(T, aPtr);
}
inline static T& SubtractPadding(T* aPtr)
{
return SUBTRACT_PADDING(T, aPtr);
}
};
template <class T>
inline T& AddPadding(T* aPtr)
{
return TemplatedPadder<T>::AddPadding(aPtr);
}
template <class T>
inline T& SubtractPadding(T* aPtr)
{
return TemplatedPadder<T>::SubtractPadding(aPtr);
}
TBool CalculateDObjectSize(); // returns false if unable to determine
extern TBool gRunningWithOldDefinition;
/* The SAFE_MEMBER macro exists because DObject grew by 64 bits between 9.1 and 9.2, therefore to write a
* DObject-derived class (such as a DLogicalChannel in an LDD) that can be compiled on one but also works on the
* other requires that you be very careful accessing member data of your DObject-derived objects, because the
* offsets are different on the two OS releases. This macro abstracts the differences away by calculating when
* an 8 byte correction needs to be applied to where the compiler thinks the variable is versus where the runtime
* knows it is. By necessity, it has a weird definition, that relies on the above helper macros and also on
* CalculateDObjectSize being called at some point before the first time any code using SAFE_MACRO is run.
* It is recommended that for an LDD, you call it from within your DECLARE_EXTENSION_LDD before doing anything
* else.
*
* SAFE_MEMBER can only be used to access member data of DObject-derived classes, and should be used in ALL
* places where the instance variables are used or set, this includes instance variables of the superclass and
* instance variables in DObject-derived objects you define yourself. Accesses to instance variables of DObject
* itself must NOT use this macro, since the DObject variable offsets do not change. In order to make sure your
* class is large enough and that the macro can be used consistantly, you must include a DOBJECT_PADDING at
* the *end* of all of your DObject subclass definition. You won't get any warning if you forget to do this,
* It will just crash. Likewise if you use SAFE_MEMBER to access the member data of the DObject itself.
*
* In other words:
* DO use SAFE_MEMBER to access the member data of DMyClassThatIsDerivedFromDObject
* DO use SAFE_MEMBER to access the member data of DLogicalChannel/DLogicalDevice/DThread etc
* DON'T use it to access the member data of DObject itself
* ALWAYS include a DOBJECT_PADDING at the end of your DMyDObjectDerivedClass - ie after any other member data
*
*/
#define SAFE_MEMBER(variable) ( \
(KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? variable : ( \
(KCompiledUsingOldDefinition && !gRunningWithOldDefinition) ? AddPadding(&variable) : ( \
(!KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? SubtractPadding(&variable) : ( \
/* running and compiling with new-definition DObject */ variable ))))
/* Old definition that doesn't require templating to work, (so is callable from non-C++). A consequence is you
* have to explicitly give the type of the variable.
*/
//#define SAFE_MEMBER(type, variable) ( \
// (KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? variable : ( \
// (KCompiledUsingOldDefinition && !gRunningWithOldDefinition) ? ADD_PADDING(type, &variable) : ( \
// (!KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? SUBTRACT_PADDING(type, &variable) : ( \
// /* running and compiling with new-definition DObject */ variable ))))
/* These macros are equivalent to _FOFF and _LOFF and should be used whenever
* f refers to a member variable that you would need to use SAFE_MEMBER on
*/
#define _SAFE_FOFF(c,f) (((TInt)& SAFE_MEMBER((((c *)0x1000)->f) ) )-0x1000)
#define _SAFE_LOFF(p,T,f) ((T*)(((TUint8*)(p))-_SAFE_FOFF(T,f)))
//END TOMSCI
#endif