📄 console.cpp
字号:
// CONSOLE.CPP
//
// Copyright (c) 1997-2002 Symbian Ltd. All rights reserved.
#include <bldvariant.hrh>
#include <w32std.h>
#include <e32hal.h>
#if !defined(__SERIES60__)
#include <fontids.h>
#endif
#include <gdi.h>
#include <e32math.h>
#include <eikenv.h>
#include "iomain.h"
#include "console.h"
#include <oplerr.h>
#include "oplr.h"
#if defined(__SERIES60__)||defined(__UIQ__)
#include "oplutil.h"
#endif
COplConsole::COplConsole(RWsSession& aSession)
:iWindow(aSession),iCurrentPos(1,1)
#if defined(__SERIES60__)||defined(__UIQ__)
,iIsFontToBeReleased(ETrue) // Assume font is to be released
#endif
{
}
COplConsole::~COplConsole()
{
// Drop the loaded font.
if (iLoadedConsoleFontId)
iDevice->RemoveFile(iLoadedConsoleFontId);
iWindow.Close();
delete iGc;
}
void COplConsole::ConstructL(CWsScreenDevice* aDevice,CWsEventHandler* aEventHandler,RWindowGroup& aParent,TDisplayMode aDisplayMode)
{
iEventHandler=aEventHandler;
iDevice=aDevice;
iRootWin=&aParent;
#if defined(__SERIES60__)
// Fix defect 817867 "reset the default window" by making the Series 60 status pane
// invisible at startup.
CEikStatusPane* statusPane=CEikonEnv::Static()->AppUiFactory()->StatusPane();
if (statusPane)
statusPane->MakeVisible(EFalse);
#endif
User::LeaveIfError(iWindow.Construct(aParent,aDisplayMode,1));
User::LeaveIfError(iDevice->CreateContext(iGc));
iGc->Activate(iWindow);
iGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
iGc->SetPenStyle(CGraphicsContext::ESolidPen);
iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
SetInverseAndUnderline(EFalse,EFalse);
TAlgStyle style;
style.SetWidthFactor(1);
style.SetHeightFactor(1);
#if defined(__SERIES60__)
User::LeaveIfError(SetStandardFont((CFont*)CEikonEnv::Static()->DenseFont(),style,EFalse,EFalse));
#elif defined(__UIQ__)
User::LeaveIfError(SetStandardFont((CFont*)CEikonEnv::Static()->LegendFont(),style,EFalse,EFalse));
#else
// Attempt to load the font by UID. If that fails, install it into FBSERV and try again.
TInt error=SetFontByUid(TUid::Uid(KScreenFontUidCourierNormal11),style,EFalse,EFalse); //HAS FontByName pair
if (error)
{
_LIT(KConsoleFontFileName,"Eon14.gdr");
TFindFile fontFile(TheRuntime()->ConEnv()->FsSession());
// First attempt to look for it in \System\Libs\. We now install it there by default
// because on Crystal EON14.GDR causes problems with checkboxes used in other
// applications. It also causes problems for backup/install because it is constantly
// marked as "In use". If we can't find it there, fall back to \System\Fonts\ which
// allows us to still run on WINS by default.
error=fontFile.FindByDir(KConsoleFontFileName,KSystemLibsPath);
if (error)
{
_LIT(KSystemFontsPath,"\\System\\Fonts\\");
User::LeaveIfError(fontFile.FindByDir(KConsoleFontFileName,KSystemFontsPath));
}
// If we get to here, should be OK to Add to FBSERV
User::LeaveIfError(iDevice->AddFile(fontFile.File(),iLoadedConsoleFontId));
// Now FBSERV is aware of it, try to load it once more...
User::LeaveIfError(SetFontByUid(TUid::Uid(KScreenFontUidCourierNormal11),style,EFalse,EFalse));
}
#endif
iWindow.Activate();
}
#if defined(__SERIES60__)||defined(__UIQ__)
TInt COplConsole::SetStyle(TAlgStyle aAlgStyle,TBool aInverse,TBool aUnderline)
{
TAlgStyle style=iFontStyle;
style.SetIsItalic(aAlgStyle.IsItalic());
if (!(iFontStyle==style))
{
const CFont* font;
TBool standardFont=OplUtil::IsStandardFontUid(iFontUid);
if (standardFont)
font=OplUtil::MapFontUidToStandardFontL(iFontUid);
else
{
TInt ret=iDevice->GetFontById((CFont*&)font,iFontUid,aAlgStyle); //NEEDS FontByName
if (ret!=KErrNone)
{
if (ret==KErrNotFound || ret==KErrGeneral)
ret=KOplErrFontNotLoaded;
return ret;
}
}
ReleaseCurrentFontIfNecessary();
iGc->UseFont(font);
iIsFontToBeReleased=(standardFont)?EFalse:ETrue;
iFont=(CFont*)font;
iFontStyle=style;
// char size unchanged !?!
}
SetInverseAndUnderline(aInverse,aUnderline);
return KErrNone;
}
void COplConsole::ReleaseCurrentFontIfNecessary()
{
if (iFont)
{
if (iIsFontToBeReleased!=EFalse)
{
iDevice->ReleaseFont(iFont);
iFont=NULL;
iIsFontToBeReleased=EFalse;
}
}
}
#else
TInt COplConsole::SetStyle(TAlgStyle aAlgStyle,TBool aInverse,TBool aUnderline)
{
TAlgStyle style=iFontStyle;
style.SetIsItalic(aAlgStyle.IsItalic());
if (!(iFontStyle==style))
{
CFont* font;
TInt ret=iDevice->GetFontById(font,iFontUid,style);
if (ret!=KErrNone)
{
if (ret==KErrGeneral)
ret=KOplErrFontNotLoaded;
return ret;
}
if (iFont)
iDevice->ReleaseFont(iFont);
iGc->UseFont(font);
iFont=font;
iFontStyle=style;
// char size unchanged !?!
}
SetInverseAndUnderline(aInverse,aUnderline);
return KErrNone;
}
#endif
void COplConsole::SetInverseAndUnderline(TBool aInverse,TBool aUnderline)
{
if ((aInverse&&!(iFlags&EConsoleInverse))||((!aInverse)&&(iFlags&EConsoleInverse)))
{ // need to set gc to aInverse
if (aInverse)
{
iGc->SetBrushColor(KRgbBlack);
iGc->SetPenColor(KRgbWhite);
iFlags|=EConsoleInverse;
}
else
{
iGc->SetBrushColor(KRgbWhite);
iGc->SetPenColor(KRgbBlack);
iFlags&=~EConsoleInverse;
}
}
if ((aUnderline&&!(iFlags&EConsoleUnderline))||((!aUnderline)&&(iFlags&EConsoleUnderline)))
{ // need to set gc to use underline
iGc->SetUnderlineStyle((aUnderline)?EUnderlineOn:EUnderlineOff);
if (aUnderline)
iFlags|=EConsoleUnderline;
else
iFlags&=~EConsoleUnderline;
}
}
#ifdef ___NOT_YET____
CFont* COplConsole::GetFontByNameL(TPtrC aFontName,TAlgStyle /*aAlgStyle*/,TBool aInverse,TBool aUnderline)
{
TFontSpec fontSpec(aFontName,200);
CFont* font;
TInt err=((CWsScreenDevice*)iDevice)->GetNearestFontInTwips(font,fontSpec);
if (err!=KErrNone)
{
if (err==KErrNotFound)
err=KOplErrFontNotLoaded;
User::Leave(err);
}
return font;
}
#endif
#ifdef _NOT_YET_
// FontByName not currently used by OPLT.
TInt COplConsole::SetFontByName(TPtrC aFontName,TAlgStyle /*aAlgStyle*/,TBool aInverse,TBool aUnderline) //IS FontByName pair
{
TInt ret=ResizeWindow();
if (ret!=KErrNone)
return ret;
TFontSpec fontSpec(aFontName,200);
TFontStyle myStyle;
fontSpec.iFontStyle=myStyle;
//is it a standard font?
// TBool standardFont=test if font is standard();
CFont* font;
TInt err=((CWsScreenDevice*)iDevice)->GetNearestFontInTwips(font,fontSpec);
if (err!=KErrNone)
{
if (err==KErrNotFound)
err=KOplErrFontNotLoaded;
return err;
}
ReleaseCurrentFontIfNecessary();
iGc->UseFont(font); //pukka because unused
iFont=font;
// iIsFontToBeReleased=(standardFont)?EFalse:ETrue;
// iFontUid=aUid;
// iFontStyle=aAlgStyle;
TInt charWidth=iFont->MaxNormalCharWidthInPixels();
if (charWidth==0)
charWidth=iFont->MaxCharWidthInPixels();
iCharSizeInPixels=TSize(charWidth,iFont->HeightInPixels());
ResetScreenSize();
SetCursorToFont();
SetInverseAndUnderline(aInverse,aUnderline);
iCurrentPos=TPoint(1,1);
DrawCursorIfOn(iCurrentPos);
return KErrNone;
}
#endif
#if defined(__SERIES60__)||defined(__UIQ__)
TInt COplConsole::SetFontByUidL(TUid aUid,TAlgStyle aAlgStyle,TBool aInverse,TBool aUnderline) //NEEDS FontByName pair?
{
TInt ret=ResizeWindow();
if (ret!=KErrNone)
return ret;
if (iFontUid!=aUid || !(aAlgStyle==iFontStyle))
{ // need to change font
const CFont* font;
TBool standardFont=OplUtil::IsStandardFontUid(iFontUid);
if (standardFont)
font=OplUtil::MapFontUidToStandardFontL(iFontUid);
else
{
ret=iDevice->GetFontById((CFont*&)font,aUid,aAlgStyle); //NEEDS FontByName
if (ret!=KErrNone)
{
if (ret==KErrNotFound)
ret=KOplErrFontNotLoaded;
return ret;
}
}
ReleaseCurrentFontIfNecessary();
iGc->UseFont(font); //pukka
iIsFontToBeReleased=(standardFont)?EFalse:ETrue;
iFont=(CFont*)font;
iFontUid=aUid;
iFontStyle=aAlgStyle;
TInt charWidth=iFont->MaxNormalCharWidthInPixels();
if (charWidth==0)
charWidth=iFont->MaxCharWidthInPixels();
iCharSizeInPixels=TSize(charWidth,iFont->HeightInPixels());
ResetScreenSize();
SetCursorToFont();
}
SetInverseAndUnderline(aInverse,aUnderline);
iCurrentPos=TPoint(1,1);
DrawCursorIfOn(iCurrentPos);
return KErrNone;
}
/*
* Use one of the CEikonEnv "built-in" fonts:
*/
TInt COplConsole::SetStandardFont(const CFont* aFont,TAlgStyle /*aAlgStyle*/,TBool aInverse,TBool aUnderline) //IS FontByName pair
{
TInt ret=ResizeWindow();
if (ret!=KErrNone)
return ret;
ReleaseCurrentFontIfNecessary();
iGc->UseFont(aFont); //pukka
iIsFontToBeReleased=EFalse;//This is a standard font.
iFont=(CFont*)aFont;
// TInt charWidth=iFont->MaxNormalCharWidthInPixels();
TInt charWidth=iFont->WidthZeroInPixels();
if (charWidth==0)
charWidth=iFont->MaxCharWidthInPixels();
iCharSizeInPixels=TSize(charWidth,iFont->HeightInPixels());
ResetScreenSize();
SetCursorToFont();
SetInverseAndUnderline(aInverse,aUnderline);
iCurrentPos=TPoint(1,1);
DrawCursorIfOn(iCurrentPos);
return KErrNone;
}
#else
TInt COplConsole::SetFontByUid(TUid aUid,TAlgStyle aAlgStyle,TBool aInverse,TBool aUnderline) //NEEDS FontByName pair?
{
TInt ret=ResizeWindow();
if (ret!=KErrNone)
return ret;
if (iFontUid!=aUid || !(aAlgStyle==iFontStyle))
{ // need to change font
CFont* font;
ret=iDevice->GetFontById(font,aUid,aAlgStyle);
if (ret!=KErrNone)
{
if (ret==KErrNotFound)
ret=KOplErrFontNotLoaded;
return ret;
}
if (iFont)
iDevice->ReleaseFont(iFont);
iGc->UseFont(font);
iFont=font;
iFontUid=aUid;
iFontStyle=aAlgStyle;
TInt charWidth=iFont->MaxNormalCharWidthInPixels();
if (charWidth==0)
charWidth=iFont->MaxCharWidthInPixels();
iCharSizeInPixels=TSize(charWidth,iFont->HeightInPixels());
ResetScreenSize();
SetCursorToFont();
}
SetInverseAndUnderline(aInverse,aUnderline);
iCurrentPos=TPoint(1,1);
DrawCursorIfOn(iCurrentPos);
return KErrNone;
}
#endif
TInt COplConsole::ResizeWindow()
{
TMachineInfoV1Buf machInfo;
UserHal::MachineInfo(machInfo);
TRect rect(TPoint(0,0),machInfo().iDisplaySizeInPixels);
TInt ret=iWindow.SetExtentErr(rect.iTl,machInfo().iDisplaySizeInPixels);
if (ret==KErrNone)
DoClearRect(rect);
return ret;
}
void COplConsole::ResetScreenSize()
{
TSize windowSize(iWindow.Size());
iScreenSizeInChars=windowSize;
iScreenSizeInChars.iWidth/=iCharSizeInPixels.iWidth;
iScreenSizeInChars.iHeight/=iCharSizeInPixels.iHeight;
iTopLeft.iX=(windowSize.iWidth-(iScreenSizeInChars.iWidth*iCharSizeInPixels.iWidth))/2;
iTopLeft.iY=(windowSize.iHeight-(iScreenSizeInChars.iHeight*iCharSizeInPixels.iHeight))/2;
SetScreen(iScreenSizeInChars,TPoint(1,1)); // will not fail in this case
}
TInt COplConsole::SetScreen(TSize aSizeInChars,TPoint aPosInChars)
{
if (aPosInChars==TPoint(0,0))
{
TSize size=(iScreenSizeInChars-aSizeInChars);
aPosInChars.iX=size.iWidth/2+1;
aPosInChars.iY=size.iHeight/2+1;
}
TRect rect=TRect(aPosInChars,aSizeInChars);
if (aPosInChars.iX<1 || aPosInChars.iY<1 || aSizeInChars.iWidth<1 || aSizeInChars.iHeight<1 ||
iScreenSizeInChars.iWidth<rect.iBr.iX-1 ||
iScreenSizeInChars.iHeight<rect.iBr.iY-1)
return KErrArgument;
iScreenRectInChars=rect;
iGc->SetClippingRect(CharsToPixels(TRect(TPoint(1,1),aSizeInChars))); // only allow drawing to screen area
return KErrNone;
}
TRect COplConsole::CharsToPixels(const TRect& aCharRect)
{
TInt charWidth=iCharSizeInPixels.iWidth;
TInt charHeight=iCharSizeInPixels.iHeight;
TPoint topLeft(iTopLeft.iX+(iScreenRectInChars.iTl.iX-1)*charWidth,iTopLeft.iY+(iScreenRectInChars.iTl.iY-1)*charHeight);
TPoint tl((topLeft.iX+(aCharRect.iTl.iX-1)*charWidth),(topLeft.iY+(aCharRect.iTl.iY-1)*charHeight));
TPoint br((topLeft.iX+(aCharRect.iBr.iX-1)*charWidth),(topLeft.iY+(aCharRect.iBr.iY-1)*charHeight));
return TRect(tl,br);
}
void COplConsole::ScreenInfo(SScreenInfo& aScreenInfo)
{
aScreenInfo.iLeftInPixels=(TUint16)iTopLeft.iX;
aScreenInfo.iTopInPixels=(TUint16)iTopLeft.iY;
TSize size=iScreenRectInChars.Size();
aScreenInfo.iTextWidth=(TUint16)size.iWidth;
aScreenInfo.iTextHeight=(TUint16)size.iHeight;
aScreenInfo.iWindowId=1;
aScreenInfo.iNotUsed=0;
aScreenInfo.iCharWidth=(TUint16)iCharSizeInPixels.iWidth;
aScreenInfo.iCharHeight=(TUint16)iCharSizeInPixels.iHeight;
aScreenInfo.iFontUid=iFontUid.iUid;
}
void COplConsole::DoClearRect(const TRect& aRectInPixels)
{
if (iFlags&EConsoleInverse)
iGc->SetBrushColor(KRgbWhite);
iGc->Clear(aRectInPixels);
if (iFlags&EConsoleInverse)
iGc->SetBrushColor(KRgbBlack);
}
void COplConsole::Cls()
{
DoClearRect(CharsToPixels(TRect(TPoint(1,1),iScreenRectInChars.Size())));
iCurrentPos=TPoint(1,1);
DrawCursorIfOn(iCurrentPos);
}
void COplConsole::ClearRect(const TRect& aRectInChars)
{
DoClearRect(CharsToPixels(aRectInChars));
}
TPoint COplConsole::CurrentPos() const
{
return iCurrentPos;
}
TInt COplConsole::At(const TPoint& aPos)
{
if (aPos.iX<1 || aPos.iX>iScreenRectInChars.Size().iWidth || aPos.iY<1 || aPos.iY>iScreenRectInChars.Size().iHeight)
return KErrArgument;
iCurrentPos=aPos;
DrawCursorIfOn(iCurrentPos);
return KErrNone;
}
void COplConsole::BackSpace()
{
if (iCurrentPos.iX>1)
iCurrentPos.iX--;
}
void COplConsole::Cr()
{
iCurrentPos.iX=1;
}
void COplConsole::Lf()
{
ScrollIfNeeded();
iCurrentPos.iY++;
}
void COplConsole::Tab()
{
ScrollIfNeeded();
iCurrentPos.iX=((iCurrentPos.iX+(KTabStop-1))&~(KTabStop-1))+1;
WrapIfNeeded();
}
void COplConsole::ScrollIfNeeded()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -