First public contribution.
1 // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\drivers\edisp\epoc\generic\wd_vt100.cpp
15 // Display/Keyboard driver using VT100 terminal
24 * Define a comms driver and port to use.
27 //#define __USE_RDEBUG_OUTPUT
28 #define __USE_SERIAL_INPUT
29 const TInt KPortNumber=1;
31 #if defined(__USE_SERIAL_INPUT) || !defined(__USE_RDEBUG_OUTPUT)
32 #define __COMMS_DRIVER_NEEDED
33 _LIT(KPddName,"EUART");
34 _LIT(KLddName,"ECOMM");
37 class CSerialKeyboard : public CActive
40 static CSerialKeyboard* NewL();
50 #ifdef __COMMS_DRIVER_NEEDED
56 #define SHIFTED(x) (0x8000|(x))
57 #define ISSHIFTED(x) (0x8000&(x))
58 #define FUNCED(x) (0x4000|(x))
59 #define ISFUNCED(x) (0x4000&(x))
60 #define CTRLED(x) (0x2000|(x))
61 #define ISCTRLED(x) (0x2000&(x))
62 #define STDKEY(x) (0x1FFF&(x))
64 const TUint16 convertCode[] =
66 /*00 NUL*/ EStdKeyNull,
67 /*01 SOH*/ CTRLED('A'), // ^A
68 /*02 STX*/ CTRLED('B'), // ^B
69 /*03 ETX*/ CTRLED('C'), // ^C
70 /*04 EOT*/ CTRLED('D'), // ^D
71 /*05 ENQ*/ CTRLED('E'), // ^E
72 /*06 ACK*/ CTRLED('F'), // ^F
73 /*07 BEL*/ CTRLED('G'), // ^G
74 /*08 BS */ EStdKeyBackspace,
75 /*09 TAB*/ CTRLED(FUNCED('5')),
76 /*0a LF */ CTRLED('J'), // ^J
77 /*0b VT */ CTRLED('K'), // ^K
78 /*0c FF */ CTRLED('L'), // ^L
79 /*0d CR */ EStdKeyEnter,
80 /*0e SO */ CTRLED('N'), // ^N
81 /*0f SI */ CTRLED('O'), // ^O
82 /*10 DLE*/ CTRLED('P'), // ^P
83 /*11 DC1*/ CTRLED('Q'), // ^Q
84 /*12 DC2*/ CTRLED('R'), // ^R
85 /*13 DC3*/ CTRLED('S'), // ^S
86 /*14 DC4*/ CTRLED('T'), // ^T
87 /*15 NAK*/ CTRLED('U'), // ^U
88 /*16 SYN*/ CTRLED('V'), // ^V
89 /*17 ETB*/ CTRLED('W'), // ^W
90 /*18 CAN*/ CTRLED('X'), // ^X
91 /*19 EM */ CTRLED('Y'), // ^Y
92 /*1a SUB*/ CTRLED('Z'), // ^Z
93 /*1b ESC*/ EStdKeyEscape,
94 /*1c FS */ EStdKeyNull, // ^backslash -> ignored
95 /*1d GS */ EStdKeyNull, // ^] -> ignored
96 /*1e RS */ EStdKeyNull, // ^^ -> ignored
97 /*1f US */ EStdKeyNull, // ^_ -> ignored
99 /*21*/ SHIFTED('1'), // !
100 /*22*/ SHIFTED('2'), // "
101 /*23*/ EStdKeyHash, // #
102 /*24*/ SHIFTED('4'), // $
103 /*25*/ SHIFTED('5'), // %
104 /*26*/ SHIFTED('7'), // &
105 /*27*/ EStdKeySingleQuote,
106 /*28*/ SHIFTED('9'), // (
107 /*29*/ SHIFTED('0'), // )
108 /*2a*/ SHIFTED('8'), // *
109 /*2b*/ SHIFTED(EStdKeyEquals), // +
110 /*2c*/ EStdKeyComma, // ,
111 /*2d*/ EStdKeyMinus, // -
112 /*2e*/ EStdKeyFullStop, // .
113 /*2f*/ EStdKeyForwardSlash,// forward slash
124 /*3a*/ SHIFTED(EStdKeySemiColon), // :
125 /*3b*/ EStdKeySemiColon, // ;
126 /*3c*/ SHIFTED(EStdKeyComma), // <
127 /*3d*/ EStdKeyEquals, // =
128 /*3e*/ SHIFTED(EStdKeyFullStop), // >
129 /*3f*/ SHIFTED(EStdKeyForwardSlash), // ?
130 /*40*/ SHIFTED(EStdKeySingleQuote), // @
157 /*5b*/ EStdKeySquareBracketLeft, // [
158 /*5c*/ EStdKeyBackSlash, // backslash
159 /*5d*/ EStdKeySquareBracketRight, // ]
160 /*5e*/ SHIFTED('6'), // ^
161 /*5f*/ SHIFTED(EStdKeyMinus), // _
162 /*60*/ EStdKeyXXX, // Actually `
189 /*7b*/ SHIFTED(EStdKeySquareBracketLeft), // {
190 /*7c*/ SHIFTED(EStdKeyBackSlash), // |
191 /*7d*/ SHIFTED(EStdKeySquareBracketRight), // }
192 /*7e*/ SHIFTED(EStdKeyHash), // ~
196 CSerialKeyboard* CSerialKeyboard::NewL()
198 CSerialKeyboard* self = new(ELeave) CSerialKeyboard;
203 CSerialKeyboard::CSerialKeyboard()
208 void CSerialKeyboard::ConstructL()
210 #ifdef __COMMS_DRIVER_NEEDED
211 // load and connect to serial port
212 TInt r=User::LoadPhysicalDevice(KPddName);
213 if (r!=KErrNone && r!=KErrAlreadyExists)
215 r=User::LoadLogicalDevice (KLddName);
216 if (r!=KErrNone && r!=KErrAlreadyExists)
219 r=iDevComm.Open(KPortNumber);
220 User::LeaveIfError(r);
223 TCommConfigV01& cfg=cfgBuf();
224 iDevComm.Config(cfgBuf);
225 cfg.iRate=EBps115200;
226 cfg.iDataBits=EData8;
227 cfg.iStopBits=EStop1;
228 cfg.iParity=EParityNone;
229 cfg.iHandshake=0;//KConfigObeyXoff|KConfigSendXoff;
230 cfg.iFifo=EFifoEnable;
231 cfg.iTerminatorCount=0;
232 cfg.iSIREnable=ESIRDisable;
233 User::LeaveIfError(iDevComm.SetConfig(cfgBuf));
236 CActiveScheduler::Add(this);
239 CSerialKeyboard::~CSerialKeyboard()
244 void CSerialKeyboard::GetKey()
246 __ASSERT_ALWAYS(!IsActive(), User::Panic(_L("CSerialKeyboard"),1));
249 #ifdef __USE_SERIAL_INPUT
250 iDevComm.Read(iStatus,iBuf,1);
255 TInt CSerialKeyboard::KeyCode()
258 #ifdef __USE_SERIAL_INPUT
265 void CSerialKeyboard::RunL()
270 // convert character to keycode and shift, func, ctrl status
271 TUint16 code = convertCode[c];
272 TBool isShifted = ISSHIFTED(code);
273 TBool isFunced = ISFUNCED(code);
274 TBool isCtrled = ISCTRLED(code);
275 TUint8 stdKey = STDKEY(code);
278 // post it as a sequence of events
281 e.Set(TRawEvent::EKeyDown,EStdKeyRightShift,0);
282 UserSvr::AddEvent(e);
286 e.Set(TRawEvent::EKeyDown,EStdKeyLeftCtrl,0);
287 UserSvr::AddEvent(e);
291 e.Set(TRawEvent::EKeyDown,EStdKeyLeftFunc,0);
292 UserSvr::AddEvent(e);
295 e.Set(TRawEvent::EKeyDown,stdKey,0);
296 UserSvr::AddEvent(e);
298 e.Set(TRawEvent::EKeyUp,stdKey,0);
299 UserSvr::AddEvent(e);
303 e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0);
304 UserSvr::AddEvent(e);
308 e.Set(TRawEvent::EKeyUp,EStdKeyLeftCtrl,0);
309 UserSvr::AddEvent(e);
313 e.Set(TRawEvent::EKeyUp,EStdKeyRightShift,0);
314 UserSvr::AddEvent(e);
322 void CSerialKeyboard::DoCancel()
324 #ifdef __USE_SERIAL_INPUT
325 iDevComm.ReadCancel();
330 class CScreenDriverVT100 : public CScreenDriver
333 CScreenDriverVT100();
334 virtual void Init(TSize &aScreenSize,TSize &aFontSize);
335 virtual void Blit(const TText *aBuffer,TInt aLength,const TPoint &aPosition);
336 virtual TBool ScrollUp(const TRect& aRect);
337 virtual void Clear(const TRect& aRect);
339 virtual void SetPixel(const TPoint& aPoint,TUint8 aColour);
340 virtual TInt GetPixel(const TPoint& aPoint);
341 virtual void SetWord(const TPoint& aPoint,TInt aWord);
342 virtual TInt GetWord(const TPoint& aPoint);
343 virtual void SetLine(const TPoint& aPoint,const TPixelLine& aPixelLine);
344 virtual void GetLine(const TPoint& aPoint,TPixelLine& aPixelLine);
346 virtual TInt SetMode(TVideoMode aMode);
348 virtual void SetPaletteEntry(TColorIndex anIndex,TUint8 aRed,TUint8 aGreen,TUint8 aBlue) {}
349 virtual void GetPaletteEntry(TColorIndex anIndex,TUint8 &aRed,TUint8 &aGreen,TUint8 &aBlue) {}
350 virtual void SetForegroundColor(TColorIndex anIndex) {}
351 virtual void SetBackgroundColor(TColorIndex anIndex) {}
352 virtual void GetAttributeColors(TColorIndex* anArray) {}
355 void Update(const TRect &aRect);
356 void Print(const TDesC8& aDes);
357 TUint8 *iScreenBuffer;
359 CSerialKeyboard *iSerialKeyboard;
362 const TInt KScreenWidth = 80;
363 const TInt KScreenHeight = 24;
365 CScreenDriverVT100::CScreenDriverVT100()
372 EXPORT_C CScreenDriver *CScreenDriver::New()
374 // Return the actual screen driver.
378 CScreenDriverVT100 *pS=new CScreenDriverVT100;
379 pS->iScreenBuffer=new TUint8 [KScreenWidth*KScreenHeight];
383 void CScreenDriverVT100::Init(TSize& aScreenSize, TSize& aFontSize)
385 // Report screen information
386 aFontSize=TSize(8,10);
387 aScreenSize=TSize(KScreenWidth,KScreenHeight);
390 TRAPD(r,iSerialKeyboard = CSerialKeyboard::NewL());
391 // must panic if there are not enough resources to continue
392 __ASSERT_ALWAYS(r==KErrNone, User::Panic(_L("CSerialKeyboard"),2));
394 iSerialKeyboard->GetKey();
397 TInt CScreenDriverVT100::SetMode(TVideoMode aMode)
399 // Set the screen mode
402 return(KErrNotSupported);
405 void CScreenDriverVT100::Update(const TRect &aRect)
410 for (i=aRect.iTl.iY; i<=aRect.iBr.iY; i++)
412 buf.Format(_L8("\x1b[%02d;%02dH"), i+1, aRect.iTl.iX+1);
413 TPtrC8 ptr(iScreenBuffer+(aRect.iTl.iX+i*KScreenWidth),aRect.iBr.iX-aRect.iTl.iX);
417 Print(_L8("\x1b[01;01H"));
420 void CScreenDriverVT100::Blit(const TText *aBuffer, TInt aLength, const TPoint &aPosition)
422 // Write contiguous block of characters to some segment of a line on the display
425 TUint8 *ptr=iScreenBuffer+(aPosition.iX+aPosition.iY*KScreenWidth);
426 const TText* endBuf = aBuffer + aLength;
427 while (aBuffer < endBuf)
428 *ptr++ = (TUint8)*aBuffer++;
429 Update(TRect(aPosition.iX, aPosition.iY, aPosition.iX+aLength, aPosition.iY));
432 TBool CScreenDriverVT100::ScrollUp(const TRect& aRect)
434 // Scroll a rectangle of the screen up one line, don't update bottom line
438 for (j=aRect.iTl.iY; j<aRect.iBr.iY; j++)
440 TUint8 *ptr=iScreenBuffer+(aRect.iTl.iX+j*KScreenWidth);
441 Mem::Copy(ptr, ptr+KScreenWidth, aRect.iBr.iX-aRect.iTl.iX);
443 if ((aRect.iTl.iX<=1) && (aRect.iBr.iX>=KScreenWidth-2))
445 // Optimisation: range of whole lines
448 buf.Format(_L8("\x1b[%02d;%02dH\xd\xa\xba\x1b[%02dC\xba"), aRect.iBr.iY, 1, aRect.iBr.iX);
451 buf.Format(_L8("\x1b[%02d;%02dr\xd\xa"), aRect.iTl.iY+1, aRect.iBr.iY);
453 Print(_L8("\x1b[01;01H"));
461 void CScreenDriverVT100::Clear(const TRect& aRect)
463 // Clear a rectangle of the screen
468 for (j=aRect.iTl.iY; j<=aRect.iBr.iY; j++)
470 TUint8 *ptr=iScreenBuffer+(aRect.iTl.iX+j*KScreenWidth);
471 Mem::FillZ(ptr, aRect.iBr.iX-aRect.iTl.iX);
473 if ((aRect.iTl.iY == aRect.iBr.iY) && (aRect.iTl.iX==0) && (aRect.iBr.iX==KScreenWidth-1))
475 // Optimisation: one whole line
476 buf.Format(_L8("\x1b[%02d;%02dH"), aRect.iTl.iY, 1);
479 buf.Format(_L8("\x1b[2K"));
481 Print(_L8("\x1b[01;01H"));
483 else if ((aRect.iTl.iY == 0) && (aRect.iBr.iY == KScreenHeight-1) &&
484 (aRect.iTl.iX == 0) && (aRect.iBr.iX == KScreenWidth-1))
486 // Optimisation: whole screen
487 buf.Format(_L8("\x1b[2J"));
489 Print(_L8("\x1b[01;01H"));
495 void CScreenDriverVT100::SetPixel(const TPoint& /*aPoint*/,TUint8 /*aColour*/)
499 TInt CScreenDriverVT100::GetPixel(const TPoint& /*aPoint*/)
504 void CScreenDriverVT100::SetWord(const TPoint& /*aPoint*/,TInt /*aWord*/)
508 TInt CScreenDriverVT100::GetWord(const TPoint& /*aPoint*/)
513 void CScreenDriverVT100::SetLine(const TPoint& /*aPoint*/,const TPixelLine& /*aPixelLine*/)
517 void CScreenDriverVT100::GetLine(const TPoint& /*aPoint*/,TPixelLine& /*aPixelLine*/)
521 void CScreenDriverVT100::Print(const TDesC8& aDes)
523 #ifdef __USE_RDEBUG_OUTPUT
524 TBuf<256> unicodeBuf;
525 unicodeBuf.Copy(aDes);
526 RDebug::RawPrint(unicodeBuf);
528 RBusDevComm c=iSerialKeyboard->iDevComm;
531 User::WaitForRequest(s);