⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 terminalcontrol.cpp

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*    terminalcontrol.cpp * * A terminal UI control class * * Copyright 2002-2005 Petteri Kangaslampi * * See license.txt for full copyright and license information.*/#include <e32std.h>#include <gdi.h>#include <eikenv.h>#include <e32svr.h>#include "terminalcontrol.h"#ifdef PUTTY_S60#include "termfepext1.h"#include <aknedsts.h>#endif#include "logfile.h"_LIT(KPanic, "TerminalControl");const TUint KNewline = 0x2028; // unicode forced line break_LIT(KTerminalControl, "tc");#ifdef LOGFILE_ENABLEDstatic void AssertFail(TInt aLine) {    LFPRINT((_L("ASSERT FAIL: terminalcontrol.cpp %d"), aLine));    User::Panic(KTerminalControl, aLine);}#define assert(x) __ASSERT_ALWAYS(x, AssertFail(__LINE__))#else#define assert(x) __ASSERT_ALWAYS(x, User::Panic(KTerminalControl, __LINE__))#endif#define TRACE LFPRINT((_L("terminalcontrol.cpp %d"), __LINE__))// Cursor and selection color XOR bit masks// 0x00bbggrr#define KCursorFgXor TRgb(0x00ffffff)#define KCursorBgXor TRgb(0x00ffffff)#define KSelectionFgXor TRgb(0x0000ffff)#define KSelectionBgXor TRgb(0x0000ffff)#define KFepEditFgXor TRgb(0x00ffffff)#define KFepEditBgXor TRgb(0x00ffffff)CTerminalControl::CTerminalControl(MTerminalObserver &aObserver)    : iObserver(aObserver) {    iGrayed = EFalse;    iCursorX = -1;    iCursorY = -1;}CTerminalControl::~CTerminalControl() {    delete [] iChars;    delete [] iAttributes;#ifdef PUTTY_S60    delete iFepExt1;#endif}void CTerminalControl::ConstructL(const TRect &aRect,                                  RWindow &aContainerWindow) {    SetContainerWindowL(aContainerWindow);    SetRect(aRect);    Resize();    AllocateBuffersL();    Clear();#ifdef PUTTY_S60    iFepExt1 = CTermFepExt1::NewL(*this);#endif}void CTerminalControl::SetGrayed(TBool aGrayed) {    iGrayed = aGrayed;    DrawDeferred();}// Resizes the terminal in response to size or font changevoid CTerminalControl::Resize() {    TRect rect = Rect();    TInt width = rect.iBr.iX - rect.iTl.iX;    TInt height = rect.iBr.iY - rect.iTl.iY;    assert((iFontWidth > 0) && (iFontHeight > 0));    assert((width >= iFontWidth) && (height >= iFontHeight));    iCharWidth = width / iFontWidth;    iCharHeight = height / iFontHeight;    TRAPD(error, AllocateBuffersL());    iObserver.TerminalSizeChanged(iCharWidth, iCharHeight);    if ( error != KErrNone ) {        User::Panic(KPanic, error);    }        if ( iCursorX >= iCharWidth ) {        iCursorX = iCharWidth - 1;    }    if ( iCursorY >= iCharHeight ) {        iCursorY = iCharHeight - 1;    }    if ( iSelectX >= iCharWidth ) {        iSelectX = iCharWidth - 1;    }    if ( iSelectY >= iCharHeight ) {        iSelectY = iCharHeight - 1;    }    if ( iMarkX >= iCharWidth ) {        iMarkX = iCharWidth - 1;    }    if ( iMarkY >= iCharHeight ) {        iMarkY = iCharHeight - 1;    }}// (re)allocate character and attribute buffersvoid CTerminalControl::AllocateBuffersL() {    delete [] iChars;    iChars = NULL;    delete [] iAttributes;    iAttributes = NULL;    iChars = new (ELeave) TText[iCharWidth*iCharHeight];    iAttributes = new (ELeave) TTerminalAttribute[iCharWidth*iCharHeight];    Clear();}// Clear the buffersvoid CTerminalControl::Clear() {    TText *c = iChars;    TTerminalAttribute *a = iAttributes;    TInt num = iCharWidth * iCharHeight;    while ( num-- ) {        *c++ = ' ';        a->iFgColor = KRgbBlack;        a->iBgColor = KRgbWhite;        a->iBold = EFalse;        a->iUnderline = EFalse;        a++;    }}// Draws text on the terminal window. The coordinates are zero-based// character coordinates inside the terminal.void CTerminalControl::DrawText(TInt aX, TInt aY, const TDesC &aText,                                TBool aBold, TBool aUnderline,                                TRgb aForeground, TRgb aBackground) {    // Don't draw text while grayed out    if ( iGrayed ) {        return;    }    // Check that we are at least partially on screen    if ( (aX < 0) || (aY < 0) || (aX >= iCharWidth) || (aY >= iCharHeight) ) {        return;    }    // Write the text to our character and attribute buffers    TInt numChars = aText.Length();    if ( numChars > (iCharWidth - aX) ) {        numChars = iCharWidth - aX;    }    TText *c = &iChars[aX + aY*iCharWidth];    TTerminalAttribute *a = &iAttributes[aX + aY * iCharWidth];    for ( TInt i = 0; i < numChars; i++ ) {        *c++ = aText[i];        a->iFgColor = aForeground;        a->iBgColor = aBackground;        a->iBold = aBold;        a->iUnderline = aUnderline;        a++;    }        // Actually draw the text on screen    UpdateDisplay(aX, aY, numChars);}// Set cursor positionvoid CTerminalControl::SetCursor(TInt aX, TInt aY) {    // Remember old position, set new    TInt oldCursorX = iCursorX;    TInt oldCursorY = iCursorY;    iCursorX = aX;    iCursorY = aY;    if ( iGrayed ) {        return;    }    // Redraw the affected character cells if they are inside the terminal    if ( (oldCursorX >= 0) && (oldCursorX < iCharWidth) &&         (oldCursorY >= 0) && (oldCursorY < iCharHeight) ) {        UpdateDisplay(oldCursorX, oldCursorY, 1);    }    if ( (iCursorX >= 0) && (iCursorX < iCharWidth) &&         (iCursorY >= 0) && (iCursorY < iCharHeight) ) {        UpdateDisplay(iCursorX, iCursorY, 1);    }}// Set modifiers for next key eventvoid CTerminalControl::SetNextKeyModifiers(TUint aModifiers) {    iNextKeyModifiers = aModifiers;}// Set select modevoid CTerminalControl::SetSelectMode(TBool aSelectMode) {    iSelectMode = aSelectMode;    iHaveSelection = EFalse;    iSelectX = iCursorX;    iSelectY = iCursorY;    if ( iSelectX < 0 ) {        iSelectX = 0;    }    if ( iSelectX >= iCharWidth ) {        iSelectX = iCharWidth - 1;    }    if ( iSelectY < 0 ) {        iSelectY = 0;    }    if ( iSelectY >= iCharHeight ) {        iSelectY = iCharHeight - 1;    }    DrawDeferred();}// Set markvoid CTerminalControl::SetMark() {    if ( !iSelectMode ) {        return;    }    iHaveSelection = ETrue;    iMarkX = iSelectX;    iMarkY = iSelectY;    DrawDeferred();}// Remove selectionvoid CTerminalControl::RemoveMark() {    iHaveSelection = EFalse;    if ( iSelectX >= iCharWidth ) {        iSelectX = iCharWidth - 1;    }    DrawDeferred();}// Copy current selectionconst HBufC *CTerminalControl::CopySelectionLC() {    if ( !iHaveSelection ) {        return HBufC::NewLC(0);    }    TInt x1, y1, x2, y2;    GetSelectionInScanOrder(x1, y1, x2, y2);    // Calculate a (fairly accurate) upper bound on the output text size.    // The final text size may be less as the algorithm removes trailing    // whitespace from lines.    TInt maxTextLen = 0;    if ( y1 == y2 ) {        maxTextLen = x2 - x1;        assert(maxTextLen >= 0);    } else {        assert(y2 > y1);        // Note that we need to add one character per linefeed        maxTextLen = (iCharWidth - x1 + 1 +                      (iCharWidth+1) * (y2 - y1 - 1) +                      x2);    }    // Allocate the buffer    HBufC *buf = HBufC::NewLC(maxTextLen);        if ( maxTextLen == 0 ) {        return buf;    }    TPtr16 des = buf->Des();    // Copy text to the buffer, appending a newline after each line and    // removing trailing whitespace. One exception: If the selection is on    // a single line and contains nothing but spaces, we'll copy it as such,    // since we can only assume the user wanted to copy spaces.    if ( y1 == y2 ) {        // Single-line selection        TInt len = x2-x1;        TText *chars = &iChars[y1*iCharWidth + x1];        while ( (chars[len-1] == ' ') && (len > 0) ) {            len--;        }        if ( len == 0 ) {            // Nothing but spaces -- let's copy them all            len = x2-x1;        }        des.Append(TPtrC(chars, len));    } else {        // Multi-line selection.        // Start of the selection to the end of the first line        TInt len = iCharWidth - x1;        TText *chars = &iChars[y1*iCharWidth + x1];        while ( (chars[len-1] == ' ') && (len > 0) ) {            len--;        }        des.Append(TPtrC(chars, len));        des.Append(KNewline);        // Full lines        for ( TInt y = (y1+1); y < y2; y++ ) {            len = iCharWidth;            chars = &iChars[y*iCharWidth];            while ( (chars[len-1] == ' ') && (len > 0) ) {                len--;            }            des.Append(TPtrC(chars, len));            des.Append(KNewline);        }        // Start of the last line to the end of the selection        len = x2;        chars = &iChars[y2*iCharWidth];        while ( (chars[len-1] == ' ') && (len > 0) ) {            len--;        }        des.Append(TPtrC(chars, len));    }        return buf;}// Gets the current selection in raster scan ordervoid CTerminalControl::GetSelectionInScanOrder(    TInt &aStartX, TInt &aStartY, TInt &aEndX, TInt &aEndY) const {        // Flip mark and selection cursor coordinates as necessary so that we    // have the selection in raster scan order    aStartY = iSelectY;    aStartX = iSelectX;    if ( iMarkY < aStartY ) {        aStartY = iMarkY;        aStartX = iMarkX;    }    aEndY = iMarkY;    aEndX = iMarkX;    if ( iSelectY > aEndY ) {        aEndY = iSelectY;        aEndX = iSelectX;    }    if ( (aEndY == aStartY) && (aStartX > aEndX) ) {        TInt tmp = aEndX;        aEndX = aStartX;        aStartX = tmp;    }}// Calculate the final colors for a character cellvoid CTerminalControl::GetFinalColors(TInt aX, TInt aY, TRgb &aForeground,                                      TRgb &aBackground) const {    assert((aX >= 0) && (aX < iCharWidth));    assert((aY >= 0) && (aY < iCharHeight));    // Basic character colors    TTerminalAttribute *attribs = &iAttributes[aY * iCharWidth + aX];    TRgb fg = attribs->iFgColor;    TRgb bg = attribs->iBgColor;    // FEP editor    if ( iFepEditActive && (aY == iFepEditY) &&         (aX >= iFepEditX) && (aX < (iFepEditX + iFepEditDisplayLen)) ) {        // Note that we use the FEP edit start position as a reference for the        // whole FEP editor display. This way the color stays constant        // regardless of the underlying content        attribs = &iAttributes[iFepEditOrigY * iCharWidth + iFepEditOrigX];        // Selection and cursor are not visible in the FEP editor        aForeground = attribs->iFgColor ^ KFepEditFgXor;        aBackground = attribs->iBgColor ^ KFepEditBgXor;        return;    }    // Selection    if ( iHaveSelection ) {                TInt selStartX, firstSelLine, selEndX, lastSelLine;        GetSelectionInScanOrder(selStartX, firstSelLine, selEndX, lastSelLine);        TBool inSelection = EFalse;        if ( aY == firstSelLine ) {            // On the first selected line            if ( aY == lastSelLine ) {                // This line is both the first and the last selected line                if ( (aX >= selStartX) && (aX < selEndX) ) {                    inSelection = ETrue;                }            } else {                if ( aX >= selStartX ) {                    inSelection = ETrue;                }            }        } else if ( aY == lastSelLine ) {            // Last selected line            if ( aX < selEndX ) {                inSelection = ETrue;            }        } else if ( (aY > firstSelLine) && (aY < lastSelLine) ) {            // On a fully selected line            inSelection = ETrue;        }        if ( inSelection ) {            fg = fg ^ KSelectionFgXor;            bg = bg ^ KSelectionBgXor;        }    }    // Cursor    if ( (aX == iCursorX) && (aY == iCursorY) ) {        fg = fg ^ KCursorFgXor;        bg = bg ^ KCursorBgXor;    }    aForeground = fg;    aBackground = bg;}// Get the final character for a character cellTText CTerminalControl::FinalChar(TInt aX, TInt aY) const {    assert((aX >= 0) && (aX < iCharWidth));    assert((aY >= 0) && (aY < iCharHeight));        // FEP editor

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -