sl@0: // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\drivers\edisp\epoc\generic\wd_vt100.cpp sl@0: // Display/Keyboard driver using VT100 terminal sl@0: // sl@0: // sl@0: sl@0: #include "ws_std.h" sl@0: #include sl@0: #include sl@0: sl@0: /** sl@0: * Define a comms driver and port to use. sl@0: */ sl@0: sl@0: //#define __USE_RDEBUG_OUTPUT sl@0: #define __USE_SERIAL_INPUT sl@0: const TInt KPortNumber=1; sl@0: sl@0: #if defined(__USE_SERIAL_INPUT) || !defined(__USE_RDEBUG_OUTPUT) sl@0: #define __COMMS_DRIVER_NEEDED sl@0: _LIT(KPddName,"EUART"); sl@0: _LIT(KLddName,"ECOMM"); sl@0: #endif sl@0: sl@0: class CSerialKeyboard : public CActive sl@0: { sl@0: public: sl@0: static CSerialKeyboard* NewL(); sl@0: ~CSerialKeyboard(); sl@0: void GetKey(); sl@0: public: sl@0: CSerialKeyboard(); sl@0: void ConstructL(); sl@0: void RunL(); sl@0: void DoCancel(); sl@0: TInt KeyCode(); sl@0: public: sl@0: #ifdef __COMMS_DRIVER_NEEDED sl@0: RBusDevComm iDevComm; sl@0: TBuf8<1> iBuf; sl@0: #endif sl@0: }; sl@0: sl@0: #define SHIFTED(x) (0x8000|(x)) sl@0: #define ISSHIFTED(x) (0x8000&(x)) sl@0: #define FUNCED(x) (0x4000|(x)) sl@0: #define ISFUNCED(x) (0x4000&(x)) sl@0: #define CTRLED(x) (0x2000|(x)) sl@0: #define ISCTRLED(x) (0x2000&(x)) sl@0: #define STDKEY(x) (0x1FFF&(x)) sl@0: sl@0: const TUint16 convertCode[] = sl@0: { sl@0: /*00 NUL*/ EStdKeyNull, sl@0: /*01 SOH*/ CTRLED('A'), // ^A sl@0: /*02 STX*/ CTRLED('B'), // ^B sl@0: /*03 ETX*/ CTRLED('C'), // ^C sl@0: /*04 EOT*/ CTRLED('D'), // ^D sl@0: /*05 ENQ*/ CTRLED('E'), // ^E sl@0: /*06 ACK*/ CTRLED('F'), // ^F sl@0: /*07 BEL*/ CTRLED('G'), // ^G sl@0: /*08 BS */ EStdKeyBackspace, sl@0: /*09 TAB*/ CTRLED(FUNCED('5')), sl@0: /*0a LF */ CTRLED('J'), // ^J sl@0: /*0b VT */ CTRLED('K'), // ^K sl@0: /*0c FF */ CTRLED('L'), // ^L sl@0: /*0d CR */ EStdKeyEnter, sl@0: /*0e SO */ CTRLED('N'), // ^N sl@0: /*0f SI */ CTRLED('O'), // ^O sl@0: /*10 DLE*/ CTRLED('P'), // ^P sl@0: /*11 DC1*/ CTRLED('Q'), // ^Q sl@0: /*12 DC2*/ CTRLED('R'), // ^R sl@0: /*13 DC3*/ CTRLED('S'), // ^S sl@0: /*14 DC4*/ CTRLED('T'), // ^T sl@0: /*15 NAK*/ CTRLED('U'), // ^U sl@0: /*16 SYN*/ CTRLED('V'), // ^V sl@0: /*17 ETB*/ CTRLED('W'), // ^W sl@0: /*18 CAN*/ CTRLED('X'), // ^X sl@0: /*19 EM */ CTRLED('Y'), // ^Y sl@0: /*1a SUB*/ CTRLED('Z'), // ^Z sl@0: /*1b ESC*/ EStdKeyEscape, sl@0: /*1c FS */ EStdKeyNull, // ^backslash -> ignored sl@0: /*1d GS */ EStdKeyNull, // ^] -> ignored sl@0: /*1e RS */ EStdKeyNull, // ^^ -> ignored sl@0: /*1f US */ EStdKeyNull, // ^_ -> ignored sl@0: /*20*/ EStdKeySpace, sl@0: /*21*/ SHIFTED('1'), // ! sl@0: /*22*/ SHIFTED('2'), // " sl@0: /*23*/ EStdKeyHash, // # sl@0: /*24*/ SHIFTED('4'), // $ sl@0: /*25*/ SHIFTED('5'), // % sl@0: /*26*/ SHIFTED('7'), // & sl@0: /*27*/ EStdKeySingleQuote, sl@0: /*28*/ SHIFTED('9'), // ( sl@0: /*29*/ SHIFTED('0'), // ) sl@0: /*2a*/ SHIFTED('8'), // * sl@0: /*2b*/ SHIFTED(EStdKeyEquals), // + sl@0: /*2c*/ EStdKeyComma, // , sl@0: /*2d*/ EStdKeyMinus, // - sl@0: /*2e*/ EStdKeyFullStop, // . sl@0: /*2f*/ EStdKeyForwardSlash,// forward slash sl@0: /*30*/ '0', sl@0: /*31*/ '1', sl@0: /*32*/ '2', sl@0: /*33*/ '3', sl@0: /*34*/ '4', sl@0: /*35*/ '5', sl@0: /*36*/ '6', sl@0: /*37*/ '7', sl@0: /*38*/ '8', sl@0: /*39*/ '9', sl@0: /*3a*/ SHIFTED(EStdKeySemiColon), // : sl@0: /*3b*/ EStdKeySemiColon, // ; sl@0: /*3c*/ SHIFTED(EStdKeyComma), // < sl@0: /*3d*/ EStdKeyEquals, // = sl@0: /*3e*/ SHIFTED(EStdKeyFullStop), // > sl@0: /*3f*/ SHIFTED(EStdKeyForwardSlash), // ? sl@0: /*40*/ SHIFTED(EStdKeySingleQuote), // @ sl@0: /*41*/ SHIFTED('A'), sl@0: /*42*/ SHIFTED('B'), sl@0: /*43*/ SHIFTED('C'), sl@0: /*44*/ SHIFTED('D'), sl@0: /*45*/ SHIFTED('E'), sl@0: /*46*/ SHIFTED('F'), sl@0: /*47*/ SHIFTED('G'), sl@0: /*48*/ SHIFTED('H'), sl@0: /*49*/ SHIFTED('I'), sl@0: /*4a*/ SHIFTED('J'), sl@0: /*4b*/ SHIFTED('K'), sl@0: /*4c*/ SHIFTED('L'), sl@0: /*4d*/ SHIFTED('M'), sl@0: /*4e*/ SHIFTED('N'), sl@0: /*4f*/ SHIFTED('O'), sl@0: /*50*/ SHIFTED('P'), sl@0: /*51*/ SHIFTED('Q'), sl@0: /*52*/ SHIFTED('R'), sl@0: /*53*/ SHIFTED('S'), sl@0: /*54*/ SHIFTED('T'), sl@0: /*55*/ SHIFTED('U'), sl@0: /*56*/ SHIFTED('V'), sl@0: /*57*/ SHIFTED('W'), sl@0: /*58*/ SHIFTED('X'), sl@0: /*59*/ SHIFTED('Y'), sl@0: /*5a*/ SHIFTED('Z'), sl@0: /*5b*/ EStdKeySquareBracketLeft, // [ sl@0: /*5c*/ EStdKeyBackSlash, // backslash sl@0: /*5d*/ EStdKeySquareBracketRight, // ] sl@0: /*5e*/ SHIFTED('6'), // ^ sl@0: /*5f*/ SHIFTED(EStdKeyMinus), // _ sl@0: /*60*/ EStdKeyXXX, // Actually ` sl@0: /*61*/ 'A', sl@0: /*62*/ 'B', sl@0: /*63*/ 'C', sl@0: /*64*/ 'D', sl@0: /*65*/ 'E', sl@0: /*66*/ 'F', sl@0: /*67*/ 'G', sl@0: /*68*/ 'H', sl@0: /*69*/ 'I', sl@0: /*6a*/ 'J', sl@0: /*6b*/ 'K', sl@0: /*6c*/ 'L', sl@0: /*6d*/ 'M', sl@0: /*6e*/ 'N', sl@0: /*6f*/ 'O', sl@0: /*70*/ 'P', sl@0: /*71*/ 'Q', sl@0: /*72*/ 'R', sl@0: /*73*/ 'S', sl@0: /*74*/ 'T', sl@0: /*75*/ 'U', sl@0: /*76*/ 'V', sl@0: /*77*/ 'W', sl@0: /*78*/ 'X', sl@0: /*79*/ 'Y', sl@0: /*7a*/ 'Z', sl@0: /*7b*/ SHIFTED(EStdKeySquareBracketLeft), // { sl@0: /*7c*/ SHIFTED(EStdKeyBackSlash), // | sl@0: /*7d*/ SHIFTED(EStdKeySquareBracketRight), // } sl@0: /*7e*/ SHIFTED(EStdKeyHash), // ~ sl@0: /*7f*/ EKeyDelete sl@0: }; sl@0: sl@0: CSerialKeyboard* CSerialKeyboard::NewL() sl@0: { sl@0: CSerialKeyboard* self = new(ELeave) CSerialKeyboard; sl@0: self->ConstructL(); sl@0: return self; sl@0: } sl@0: sl@0: CSerialKeyboard::CSerialKeyboard() sl@0: : CActive(0) sl@0: { sl@0: } sl@0: sl@0: void CSerialKeyboard::ConstructL() sl@0: { sl@0: #ifdef __COMMS_DRIVER_NEEDED sl@0: // load and connect to serial port sl@0: TInt r=User::LoadPhysicalDevice(KPddName); sl@0: if (r!=KErrNone && r!=KErrAlreadyExists) sl@0: User::Leave(r); sl@0: r=User::LoadLogicalDevice (KLddName); sl@0: if (r!=KErrNone && r!=KErrAlreadyExists) sl@0: User::Leave(r); sl@0: sl@0: r=iDevComm.Open(KPortNumber); sl@0: User::LeaveIfError(r); sl@0: sl@0: TCommConfig cfgBuf; sl@0: TCommConfigV01& cfg=cfgBuf(); sl@0: iDevComm.Config(cfgBuf); sl@0: cfg.iRate=EBps115200; sl@0: cfg.iDataBits=EData8; sl@0: cfg.iStopBits=EStop1; sl@0: cfg.iParity=EParityNone; sl@0: cfg.iHandshake=0;//KConfigObeyXoff|KConfigSendXoff; sl@0: cfg.iFifo=EFifoEnable; sl@0: cfg.iTerminatorCount=0; sl@0: cfg.iSIREnable=ESIRDisable; sl@0: User::LeaveIfError(iDevComm.SetConfig(cfgBuf)); sl@0: #endif sl@0: sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: CSerialKeyboard::~CSerialKeyboard() sl@0: { sl@0: Cancel(); sl@0: } sl@0: sl@0: void CSerialKeyboard::GetKey() sl@0: { sl@0: __ASSERT_ALWAYS(!IsActive(), User::Panic(_L("CSerialKeyboard"),1)); sl@0: sl@0: // wait for a key sl@0: #ifdef __USE_SERIAL_INPUT sl@0: iDevComm.Read(iStatus,iBuf,1); sl@0: #endif sl@0: SetActive(); sl@0: } sl@0: sl@0: TInt CSerialKeyboard::KeyCode() sl@0: { sl@0: TInt c=-1; sl@0: #ifdef __USE_SERIAL_INPUT sl@0: if (iBuf.Length()>0) sl@0: c=iBuf[0]; sl@0: #endif sl@0: return c; sl@0: } sl@0: sl@0: void CSerialKeyboard::RunL() sl@0: { sl@0: TInt c=KeyCode(); sl@0: if (c>=0) sl@0: { sl@0: // convert character to keycode and shift, func, ctrl status sl@0: TUint16 code = convertCode[c]; sl@0: TBool isShifted = ISSHIFTED(code); sl@0: TBool isFunced = ISFUNCED(code); sl@0: TBool isCtrled = ISCTRLED(code); sl@0: TUint8 stdKey = STDKEY(code); sl@0: TRawEvent e; sl@0: sl@0: // post it as a sequence of events sl@0: if (isShifted) sl@0: { sl@0: e.Set(TRawEvent::EKeyDown,EStdKeyRightShift,0); sl@0: UserSvr::AddEvent(e); sl@0: } sl@0: if (isCtrled) sl@0: { sl@0: e.Set(TRawEvent::EKeyDown,EStdKeyLeftCtrl,0); sl@0: UserSvr::AddEvent(e); sl@0: } sl@0: if (isFunced) sl@0: { sl@0: e.Set(TRawEvent::EKeyDown,EStdKeyLeftFunc,0); sl@0: UserSvr::AddEvent(e); sl@0: } sl@0: sl@0: e.Set(TRawEvent::EKeyDown,stdKey,0); sl@0: UserSvr::AddEvent(e); sl@0: sl@0: e.Set(TRawEvent::EKeyUp,stdKey,0); sl@0: UserSvr::AddEvent(e); sl@0: sl@0: if (isFunced) sl@0: { sl@0: e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0); sl@0: UserSvr::AddEvent(e); sl@0: } sl@0: if (isCtrled) sl@0: { sl@0: e.Set(TRawEvent::EKeyUp,EStdKeyLeftCtrl,0); sl@0: UserSvr::AddEvent(e); sl@0: } sl@0: if (isShifted) sl@0: { sl@0: e.Set(TRawEvent::EKeyUp,EStdKeyRightShift,0); sl@0: UserSvr::AddEvent(e); sl@0: } sl@0: } sl@0: sl@0: // get another key sl@0: GetKey(); sl@0: } sl@0: sl@0: void CSerialKeyboard::DoCancel() sl@0: { sl@0: #ifdef __USE_SERIAL_INPUT sl@0: iDevComm.ReadCancel(); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: class CScreenDriverVT100 : public CScreenDriver sl@0: { sl@0: public: sl@0: CScreenDriverVT100(); sl@0: virtual void Init(TSize &aScreenSize,TSize &aFontSize); sl@0: virtual void Blit(const TText *aBuffer,TInt aLength,const TPoint &aPosition); sl@0: virtual TBool ScrollUp(const TRect& aRect); sl@0: virtual void Clear(const TRect& aRect); sl@0: sl@0: virtual void SetPixel(const TPoint& aPoint,TUint8 aColour); sl@0: virtual TInt GetPixel(const TPoint& aPoint); sl@0: virtual void SetWord(const TPoint& aPoint,TInt aWord); sl@0: virtual TInt GetWord(const TPoint& aPoint); sl@0: virtual void SetLine(const TPoint& aPoint,const TPixelLine& aPixelLine); sl@0: virtual void GetLine(const TPoint& aPoint,TPixelLine& aPixelLine); sl@0: sl@0: virtual TInt SetMode(TVideoMode aMode); sl@0: sl@0: virtual void SetPaletteEntry(TColorIndex anIndex,TUint8 aRed,TUint8 aGreen,TUint8 aBlue) {} sl@0: virtual void GetPaletteEntry(TColorIndex anIndex,TUint8 &aRed,TUint8 &aGreen,TUint8 &aBlue) {} sl@0: virtual void SetForegroundColor(TColorIndex anIndex) {} sl@0: virtual void SetBackgroundColor(TColorIndex anIndex) {} sl@0: virtual void GetAttributeColors(TColorIndex* anArray) {} sl@0: sl@0: // sl@0: void Update(const TRect &aRect); sl@0: void Print(const TDesC8& aDes); sl@0: TUint8 *iScreenBuffer; sl@0: private: sl@0: CSerialKeyboard *iSerialKeyboard; sl@0: }; sl@0: sl@0: const TInt KScreenWidth = 80; sl@0: const TInt KScreenHeight = 24; sl@0: sl@0: CScreenDriverVT100::CScreenDriverVT100() sl@0: // sl@0: // Constructor sl@0: // sl@0: { sl@0: } sl@0: sl@0: EXPORT_C CScreenDriver *CScreenDriver::New() sl@0: // sl@0: // Return the actual screen driver. sl@0: // sl@0: { sl@0: sl@0: CScreenDriverVT100 *pS=new CScreenDriverVT100; sl@0: pS->iScreenBuffer=new TUint8 [KScreenWidth*KScreenHeight]; sl@0: return pS; sl@0: } sl@0: sl@0: void CScreenDriverVT100::Init(TSize& aScreenSize, TSize& aFontSize) sl@0: { sl@0: // Report screen information sl@0: aFontSize=TSize(8,10); sl@0: aScreenSize=TSize(KScreenWidth,KScreenHeight); sl@0: sl@0: // start keyboard sl@0: TRAPD(r,iSerialKeyboard = CSerialKeyboard::NewL()); sl@0: // must panic if there are not enough resources to continue sl@0: __ASSERT_ALWAYS(r==KErrNone, User::Panic(_L("CSerialKeyboard"),2)); sl@0: sl@0: iSerialKeyboard->GetKey(); sl@0: } sl@0: sl@0: TInt CScreenDriverVT100::SetMode(TVideoMode aMode) sl@0: // sl@0: // Set the screen mode sl@0: // sl@0: { sl@0: return(KErrNotSupported); sl@0: } sl@0: sl@0: void CScreenDriverVT100::Update(const TRect &aRect) sl@0: { sl@0: TBuf8<0x100> buf; sl@0: TInt i; sl@0: sl@0: for (i=aRect.iTl.iY; i<=aRect.iBr.iY; i++) sl@0: { sl@0: buf.Format(_L8("\x1b[%02d;%02dH"), i+1, aRect.iTl.iX+1); sl@0: TPtrC8 ptr(iScreenBuffer+(aRect.iTl.iX+i*KScreenWidth),aRect.iBr.iX-aRect.iTl.iX); sl@0: buf.Append(ptr); sl@0: Print(buf); sl@0: } sl@0: Print(_L8("\x1b[01;01H")); sl@0: } sl@0: sl@0: void CScreenDriverVT100::Blit(const TText *aBuffer, TInt aLength, const TPoint &aPosition) sl@0: // sl@0: // Write contiguous block of characters to some segment of a line on the display sl@0: // sl@0: { sl@0: TUint8 *ptr=iScreenBuffer+(aPosition.iX+aPosition.iY*KScreenWidth); sl@0: const TText* endBuf = aBuffer + aLength; sl@0: while (aBuffer < endBuf) sl@0: *ptr++ = (TUint8)*aBuffer++; sl@0: Update(TRect(aPosition.iX, aPosition.iY, aPosition.iX+aLength, aPosition.iY)); sl@0: } sl@0: sl@0: TBool CScreenDriverVT100::ScrollUp(const TRect& aRect) sl@0: // sl@0: // Scroll a rectangle of the screen up one line, don't update bottom line sl@0: // sl@0: { sl@0: TInt j; sl@0: for (j=aRect.iTl.iY; j=KScreenWidth-2)) sl@0: { sl@0: // Optimisation: range of whole lines sl@0: TBuf8<0x100> buf; sl@0: // cursor pos sl@0: buf.Format(_L8("\x1b[%02d;%02dH\xd\xa\xba\x1b[%02dC\xba"), aRect.iBr.iY, 1, aRect.iBr.iX); sl@0: Print(buf); sl@0: // set scroll region sl@0: buf.Format(_L8("\x1b[%02d;%02dr\xd\xa"), aRect.iTl.iY+1, aRect.iBr.iY); sl@0: Print(buf); sl@0: Print(_L8("\x1b[01;01H")); sl@0: } sl@0: else sl@0: Update(aRect); sl@0: sl@0: return(ETrue); sl@0: } sl@0: sl@0: void CScreenDriverVT100::Clear(const TRect& aRect) sl@0: // sl@0: // Clear a rectangle of the screen sl@0: // sl@0: { sl@0: TInt j; sl@0: TBuf8<0x100> buf; sl@0: for (j=aRect.iTl.iY; j<=aRect.iBr.iY; j++) sl@0: { sl@0: TUint8 *ptr=iScreenBuffer+(aRect.iTl.iX+j*KScreenWidth); sl@0: Mem::FillZ(ptr, aRect.iBr.iX-aRect.iTl.iX); sl@0: } sl@0: if ((aRect.iTl.iY == aRect.iBr.iY) && (aRect.iTl.iX==0) && (aRect.iBr.iX==KScreenWidth-1)) sl@0: { sl@0: // Optimisation: one whole line sl@0: buf.Format(_L8("\x1b[%02d;%02dH"), aRect.iTl.iY, 1); sl@0: Print(buf); sl@0: // Erase line sl@0: buf.Format(_L8("\x1b[2K")); sl@0: Print(buf); sl@0: Print(_L8("\x1b[01;01H")); sl@0: } sl@0: else if ((aRect.iTl.iY == 0) && (aRect.iBr.iY == KScreenHeight-1) && sl@0: (aRect.iTl.iX == 0) && (aRect.iBr.iX == KScreenWidth-1)) sl@0: { sl@0: // Optimisation: whole screen sl@0: buf.Format(_L8("\x1b[2J")); sl@0: Print(buf); sl@0: Print(_L8("\x1b[01;01H")); sl@0: } sl@0: else sl@0: Update(aRect); sl@0: } sl@0: sl@0: void CScreenDriverVT100::SetPixel(const TPoint& /*aPoint*/,TUint8 /*aColour*/) sl@0: { sl@0: } sl@0: sl@0: TInt CScreenDriverVT100::GetPixel(const TPoint& /*aPoint*/) sl@0: { sl@0: return 0; sl@0: } sl@0: sl@0: void CScreenDriverVT100::SetWord(const TPoint& /*aPoint*/,TInt /*aWord*/) sl@0: { sl@0: } sl@0: sl@0: TInt CScreenDriverVT100::GetWord(const TPoint& /*aPoint*/) sl@0: { sl@0: return 0; sl@0: } sl@0: sl@0: void CScreenDriverVT100::SetLine(const TPoint& /*aPoint*/,const TPixelLine& /*aPixelLine*/) sl@0: { sl@0: } sl@0: sl@0: void CScreenDriverVT100::GetLine(const TPoint& /*aPoint*/,TPixelLine& /*aPixelLine*/) sl@0: { sl@0: } sl@0: sl@0: void CScreenDriverVT100::Print(const TDesC8& aDes) sl@0: { sl@0: #ifdef __USE_RDEBUG_OUTPUT sl@0: TBuf<256> unicodeBuf; sl@0: unicodeBuf.Copy(aDes); sl@0: RDebug::RawPrint(unicodeBuf); sl@0: #else sl@0: RBusDevComm c=iSerialKeyboard->iDevComm; sl@0: TRequestStatus s; sl@0: c.Write(s,aDes); sl@0: User::WaitForRequest(s); sl@0: #endif sl@0: } sl@0: