Added terminalkeyboard console (terminalkeyboardcons.dll)
authorTom Sutcliffe <thomas.sutcliffe@accenture.com>
Mon, 23 Aug 2010 18:10:31 +0100
changeset 33 cfabd0207208
parent 32 50af04b02d7d
child 34 284c68d7a3ac
Added terminalkeyboard console (terminalkeyboardcons.dll)
build/ncp/platform.mmh
build/s60/tb92/platform.mmh
documentation/common_mmh.pod
plugins/consoles/common/bld.inf
plugins/consoles/terminalkeyboardcons/terminalkeyboardcons.cpp
plugins/consoles/terminalkeyboardcons/terminalkeyboardcons.h
plugins/consoles/terminalkeyboardcons/terminalkeyboardcons.mmp
plugins/consoles/vt100cons/src/vt100/vtc_cursor_tracker.cpp
plugins/consoles/vt100cons/src/vt100/vtc_cursor_tracker.h
--- a/build/ncp/platform.mmh	Fri Aug 13 16:18:06 2010 +0100
+++ b/build/ncp/platform.mmh	Mon Aug 23 18:10:31 2010 +0100
@@ -20,5 +20,6 @@
 #define FSHELL_NO_APPARC_SUPPORT
 #define FSHELL_FLEXIBLEMM_AWARE
 #define FSHELL_ARM11XX_SUPPORT
+#define FSHELL_TRACECORE_SUPPORT
 
 #endif // FSHELL_PLATFORM_MMH
--- a/build/s60/tb92/platform.mmh	Fri Aug 13 16:18:06 2010 +0100
+++ b/build/s60/tb92/platform.mmh	Mon Aug 23 18:10:31 2010 +0100
@@ -29,5 +29,6 @@
 #define FSHELL_DYNAMICSTARTUP_SUPPORT
 
 #define FSHELL_TESTEXECUTE_SUPPORT
+#define FSHELL_TRACECORE_SUPPORT
 
 #endif // FSHELL_PLATFORM_MMH
--- a/documentation/common_mmh.pod	Fri Aug 13 16:18:06 2010 +0100
+++ b/documentation/common_mmh.pod	Mon Aug 23 18:10:31 2010 +0100
@@ -218,6 +218,10 @@
 
 The TestExecute APIs are available.
 
+=item FSHELL_TRACECORE_SUPPORT
+
+The TraceCore APIs are available.
+
 =back
 
 A couple of further macros follow - these are specifically for platforms that provide an custom implementation of the relevant command rather than using fshell's built-in version.
--- a/plugins/consoles/common/bld.inf	Fri Aug 13 16:18:06 2010 +0100
+++ b/plugins/consoles/common/bld.inf	Mon Aug 23 18:10:31 2010 +0100
@@ -49,3 +49,7 @@
 PRJ_MMPFILES
 ..\tefcons\tefcons.mmp
 #endif
+
+#ifdef FSHELL_TRACECORE_SUPPORT
+..\terminalkeyboardcons\terminalkeyboardcons.mmp
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/terminalkeyboardcons/terminalkeyboardcons.cpp	Mon Aug 23 18:10:31 2010 +0100
@@ -0,0 +1,393 @@
+// terminalkeyboardcons.cpp
+// 
+// Copyright (c) 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
+//
+#include "terminalkeyboardcons.h"
+#include <fshell/common.mmh>
+#include <e32debug.h>
+#include <fshell/memoryaccess.h>
+
+const TInt KTkbdMessageId = 0xD6;
+// These are the defaults unless overridden by --console-size
+const TInt KWidth = 80;
+const TInt KHeight = 24;
+
+class CMessageWatcher : public CActive
+	{
+public:
+	CMessageWatcher(CTerminalKeyboardCons& aConsole)
+		: CActive(CActive::EPriorityStandard), iConsole(aConsole)
+		{
+		CActiveScheduler::Add(this);
+		iConsole.iDriver.RequestMessage(iStatus);
+		SetActive();
+		}
+
+	void DoCancel()
+		{
+		iConsole.iDriver.CancelMessage();
+		}
+
+	void RunL()
+		{
+		iConsole.MessageReceived(iStatus.Int());
+		if (iStatus.Int() == KErrNone)
+			{
+			iConsole.iDriver.RequestMessage(iStatus);
+			SetActive();
+			}
+		}
+
+	~CMessageWatcher()
+		{
+		Cancel();
+		}
+
+private:
+	CTerminalKeyboardCons& iConsole;
+	};
+
+
+CTerminalKeyboardCons::CTerminalKeyboardCons()
+	: iTracker(TSize(KWidth, KHeight), this)
+	{
+	}
+
+CTerminalKeyboardCons::~CTerminalKeyboardCons()
+	{
+	CleanupUnderlyingConsole();
+	delete iWatcher;
+	iDriver.Close();
+	iTextBuffer.Close();
+	iMungedTextBuffer.Close();
+	}
+
+TInt CTerminalKeyboardCons::Create(const TDesC& aTitle, TSize aSize)
+	{
+	TRAPD(err, ConstructL(aTitle, aSize));
+	HandleConsoleCreationError(_L("TerminalKeyboard"), err);
+	return err;
+	}
+
+void CTerminalKeyboardCons::ConstructL(const TDesC& aTitle, const TSize& aSize)
+	{
+	if (aTitle == _L("debug")) SetDebug(ETrue);
+	if (aSize.iWidth > 10 && aSize.iHeight > 10)
+		{
+		// Override size now we know it, checking that it's sane-ish - be sure to do this before anything that uses the console size!
+		new (&iTracker) TCursorTracker(aSize, this);
+		}
+
+	iTextBuffer.CreateMaxL(ScreenSize().iWidth * ScreenSize().iHeight);
+#ifdef SHOW_TEXTSHELL_BORDERS
+	iMungedTextBuffer.CreateL((ScreenSize().iWidth + 2) * (ScreenSize().iHeight + 2));
+#endif
+
+	TInt err = User::LoadLogicalDevice(KTcLddDriverName);
+	if (err && err != KErrAlreadyExists)
+		{
+		Message(EError, _L("Couldn't load LDD %S: %d"), &KTcLddDriverName, err);
+		User::Leave(err);
+		}
+
+	// Idiotic driver only accepts connections from processes with nokia vid - like that will stop us
+	TUint originalVid = RProcess().VendorId();
+	RMemoryAccess memAccess;
+	User::LeaveIfError(memAccess.Open());
+	TProcessProperties props;
+	props.iVid = 0x101FB657;
+	RProcess me; me.Open(RProcess().Id());
+	memAccess.SetProcessProperties(me, props);
+
+	err = iDriver.Open();
+
+	props.iVid = originalVid;
+	memAccess.SetProcessProperties(me, props);
+	me.Close();
+	memAccess.Close();
+
+	if (err)
+		{
+		Message(EError, _L("Couldn't open RTcDriver: %d"), err);
+		User::Leave(err);
+		}
+
+	err = iDriver.Subscribe(KTkbdMessageId);
+	if (err)
+		{
+		Message(EError, _L("Couldn't subscribe: %d"), err);
+		User::Leave(err);
+		}
+
+	iWatcher = new(ELeave) CMessageWatcher(*this);
+	CleanupUnderlyingConsole();
+
+	ClearScreen();
+	}
+
+	
+TInt CTerminalKeyboardCons::Extension_(TUint aExtensionId, TAny*& a0, TAny* a1)
+	{
+	/*if (aExtensionId == ConsoleMode::KSetConsoleModeExtension)
+		{
+		ConsoleMode::TMode mode = (ConsoleMode::TMode)(TInt)a1;
+		iInputController->SetMode(mode);
+		iOutputController->SetMode(mode);
+		return KErrNone;
+		}
+	else*/
+	/*else if (aExtensionId == ConsoleAttributes::KSetConsoleAttributesExtension)
+		{
+		ConsoleAttributes::TAttributes* attributes = (ConsoleAttributes::TAttributes*)a1;
+		return iOutputController->SetAttributes(attributes->iAttributes, attributes->iForegroundColor, attributes->iBackgroundColor);
+		}*/
+	
+	TInt ret = MIosrvConsoleHelper_Extension(aExtensionId, a0, a1);
+	if (ret == KErrExtensionNotSupported) ret = CConsoleBase::Extension_(aExtensionId, a0, a1);
+	return ret;
+	}
+
+void CTerminalKeyboardCons::MessageReceived(TInt aError)
+	{
+	Message(EDebug, _L("MessageReceived err=%d"), aError);
+	TInt err = aError;
+	if (err == KErrNone)
+		{
+		TPtrC8 data;
+		err = iDriver.GetMessageData(data);
+		if (!err && data.Length() < 1) err = KErrCorrupt;
+		if (!err && !iGotKey)
+			{
+			TUint16 rawkey = data[0];
+			Message(EDebug, _L("CTerminalKeyboardCons got key %d"), (TInt)rawkey);
+
+			// Terminal keyboard doesn't support control keys or cursor keys so we use our own two-stage sticky modifier (like unix meta key I think?)
+			if (iBacktickModifierDown)
+				{
+				// Terminal keyboard sends 2,4,6,8 for cursors, so we translate backtick-2 (ie backtick-leftarrow) as meaning left arrow
+				if (rawkey == '2') rawkey = (TUint16)EKeyUpArrow;
+				else if (rawkey == '4') rawkey = (TUint16)EKeyLeftArrow;
+				else if (rawkey == '6') rawkey = (TUint16)EKeyRightArrow;
+				else if (rawkey == '8') rawkey = (TUint16)EKeyDownArrow;
+				else if (rawkey >= 'a' && rawkey <= 'z')
+					{
+					// backtick-c means CTRL-C
+					rawkey = rawkey - 'a'+1;
+					}
+				else if (rawkey == ' ') rawkey = '`'; // backtick-space is how you do a backtick
+				else if (rawkey == '`') rawkey = (TUint16)EKeyEscape; // backtick-backtick is 'escape'
+				else if (rawkey == '1') rawkey = (TUint16)EKeyTab; // backtick-1 is 'tab'
+				iBacktickModifierDown = EFalse;
+				Message(EDebug, _L("Backtick escape converted to %d"), (TInt)rawkey);
+				}
+			else if (rawkey == '`')
+				{
+				iBacktickModifierDown = ETrue;
+				return;
+				}
+
+			iKeyCode = (TKeyCode)rawkey; // Close enough for now!
+			iGotKey = ETrue;
+			}
+		}
+	if (iClientStatus)
+		{
+		User::RequestComplete(iClientStatus, err);
+		if (err == KErrNone) iGotKey = EFalse;
+		}
+	}
+
+void CTerminalKeyboardCons::Read(TRequestStatus& aStatus)
+	{
+	/*if (iClientStatus)
+		{
+		TRequestStatus* stat = &aStatus;
+		User::RequestComplete(stat, KErrInUse);
+		}
+	else*/
+		{
+		aStatus = KRequestPending;
+		iClientStatus = &aStatus;
+		if (iGotKey)
+			{
+			iGotKey = EFalse;
+			User::RequestComplete(iClientStatus, KErrNone);
+			}
+		}
+	}
+
+void CTerminalKeyboardCons::ReadCancel()
+	{
+	if (iClientStatus)
+		{
+		User::RequestComplete(iClientStatus, KErrCancel);
+		}
+	}
+
+void CTerminalKeyboardCons::Write(const TDesC& aDes)
+	{
+	for (TInt i = 0; i < aDes.Length(); i++)
+		{
+		TInt textBufPos = CursorPos().iY * ScreenSize().iWidth + CursorPos().iX;
+		TChar ch(aDes[i]);
+		iTracker.WriteChar(ch);
+		if (ch.IsPrint()) iTextBuffer[textBufPos] = aDes[i];
+		}
+
+	Update();
+	}
+	
+TPoint CTerminalKeyboardCons::CursorPos() const
+	{
+	return iTracker.CursorPos();
+	}
+
+void CTerminalKeyboardCons::SetCursorPosAbs(const TPoint& aPoint)
+	{
+	iTracker.SetCursorPosAbs(aPoint);
+	}
+
+void CTerminalKeyboardCons::SetCursorPosRel(const TPoint& aPoint)
+	{
+	iTracker.SetCursorPosRel(aPoint);
+	}
+
+void CTerminalKeyboardCons::SetCursorHeight(TInt /*aPercentage*/)
+	{
+	//iOutputController->SetCursorHeight(aPercentage);
+	}
+
+void CTerminalKeyboardCons::SetTitle(const TDesC& /*aDes*/)
+	{
+	//iOutputController->SetTitle(aDes);
+	}
+
+void CTerminalKeyboardCons::ClearScreen()
+	{
+	SetCursorPosAbs(TPoint(0,0));
+	iTextBuffer.Fill(' ');
+	Update();
+	}
+
+void CTerminalKeyboardCons::ClearToEndOfLine()
+	{
+	iTextBuffer.MidTPtr(CursorPos().iY * ScreenSize().iWidth + CursorPos().iX, ScreenSize().iWidth - CursorPos().iX).Fill(' ');
+	Update();
+	}
+
+TSize CTerminalKeyboardCons::ScreenSize() const
+	{
+	return iTracker.ConsoleSize();
+	}
+
+TKeyCode CTerminalKeyboardCons::KeyCode() const
+	{
+	return iKeyCode;
+	}
+
+TUint CTerminalKeyboardCons::KeyModifiers() const
+	{
+	return iKeyModifiers;
+	}
+
+// All these magic vals are as per the DOS 437 codepage http://en.wikipedia.org/wiki/CP437 and not Windows-1252 like the ws_win.cpp source incorrectly states
+// See also http://en.wikipedia.org/wiki/Box_drawing_characters
+enum
+	{
+	EBoxHorizontalBar = 0xCD,
+	EBoxVerticalBar = 0xBA,
+	EBoxTopLeft = 0xC9,
+	EBoxTopRight = 0xBB,
+	EBoxBottomLeft = 0xC8,
+	EBoxBottomRight = 0xBC,
+	};
+
+void CTerminalKeyboardCons::Update()
+	{
+#ifdef SHOW_TEXTSHELL_BORDERS
+	// Update munged buffer
+	const TInt contentWidth = ScreenSize().iWidth;
+	const TInt width = contentWidth + 2;
+	iMungedTextBuffer.SetLength(width);
+	iMungedTextBuffer.Fill(TChar(EBoxHorizontalBar));
+	iMungedTextBuffer[0] = EBoxTopLeft;
+	iMungedTextBuffer[width-1] = EBoxTopRight;
+
+	for (TInt i = 0; i < ScreenSize().iHeight; i++)
+		{
+		TPtrC line(iTextBuffer.Mid(i*contentWidth, contentWidth));
+		iMungedTextBuffer.AppendFormat(_L("%c%S%c"), EBoxVerticalBar, &line, EBoxVerticalBar);
+		}
+	
+	iMungedTextBuffer.Append(EBoxBottomLeft);
+	iMungedTextBuffer.SetLength(iMungedTextBuffer.Length() + contentWidth);
+	iMungedTextBuffer.RightTPtr(contentWidth).Fill(EBoxHorizontalBar);
+	iMungedTextBuffer.Append(EBoxBottomRight);
+	
+	// And send the munged buffer
+	Transmit(iMungedTextBuffer, width, ScreenSize().iHeight + 2);
+#else
+	// Just send it straight
+	Transmit(iTextBuffer, ScreenSize().iWidth, ScreenSize().iHeight);
+#endif
+	}
+
+void CTerminalKeyboardCons::Transmit(const TDesC& aBuf, TInt aWidth, TInt aHeight)
+	{
+	// This is how terminal keyboard does it - pretty horrible really
+
+	static const TInt KMaxLen = 200; // This is what terminal keyboard uses - technically you could go as far as a total of 256
+	TInt numLinesPerPrint = KMaxLen / aWidth;
+
+	TBuf<256> line;
+	TInt startLine = 0;
+	while (startLine < aHeight)
+		{
+		if (startLine == 0)
+			{
+			// First line has extra info
+			line.Format(_L("#$STIConsole#$%02d%02X%02X"), startLine, aWidth, aHeight);
+			}
+		else
+			{
+			line.Format(_L("#$STIConsole#$%02d"), startLine);
+			}
+
+		for (TInt i = 0; i < numLinesPerPrint; i++)
+			{
+			TPtrC theContents(aBuf.Mid((startLine+i)*aWidth, aWidth));
+			//RDebug::Printf("line len=%d theContents len=%d", line.Length(), theContents.Length());
+			line.Append(theContents);
+			}
+
+		RDebug::Print(line);
+		startLine += numLinesPerPrint;
+		}
+	}
+
+void CTerminalKeyboardCons::ConsoleScrolled(TInt aNumberOfLines)
+	{
+	TInt numChars = Abs(aNumberOfLines) * ScreenSize().iWidth;
+	if (aNumberOfLines > 0)
+		{
+		iTextBuffer.Delete(0, numChars);
+		iTextBuffer.AppendFill(' ', numChars);
+		}
+	else if (aNumberOfLines < 0)
+		{
+		iTextBuffer.SetLength(iTextBuffer.Length() - numChars);
+		while (numChars--) iTextBuffer.Insert(0, _L(" "));
+		}
+	}
+
+extern "C" EXPORT_C TAny* NewConsole()
+	{
+	return new CTerminalKeyboardCons;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/terminalkeyboardcons/terminalkeyboardcons.h	Mon Aug 23 18:10:31 2010 +0100
@@ -0,0 +1,72 @@
+// terminalkeyboardcons.h
+// 
+// Copyright (c) 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 TERMINALKEYBOARDCONS_H
+#define TERMINALKEYBOARDCONS_H
+
+#include <e32std.h>
+#include <e32cons.h>
+#include <TcDriverIf.h>
+#include <fshell/consoleextensions.h>
+#include "vtc_cursor_tracker.h"
+class CMessageWatcher;
+
+//#define SHOW_TEXTSHELL_BORDERS
+
+NONSHARABLE_CLASS(CTerminalKeyboardCons) : public CConsoleBase, public MIosrvConsoleHelper, public MConsoleScrollHandler
+	{
+public:
+	CTerminalKeyboardCons();
+	virtual ~CTerminalKeyboardCons();
+
+public: // From CConsoleBase
+	virtual TInt Create(const TDesC& aTitle, TSize aSize);
+	virtual void Read(TRequestStatus& aStatus);
+	virtual void ReadCancel();
+	virtual void Write(const TDesC& aDes);
+	virtual TPoint CursorPos() const;
+	virtual void SetCursorPosAbs(const TPoint& aPoint);
+	virtual void SetCursorPosRel(const TPoint& aPoint);
+	virtual void SetCursorHeight(TInt aPercentage);
+	virtual void SetTitle(const TDesC& aTitle);
+	virtual void ClearScreen();
+	virtual void ClearToEndOfLine();
+	virtual TSize ScreenSize() const;
+	virtual TKeyCode KeyCode() const;
+	virtual TUint KeyModifiers() const;
+	virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);
+
+private: // From MConsoleScrollHandler
+	void ConsoleScrolled(TInt aNumberOfLines);
+
+private:
+	virtual void ConstructL(const TDesC& aTitle, const TSize& aSize);
+	void Update();
+	void MessageReceived(TInt aError);
+	void Transmit(const TDesC& aBuf, TInt aWidth, TInt aHeight);
+
+protected:
+	TRequestStatus* iClientStatus;
+	TBool iGotKey;
+	TKeyCode iKeyCode;
+	TUint iKeyModifiers;
+	CConsoleBase* iUnderlyingConsole;
+	RTcDriver iDriver;
+
+	RBuf iTextBuffer;
+	RBuf iMungedTextBuffer; // With the borders
+	TCursorTracker iTracker;
+	CMessageWatcher* iWatcher;
+	friend class CMessageWatcher;
+	TBool iBacktickModifierDown;
+	};
+
+#endif // TERMINALKEYBOARDCONS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/terminalkeyboardcons/terminalkeyboardcons.mmp	Mon Aug 23 18:10:31 2010 +0100
@@ -0,0 +1,33 @@
+// terminalkeyboardcons.mmp
+// 
+// Copyright (c) 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
+//
+#include <fshell/common.mmh>
+
+target			terminalkeyboardcons.dll
+targettype		DLL
+uid				0x1000008d 0x100039e7 // Note this MUST be set to 0x100039e7
+capability		FSHELL_CAP_MMP_NORMAL
+
+sourcepath		.
+userinclude		.
+userinclude		..\vt100cons\src\vt100 // For vtc_cursor_tracker.h
+#include <fshell/fsh_system_include.mmh>
+
+source			terminalkeyboardcons.cpp
+sourcepath		..\vt100cons\src\vt100
+source			vtc_cursor_tracker.cpp
+
+library			euser.lib
+library			econs.lib
+library			consoleextensions.lib
+
+nostrictdef
+deffile			..\common\~\console.def
--- a/plugins/consoles/vt100cons/src/vt100/vtc_cursor_tracker.cpp	Fri Aug 13 16:18:06 2010 +0100
+++ b/plugins/consoles/vt100cons/src/vt100/vtc_cursor_tracker.cpp	Mon Aug 23 18:10:31 2010 +0100
@@ -17,15 +17,15 @@
 // Constants.
 //
 
-const TInt KTabSize = 8;
+const TInt KTabSize = 4;
 
 
 //
 // TCursorTracker.
 //
 
-TCursorTracker::TCursorTracker(TSize aConsoleSize)
-	: iConsoleSize(aConsoleSize), iCursorPos(TPoint(0, 0))
+TCursorTracker::TCursorTracker(TSize aConsoleSize, MConsoleScrollHandler* aScrollHander)
+	: iConsoleSize(aConsoleSize), iCursorPos(TPoint(0, 0)), iScrollHandler(aScrollHander)
 	{
 	}
 
@@ -135,6 +135,7 @@
 		{
 		// Reached the end of the line and there's no space below - console will scroll up a line and jump to the beginning of the newly exposed line.
 		iCursorPos.iX = 0;
+		if (iScrollHandler) iScrollHandler->ConsoleScrolled(1);
 		}
 	}
 
@@ -148,6 +149,7 @@
 	else
 		{
 		iCursorPos.iX = 0;
+		if (iScrollHandler) iScrollHandler->ConsoleScrolled(1);
 		}
 	}
 
--- a/plugins/consoles/vt100cons/src/vt100/vtc_cursor_tracker.h	Fri Aug 13 16:18:06 2010 +0100
+++ b/plugins/consoles/vt100cons/src/vt100/vtc_cursor_tracker.h	Mon Aug 23 18:10:31 2010 +0100
@@ -16,6 +16,12 @@
 #include <e32std.h>
 
 
+class MConsoleScrollHandler
+	{
+public:
+	virtual void ConsoleScrolled(TInt aNumberOfLines) = 0; // Positive aNumberOfLines means scrolled off the bottom. Negative means scrolled up
+	};
+
 /**
  * This class is responsible for tracking the cursor position within the console
  * window based on the data that is written to it. The cursor position is tracked
@@ -26,9 +32,10 @@
 class TCursorTracker
 	{
 public:
-	TCursorTracker(TSize aConsoleSize);
+	TCursorTracker(TSize aConsoleSize, MConsoleScrollHandler* aScrollHander = NULL);
 	void Write(const TDesC& aDes);
 	void Write(const TDesC8& aDes);
+	void WriteChar(TChar aChar);
 	void SetCursorPosAbs(const TPoint& aPoint);
 	void SetCursorPosRel(const TPoint& aPoint);
 	void Reset();
@@ -39,11 +46,10 @@
 	void CursorRight();
 	void LineFeed();
 	void CarriageReturn();
-	void WriteChar(TChar aChar);
 private:
 	const TSize iConsoleSize;
 	TPoint iCursorPos;
+	MConsoleScrollHandler* iScrollHandler;
 	};
 
-
 #endif // VTC_CURSOR_TRACKER_H