// EIKENV.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <eikenv.h>
#include <eikappui.h>
#include <eikver.h>
#include <eikmsg.h>
#include <eikpanic.h>
#include <eikon.rsg>
#include <eikon.mbg>
#include <eikdef.hrh>
#include <eikdialg.hrh>
#include <txtfmlyr.h>
#include <txtfrmat.h>
#include <coeccntx.h>
#include <eikcmbut.h>
#include <eiklabel.h>
#include <eikimage.h>
#include <eikalert.h>
#include <eikinfo.h>
#include <eikdebug.h>
#include <eikscncl.h>
#include <barsread.h>
#include <prnsetup.h>
#include <bautils.h>
#include <basched.h>
#include <apparc.h>
#include <apgdoor.h>
#include <eikdoc.h>
#include <eikapp.h>
#include <eikproc.h>
#include <eikrutil.h>
#include <eiksfont.h>
#include <eikdll.h>
#include <s32file.h>
#include <apgwgnam.h>
#include <baerror.h>
#include <coeerror.h>
#include <eiksvdef.h>
#include <basndut.h>
#include <e32hal.h>
#include <fepbase.h>
#include <eikcolor.h>
#include <eikpriv.rsg>

const TUid KUidDefaultPageSize={268435860};
const TUid KUidDefaultPrinterModelUid={268435924};
const TUid KWinPrintPdlUid={268435709};

GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
	{
	return(KErrNone);
	}

GLDEF_C void Panic(TEikPanic aPanic)
	{
	User::Panic(_L("EIKON"),aPanic);
	}

class CEikErrorIdler : public CIdle
	{
public:
	static CEikErrorIdler* NewL();
private:
	CEikErrorIdler() : CIdle(EPriorityLow) { }
public:
	TTime iTime;
	TInt iError;
	TInt iContext;
	};

CEikErrorIdler* CEikErrorIdler::NewL()
	{
	CEikErrorIdler* self=new(ELeave) CEikErrorIdler;
	CActiveScheduler::Add(self);
	return(self);
	}

enum TEikEnvFlags
	{
	EAutoForwarding 		=0x02,
	EVerboseInfoReporting	=0x04
	};

EXPORT_C TVersion CEikonEnv::Version()
    { // static
    return(TVersion(KEikMajorVersionNumber,KEikMinorVersionNumber,KEikBuildVersionNumber));
    }

EXPORT_C void CEikonEnv::InitSystemFontsL()
	{
    InitSystemResourceFileL();
	TResourceReader reader;
	CreateResourceReaderLC(reader,R_EIK_SYSTEM_FONTS);
	reader.ReadInt16();
	CWsScreenDevice& screenDev=*ScreenDevice();
	iNormalFont=EikResourceUtils::CreateScreenFontL(reader,screenDev);
	iTitleFont=EikResourceUtils::CreateScreenFontL(reader,screenDev);
	iAnnotationFont=EikResourceUtils::CreateScreenFontL(reader,screenDev);
	iLegendFont=EikResourceUtils::CreateScreenFontL(reader,screenDev);
	iDenseFont=EikResourceUtils::CreateScreenFontL(reader,screenDev);
	iSymbolFont=EikResourceUtils::CreateScreenFontL(reader,screenDev);
	CleanupStack::PopAndDestroy(); // reader
    }

EXPORT_C CEikonEnv::CEikonEnv()
    {
    __DECLARE_NAME(_S("CEikEnv"));
    }

EXPORT_C CEikonEnv::~CEikonEnv()
    {
    delete(iSingleLineParaFormatLayer);
	delete(iParaFormatLayer);
	delete(iCharFormatLayer);
	delete iColorList;
    }

EXPORT_C void CEikonEnv::DestroyEnvironment()
    {
    User::Free(iKeyPressLabels);
	delete(iAlertWin);
	iAlertWin=NULL;
	delete(iErrorIdler);
    ReleaseScreenFont(CONST_CAST(CFont*,iDenseFont));
    ReleaseScreenFont(CONST_CAST(CFont*,iAnnotationFont));
    ReleaseScreenFont(CONST_CAST(CFont*,iTitleFont));
	ReleaseScreenFont(CONST_CAST(CFont*,iLegendFont));
	ReleaseScreenFont(CONST_CAST(CFont*,iSymbolFont));
	delete(iInfoMsgWin);
	BusyMsgCancel();
	delete(CONST_CAST(CFbsBitmap*,iTexturedBitmap));
	delete(CONST_CAST(CFbsBitmap*,iGrayBitmap));
	delete(CONST_CAST(CFbsBitmap*,iOptionBitmap));
	delete(CONST_CAST(CFbsBitmap*,iHighlightedOptionBitmap));
	delete(CONST_CAST(CFbsBitmap*,iOptionMaskBitmap));
	DeleteResourceFile(iPrivateResourceFileOffset);
    CCoeEnv::DestroyEnvironment();
    }

const TInt KUidBaflDllValue16=0x10003A0F; // !!! should be in BAERROR.H

TErrorHandlerResponse CEikonEnv::PrepareToHandleError(TInt aError)
	{
	if (aError!=KErrExtendedWithText)
		ErrorContextText().Zero();
	const SExtendedError& extErr=CBaActiveScheduler::ExtendedError();
	CEikAppUi* appUi=EikAppUi();
	while (appUi)
		{
		TErrorHandlerResponse ret=appUi->HandleError(aError,extErr,ErrorText(),ErrorContextText());
		if (ret!=EErrorNotHandled)
			return(ret);
		appUi=appUi->ContainerAppUi();
		}
	TErrorHandlerResponse ret=EAlertDisplay;
	if (aError!=KErrExtendedWithText)
		{
    	TInt rid=iSystemResourceFileOffset+1-aError;
    	if (aError==KErrExtended)
			{
			if (extErr.iInformation)
				ret=EInfoDisplay;
			rid=extErr.iErrorNumber;
			switch (extErr.iComponent.iUid)
				{
			case 0:
				break;
#if defined(_UNICODE)
			case KUidBaflDllValue16:
#else
			case KUidBaflDllValue8:
#endif
				rid+=R_EIK_BAFL_ERROR_OFFSET;
				break;
#if defined(_UNICODE)
			case KUidConeDllValue16:
#else
			case KUidConeDllValue8:
#endif
				rid+=R_EIK_CONE_ERROR_OFFSET;
				break;
			case KUidBaflErrorHandlerValue:
				ret=CBaErrorHandler::CallBack(extErr.iErrorNumber,ErrorText(),ErrorContextText());
				if (ret!=EErrorNotHandled)
					return(ret);
				ret=EAlertDisplay; //fall through
			default:
    			rid=iSystemResourceFileOffset+1-KErrUnknown;
				}
			}
		else if (aError>KErrNotFound || aError<KErrDirFull)
    		rid=iSystemResourceFileOffset+1-KErrUnknown;
    	ReadResource(ErrorText(),rid);
		}
	return(ret);
	}

void CEikonEnv::DoHandleError(TErrorHandlerResponse aType)
	{
	if (aType==EInfoDisplay)
		InfoMsg(ErrorText());
	else if (aType==EAlertDisplay)
		{
		if (ErrorContextText().Length())
			AlertWin(ErrorContextText(),ErrorText());
		else
			AlertWin(ErrorText(),ErrorContextText());
		}
	}

EXPORT_C void CEikonEnv::HandleError(TInt aError)
    {
	BusyMsgCancel();
	if (aError==KLeaveWithoutAlert)
		return;
	if (!iSystemResourceFileOffset)
		User::Exit(aError); // not finished initializing
	TErrorHandlerResponse type=PrepareToHandleError(aError);
	DoHandleError(type);
    }

EXPORT_C void CEikonEnv::HandleErrorWithContext(TInt aError,TInt aContextRid)
	{
	TErrorHandlerResponse type=PrepareToHandleError(aError);
	if (!ErrorContextText().Length())
		ReadResource(ErrorContextText(),aContextRid);
	DoHandleError(type);
	}

EXPORT_C void CEikonEnv::NotifyIdleErrorWhileRedrawing(TInt aError)
	{
	NotifyIdleError(aError,R_EIK_TBUF_ERROR_WHILE_REDRAWING);
	}

EXPORT_C void CEikonEnv::NotifyIdleError(TInt aError,TInt aContextRid)
	{
	TTime time;
	time.HomeTime();
	TTimeIntervalSeconds gap;
	TInt err=time.SecondsFrom(iErrorIdler->iTime,gap);
	if (!err && gap<TTimeIntervalSeconds(60))
		return; // less than one minute since previous notification
	iErrorIdler->iError=aError;
	iErrorIdler->iContext=aContextRid;
	iErrorIdler->iTime=time;
	iErrorIdler->Cancel();
	iErrorIdler->Start(TCallBack(IdleErrorCallBack,this));
	}

TInt CEikonEnv::IdleErrorCallBack(TAny* aThis)
	{ // static
	CEikonEnv* self=(CEikonEnv*)aThis;
	self->HandleErrorWithContext(self->iErrorIdler->iError,self->iErrorIdler->iContext);
	return(EFalse); // single shot callback
	}

EXPORT_C void CEikonEnv::LeaveWithErrorContext(TInt aError,const TDesC& aContextText)
	{
	GetErrorText(ErrorText(),aError);
	BaflUtils::CopyWithTruncation(ErrorContextText(),aContextText);
	User::Leave(KErrExtendedWithText);
	}

EXPORT_C void CEikonEnv::GetErrorText(TDes& aDes,TInt aError) const
    {
	TInt error=aError;
	if (error>KErrNotFound || error<KErrDirFull)
		error=KErrUnknown;
    ReadResource(aDes,iSystemResourceFileOffset+1-error);
    }

EXPORT_C void CEikonEnv::AlertWin(const TDesC& aMsg)
	{
    AlertWin(aMsg,TPtrC());
	}

EXPORT_C void CEikonEnv::AlertWin(const TDesC& aMsg1,const TDesC& aMsg2)
	{
    if (iAlertWin)
		iAlertWin->RunAlert(aMsg1,aMsg2);
	else
		{
		// use the notifier - button 1 text defaults to language specific "Continue"
		TRequestStatus status;
		RNotifier notifier;
		if (!(notifier.Connect()))
			{
			TInt tmp=0;
			notifier.Notify(aMsg1,aMsg2,TPtrC(),TPtrC(),tmp,status); 
			User::WaitForRequest(status);
			notifier.Close();
			}
		}
	}

EXPORT_C void CEikonEnv::DestroyScreen()
    {
    if (iClockDll)
        iClockDll->Destroy();
	delete(iPictureFactory);
    delete(iProcess); // not before screen is destroyed, in case there are bitmap pictures in the document
	delete iWgName; // may be accessed during destruction of AppUi
    CCoeEnv::DestroyScreen();
    }

EXPORT_C void CEikonEnv::LeaveWithInfoMsg(TInt aResourceId,...)
    {
    if (aResourceId)
        {
	    VA_LIST list;
        VA_START(list,aResourceId);
        InfoMsg(aResourceId,list);
        }
    CBaActiveScheduler::LeaveNoAlert();
    }

EXPORT_C void CEikonEnv::VerboseInfoMsg(const TDesC& aDes)
	{
    if (iEikonEnvFlags&EVerboseInfoReporting)
		InfoMsg(aDes);
	}

EXPORT_C void CEikonEnv::InfoMsg(const TDesC& aDes)
	{
    iInfoMsgWin->StartDisplay(aDes,EHRightVTop);
	}

EXPORT_C void CEikonEnv::InfoMsgWithAlignment(TCoeAlignment aCorner,const TDesC& aDes)
	{
    iInfoMsgWin->StartDisplay(aDes,aCorner);
	}

EXPORT_C void CEikonEnv::InfoMsg(TInt aResourceId,VA_LIST aList)
    {
    TEikInfoMsgBuf formatString;
	ReadResource(formatString,aResourceId);
	TEikInfoMsgBuf messageString;
	messageString.FormatList(formatString,aList);
	InfoMsg(messageString);
    }

EXPORT_C void CEikonEnv::InfoMsg(TInt aResourceId,...)
    {
    VA_LIST list;
    VA_START(list,aResourceId);
    InfoMsg(aResourceId,list);
    }

EXPORT_C void CEikonEnv::InfoMsgWithAlignment(TCoeAlignment aCorner,TInt aResourceId,VA_LIST aList)
    {
    TEikInfoMsgBuf formatString;
	ReadResource(formatString,aResourceId);
	TEikInfoMsgBuf messageString;
	messageString.FormatList(formatString,aList);
	InfoMsgWithAlignment(aCorner,messageString);
    }

EXPORT_C void CEikonEnv::InfoMsgWithAlignment(TCoeAlignment aCorner,TInt aResourceId,...)
    {
    VA_LIST list;
    VA_START(list,aResourceId);
    InfoMsgWithAlignment(aCorner,aResourceId,list);
    }

EXPORT_C void CEikonEnv::InfoMsgCancel()
    {
    iInfoMsgWin->CancelDisplay();
    }

void CEikonEnv::PrepareBusyMsgL()
	{
	if (iBusyMsgWin)
		return;
	CEikBusyMsgWin* busyMsgWin=new(ELeave) CEikBusyMsgWin(*this);
	CleanupStack::PushL(busyMsgWin);
	busyMsgWin->ConstructL(iRootWin);
	CleanupStack::Pop();
	iBusyMsgWin=busyMsgWin;
	}

EXPORT_C void CEikonEnv::BusyMsgL(const TDesC& aDes)
	{
	PrepareBusyMsgL();
    iBusyMsgWin->StartDisplay(aDes,EHRightVBottom);
	}

EXPORT_C void CEikonEnv::BusyMsgL(const TDesC& aDes,TCoeAlignment aCorner)
	{
	PrepareBusyMsgL();
	iBusyMsgWin->StartDisplay(aDes,aCorner);
	}

EXPORT_C void CEikonEnv::BusyMsgL(TInt aResourceId)
	{
    TEikBusyMsgBuf msg; 
    ReadResource(msg,aResourceId);
	BusyMsgL(msg);
	}

EXPORT_C void CEikonEnv::BusyMsgL(const TDesC& aDes,TTimeIntervalMicroSeconds32 aInitialDelay)
	{
	BusyMsgL(aDes,EHRightVBottom,aInitialDelay);
	}

EXPORT_C void CEikonEnv::BusyMsgL(const TDesC& aDes,TCoeAlignment aCorner,TTimeIntervalMicroSeconds32 aInitialDelay)
	{
	PrepareBusyMsgL();
	iBusyMsgWin->StartDisplaySpecifyingInitialDelay(aDes,aCorner,aInitialDelay);
	}

EXPORT_C void CEikonEnv::BusyMsgL(TInt aResourceId,TTimeIntervalMicroSeconds32 aInitialDelay)
	{
    TEikBusyMsgBuf msg; 
    ReadResource(msg,aResourceId);
	BusyMsgL(msg,aInitialDelay);
	}

EXPORT_C void CEikonEnv::BusyMsgCancel()
    {
	delete iBusyMsgWin;
	iBusyMsgWin=NULL;
    }

EXPORT_C void CEikonEnv::Beep()
    { // static
	TInt frequency=1760;
	TInt amplitude=100;
	TTimeIntervalMicroSeconds32 duration=100000;
	TSoundInfoV1Buf sbuf;
	UserHal::SoundInfo(sbuf);
	TSoundInfoV1& soundInfo=*(TSoundInfoV1*)sbuf.Ptr();
	SoundUtilities::TDeviceVolume volume;
	if (soundInfo.iBeepLoud)
		volume=SoundUtilities::EToneLoud;
	else if (soundInfo.iBeepEnabled)
		volume=SoundUtilities::EToneQuiet;
	else
		volume=SoundUtilities::EToneOff;  
	SoundUtilities::PlayTone(frequency,duration,amplitude,volume);
    }

EXPORT_C TInt CEikonEnv::ResourceFileVersionNumber() const
    {
    return(EEikResourceSignatureValue);
    }

EXPORT_C void CEikonEnv::AddWindowShadow(CCoeControl* aWinArea)
    {
    aWinArea->DrawableWindow()->SetShadowHeight(3); // six pixels
    }

EXPORT_C void CEikonEnv::ControlStackReadyL()
	{
	CEikDebugPreferences* debugPrefs=CEikDebugPreferences::NewLC();
#if defined(_DEBUG)	// debug keys always on
	debugPrefs->SetKeysOn(ETrue);
#else
	TRAPD(err,debugPrefs->RestoreL());
	if(err==KErrNoMemory)
		User::Leave(KErrNoMemory);
#endif
	if(debugPrefs->KeysOn())
		{
		CEikDebugKeys* debugKeys=new(ELeave) CEikDebugKeys;
		debugKeys->ConstructL(); // after control stack initialized
		}
	CleanupStack::PopAndDestroy();	// debugPrefs

	InitAlertWinL();
	iErrorIdler=CEikErrorIdler::NewL();
	}

EXPORT_C void CEikonEnv::ConstructL()
	{
    CCoeEnv::ConstructL();
	InitPrivateResourceFileL();
	InitColorsL();
	iEditableControlStandardHeight=19; // height of normal font+room for borders+gapabovetext 15+3+1 !! should vary with the font
	InitInfoMsgL();
	TPtrC filename;
	iTexturedBitmap=CreateBitmapL(filename,EMbmEikonTextured);
	iGrayBitmap=CreateBitmapL(filename,EMbmEikonGray);
	iOptionBitmap=CreateBitmapL(filename,EMbmEikonOpti);
	iHighlightedOptionBitmap=CreateBitmapL(filename,EMbmEikonOptih);
	iOptionMaskBitmap=CreateBitmapL(filename,EMbmEikonOptim);
	iWgName=CApaWindowGroupName::NewL(iWsSession);
	ReadResource(iNudgeChars,R_EIK_TBUF_NUDGE_CHARS);
	}

void CEikonEnv::SetUpFepL(const CEikApplication& aApplication)
	{
	TResourceReader resourceReader;
	CreateResourceReaderLC(resourceReader, R_EIK_FEP_DEFAULT_DATA);
	const TPtrC fileNameOfFepDll=resourceReader.ReadTPtrC();
	const TUint onKeyCharacterCodeForFoldedMatch=resourceReader.ReadUint32();
	const TUint onKeyModifierMask=resourceReader.ReadUint32();
	const TUint onKeyModifierValues=resourceReader.ReadUint32();
	const TUint offKeyCharacterCodeForFoldedMatch=resourceReader.ReadUint32();
	const TUint offKeyModifierMask=resourceReader.ReadUint32();
	const TUint offKeyModifierValues=resourceReader.ReadUint32();
	const TBool isOn=resourceReader.ReadUint8();
	TParse* parser=new(ELeave) TParse;
	CleanupStack::PushL(parser);
	aApplication.SetToIniFileNameL(*parser);
	CCoeEnv::SetUpFepL(CCoeFepParameters::NewLC(aApplication.AppDllUid(), parser->FullName(), TFepOnOrOffKeyData(onKeyCharacterCodeForFoldedMatch, onKeyModifierMask, onKeyModifierValues), TFepOnOrOffKeyData(offKeyCharacterCodeForFoldedMatch, offKeyModifierMask, offKeyModifierValues), isOn, aApplication.AllWindowsMustBeBackedUpWindows()), fileNameOfFepDll);
	CleanupStack::Pop(); // object returned by CCoeFepParameters::NewLC
	CleanupStack::PopAndDestroy(2); // parser and resourceReader
	}

void CEikonEnv::InitSystemResourceFileL()
    {
    TFileName fileName(_L("z:\\System\\Data\\eikon.rsc"));
	BaflUtils::NearestLanguageFile(FsSession(),fileName);
	iSystemResourceFileOffset=AddResourceFileL(fileName);
	iKeyPressLabels=AllocReadResourceAsDes8L(R_EIK_KEYPRESS_LABELS);
    }

void CEikonEnv::InitPrivateResourceFileL()
    {
    TFileName fileName(_L("z:\\System\\Data\\eikpriv.rsc"));
	BaflUtils::NearestLanguageFile(FsSession(),fileName);
	iPrivateResourceFileOffset=AddResourceFileL(fileName);
    }

void CEikonEnv::InitInfoMsgL()
	{
    iInfoMsgWin=new(ELeave) CEikInfoMsgWin(*this);
	iInfoMsgWin->ConstructL(iRootWin);
	}

void CEikonEnv::InitAlertWinL()
	{
    iAlertWin=new(ELeave) CEikAlert;
	TRAPD(err,iAlertWin->ConstructL());
	if (err)
		{
		delete(iAlertWin);
		iAlertWin=NULL;
		User::Leave(err);
		}
	}

EXPORT_C void CEikonEnv::AllocInfoMsg()
    {
    TInt allocSize;
	TInt allocCount=User::Heap().AllocSize(allocSize);
	InfoMsg(R_EIK_DBG_TBUF_ALLOC_INFO,allocCount,allocSize);
    }

EXPORT_C void CEikonEnv::WservAllocInfoMsg()
    {
    InfoMsg(R_EIK_DBG_TBUF_WSERV_COUNT,iWsSession.ResourceCount());
    }

EXPORT_C void CEikonEnv::FservAllocInfoMsg()
    {
    InfoMsg(R_EIK_DBG_TBUF_FSERV_COUNT,iFsSession.ResourceCount());
    }

EXPORT_C RAnimDll& CEikonEnv::ClockDllL()
    {
    if (!iClockDll)
        {
        iClockDll=new(ELeave) RAnimDll(iWsSession);
#if defined(__WINS__)
        TInt err=iClockDll->Load(_L("CLOCKA.DLL"));
#else
        TInt err=iClockDll->Load(_L("Z:\\SYSTEM\\LIBS\\CLOCKA.DLL"));
#endif
        if (err)
            {
            iClockDll->Destroy();
            iClockDll=NULL;
            User::Leave(err);
            }
        }
    return(*iClockDll);
    }

EXPORT_C CWsBitmap* CEikonEnv::CreateBitmapL(const TDesC& aFileName,TInt aId)
	{
    TPtrC ptr=aFileName;
    if (!ptr.Length())
        ptr.Set(_L("z:\\System\\Data\\eikon.mbm"));
	else if (ptr==_L("*"))
		ptr.Set(EikAppUi()->Application()->BitmapStoreName());
	CWsBitmap* tmp=new(ELeave) CWsBitmap(iWsSession);
	TInt ret=tmp->Load(ptr,aId);
	if (ret)
		{
		delete(tmp);
		LeaveWithErrorContext(ret,ptr);
		}
	tmp->SetSizeInTwips(iScreen);
	return(tmp);
	}

EXPORT_C CParaFormatLayer* CEikonEnv::SystemSingleLineParaFormatLayerL()
    {
    if (!iSingleLineParaFormatLayer)
        iSingleLineParaFormatLayer=NewDefaultSingleLineParaFormatLayerL();
    return(iSingleLineParaFormatLayer);
    }

EXPORT_C CParaFormatLayer* CEikonEnv::SystemParaFormatLayerL()
    {
    if (!iParaFormatLayer)
        iParaFormatLayer=NewDefaultParaFormatLayerL();
    return(iParaFormatLayer);
    }

EXPORT_C CCharFormatLayer* CEikonEnv::SystemCharFormatLayerL()
    {
    if (!iCharFormatLayer)
        iCharFormatLayer=NewDefaultCharFormatLayerL();
    return(iCharFormatLayer);
    }

EXPORT_C CParaFormatLayer* CEikonEnv::NewDefaultSingleLineParaFormatLayerL()
    { // static
    CParaFormat* format=CParaFormat::NewLC();
	format->iLineSpacingInTwips=0;
	TParaFormatMask mask;
	mask.SetAttrib(EAttLineSpacing);
    CParaFormatLayer* layer=CParaFormatLayer::NewL(format,mask);
	CleanupStack::PopAndDestroy(); // format
	return layer;
    }

EXPORT_C CParaFormatLayer* CEikonEnv::NewDefaultParaFormatLayerL()
    { // static
    CParaFormat* format=CParaFormat::NewLC();
	format->iLineSpacingInTwips=KEikDefaultLineSpacingInTwips;
	TParaFormatMask mask;
	mask.SetAttrib(EAttLineSpacing);
    CParaFormatLayer* layer=CParaFormatLayer::NewL(format,mask);
	CleanupStack::PopAndDestroy(); // format
	return layer;
    }

#define KEikDefaultCharFormatColor KRgbBlack

EXPORT_C CCharFormatLayer* CEikonEnv::NewDefaultCharFormatLayerL()
    { // static
    TCharFormatMask defaultCharFormatMask;
	TBuf<KMaxTypefaceNameLength> typeface;
	CEikonEnv* self=CEikonEnv::Static();
	self->ReadResource(typeface,R_EIK_DEFAULT_CHAR_FORMAT_TYPEFACE);

	TResourceReader reader;
	self->CreateResourceReaderLC(reader,R_EIK_DEFAULT_CHAR_FORMAT_HEIGHT);
	TInt height=reader.ReadInt16();
	CleanupStack::PopAndDestroy(); // reader

	TCharFormat defaultCharFormat(typeface,height);
	defaultCharFormatMask.SetAttrib(EAttFontTypeface);
	defaultCharFormatMask.SetAttrib(EAttFontHeight);
    return CCharFormatLayer::NewL(defaultCharFormat,defaultCharFormatMask);
    }

EXPORT_C void CEikonEnv::GetPrinterNamesL(CPrinterModelList* aModelNameList,CDesCArray& aPrinterNameList)
	{//static
	aPrinterNameList.Reset();
	const TInt count=aModelNameList->ModelCount();
	for (TInt i=0;i<count;i++)
		{
		TPrinterModelName name=(*aModelNameList)[i].iModelName;
		aPrinterNameList.AppendL(name);
		}
	}

EXPORT_C void CEikonEnv::LaunchPopupMenuL(TInt aResourceId,const TPoint& aTargetPos,TPopupTargetPosType aTargetType,const CEikHotKeyTable* aHotKeyTable)
    {
    EikAppUi()->LaunchPopupMenuL(aResourceId,aTargetPos,aTargetType,aHotKeyTable);
    }

// here for now

EXPORT_C void CEikonEnv::SetContextTextured(MCoeControlBrushContext* aContext) const
    {
    aContext->iBrushStyle=CGraphicsContext::EPatternedBrush;
    aContext->iBitmap=iTexturedBitmap;
    }

EXPORT_C void CEikonEnv::SetTexturedBrush(CGraphicsContext& aGc) const
    {
    aGc.UseBrushPattern(iTexturedBitmap);
	aGc.SetBrushStyle(CGraphicsContext::EPatternedBrush);
    }

EXPORT_C void CEikonEnv::FillTexturedRect(const TRect& aRect) const
    {
    CWindowGc& gc=SystemGc();
    gc.SetPenStyle(CGraphicsContext::ENullPen);
    SetTexturedBrush(gc);
    gc.DrawRect(aRect);
    gc.SetPenStyle(CGraphicsContext::ESolidPen);
    }

EXPORT_C void CEikonEnv::AddDialogLikeControlToStackL(CCoeControl* aControl)
    {
	CEikAppUi* appUi=EikAppUi();
	if (appUi->IsDisplayingControlBetweenPriorities(ECoeStackPriorityDialog, ECoeStackPriorityFep))
		CBaActiveScheduler::LeaveNoAlert();
	aControl->SetPointerCapture(ETrue);
    appUi->AddToStackL(aControl,ECoeStackPriorityDialog);
    }

EXPORT_C void CEikonEnv::AddAlertDialogLikeControlToStackL(CCoeControl* aControl)
    {
	CEikAppUi* appUi=EikAppUi();
	if (appUi->IsDisplayingControlBetweenPriorities(ECoeStackPriorityAlert, ECoeStackPriorityFep))
		CBaActiveScheduler::LeaveNoAlert();
	aControl->SetPointerCapture(ETrue);
    appUi->AddToStackL(aControl,ECoeStackPriorityAlert);
    }

EXPORT_C void CEikonEnv::AddSleepingDialogToStackL(CCoeControl* aControl)
	{
	aControl->SetPointerCapture(ETrue);
    EikAppUi()->AddToStackL(aControl,ECoeStackPriorityDialog,ECoeStackFlagRefusesAllKeys|ECoeStackFlagRefusesFocus|ECoeStackFlagSharable);
	}

EXPORT_C void CEikonEnv::AddSleepingAlertDialogToStackL(CCoeControl* aControl)
	{
	aControl->SetPointerCapture(ETrue);
    EikAppUi()->AddToStackL(aControl,ECoeStackPriorityAlert,ECoeStackFlagRefusesAllKeys|ECoeStackFlagRefusesFocus|ECoeStackFlagSharable);
	}

EXPORT_C void CEikonEnv::RemoveFromStack(CCoeControl* aControl)
    {
    EikAppUi()->RemoveFromStack(aControl);
    }

EXPORT_C void CEikonEnv::RouseSleepingDialog(CCoeControl* aControl,TBool aRoused)
	{
    CEikAppUi* appUi=EikAppUi();
	appUi->UpdateStackedControlFlags(aControl,aRoused? 0: ECoeStackFlagRefusesAllKeys|ECoeStackFlagRefusesFocus,ECoeStackFlagRefusesAllKeys|ECoeStackFlagRefusesFocus);
	appUi->HandleStackChanged();
	}

EXPORT_C void CEikonEnv::DrawCursor(const CCoeControl* aControl,const TPoint& aPosition,TInt aWidth)
    {
    DrawCursor(aControl,aPosition,aWidth,iNormalFont->AscentInPixels(),iNormalFont->HeightInPixels());
    }

EXPORT_C void CEikonEnv::DrawCursor(const CCoeControl* aControl,const TPoint& aPosition,TInt aWidth,TInt aAscent,TInt aHeight)
    {
    if (!aControl->IsFocused())
        Panic(EEikPanicCursorControlNotFocused);
    TTextCursor cursor;
    cursor.iType=TTextCursor::ETypeRectangle;
    cursor.iHeight=aHeight;
    cursor.iWidth=aWidth;
    cursor.iAscent=aAscent;
    cursor.iFlags=0;
    cursor.iColor=KRgbWhite;
    iRootWin.SetTextCursor(*aControl->DrawableWindow(),aPosition,cursor);
    iCursorWindow=aControl;
    }

EXPORT_C void CEikonEnv::HideCursor(const CCoeControl* aControl)
    {
    if (aControl!=iCursorWindow)
#ifdef _DEBUG
        Panic(EEikPanicControlNotCursorOwner); // would steal cursor
#else
		return;
#endif
    iCursorWindow=NULL;
    iRootWin.CancelTextCursor();
    }

EXPORT_C CEikCommandButton* CEikonEnv::CreateStandardTabButtonL() const
    {
    CEikCommandButton *tabButton= new(ELeave) CEikCommandButton;
    CleanupStack::PushL(tabButton);
	TBuf<1> buf;
	buf.Append(TChar(ESymFontTabout));
	tabButton->SetTextL(buf);
	tabButton->Label()->SetFont(iSymbolFont);
	const TInt height=iEditableControlStandardHeight;
	tabButton->SetSizeL(TSize(height+3,height));
    CleanupStack::Pop();
    return(tabButton);
    }

EXPORT_C TPtrC CEikonEnv::KeyPressLabel(TInt aIndex) const
    {
    TResourceReader reader;
    return(reader.ReadTPtrC(aIndex,iKeyPressLabels));
    }

EXPORT_C TBool CEikonEnv::ConfirmLossOfAllChangesL() const
	{
    return(QueryWinL(R_EIK_TBUF_CONFIRM_ALL_LOST,R_EIK_TBUF_Y_DISCARDS));
	}

EXPORT_C TBool CEikonEnv::QueryWinL(TInt aFirstLineId,TInt aSecondLineId) const
	{
    TBuf<60> firstLine;
	TBuf<60> secondLine;
	ReadResource(firstLine,aFirstLineId);
	if (aSecondLineId)
		ReadResource(secondLine,aSecondLineId);
	return(QueryWinL(firstLine,secondLine));
	}

EXPORT_C TBool CEikonEnv::QueryWinL(const TDesC& aFirstLine,const TDesC& aSecondLine)
	{
    CEikDialog* dialog=NULL;
	if (aSecondLine.Length())
		dialog=new(ELeave) CEikInfoDialog(aFirstLine,aSecondLine,CEikInfoDialog::EIgnoreEnter);
	else
		dialog=new(ELeave) CEikInfoDialog(aFirstLine,CEikInfoDialog::EIgnoreEnter);
	return(dialog->ExecuteLD(R_EIK_DIALOG_QUERY));
	}

EXPORT_C void CEikonEnv::InfoWinL(TInt aFirstLineId,TInt aSecondLineId) const
	{
    TBuf<60> firstLine;
	TBuf<60> secondLine;
	ReadResource(firstLine,aFirstLineId);
	if (aSecondLineId)
		ReadResource(secondLine,aSecondLineId);
	InfoWinL(firstLine,secondLine);
	}

EXPORT_C void CEikonEnv::InfoWinL(const TDesC& aFirstLine,const TDesC& aSecondLine)
	{
    CEikDialog* dialog=new(ELeave) CEikInfoDialog(aFirstLine,aSecondLine);
	dialog->ExecuteLD(R_EIK_DIALOG_INFO);
	}

//internalise printer port flag 
EXPORT_C void InternalizeL(TEikPortFlag& aThing,RReadStream& aStream)
	{
	TInt thing=aStream.ReadUint8L();
	if (thing>EFilePort) // or whatever the range check is
		User::Leave(KErrCorrupt);
	//
	aThing=TEikPortFlag(thing);
	}

EXPORT_C CPrintSetup* CEikonEnv::NewDefaultPrintSetupL()
    {
    CPrintSetup* printSetup=CPrintSetup::NewL();
	CleanupStack::PushL(printSetup);
	TBuf<40> dir;
	ReadResource(dir,R_EIK_TBUF_PRINTER_DIR);
	printSetup->AddPrinterDriverDirL(dir); 
	TUid uid=KWinPrintPdlUid; //{268435709}; // KWinPrintPdlUid
	TPageMargins margins;									 
	margins.iMargins.iLeft=1440;
	margins.iMargins.iRight=1440;			
	margins.iMargins.iTop=1440;		   
	margins.iMargins.iBottom=1440;
	margins.iHeaderOffset=720;
	margins.iFooterOffset=720;
	printSetup->iNumOfFirstPage=1;
	TPageSpec pageSpec;
	TSize size=KA4PaperSizeInTwips;	//read it from the system.ini file
	CDictionaryStore* iniFile=NULL;
	TRAPD(err,iniFile=CDictionaryFileStore::SystemL(FsSession()));
	if (err==KErrNone)
		CleanupStack::PushL(iniFile);
	if (err==KErrNone && iniFile->IsPresentL(KUidDefaultPrinterModelUid))
		{
		RDictionaryReadStream stream;
		stream.OpenLC(*iniFile,KUidDefaultPrinterModelUid);
		uid.iUid=stream.ReadInt32L();
		CleanupStack::PopAndDestroy(); // stream
		}
	TBool present=(err==KErrNone && iniFile->IsPresentL(KUidDefaultPageSize));
	if (present)
		{
		RDictionaryReadStream stream;
		stream.OpenLC(*iniFile,KUidDefaultPageSize);
		stream>> size;
		CleanupStack::PopAndDestroy(); // stream
		}
	if (size==TSize(0,0) || !present)
		{
		TResourceReader reader;
		CreateResourceReaderLC(reader,R_EIK_COUNTRY_DEFAULT_PAGE_SIZE);
		size.iWidth=reader.ReadInt32();
		size.iHeight=reader.ReadInt32();
		CleanupStack::PopAndDestroy();	  //reader
		}
	if (err==KErrNone)
		CleanupStack::PopAndDestroy(); //iniFile
	printSetup->CreatePrinterDeviceL(uid,FsSession());
	pageSpec.iPortraitPageSize=size;
	printSetup->iPageMarginsInTwips=margins;
  	printSetup->PrinterDevice()->SelectPageSpecInTwips(pageSpec);
	printSetup->Header()->CreateTextL();
	printSetup->Footer()->CreateTextL();
	CleanupStack::Pop(); // printSetup
	return printSetup;
    }

EXPORT_C void CEikonEnv::SetVerboseInfoReporting(TBool aVerbose)
	{
    iEikonEnvFlags&=(~EVerboseInfoReporting);
	if (aVerbose)
		iEikonEnvFlags|=EVerboseInfoReporting;
	}

EXPORT_C void CEikonEnv::SetAutoForwarding(TBool aForwarding)
	{
    iEikonEnvFlags&=(~EAutoForwarding);
	if (aForwarding)
		{
		iEikonEnvFlags|=EAutoForwarding;
		if (!iForwardsCount)
	   		iRootWin.SetOrdinalPosition(0,ECoeWinPriorityNeverAtFront);
		}
	}

#pragma warning( disable : 4706 )

EXPORT_C void CEikonEnv::BringForwards(TBool aForwards,TInt aPriority)
	{
    if (!(iEikonEnvFlags&EAutoForwarding))
		return;
	if (aForwards)
		{
		if (!iForwardsCount++)
    		iRootWin.SetOrdinalPosition(0,aPriority); 
		}
	else if (!--iForwardsCount)
   		iRootWin.SetOrdinalPosition(0,ECoeWinPriorityNeverAtFront); 
	}

EXPORT_C MPictureFactory* CEikonEnv::PictureFactory()const
	{
	return iPictureFactory;
	}

// duplicated in EIKPROC.CPP
const TUid KUidEikLastOpenFile={0x100000fb};

EXPORT_C void CEikonEnv::ConstructAppFromCommandLineL(const CApaCommandLine& aCommandLine)
	{
	ConstructL();
	iProcess=CEikProcess::NewL(iFsSession);
	iPictureFactory = new(ELeave) TApaPictureFactory(iProcess);
	TPtrC libraryName=aCommandLine.LibraryName();
	TPtrC documentName=aCommandLine.DocumentName();
	TPtrC8 tail=aCommandLine.TailEnd();
	TApaCommand command=aCommandLine.Command();

	TFileName* scratch=new(ELeave) TFileName;
	CleanupStack::PushL(scratch);
	CEikScreenClearerWin* clearer=NULL;
	if (command==EApaCommandBackground)
		iRootWin.SetOrdinalPosition(-1000);
	else
		clearer=CEikScreenClearerWin::NewLC();
	if (command==EApaCommandOpen && !libraryName.Length())
		{
		iProcess->AppFromDocL(*scratch,documentName);
		libraryName.Set(*scratch);
		}
	if (!libraryName.Length())
		Panic(EEikPanicNoLibraryOnCommandLine);
	CEikDocument* doc=(CEikDocument*)iProcess->AddNewDocumentL(libraryName);
	iProcess->SetMainDocument(doc);
	UpdateTaskNameL();
	doc->PrepareToEditL(); // creates AppUi
	SetUpFepL(*(CEikApplication*)doc->Application());
	if (clearer)
		CleanupStack::PopAndDestroy(); // clearer
	*scratch=documentName;
	TBool doOpen=EikAppUi()->ProcessCommandParametersL(command,*scratch,tail);
	if (!scratch->Length())
		{
		CleanupStack::PopAndDestroy(); // scratch
		return;
		}
	iProcess->SetMainDocFileName(*scratch);
	UpdateTaskNameL();
	CFileStore* docStore=NULL;
	TRAPD(err,docStore=doc->OpenFileL(doOpen,*scratch,FsSession()));
	if (err==KErrCorrupt || err==KErrEof)
		{ // remove "last used file" stream from app ini file
		CDictionaryStore* iniFile=EikAppUi()->Application()->OpenIniFileLC(FsSession());
		if (iniFile!=NULL)
			{
			iniFile->RemoveL(KUidEikLastOpenFile);
			iniFile->CommitL();
			CleanupStack::PopAndDestroy(); // iniFile
			}
		}
	User::LeaveIfError(err);
	iProcess->SetMainStore(docStore);
	CleanupStack::PopAndDestroy(); // scratch
	doc->SetEditStoreL(docStore);
	}

EXPORT_C void CEikonEnv::UpdateTaskNameL()
	{
	CEikDocument* eikDoc=(CEikDocument*)(iProcess->MainDocument());
	eikDoc->UpdateTaskNameL(iWgName);
	TPtrC name=iWgName->Caption();
#if defined(__EPOC32__)
    RProcess().Rename(name);
	TUidType uidType=RProcess().Type();
	RProcess().SetType(TUidType(uidType[0], uidType[1], iWgName->AppUid()));	
#endif
	RThread().Rename(name);
	iWgName->SetWindowGroupName(iRootWin);
	}

EXPORT_C void CEikonEnv::DisplayTaskList() 
	{
	TEikServEvent taskListMsg=EEikServShowTaskList;
	SendEventToEikonServer(EEventUser, &taskListMsg, sizeof(taskListMsg));
	}

EXPORT_C void CEikonEnv::SendEventToEikonServer(TInt aEvent,const TAny* aPtr,TInt aLength)
	{
    TWsEvent event;
	event.SetType(aEvent);
	if (aLength>TWsEvent::EWsEventDataSize)
		Panic(EEikPanicOverlongEikonServerMessage);
	Mem::Copy(event.EventData(),aPtr,aLength);
	TInt wgId=iWsSession.FindWindowGroupIdentifier(0, __EIKON_SERVER_NAME, 0);
	iWsSession.SendEventToWindowGroup(wgId,event);
	}

EXPORT_C TThreadId CEikonEnv::StartAppL(const CApaCommandLine& aCommandLine)
	{
    return EikDll::StartAppL(aCommandLine);
	}

EXPORT_C void CEikonEnv::SetBusy(TBool aBusy)
	{
	TBool busyChanged=EFalse;
	if (aBusy)
		{
		if (!iBusyCount++)
			{
			iWgName->SetBusy(ETrue);
			busyChanged=ETrue;
			}
		}
	else
		{
		if (!--iBusyCount)
			{
			iWgName->SetBusy(EFalse);
			busyChanged=ETrue;
			}
		}
	if (busyChanged)
		iWgName->SetWindowGroupName(iRootWin);
	}

EXPORT_C TBool CEikonEnv::IsBusy() const
	{
	return iWgName->IsBusy();
	}

EXPORT_C void CEikonEnv::SetSystem(TBool aSystem)
	{
	iWgName->SetSystem(aSystem);
	iWgName->SetWindowGroupName(iRootWin);
	}

EXPORT_C TBool CEikonEnv::IsSystem() const
	{
	return iWgName->IsSystem();
	}

EXPORT_C void CEikonEnv::SetDocNameIsAFile(TBool aDocNameIsAFile)
	{
	iWgName->SetDocNameIsAFile(aDocNameIsAFile);
	iWgName->SetWindowGroupName(iRootWin);
	}

EXPORT_C TBool CEikonEnv::DocNameIsAFile() const
	{
	return iWgName->DocNameIsAFile();
	}
EXPORT_C void CEikonEnv::SetRespondsToShutdownEvent(TBool aRespondsToShutdownEvent)
	{
	iWgName->SetRespondsToShutdownEvent(aRespondsToShutdownEvent);
	iWgName->SetWindowGroupName(iRootWin);
	}

EXPORT_C TBool CEikonEnv::RespondsToShutdownEvent() const
	{
	return iWgName->RespondsToShutdownEvent();
	}

EXPORT_C void CEikonEnv::SetRespondsToSwitchFilesEvent(TBool aRespondsToSwitchFilesEvent)
	{
	iWgName->SetRespondsToSwitchFilesEvent(aRespondsToSwitchFilesEvent);
	iWgName->SetWindowGroupName(iRootWin);
	}

EXPORT_C TBool CEikonEnv::RespondsToSwitchFilesEvent() const
	{
	return iWgName->RespondsToSwitchFilesEvent();
	}

EXPORT_C TRgb CEikonEnv::ControlColor(TEikLogicalColor aLogicalColor,const CCoeControl& aControl) const
	{
	TRgb color=Color(aLogicalColor);
	aControl.GetColor(aLogicalColor,color);
	return color;
	}

void CEikonEnv::InitColorsL()
	{
	TInt numGrays=0;
	TInt numColors=0;
	TDisplayMode defaultMode=WsSession().GetDefModeMaxNumColors(numColors,numGrays);
	const TInt resId=(defaultMode>=EColor16? R_EIK_COLOR_COLOR16 : R_EIK_COLOR_GRAY4);
	CEikColorArray* colorArray=EikResourceUtils::CreateColorArrayLC(resId,this);
	__ASSERT_ALWAYS(colorArray->Count()==EEikColorLabelHighlightFullEmphasis+1,Panic(EEikPanicInvalidColorRange));
	CArrayFix<TRgb>* colors=new(ELeave) CArrayFixFlat<TRgb>(8);
	CleanupStack::PushL(colors);
	for (TInt ii=EEikColorWindowBackground;ii<=EEikColorLabelHighlightFullEmphasis;ii++)
		{
		__ASSERT_ALWAYS(colorArray->Contains(ii),Panic(EEikPanicLogicalColorNotFound));
		colors->InsertL(STATIC_CAST(TEikLogicalColor,ii),colorArray->Color(ii));
		}
	iColorList=CEikColorList::NewL(colors);
	CleanupStack::Pop(); // colors
	CleanupStack::PopAndDestroy(); // colorArray
	}

EXPORT_C void CEikonEnv::Reserved_1()
	{}
EXPORT_C void CEikonEnv::Reserved_2()
	{}

