os/kernelhwsrv/kernel/eka/drivers/edisp/epoc/generic/wd_vt100.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\drivers\edisp\epoc\generic\wd_vt100.cpp
    15 // Display/Keyboard driver using VT100 terminal
    16 // 
    17 //
    18 
    19 #include "ws_std.h"
    20 #include <d32comm.h>
    21 #include <e32svr.h>
    22 
    23 /**
    24  * Define a comms driver and port to use.
    25  */
    26 
    27 //#define __USE_RDEBUG_OUTPUT
    28 #define __USE_SERIAL_INPUT
    29 const TInt KPortNumber=1;
    30 
    31 #if defined(__USE_SERIAL_INPUT) || !defined(__USE_RDEBUG_OUTPUT)
    32 #define __COMMS_DRIVER_NEEDED
    33 _LIT(KPddName,"EUART");
    34 _LIT(KLddName,"ECOMM");
    35 #endif
    36 
    37 class CSerialKeyboard : public CActive
    38 	{
    39 public:
    40 	static CSerialKeyboard* NewL();
    41 	~CSerialKeyboard();
    42 	void GetKey();
    43 public:
    44 	CSerialKeyboard();
    45 	void ConstructL();
    46 	void RunL();
    47 	void DoCancel();
    48 	TInt KeyCode();
    49 public:
    50 #ifdef __COMMS_DRIVER_NEEDED
    51 	RBusDevComm iDevComm;
    52 	TBuf8<1> iBuf;
    53 #endif
    54 	};
    55 
    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))
    63 
    64 const TUint16 convertCode[] =
    65 	{
    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
    98 /*20*/  EStdKeySpace,
    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
   114 /*30*/  '0',
   115 /*31*/  '1',
   116 /*32*/  '2',
   117 /*33*/  '3',
   118 /*34*/  '4',
   119 /*35*/  '5',
   120 /*36*/  '6',
   121 /*37*/  '7',
   122 /*38*/  '8',
   123 /*39*/  '9',
   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),  // @
   131 /*41*/  SHIFTED('A'),
   132 /*42*/  SHIFTED('B'),
   133 /*43*/  SHIFTED('C'),
   134 /*44*/  SHIFTED('D'),
   135 /*45*/  SHIFTED('E'),
   136 /*46*/  SHIFTED('F'),
   137 /*47*/  SHIFTED('G'),
   138 /*48*/  SHIFTED('H'),
   139 /*49*/  SHIFTED('I'),
   140 /*4a*/  SHIFTED('J'),
   141 /*4b*/  SHIFTED('K'),
   142 /*4c*/  SHIFTED('L'),
   143 /*4d*/  SHIFTED('M'),
   144 /*4e*/  SHIFTED('N'),
   145 /*4f*/  SHIFTED('O'),
   146 /*50*/  SHIFTED('P'),
   147 /*51*/  SHIFTED('Q'),
   148 /*52*/  SHIFTED('R'),
   149 /*53*/  SHIFTED('S'),
   150 /*54*/  SHIFTED('T'),
   151 /*55*/  SHIFTED('U'),
   152 /*56*/  SHIFTED('V'),
   153 /*57*/  SHIFTED('W'),
   154 /*58*/  SHIFTED('X'),
   155 /*59*/  SHIFTED('Y'),
   156 /*5a*/  SHIFTED('Z'),
   157 /*5b*/  EStdKeySquareBracketLeft,   // [
   158 /*5c*/  EStdKeyBackSlash,           // backslash
   159 /*5d*/  EStdKeySquareBracketRight,  // ]
   160 /*5e*/  SHIFTED('6'),               // ^
   161 /*5f*/  SHIFTED(EStdKeyMinus),      // _
   162 /*60*/  EStdKeyXXX,					// Actually `
   163 /*61*/  'A',
   164 /*62*/  'B',
   165 /*63*/  'C',
   166 /*64*/  'D',
   167 /*65*/  'E',
   168 /*66*/  'F',
   169 /*67*/  'G',
   170 /*68*/  'H',
   171 /*69*/  'I',
   172 /*6a*/  'J',
   173 /*6b*/  'K',
   174 /*6c*/  'L',
   175 /*6d*/  'M',
   176 /*6e*/  'N',
   177 /*6f*/  'O',
   178 /*70*/  'P',
   179 /*71*/  'Q',
   180 /*72*/  'R',
   181 /*73*/  'S',
   182 /*74*/  'T',
   183 /*75*/  'U',
   184 /*76*/  'V',
   185 /*77*/  'W',
   186 /*78*/  'X',
   187 /*79*/  'Y',
   188 /*7a*/  'Z',
   189 /*7b*/  SHIFTED(EStdKeySquareBracketLeft),  // {
   190 /*7c*/  SHIFTED(EStdKeyBackSlash),          // |
   191 /*7d*/  SHIFTED(EStdKeySquareBracketRight),	// }
   192 /*7e*/  SHIFTED(EStdKeyHash),				// ~
   193 /*7f*/  EKeyDelete
   194 	};
   195 
   196 CSerialKeyboard* CSerialKeyboard::NewL()
   197 	{
   198 	CSerialKeyboard* self = new(ELeave) CSerialKeyboard;
   199 	self->ConstructL();
   200 	return self;
   201 	}
   202 
   203 CSerialKeyboard::CSerialKeyboard()
   204 	:	CActive(0)
   205 	{
   206 	}
   207 
   208 void CSerialKeyboard::ConstructL()
   209 	{
   210 #ifdef __COMMS_DRIVER_NEEDED
   211 	// load and connect to serial port
   212 	TInt r=User::LoadPhysicalDevice(KPddName);
   213 	if (r!=KErrNone && r!=KErrAlreadyExists)
   214 		User::Leave(r);
   215 	r=User::LoadLogicalDevice (KLddName);
   216 	if (r!=KErrNone && r!=KErrAlreadyExists)
   217 		User::Leave(r);
   218 
   219 	r=iDevComm.Open(KPortNumber);
   220 	User::LeaveIfError(r);
   221 
   222 	TCommConfig cfgBuf;
   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));
   234 #endif
   235 
   236 	CActiveScheduler::Add(this);
   237 	}
   238 
   239 CSerialKeyboard::~CSerialKeyboard()
   240 	{
   241 	Cancel();
   242 	}
   243 
   244 void CSerialKeyboard::GetKey()
   245 	{
   246 	__ASSERT_ALWAYS(!IsActive(), User::Panic(_L("CSerialKeyboard"),1));
   247 
   248 	// wait for a key
   249 #ifdef __USE_SERIAL_INPUT
   250 	iDevComm.Read(iStatus,iBuf,1);
   251 #endif
   252 	SetActive();
   253 	}
   254 
   255 TInt CSerialKeyboard::KeyCode()
   256 	{
   257 	TInt c=-1;
   258 #ifdef __USE_SERIAL_INPUT
   259 	if (iBuf.Length()>0)
   260 		c=iBuf[0];
   261 #endif
   262 	return c;
   263 	}
   264 
   265 void CSerialKeyboard::RunL()
   266 	{
   267 	TInt c=KeyCode();
   268 	if (c>=0)
   269 		{
   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);
   276 		TRawEvent e;
   277 
   278 		// post it as a sequence of events
   279 		if (isShifted)
   280 			{
   281 			e.Set(TRawEvent::EKeyDown,EStdKeyRightShift,0);
   282 			UserSvr::AddEvent(e);
   283 			}
   284 		if (isCtrled)
   285 			{
   286 			e.Set(TRawEvent::EKeyDown,EStdKeyLeftCtrl,0);
   287 			UserSvr::AddEvent(e);
   288 			}
   289 		if (isFunced)
   290 			{
   291 			e.Set(TRawEvent::EKeyDown,EStdKeyLeftFunc,0);
   292 			UserSvr::AddEvent(e);
   293 			}
   294 
   295 		e.Set(TRawEvent::EKeyDown,stdKey,0);
   296 		UserSvr::AddEvent(e);
   297 
   298 		e.Set(TRawEvent::EKeyUp,stdKey,0);
   299 		UserSvr::AddEvent(e);
   300 
   301 		if (isFunced)
   302 			{
   303 			e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0);
   304 			UserSvr::AddEvent(e);
   305 			}
   306 		if (isCtrled)
   307 			{
   308 			e.Set(TRawEvent::EKeyUp,EStdKeyLeftCtrl,0);
   309 			UserSvr::AddEvent(e);
   310 			}
   311 		if (isShifted)
   312 			{
   313 			e.Set(TRawEvent::EKeyUp,EStdKeyRightShift,0);
   314 			UserSvr::AddEvent(e);
   315 			}
   316 		}
   317 
   318 	// get another key
   319 	GetKey();
   320 	}
   321 
   322 void CSerialKeyboard::DoCancel()
   323 	{
   324 #ifdef __USE_SERIAL_INPUT
   325 	iDevComm.ReadCancel();
   326 #endif
   327 	}
   328 
   329 
   330 class CScreenDriverVT100 : public CScreenDriver
   331 	{
   332 public:
   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);
   338 
   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);
   345 
   346 	virtual TInt SetMode(TVideoMode aMode);
   347 
   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) {}
   353 
   354 	//
   355 	void Update(const TRect &aRect);
   356 	void Print(const TDesC8& aDes);
   357 	TUint8 *iScreenBuffer;
   358 private:
   359 	CSerialKeyboard *iSerialKeyboard;
   360 	};
   361 
   362 const TInt KScreenWidth = 80;
   363 const TInt KScreenHeight = 24;
   364 
   365 CScreenDriverVT100::CScreenDriverVT100()
   366 //
   367 // Constructor
   368 //
   369 	{
   370 	}
   371 
   372 EXPORT_C CScreenDriver *CScreenDriver::New()
   373 //
   374 // Return the actual screen driver.
   375 //
   376 	{
   377 
   378     CScreenDriverVT100 *pS=new CScreenDriverVT100;
   379 	pS->iScreenBuffer=new TUint8 [KScreenWidth*KScreenHeight];
   380 	return pS;
   381 	}
   382 
   383 void CScreenDriverVT100::Init(TSize& aScreenSize, TSize& aFontSize)
   384 	{
   385 	// Report screen information
   386 	aFontSize=TSize(8,10);
   387 	aScreenSize=TSize(KScreenWidth,KScreenHeight);
   388 
   389 	// start keyboard
   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));
   393 
   394 	iSerialKeyboard->GetKey();
   395 	}
   396 
   397 TInt CScreenDriverVT100::SetMode(TVideoMode aMode)
   398 //
   399 // Set the screen mode
   400 //
   401 	{
   402 	return(KErrNotSupported);
   403 	}
   404 
   405 void CScreenDriverVT100::Update(const TRect &aRect)
   406 	{
   407 	TBuf8<0x100> buf;
   408 	TInt i;
   409 
   410 	for (i=aRect.iTl.iY; i<=aRect.iBr.iY; i++)
   411 		{
   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);
   414 		buf.Append(ptr);
   415 		Print(buf);
   416 		}
   417 	Print(_L8("\x1b[01;01H"));
   418 	}
   419 
   420 void CScreenDriverVT100::Blit(const TText *aBuffer, TInt aLength, const TPoint &aPosition)
   421 //
   422 // Write contiguous block of characters to some segment of a line on the display
   423 //
   424 	{
   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));
   430 	}
   431 
   432 TBool CScreenDriverVT100::ScrollUp(const TRect& aRect)
   433 //
   434 // Scroll a rectangle of the screen up one line, don't update bottom line
   435 //
   436 	{
   437 	TInt j;
   438 	for (j=aRect.iTl.iY; j<aRect.iBr.iY; j++)
   439 		{
   440 		TUint8 *ptr=iScreenBuffer+(aRect.iTl.iX+j*KScreenWidth);
   441 		Mem::Copy(ptr, ptr+KScreenWidth, aRect.iBr.iX-aRect.iTl.iX);
   442 		}
   443 	if ((aRect.iTl.iX<=1) && (aRect.iBr.iX>=KScreenWidth-2))
   444 		{
   445 		// Optimisation: range of whole lines
   446 		TBuf8<0x100> buf;
   447 		// cursor pos
   448 		buf.Format(_L8("\x1b[%02d;%02dH\xd\xa\xba\x1b[%02dC\xba"), aRect.iBr.iY, 1, aRect.iBr.iX);
   449 		Print(buf);
   450 		// set scroll region
   451 		buf.Format(_L8("\x1b[%02d;%02dr\xd\xa"), aRect.iTl.iY+1, aRect.iBr.iY);
   452 		Print(buf);
   453 		Print(_L8("\x1b[01;01H"));
   454 		}
   455 	else
   456 		Update(aRect);
   457 
   458 	return(ETrue);
   459 	}
   460 
   461 void CScreenDriverVT100::Clear(const TRect& aRect)
   462 //
   463 // Clear a rectangle of the screen
   464 //
   465 	{
   466 	TInt j;
   467 	TBuf8<0x100> buf;
   468 	for (j=aRect.iTl.iY; j<=aRect.iBr.iY; j++)
   469 		{
   470 		TUint8 *ptr=iScreenBuffer+(aRect.iTl.iX+j*KScreenWidth);
   471 		Mem::FillZ(ptr, aRect.iBr.iX-aRect.iTl.iX);
   472 		}
   473 	if ((aRect.iTl.iY == aRect.iBr.iY) && (aRect.iTl.iX==0) && (aRect.iBr.iX==KScreenWidth-1))
   474 		{
   475 		// Optimisation: one whole line
   476 		buf.Format(_L8("\x1b[%02d;%02dH"), aRect.iTl.iY, 1);
   477 		Print(buf);
   478 		// Erase line
   479 		buf.Format(_L8("\x1b[2K"));
   480 		Print(buf);
   481 		Print(_L8("\x1b[01;01H"));
   482 		}
   483 	else if ((aRect.iTl.iY == 0) && (aRect.iBr.iY == KScreenHeight-1) &&
   484 						(aRect.iTl.iX == 0) && (aRect.iBr.iX == KScreenWidth-1))
   485 		{
   486 		// Optimisation: whole screen
   487 		buf.Format(_L8("\x1b[2J"));
   488 		Print(buf);
   489 		Print(_L8("\x1b[01;01H"));
   490 		}
   491 	else
   492 		Update(aRect);
   493 	}
   494 
   495 void CScreenDriverVT100::SetPixel(const TPoint& /*aPoint*/,TUint8 /*aColour*/)
   496 	{
   497 	}
   498 
   499 TInt CScreenDriverVT100::GetPixel(const TPoint& /*aPoint*/)
   500 	{
   501 	return 0;
   502 	}
   503 
   504 void CScreenDriverVT100::SetWord(const TPoint& /*aPoint*/,TInt /*aWord*/)
   505 	{
   506 	}
   507 
   508 TInt CScreenDriverVT100::GetWord(const TPoint& /*aPoint*/)
   509 	{
   510 	return 0;
   511 	}
   512 
   513 void CScreenDriverVT100::SetLine(const TPoint& /*aPoint*/,const TPixelLine& /*aPixelLine*/)
   514 	{
   515 	}
   516 
   517 void CScreenDriverVT100::GetLine(const TPoint& /*aPoint*/,TPixelLine& /*aPixelLine*/)
   518 	{
   519 	}
   520 
   521 void CScreenDriverVT100::Print(const TDesC8& aDes)
   522 	{
   523 #ifdef __USE_RDEBUG_OUTPUT
   524 	TBuf<256> unicodeBuf;
   525 	unicodeBuf.Copy(aDes);
   526 	RDebug::RawPrint(unicodeBuf);
   527 #else
   528 	RBusDevComm c=iSerialKeyboard->iDevComm;
   529 	TRequestStatus s;
   530 	c.Write(s,aDes);
   531 	User::WaitForRequest(s);
   532 #endif
   533 	}
   534