plugins/consoles/guicons/src/guicons.cpp
changeset 0 7f656887cf89
child 100 706c7a69e448
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // guicons.cpp
       
     2 // 
       
     3 // Copyright (c) 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include <fshell/common.mmh>
       
    14 #include "guicons.h"
       
    15 #include <ImageConversion.h>
       
    16 #include <e32Math.h>
       
    17 
       
    18 #include "defaultfontdata.inl"
       
    19 
       
    20 const TInt KAttributeMapGranularity = 3;
       
    21 
       
    22 const ConsoleAttributes::TColor KDefaultForegroundColor = ConsoleAttributes::EBlack;
       
    23 const ConsoleAttributes::TColor KDefaultBackgroundColor = ConsoleAttributes::EWhite;
       
    24 
       
    25 
       
    26 ConsoleAttributes::TAttributes DefaultAttributes()
       
    27 	{
       
    28 	return ConsoleAttributes::TAttributes(ConsoleAttributes::ENone, KDefaultForegroundColor, KDefaultBackgroundColor);
       
    29 	}
       
    30 
       
    31 TRgb MapColor(TUint aAttributes, ConsoleAttributes::TColor aColor)
       
    32 	{
       
    33 	TRgb rgb;
       
    34 
       
    35 	switch (aColor)
       
    36 		{
       
    37 		case ConsoleAttributes::EBlack:
       
    38 			if (aAttributes & ConsoleAttributes::EBold)
       
    39 				{
       
    40 				rgb = KRgbGray;
       
    41 				}
       
    42 			else
       
    43 				{
       
    44 				rgb = KRgbBlack;
       
    45 				}
       
    46 			break;
       
    47 		case ConsoleAttributes::ERed:
       
    48 			if (aAttributes & ConsoleAttributes::EBold)
       
    49 				{
       
    50 				rgb = KRgbRed;
       
    51 				}
       
    52 			else
       
    53 				{
       
    54 				rgb = KRgbDarkRed;
       
    55 				}
       
    56 			break;
       
    57 		case ConsoleAttributes::EGreen:
       
    58 			if (aAttributes & ConsoleAttributes::EBold)
       
    59 				{
       
    60 				rgb = KRgbGreen;
       
    61 				}
       
    62 			else
       
    63 				{
       
    64 				rgb = KRgbDarkGreen;
       
    65 				}
       
    66 			break;
       
    67 		case ConsoleAttributes::EYellow:
       
    68 			if (aAttributes & ConsoleAttributes::EBold)
       
    69 				{
       
    70 				rgb = KRgbYellow;
       
    71 				}
       
    72 			else
       
    73 				{
       
    74 				rgb = KRgbDarkYellow;
       
    75 				}
       
    76 			break;
       
    77 		case ConsoleAttributes::EBlue:
       
    78 			if (aAttributes & ConsoleAttributes::EBold)
       
    79 				{
       
    80 				rgb = KRgbBlue;
       
    81 				}
       
    82 			else
       
    83 				{
       
    84 				rgb = KRgbDarkBlue;
       
    85 				}
       
    86 			break;
       
    87 		case ConsoleAttributes::EMagenta:
       
    88 			if (aAttributes & ConsoleAttributes::EBold)
       
    89 				{
       
    90 				rgb = KRgbMagenta;
       
    91 				}
       
    92 			else
       
    93 				{
       
    94 				rgb = KRgbDarkMagenta;
       
    95 				}
       
    96 			break;
       
    97 		case ConsoleAttributes::ECyan:
       
    98 			if (aAttributes & ConsoleAttributes::EBold)
       
    99 				{
       
   100 				rgb = KRgbCyan;
       
   101 				}
       
   102 			else
       
   103 				{
       
   104 				rgb = KRgbDarkCyan;
       
   105 				}
       
   106 			break;
       
   107 		case ConsoleAttributes::EWhite:
       
   108 			if (aAttributes & ConsoleAttributes::EBold)
       
   109 				{
       
   110 				rgb = KRgbWhite;
       
   111 				}
       
   112 			else
       
   113 				{
       
   114 				rgb = KRgbWhite;//KRgbGray;
       
   115 				}
       
   116 			break;
       
   117 		case ConsoleAttributes::EReset:
       
   118 		case ConsoleAttributes::EUnchanged:
       
   119 		default:
       
   120 			ASSERT(EFalse);
       
   121 		}
       
   122 
       
   123 	if (aAttributes & ConsoleAttributes::EInverse)
       
   124 		{
       
   125 		rgb = ~rgb;
       
   126 		}
       
   127 
       
   128 	return rgb;
       
   129 	}
       
   130 
       
   131 void SignalSemaphore(TAny* aSemaphore)
       
   132 	{
       
   133 	((RSemaphore*)aSemaphore)->Signal();
       
   134 	}
       
   135 
       
   136 void CleanupSignalSemaphorePushL(RSemaphore& aSemaphore)
       
   137 	{
       
   138 	CleanupStack::PushL(TCleanupItem(SignalSemaphore, &aSemaphore));
       
   139 	}
       
   140 	
       
   141 void WaitForRequest(TAny* aStatus)
       
   142 	{
       
   143 	User::WaitForRequest(*(TRequestStatus*)aStatus);
       
   144 	}
       
   145 	
       
   146 void CleanupWaitForRequestPushL(TRequestStatus& aStatus)
       
   147 	{
       
   148 	CleanupStack::PushL(TCleanupItem(WaitForRequest, &aStatus));
       
   149 	}
       
   150 	
       
   151 //______________________________________________________________________________
       
   152 //						CConsoleControl
       
   153 EXPORT_C CConsoleControl* CConsoleControl::NewL(TInt aBufferSize, MConsoleUi* aUi)
       
   154 	{
       
   155 	CConsoleControl* self = new(ELeave)CConsoleControl(aUi, aBufferSize);
       
   156 	CleanupStack::PushL(self);
       
   157 	self->ConstructL(CConsoleFont::NewL(KDefaultFontImageData));
       
   158 	CleanupStack::Pop(self);
       
   159 	return self;
       
   160 	}
       
   161 
       
   162 EXPORT_C CConsoleControl* CConsoleControl::NewL(TInt aBufferSize, const TDesC& aFontFile, MConsoleUi* aUi)
       
   163 	{
       
   164 	CConsoleControl* self = new(ELeave)CConsoleControl(aUi, aBufferSize);
       
   165 	CleanupStack::PushL(self);
       
   166 	self->ConstructL(CConsoleFont::NewL(aFontFile));
       
   167 	CleanupStack::Pop(self);
       
   168 	return self;
       
   169 	}
       
   170 
       
   171 EXPORT_C CConsoleControl::~CConsoleControl()
       
   172 	{
       
   173 	delete iBlinkTimer;
       
   174 	delete iFont;
       
   175 	iCursor.Hide();
       
   176 	iBuffer.ResetAndDestroy();
       
   177 	iKeyQueue.Close();
       
   178 	}
       
   179 	
       
   180 EXPORT_C void CConsoleControl::Closed()
       
   181 	{
       
   182 	if (iUi)
       
   183 		{
       
   184 		iUi->HandleConsoleClosed(this);
       
   185 		}
       
   186 	}
       
   187 
       
   188 EXPORT_C void CConsoleControl::Draw(const TRect& aRect) const
       
   189 	{
       
   190 	CWindowGc& gc = SystemGc();
       
   191 	gc.SetBrushStyle(CGraphicsContext::ENullBrush);
       
   192 	gc.SetPenStyle(CGraphicsContext::ENullPen);
       
   193 	// Need to do a clear here, to ensure we actually draw to all the pixels in aRect that we've been asked to draw. If we don't do that, wserv generally gets upset.
       
   194 //	gc.SetBrushColor(KDefaultBackgroundColor);
       
   195 //	gc.Clear(aRect);
       
   196 	
       
   197 	for (TInt y=0; y<iSizeChars.iHeight; ++y)
       
   198 		{
       
   199 		TViewPosition line(*this, 0, y);
       
   200 		if (aRect.Intersects(LineRect(line)))
       
   201 			{
       
   202 			DrawLine(line, gc);
       
   203 			}
       
   204 		}
       
   205 
       
   206 	if (iDrawNavigator)
       
   207 		{
       
   208 		// And draw the 5-way UI
       
   209 #ifdef FSHELL_WSERV2_SUPPORT
       
   210 		// XOR draw mode doesn't seem to be supported in recent wserv, so use a colour with alpha channel instead
       
   211 		const TRgb col(15, 15, 15, 128);
       
   212 		gc.SetDrawMode(CGraphicsContext::EDrawModePEN);
       
   213 #else
       
   214 		const TRgb col(15,15,15);
       
   215 		gc.SetDrawMode(CGraphicsContext::EDrawModeXOR);
       
   216 #endif
       
   217 		gc.SetBrushColor(col);
       
   218 		gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   219 		gc.SetPenColor(col);
       
   220 		for (TInt i = 0; i < ENumButtons; i++)
       
   221 			{
       
   222 			if (aRect.Intersects(iButtonRects[i]))
       
   223 				{
       
   224 				if (i == ECenter)
       
   225 					{
       
   226 					gc.DrawEllipse(iButtonRects[i]);
       
   227 					}
       
   228 				else
       
   229 					{
       
   230 					gc.DrawRect(iButtonRects[i]);
       
   231 					}
       
   232 				}
       
   233 			}
       
   234 		}
       
   235 	}
       
   236 	
       
   237 EXPORT_C TCoeInputCapabilities CConsoleControl::InputCapabilities() const
       
   238 	{
       
   239 	return TCoeInputCapabilities(
       
   240 				TCoeInputCapabilities::ENonPredictive 
       
   241 			|	TCoeInputCapabilities::EAllText
       
   242 			|	TCoeInputCapabilities::ENavigation
       
   243 			);
       
   244 	}
       
   245 	
       
   246 EXPORT_C void CConsoleControl::FocusChanged(TDrawNow)
       
   247 	{
       
   248 	iCursor.Update();
       
   249 	if (IsFocused())
       
   250 		{
       
   251 		StartBlinking();
       
   252 		}
       
   253 	else
       
   254 		{
       
   255 		iBlinkTimer->Cancel();
       
   256 		}
       
   257 	}
       
   258 	
       
   259 EXPORT_C void CConsoleControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
   260 	{
       
   261 	if (aPointerEvent.iType == TPointerEvent::EButton1Down)
       
   262 		{
       
   263 		for (TInt i = 0; i < ENumButtons; i++)
       
   264 			{
       
   265 			if (iButtonRects[i].Contains(aPointerEvent.iPosition))
       
   266 				{
       
   267 				SimulateKeyL((TButton)i);
       
   268 				iIgnoringDrags = ETrue;
       
   269 				return;
       
   270 				}
       
   271 			}
       
   272 		iIgnoringDrags = EFalse;
       
   273 		}
       
   274 
       
   275 	if (iIgnoringDrags) return;
       
   276 	if (aPointerEvent.iType == TPointerEvent::EButton1Down)
       
   277 		{
       
   278 		iDragStart = aPointerEvent.iPosition;
       
   279 		}
       
   280 	if (aPointerEvent.iType == TPointerEvent::EDrag)
       
   281 		{
       
   282 		TPoint delta = iDragStart - aPointerEvent.iPosition;
       
   283 		TInt lines = delta.iY / iFont->GlyphSize().iHeight;
       
   284 		if (lines)
       
   285 			{
       
   286 			iViewWindow.iY += lines;
       
   287 			ViewMoved();
       
   288 			
       
   289 			iDragStart.iY -= (lines * iFont->GlyphSize().iHeight);
       
   290 			}
       
   291 		}
       
   292 	}
       
   293 	
       
   294 EXPORT_C TKeyResponse CConsoleControl::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
       
   295 	{
       
   296 	if ((!IsFocused()) || IsNonFocusing()) return EKeyWasNotConsumed;
       
   297 	
       
   298 	if (aType == EEventKey)
       
   299 		{
       
   300 		iKeyQueue.AppendL(aKeyEvent);
       
   301 		SendKey();
       
   302 		
       
   303 #ifdef LOCAL_ECHO
       
   304 		TUint code = aKeyEvent.iCode;
       
   305 		if (code == '\r') code = '\n';
       
   306 		
       
   307 		TBuf<0x20> ip;
       
   308 		ip.AppendFormat(_L("key %d"), code);
       
   309 		User::InfoPrint(ip);
       
   310 
       
   311 		TBuf<1> buf;
       
   312 		buf.Append(TChar(code));
       
   313 		Write(buf);
       
   314 #endif
       
   315 		return EKeyWasConsumed;
       
   316 		}
       
   317 	return EKeyWasNotConsumed;	
       
   318 	}
       
   319 	
       
   320 EXPORT_C void CConsoleControl::InjectKeysL(const TDesC& aKeys)
       
   321 	{
       
   322 	for (TInt i=0; i<aKeys.Length(); ++i)
       
   323 		{
       
   324 		TKeyEvent key;
       
   325 		key.iCode = aKeys[i];
       
   326 		key.iModifiers = 0;
       
   327 		iKeyQueue.AppendL(key);		
       
   328 		}
       
   329 	SendKey();
       
   330 	}
       
   331 	
       
   332 void CConsoleControl::DrawLine(TViewPosition aLine, CBitmapContext& aDrawTo) const
       
   333 	{
       
   334 	CConsoleLine* line = GetLine(aLine);
       
   335 	if (line)
       
   336 		{
       
   337 		line->Draw(aDrawTo, aLine);
       
   338 		}
       
   339 	}
       
   340 
       
   341 TRect CConsoleControl::LineRect(TViewPosition aLine) const
       
   342 	{
       
   343 	return TRect(TScreenPosition(aLine).iPoint, TSize(iFont->GlyphSize().iWidth * iSizeChars.iWidth, iFont->GlyphSize().iHeight));
       
   344 	}
       
   345 
       
   346 
       
   347 EXPORT_C void CConsoleControl::SizeChanged()
       
   348 	{
       
   349 	TSize sizePixels = Size();
       
   350 	TSize newSizeChars(sizePixels.iWidth / iFont->GlyphSize().iWidth, sizePixels.iHeight / iFont->GlyphSize().iHeight);
       
   351 	if (newSizeChars != iSizeChars)
       
   352 		{
       
   353 		iSizeChars = newSizeChars;
       
   354 		TRAP_IGNORE(SizeChangedL());
       
   355 		}
       
   356 	}
       
   357 
       
   358 CConsoleControl::CConsoleControl(MConsoleUi* aUi, TInt aBufferSize)
       
   359 	: iUi(aUi), iCursor(*this), iCurrentAttributes(ConsoleAttributes::ENone, KDefaultForegroundColor, KDefaultBackgroundColor), iBufferSize(aBufferSize)
       
   360 	{
       
   361 	}
       
   362 
       
   363 void CConsoleControl::ConstructL(CConsoleFont* aFont)
       
   364 	{
       
   365 	iBlinkTimer = CPeriodic::NewL(CActive::EPriorityStandard);
       
   366 	iFont = aFont;
       
   367 	iCursor.SetFont(*iFont);
       
   368 	SetCursorHeight(KDefaultCursorHeightPercentage);
       
   369 	}
       
   370 
       
   371 void CConsoleControl::SizeChangedL()
       
   372 	{
       
   373 	TInt bufferSize = Max(iBufferSize, iSizeChars.iHeight);
       
   374 	for (TInt i=0; i<Min(iBuffer.Count(), bufferSize); ++i)
       
   375 		{
       
   376 		iBuffer[i]->SetWidthL(iSizeChars.iWidth);
       
   377 		}
       
   378 	while (iBuffer.Count() < bufferSize)
       
   379 		{
       
   380 		CConsoleLine* line = CConsoleLine::NewL(*this, *iFont, iSizeChars.iWidth);
       
   381 		CleanupStack::PushL(line);
       
   382 		iBuffer.AppendL(line);
       
   383 		CleanupStack::Pop();
       
   384 		}
       
   385 	while (iBuffer.Count() > bufferSize)
       
   386 		{
       
   387 		delete iBuffer[iBuffer.Count()-1];
       
   388 		iBuffer.Remove(iBuffer.Count()-1);
       
   389 		}
       
   390 	iCursor.Update();
       
   391 
       
   392 	if (FivewayNavIsDisplaying()) SetDisplayFivewayNav(ETrue); // re-layout the onscreen nav if applicable
       
   393 	}
       
   394 	
       
   395 CConsoleLine* CConsoleControl::GetLine(TBufferPosition aLine) const
       
   396 	{
       
   397 	return iBuffer[aLine.iPoint.iY];
       
   398 	}
       
   399 	
       
   400 TPoint CConsoleControl::ViewPosition() const
       
   401 	{
       
   402 	return iViewWindow;
       
   403 	}
       
   404 	
       
   405 TPoint CConsoleControl::CursorWindowPosition() const
       
   406 	{
       
   407 	return iCursorWindow;
       
   408 	}
       
   409 
       
   410 TSize CConsoleControl::GlyphSize() const
       
   411 	{
       
   412 	return iFont->GlyphSize();
       
   413 	}
       
   414 	
       
   415 TBool CConsoleControl::IsSpecialChar(TChar aChar) const
       
   416 	{
       
   417 	switch(aChar)
       
   418 		{
       
   419 		case 0x00:	// Null.
       
   420 		case 0x07:	// Bell.
       
   421 		case 0x08:	// Backspace.
       
   422 		case 0x7f:	// Delete.
       
   423 		case 0x09:	// Tab.
       
   424 		case 0x0a:	// Line feed.
       
   425 		case 0x0b:	// Vertical tab.
       
   426 		case 0x0c:	// Form feed.
       
   427 		case 0x0d:	// Carriage return.
       
   428 			return ETrue;
       
   429 		default:
       
   430 			return EFalse;
       
   431 		}
       
   432 	}
       
   433 	
       
   434 void CConsoleControl::HandleSpecialChar(TChar aChar)
       
   435 	{
       
   436 	switch(aChar)
       
   437 		{
       
   438 		case 0x00:	// Null.
       
   439 			break;
       
   440 		case 0x07:	// Bell.
       
   441 			break;
       
   442 		case 0x08:	// Backspace.
       
   443 		case 0x7f:	// Delete.
       
   444 			iCursor--;
       
   445 			break;
       
   446 		case 0x09:	// horizontal tab
       
   447 			iCursor += KTabSize - (iCursor.Position().iPoint.iX % KTabSize);
       
   448 			break;
       
   449 		case 0x0a:	// line feed
       
   450 			iCursor -= iCursor.Position().iPoint.iX;
       
   451 			iCursor.Down();
       
   452 			break;
       
   453 		case 0x0b:	// Vertical tab.
       
   454 			break;
       
   455 		case 0x0c:  // Form feed
       
   456 			ClearScreen();
       
   457 			break;
       
   458 		case 0x0d:	// carriage return
       
   459 			iCursor -= iCursor.Position().iPoint.iX;
       
   460 			break;
       
   461 		default:
       
   462 			User::Invariant();
       
   463 		}
       
   464 	}
       
   465 	
       
   466 void CConsoleControl::SendKey()
       
   467 	{
       
   468 	if (iReader && iKeyQueue.Count())
       
   469 		{
       
   470 		iCurrentKey = iKeyQueue[0];
       
   471 		iKeyQueue.Remove(0);
       
   472 		iReader->ReadComplete(KErrNone);
       
   473 		iReader = NULL;
       
   474 		}
       
   475 	}
       
   476 	
       
   477 EXPORT_C void CConsoleControl::Read(MGuiConsoleReader& aReader)
       
   478 	{
       
   479 	if (iReader)
       
   480 		{
       
   481 		aReader.ReadComplete(KErrInUse);
       
   482 		}
       
   483 	else
       
   484 		{
       
   485 		iReader = &aReader;
       
   486 		SendKey();
       
   487 		}
       
   488 	}
       
   489 	
       
   490 EXPORT_C void CConsoleControl::ReadCancel()
       
   491 	{
       
   492 	iReader = NULL;
       
   493 	}
       
   494 	
       
   495 EXPORT_C void CConsoleControl::Write(const TDesC &aDes)
       
   496 	{
       
   497 	TRAP_IGNORE(WriteL(aDes));
       
   498 	}
       
   499 
       
   500 void CConsoleControl::WriteL(const TDesC &aDes)
       
   501 	{
       
   502 	TRect invalidRect;
       
   503 	for (TInt i=0; i<aDes.Length(); ++i)
       
   504 		{
       
   505 		if (IsSpecialChar(aDes[i]))
       
   506 			{
       
   507 			if (!invalidRect.IsEmpty())
       
   508 				{
       
   509 				// Draw to the invalid rectangle before handling this special character because it may cause the
       
   510 				// window to scroll, thereby invalidating the coordinates of invalidRect.
       
   511 				DrawNow(invalidRect);
       
   512 				invalidRect = TRect();
       
   513 				}
       
   514 			HandleSpecialChar(aDes[i]);
       
   515 			}
       
   516 		else
       
   517 			{
       
   518 			CConsoleLine* line = GetLine(iCursor.Position());
       
   519 			line->SetL(iCursor.Position().iPoint.iX, aDes[i], iCurrentAttributes);
       
   520 			TRect lineRect(LineRect(iCursor.Position()));
       
   521 			Window().Invalidate(lineRect);
       
   522 			if (invalidRect.IsEmpty())
       
   523 				{
       
   524 				invalidRect = lineRect;
       
   525 				}
       
   526 			else
       
   527 				{
       
   528 				invalidRect.BoundingRect(lineRect);
       
   529 				}
       
   530 			iCursor++;
       
   531 			}
       
   532 		}
       
   533 
       
   534 	if (!invalidRect.IsEmpty())
       
   535 		{
       
   536 		DrawNow(invalidRect);
       
   537 		}
       
   538 	
       
   539 	iCursor.Update();
       
   540 	}
       
   541 
       
   542 void CConsoleControl::StartBlinking()
       
   543 	{
       
   544 	if (!iBlinkTimer->IsActive())
       
   545 		{
       
   546 		iBlinkTimer->Start(500000, 500000, TCallBack(BlinkCallback, this));
       
   547 		}
       
   548 	}
       
   549 
       
   550 TInt CConsoleControl::BlinkCallback(TAny* aPtr)
       
   551 	{
       
   552 	CConsoleControl* self = static_cast<CConsoleControl*>(aPtr);
       
   553 
       
   554 	TBool neededToBlink(EFalse);
       
   555 	for (TInt y = 0; y < self->iSizeChars.iHeight; ++y)
       
   556 		{
       
   557 		TViewPosition line(*self, 0, y);
       
   558 		if (self->GetLine(line)->NeedToBlink(self->iBlinkOn))
       
   559 			{
       
   560 			neededToBlink = ETrue;
       
   561 			self->Window().Invalidate(self->LineRect(line));
       
   562 			}
       
   563 		}
       
   564 	if (neededToBlink)
       
   565 		{
       
   566 		self->iBlinkOn = !self->iBlinkOn;
       
   567 		}
       
   568 	else
       
   569 		{
       
   570 		self->iBlinkTimer->Cancel();
       
   571 		}
       
   572 
       
   573 	return KErrNone;
       
   574 	}
       
   575 	
       
   576 EXPORT_C void CConsoleControl::ViewScrollUp()
       
   577 	{
       
   578 	iViewWindow.iY--;
       
   579 	ViewMoved();
       
   580 	}
       
   581 	
       
   582 EXPORT_C void CConsoleControl::ViewScrollDown()
       
   583 	{
       
   584 	iViewWindow.iY++;
       
   585 	ViewMoved();
       
   586 	}
       
   587 	
       
   588 EXPORT_C void CConsoleControl::ViewPageUp()
       
   589 	{
       
   590 	iViewWindow.iY -= iSizeChars.iHeight-1;
       
   591 	ViewMoved();
       
   592 	}
       
   593 	
       
   594 EXPORT_C void CConsoleControl::ViewPageDown()
       
   595 	{
       
   596 	iViewWindow.iY += iSizeChars.iHeight-1;
       
   597 	ViewMoved();
       
   598 	}
       
   599 	
       
   600 EXPORT_C void CConsoleControl::ViewHome()
       
   601 	{
       
   602 	iViewWindow.iY = 0;
       
   603 	ViewMoved();
       
   604 	}
       
   605 	
       
   606 EXPORT_C void CConsoleControl::ViewEnd()
       
   607 	{
       
   608 	iViewWindow = iCursorWindow;
       
   609 	ViewMoved();
       
   610 	}
       
   611 
       
   612 void CConsoleControl::Invalidate5Way()
       
   613 	{
       
   614 	if (iDrawNavigator)
       
   615 		{
       
   616 		for (TInt i = 0; i < ENumButtons; i++)
       
   617 			{
       
   618 			Window().Invalidate(iButtonRects[i]);
       
   619 			}
       
   620 		}
       
   621 	}
       
   622 
       
   623 EXPORT_C TInt CConsoleControl::SetAttributes(TUint aAttributes, ConsoleAttributes::TColor aForegroundColor, ConsoleAttributes::TColor aBackgroundColor)
       
   624 	{
       
   625 	ConsoleAttributes::TAttributes currentAttributes = iCurrentAttributes;
       
   626 
       
   627 	if (aAttributes == ConsoleAttributes::ENone)
       
   628 		{
       
   629 		currentAttributes = DefaultAttributes();
       
   630 		}
       
   631 	else
       
   632 		{
       
   633 		currentAttributes.iAttributes = aAttributes;
       
   634 		}
       
   635 
       
   636 	switch (aForegroundColor)
       
   637 		{
       
   638 		case ConsoleAttributes::EReset:
       
   639 			currentAttributes.iForegroundColor = KDefaultForegroundColor;
       
   640 			break;
       
   641 		case ConsoleAttributes::EUnchanged:
       
   642 			// Do nothing.
       
   643 			break;
       
   644 		default:
       
   645 			currentAttributes.iForegroundColor = aForegroundColor;
       
   646 			break;
       
   647 		}
       
   648 
       
   649 	switch (aBackgroundColor)
       
   650 		{
       
   651 		case ConsoleAttributes::EReset:
       
   652 			currentAttributes.iBackgroundColor = KDefaultBackgroundColor;
       
   653 			break;
       
   654 		case ConsoleAttributes::EUnchanged:
       
   655 			// Do nothing.
       
   656 			break;
       
   657 		default:
       
   658 			currentAttributes.iBackgroundColor = aBackgroundColor;
       
   659 			break;
       
   660 		}
       
   661 
       
   662 	TRAPD(err, iFont->PrepareForegroundColorL(MapColor(currentAttributes.iAttributes, currentAttributes.iForegroundColor)));
       
   663 	if (err == KErrNone)
       
   664 		{
       
   665 		iCurrentAttributes = currentAttributes;
       
   666 		}
       
   667 
       
   668 	return err;
       
   669 	}
       
   670 	
       
   671 void CConsoleControl::ViewMoved()
       
   672 	{
       
   673 	if (iViewWindow.iY < 0) iViewWindow.iY = 0;
       
   674 	if (iViewWindow.iY + iSizeChars.iHeight > iBuffer.Count()) iViewWindow.iY = iBuffer.Count() - iSizeChars.iHeight;
       
   675 	Window().Invalidate();
       
   676 	}
       
   677 
       
   678 void CConsoleControl::CursorWindowScrollDown()
       
   679 	{
       
   680 	TBool viewWindowMatchesCursorWindow = (iViewWindow.iY == iCursorWindow.iY);
       
   681 	iCursorWindow.iY++;
       
   682 	if (iCursorWindow.iY + iSizeChars.iHeight > iBuffer.Count())
       
   683 		{
       
   684 		iCursorWindow.iY--;
       
   685 		CConsoleLine* topLine = iBuffer[0];
       
   686 		iBuffer.Remove(0);
       
   687 		topLine->Clear();
       
   688 		iBuffer.Append(topLine);
       
   689 		
       
   690 		// JB - Disabled the code below because it forces a full redraw of the window which seems
       
   691 		// unnecessary, particularly now that this function trys to efficiently scroll using
       
   692 		// RDrawableWindow::Scroll. Note though that I can't claim to fully understand this code,
       
   693 		// so this may be a dumb thing to do. Original comment follows...
       
   694 		// move this up so that the text in the view window moves up with the scrolling text.
       
   695 		// ViewScrollUp();
       
   696 		}
       
   697 	
       
   698 	if (viewWindowMatchesCursorWindow) // keep them in sync if they were when we started
       
   699 		{
       
   700 		iViewWindow.iY = iCursorWindow.iY;
       
   701 		}
       
   702 
       
   703 #ifndef FSHELL_WSERV2_SUPPORT
       
   704 	// On wserv1 we can't use Scroll if we're showing the 5-way nav - it looks bad
       
   705 	if (iDrawNavigator)
       
   706 		{
       
   707 		DrawDeferred();
       
   708 		}
       
   709 	else
       
   710 #endif
       
   711 		{
       
   712 		// on wserv2, or wserv1 when the 5-way nav isn't displayed, we can use RWindow::Scroll for better performance (although, performance only seems to be a problem on wserv1 with a wide screen. On wserv2 probably just a DrawDeferred() would be sufficient)
       
   713 		Invalidate5Way();
       
   714 		Window().Scroll(Rect(), TPoint(0, -(iFont->GlyphSize().iHeight)));
       
   715 		Invalidate5Way();
       
   716 		TRect invalidRect(LineRect(TViewPosition(*this, 0, iSizeChars.iHeight - 1)));
       
   717 		Window().Invalidate(invalidRect);
       
   718 		}
       
   719 	}
       
   720 	
       
   721 EXPORT_C TPoint CConsoleControl::CursorPos() const
       
   722 	{
       
   723 	return iCursor.Position().iPoint;
       
   724 	}
       
   725 	
       
   726 EXPORT_C void CConsoleControl::SetCursorPosAbs(const TPoint &aPoint)
       
   727 	{
       
   728 	iCursor.SetPosAbs(TConsCursorPosition(*this, aPoint));
       
   729 	iCursor.Update();
       
   730 	}
       
   731 	
       
   732 EXPORT_C void CConsoleControl::SetCursorPosRel(const TPoint &aPoint)
       
   733 	{
       
   734 	iCursor.SetPosRel(TConsCursorPosition(*this, aPoint));
       
   735 	iCursor.Update();
       
   736 	}
       
   737 	
       
   738 EXPORT_C void CConsoleControl::SetCursorHeight(TInt aPercentage)
       
   739 	{
       
   740 	iCursor.SetHeight(aPercentage);
       
   741 	iCursor.Update();
       
   742 	}
       
   743 	
       
   744 EXPORT_C void CConsoleControl::SetTitle(const TDesC &aTitle)
       
   745 	{
       
   746 	if (iUi)
       
   747 		{
       
   748 		TRAP_IGNORE(iUi->ConsoleTitleChangedL(this, aTitle));
       
   749 		}
       
   750 	}
       
   751 	
       
   752 EXPORT_C void CConsoleControl::ClearScreen()
       
   753 	{
       
   754 	Window().Invalidate();
       
   755 	for (TInt y=0; y<iBuffer.Count(); ++y)
       
   756 		{
       
   757 		iBuffer[y]->Clear();
       
   758 		}
       
   759 	iCursorWindow.iY = 0;
       
   760 	iViewWindow.iY = 0;
       
   761 	iCursor.SetPosAbs(TConsCursorPosition(*this, 0,0));
       
   762 	iCurrentAttributes = DefaultAttributes();
       
   763 	}
       
   764 	
       
   765 EXPORT_C void CConsoleControl::ClearToEndOfLine()
       
   766 	{
       
   767 	GetLine(iCursor.Position())->ClearFrom(iCursor.Position());
       
   768 	Window().Invalidate(LineRect(iCursor.Position()));
       
   769 	}
       
   770 	
       
   771 EXPORT_C TSize CConsoleControl::ScreenSize() const
       
   772 	{
       
   773 	return iSizeChars;
       
   774 	}
       
   775 	
       
   776 EXPORT_C TKeyCode CConsoleControl::KeyCode() const
       
   777 	{
       
   778 	return (TKeyCode)iCurrentKey.iCode;
       
   779 	}
       
   780 	
       
   781 EXPORT_C TUint CConsoleControl::KeyModifiers() const
       
   782 	{
       
   783 	return iCurrentKey.iModifiers;
       
   784 	}
       
   785 
       
   786 void CConsoleControl::SimulateKeyL(TButton aButton)
       
   787 	{
       
   788 	TKeyEvent key;
       
   789 	key.iRepeats = 0;
       
   790 	key.iModifiers = 0;
       
   791 	switch (aButton)
       
   792 		{
       
   793 		case EUp:
       
   794 			key.iCode = EKeyUpArrow;
       
   795 			key.iScanCode = EStdKeyUpArrow;
       
   796 			break;
       
   797 		case EDown:
       
   798 			key.iCode = EKeyDownArrow;
       
   799 			key.iScanCode = EStdKeyDownArrow;
       
   800 			break;
       
   801 		case ELeft:
       
   802 			key.iCode = EKeyLeftArrow;
       
   803 			key.iScanCode = EStdKeyLeftArrow;
       
   804 			break;
       
   805 		case ERight:
       
   806 			key.iCode = EKeyRightArrow;
       
   807 			key.iScanCode = EStdKeyRightArrow;
       
   808 			break;
       
   809 		case ECenter:
       
   810 			key.iCode = EKeyEnter;
       
   811 			key.iScanCode = EStdKeyEnter;
       
   812 			break;
       
   813 		default:
       
   814 			return;
       
   815 		}
       
   816 	iCoeEnv->SimulateKeyEventL(key, EEventKey);
       
   817 	}
       
   818 
       
   819 EXPORT_C TBool CConsoleControl::FivewayNavIsDisplaying() const
       
   820 	{
       
   821 	return iButtonRects[ECenter].Width();
       
   822 	}
       
   823 
       
   824 EXPORT_C void CConsoleControl::SetDisplayFivewayNav(TBool aShow)
       
   825 	{
       
   826 	if (aShow)
       
   827 		{
       
   828 		TRect rect(Rect());
       
   829 		TInt shortLen = Min(rect.Width(), rect.Height()); // Look nicer in landscape
       
   830 		TSize buttonSize(shortLen / 4, shortLen / 4);
       
   831 		TRect center(TPoint(rect.Width()/2 - buttonSize.iWidth/2, rect.Height() - 2*buttonSize.iHeight), buttonSize);
       
   832 		iButtonRects[ECenter] = center;
       
   833 		iButtonRects[ECenter].Shrink(5, 5);
       
   834 		iButtonRects[ELeft] = center; iButtonRects[ELeft].Move(-buttonSize.iWidth, 0);
       
   835 		iButtonRects[ERight] = center; iButtonRects[ERight].Move(buttonSize.iWidth, 0);
       
   836 		iButtonRects[EUp] = center; iButtonRects[EUp].Move(0, -buttonSize.iHeight);
       
   837 		iButtonRects[EDown] = center; iButtonRects[EDown].Move(0, buttonSize.iHeight);
       
   838 		iDrawNavigator = ETrue;
       
   839 		}
       
   840 	else
       
   841 		{
       
   842 		Mem::FillZ(iButtonRects, sizeof(iButtonRects));
       
   843 		}
       
   844 	DrawDeferred();
       
   845 	}
       
   846 
       
   847 void CConsoleControl::ActivateL()
       
   848 	{
       
   849 	Window().SetBackgroundColor(KRgbWhite);
       
   850 	CCoeControl::ActivateL();
       
   851 	}
       
   852 
       
   853 //______________________________________________________________________________
       
   854 //						Image loader thread
       
   855 // We use ICl to decode the font image. Despite ICL having the ability to create
       
   856 // a thread of it own to do the decoding, when we decode from a descriptor
       
   857 // (instead of a file), it still requires a AO RunL's in out thread to operate.
       
   858 // So, we have to create a new thread manually so that we can always load images
       
   859 // synchronously.
       
   860 
       
   861 class RImageDecodeThreadParams
       
   862 	{
       
   863 public:
       
   864 	RImageDecodeThreadParams(const TDesC& aFileName)
       
   865 		: iMode(EDecodeFile), iFileName(aFileName), iData(KNullDesC8), iBitmapHandle(KNullHandle) {}
       
   866 	RImageDecodeThreadParams(const TDesC8& aImageData)
       
   867 		: iMode(EDecodeData), iFileName(KNullDesC), iData(aImageData), iBitmapHandle(KNullHandle) {}
       
   868 	TInt Open()
       
   869 		{
       
   870 		TInt err = iBitmapReadySemaphore.CreateLocal(0);
       
   871 		if (err==KErrNone) err = iThreadExitSemaphore.CreateLocal(0);
       
   872 		if (err!=KErrNone) Close();
       
   873 		return err;
       
   874 		}
       
   875 	void Close()
       
   876 		{
       
   877 		iBitmapReadySemaphore.Close();
       
   878 		iThreadExitSemaphore.Close();
       
   879 		}
       
   880 public:
       
   881 	enum
       
   882 		{
       
   883 		EDecodeFile,
       
   884 		EDecodeData,
       
   885 		} iMode;
       
   886 	const TPtrC iFileName;
       
   887 	const TPtrC8 iData;
       
   888 	TFrameInfo iFrameInfo;
       
   889 	TInt iBitmapHandle;
       
   890 	RSemaphore iBitmapReadySemaphore;
       
   891 	RSemaphore iThreadExitSemaphore;
       
   892 	TInt iThreadError;
       
   893 	};
       
   894 	
       
   895 class CImageDecodeWaiter : public CActive
       
   896 	{
       
   897 public:
       
   898 	CImageDecodeWaiter(TInt aPriority)
       
   899 		: CActive(aPriority)
       
   900 		{
       
   901 		CActiveScheduler::Add(this);
       
   902 		}
       
   903 	void Start(CImageDecoder* aDecoder, CFbsBitmap* aBitmap)
       
   904 		{
       
   905 		TRequestStatus* stat = &iStatus;
       
   906 		aDecoder->Convert(stat, *aBitmap);
       
   907 		SetActive();
       
   908 		CActiveScheduler::Start();
       
   909 		}
       
   910 	virtual void RunL()
       
   911 		{
       
   912 		iCompletionErr = iStatus.Int();
       
   913 		CActiveScheduler::Stop();
       
   914 		}
       
   915 	virtual void DoCancel() {}
       
   916 public:
       
   917 	TInt iCompletionErr;
       
   918 	};
       
   919 
       
   920 void ImageDecodeThreadL(RImageDecodeThreadParams& aParams)
       
   921 	{
       
   922 	User::LeaveIfError(RFbsSession::Connect());
       
   923 	
       
   924 	CActiveScheduler* as = new(ELeave)CActiveScheduler;
       
   925 	CActiveScheduler::Install(as);
       
   926 	CleanupStack::PushL(as);
       
   927 	
       
   928 	RFs fs;
       
   929 	User::LeaveIfError(fs.Connect());
       
   930 	CleanupClosePushL(fs);
       
   931 	User::LeaveIfError(fs.ShareAuto());
       
   932 
       
   933 	CImageDecoder* dec = NULL;
       
   934 	switch (aParams.iMode)
       
   935 		{
       
   936 	case RImageDecodeThreadParams::EDecodeFile:
       
   937 		dec = CImageDecoder::FileNewL(fs, aParams.iFileName);
       
   938 		break;
       
   939 	case RImageDecodeThreadParams::EDecodeData:
       
   940 		dec = CImageDecoder::DataNewL(fs, aParams.iData);
       
   941 		break;
       
   942 		}
       
   943 	CleanupStack::PushL(dec);
       
   944 	
       
   945 	aParams.iFrameInfo = dec->FrameInfo();
       
   946 	CFbsBitmap* bmp = new(ELeave)CFbsBitmap;
       
   947 	CleanupStack::PushL(bmp);
       
   948 	User::LeaveIfError(bmp->Create(aParams.iFrameInfo.iOverallSizeInPixels, aParams.iFrameInfo.iFrameDisplayMode));
       
   949 	
       
   950 	
       
   951 	CImageDecodeWaiter* waiter = new(ELeave)CImageDecodeWaiter(CActive::EPriorityStandard);
       
   952 	CleanupStack::PushL(waiter);
       
   953 	
       
   954 	waiter->Start(dec, bmp);
       
   955 	User::LeaveIfError(waiter->iCompletionErr);
       
   956 	
       
   957 	aParams.iBitmapHandle = bmp->Handle();
       
   958 	aParams.iThreadError = KErrNone;
       
   959 	aParams.iBitmapReadySemaphore.Signal();
       
   960 	aParams.iThreadExitSemaphore.Wait();
       
   961 	
       
   962 	CleanupStack::PopAndDestroy(5, as); // as, fs, dec, bmp, waiter
       
   963 	}
       
   964 
       
   965 TInt ImageDecodeThead(TAny* aParams)
       
   966 	{
       
   967 	User::SetCritical(User::EProcessCritical);
       
   968 	__UHEAP_MARK;
       
   969 	RImageDecodeThreadParams* params = (RImageDecodeThreadParams*)aParams;
       
   970 
       
   971 	CTrapCleanup* cleanup = CTrapCleanup::New(); // get clean-up stack
       
   972 	if (!cleanup) return KErrNoMemory;
       
   973 	TRAPD(err, ImageDecodeThreadL(*params));
       
   974 	params->iThreadError = err;
       
   975 	if (err!=KErrNone)
       
   976 		{
       
   977 		params->iBitmapReadySemaphore.Signal();
       
   978 		}
       
   979 
       
   980 	delete cleanup;
       
   981 	REComSession::FinalClose();
       
   982 	RFbsSession::Disconnect();
       
   983 	__UHEAP_MARKEND;
       
   984 	User::SetCritical(User::ENotCritical);
       
   985 	return err;	
       
   986 	}
       
   987 
       
   988 //______________________________________________________________________________
       
   989 //						CConsoleFont
       
   990 EXPORT_C CConsoleFont* CConsoleFont::NewL(const TDesC& aFontFile)
       
   991 	{
       
   992 	CConsoleFont* self = new(ELeave)CConsoleFont;
       
   993 	CleanupStack::PushL(self);
       
   994 	self->ConstructL(aFontFile);
       
   995 	CleanupStack::Pop(self);
       
   996 	return self;
       
   997 	}
       
   998 	
       
   999 EXPORT_C CConsoleFont* CConsoleFont::NewL(const TDesC8& aEncodedFontImage)
       
  1000 	{
       
  1001 	CConsoleFont* self = new(ELeave)CConsoleFont;
       
  1002 	CleanupStack::PushL(self);
       
  1003 	self->ConstructL(aEncodedFontImage);
       
  1004 	CleanupStack::Pop(self);
       
  1005 	return self;
       
  1006 	}
       
  1007 	
       
  1008 EXPORT_C CConsoleFont::~CConsoleFont()
       
  1009 	{
       
  1010 	for (TInt i = 0; i < KNumGlyphs; ++i)
       
  1011 		{
       
  1012 		delete iChars[i];
       
  1013 		}
       
  1014 	for (TInt i = 0; i < KNumColors; ++i)
       
  1015 		{
       
  1016 		delete iColors[i];
       
  1017 		}
       
  1018 	}
       
  1019 
       
  1020 EXPORT_C TSize CConsoleFont::GlyphSize() const
       
  1021 	{
       
  1022 	return iGlyphRect.Size();
       
  1023 	}
       
  1024 
       
  1025 
       
  1026 EXPORT_C void CConsoleFont::DrawChar(TChar aChar, CBitmapContext& aDrawTo, TPoint aPosPixels, TRgb aColor)
       
  1027 	{
       
  1028 	// Note, this method assumes that the glyph's background has already been set to the appropriate color.
       
  1029 
       
  1030 	if ((aChar < KFontBitmapFirstCharCode) || (aChar > KFontBitmapLastCharCode))
       
  1031 		{
       
  1032 		aChar = KFontBitmapLastCharCode;
       
  1033 		}
       
  1034 	
       
  1035 	aDrawTo.BitBltMasked(aPosPixels, ForegroundBitmap(aColor), iGlyphRect, iChars[(TInt)aChar - KFontBitmapFirstCharCode], ETrue);
       
  1036 	}
       
  1037 
       
  1038 CConsoleFont::CConsoleFont()
       
  1039 	{
       
  1040 	}
       
  1041 
       
  1042 void CConsoleFont::ConstructL(const TDesC& aFontFile)
       
  1043 	{
       
  1044 	RImageDecodeThreadParams decodeParams(aFontFile);
       
  1045 	ConstructL(decodeParams);
       
  1046 	}
       
  1047 
       
  1048 void CConsoleFont::ConstructL(const TDesC8& aEncodedFontImage)
       
  1049 	{
       
  1050 	RImageDecodeThreadParams decodeParams(aEncodedFontImage);
       
  1051 	ConstructL(decodeParams);
       
  1052 	}
       
  1053 
       
  1054 _LIT(KImageDecodeThreadNameFmt, "ImageDecodeThread%08x");
       
  1055 
       
  1056 void CConsoleFont::ConstructL(RImageDecodeThreadParams& aDecodeParams)
       
  1057 	{
       
  1058 	User::LeaveIfError(aDecodeParams.Open());
       
  1059 	CleanupClosePushL(aDecodeParams);
       
  1060 	RThread decodeThread;
       
  1061 	CleanupClosePushL(decodeThread);
       
  1062 	// kick off the sub thread doing the decoding
       
  1063 	TInt err;
       
  1064 	TInt seq = 0;
       
  1065 	do
       
  1066 		{
       
  1067 		TBuf<0x20> threadName;
       
  1068 		threadName.AppendFormat(KImageDecodeThreadNameFmt, seq);
       
  1069 		err = decodeThread.Create(threadName, ImageDecodeThead, KDefaultStackSize, 0x1000, 0x200000, &aDecodeParams);
       
  1070 		seq++;
       
  1071 		} while (err==KErrAlreadyExists);
       
  1072 	User::LeaveIfError(err);
       
  1073 	decodeThread.Resume();
       
  1074 
       
  1075 	TRequestStatus threadExit;
       
  1076 	decodeThread.Logon(threadExit);
       
  1077 
       
  1078 	CleanupWaitForRequestPushL(threadExit); // things will probably go wrong if we leave on this line
       
  1079 	CleanupSignalSemaphorePushL(aDecodeParams.iThreadExitSemaphore);
       
  1080 	
       
  1081 	/*
       
  1082 	Now, on the cleanup stack we have:
       
  1083 	1. iThreadExitSemaphore.Signal()
       
  1084 	2. WaitForRequest(threadExit)
       
  1085 	3. decodeThread
       
  1086 	4. aDecodeParams
       
  1087 	
       
  1088 	So, if we leave now:
       
  1089 	1. We will signal the sub thread to exit
       
  1090 	2. We will then wait for the sub thread to exit
       
  1091 	3. close the sub thread handle
       
  1092 	4. close aDecodeParams, which will destroy the semaphores
       
  1093 	
       
  1094 	Note, it's important that we wait for the thread to exit before the cleanup stack
       
  1095 	if fully unwound, as if we destroy the semaphores before the sub thread has exitted,
       
  1096 	then it will panic with KERN-EXEC 0.
       
  1097 	*/
       
  1098 	
       
  1099 	// wait for it to decode the bitmap (or die)
       
  1100 	aDecodeParams.iBitmapReadySemaphore.Wait();
       
  1101 	User::LeaveIfError(aDecodeParams.iThreadError); // we will leave here if there was an error in the subthread
       
  1102 	
       
  1103 	// process decoded image
       
  1104 	TSize bmpSize = aDecodeParams.iFrameInfo.iOverallSizeInPixels;
       
  1105 	if (bmpSize.iWidth % KFontBitmapWidthChars) User::Leave(KErrCorrupt);// better error code / panic?
       
  1106 	if (bmpSize.iHeight % KFontBitmapHeightChars) User::Leave(KErrCorrupt);// better error code / panic?
       
  1107 	iGlyphRect = TRect(TPoint(0, 0), TSize(bmpSize.iWidth / KFontBitmapWidthChars, bmpSize.iHeight / KFontBitmapHeightChars));
       
  1108 	
       
  1109 	CFbsBitmap* allChars = new(ELeave)CFbsBitmap();
       
  1110 	CleanupStack::PushL(allChars);
       
  1111 	User::LeaveIfError(allChars->Duplicate(aDecodeParams.iBitmapHandle));
       
  1112 
       
  1113 	for (TInt i = 0; i < KNumGlyphs; ++i)
       
  1114 		{
       
  1115 		iChars[i] = new(ELeave)CFbsBitmap;
       
  1116 		User::LeaveIfError(iChars[i]->Create(iGlyphRect.Size(), EGray2));
       
  1117 
       
  1118 		CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(iChars[i]);
       
  1119 		CleanupStack::PushL(bitmapDevice);
       
  1120 	
       
  1121 		CBitmapContext* bitmapContext;
       
  1122 		User::LeaveIfError(bitmapDevice->CreateBitmapContext(bitmapContext));
       
  1123 		CleanupStack::PushL(bitmapContext);
       
  1124 
       
  1125 		TPoint charPos(i % KFontBitmapWidthChars, i / KFontBitmapWidthChars);
       
  1126 		TPoint pixelPos(charPos.iX * iGlyphRect.Size().iWidth, charPos.iY * iGlyphRect.Size().iHeight);
       
  1127 		TRect charRect(pixelPos, iGlyphRect.Size());
       
  1128 		bitmapContext->BitBlt(TPoint(0, 0), allChars, charRect);	
       
  1129 
       
  1130 		CleanupStack::PopAndDestroy(2, bitmapDevice);
       
  1131 		}
       
  1132 
       
  1133 	// this will clean everything up - see above comment.
       
  1134 	CleanupStack::PopAndDestroy(5, &aDecodeParams); // decodeThread, aDecodeParams
       
  1135 
       
  1136 	PrepareForegroundColorL(KDefaultForegroundColor);
       
  1137 	}
       
  1138 
       
  1139 void CConsoleFont::PrepareForegroundColorL(TRgb aColor)
       
  1140 	{
       
  1141 	CFbsBitmap* bitmap = ForegroundBitmap(aColor);
       
  1142 	if (bitmap == NULL)
       
  1143 		{
       
  1144 		bitmap = new(ELeave)CFbsBitmap;
       
  1145 		CleanupStack::PushL(bitmap);
       
  1146 		User::LeaveIfError(bitmap->Create(iGlyphRect.Size(), EColor16));
       
  1147 		CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(bitmap);
       
  1148 		CleanupStack::PushL(bitmapDevice);
       
  1149 		CBitmapContext* bitmapContext;
       
  1150 		User::LeaveIfError(bitmapDevice->CreateBitmapContext(bitmapContext));
       
  1151 		CleanupStack::PushL(bitmapContext);
       
  1152 		bitmapContext->SetBrushColor(aColor);
       
  1153 		bitmapContext->SetPenStyle(CGraphicsContext::ENullPen);
       
  1154 		bitmapContext->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1155 		bitmapContext->DrawRect(iGlyphRect);
       
  1156 		CleanupStack::PopAndDestroy(2, bitmapDevice);
       
  1157 		CleanupStack::Pop(bitmap);
       
  1158 		iColors[aColor.Color16()] = bitmap;
       
  1159 		}
       
  1160 	}
       
  1161 
       
  1162 CFbsBitmap* CConsoleFont::ForegroundBitmap(TRgb aColor)
       
  1163 	{
       
  1164 	return iColors[aColor.Color16()];
       
  1165 	}
       
  1166 
       
  1167 //______________________________________________________________________________
       
  1168 //						CConsoleLine
       
  1169 CConsoleLine* CConsoleLine::NewL(CConsoleControl& aControl, const CConsoleFont& aFont, TInt aWidth)
       
  1170 	{
       
  1171 	CConsoleLine* self = new(ELeave)CConsoleLine(aControl, aFont);
       
  1172 	CleanupStack::PushL(self);
       
  1173 	self->ConstructL(aWidth);
       
  1174 	CleanupStack::Pop(self);
       
  1175 	return self;
       
  1176 	}
       
  1177 
       
  1178 CConsoleLine::~CConsoleLine()
       
  1179 	{
       
  1180 	iText.Close();
       
  1181 	iAttributeMap.Close();
       
  1182 	}
       
  1183 
       
  1184 void CConsoleLine::SetWidthL(TInt aNewWidth)
       
  1185 	{
       
  1186 	if (aNewWidth != iWidth)
       
  1187 		{
       
  1188 		RBuf8 newText;
       
  1189 		newText.CreateL(aNewWidth);
       
  1190 		newText.Copy(iText.Left(aNewWidth));
       
  1191 		newText.Swap(iText);
       
  1192 		newText.Close();
       
  1193 		iWidth = aNewWidth;
       
  1194 		iAttributeMap.RemoveFrom(aNewWidth);
       
  1195 		}
       
  1196 	}
       
  1197 
       
  1198 void CConsoleLine::SetL(TInt aIndex, TUint8 aChar, const ConsoleAttributes::TAttributes& aAttributes)
       
  1199 	{
       
  1200 	__ASSERT_ALWAYS((aIndex < iWidth)&&(aIndex>=0), User::Invariant());
       
  1201 	iAttributeMap.AddL(aIndex, iWidth, aAttributes);
       
  1202 	if (aIndex > iText.Length())
       
  1203 		{
       
  1204 		TInt oldLen = iText.Length();
       
  1205 		iText.SetLength(aIndex);
       
  1206 		iText.MidTPtr(oldLen).Fill(' ');
       
  1207 		iText.Append(aChar);
       
  1208 		}
       
  1209 	else if (aIndex == iText.Length())
       
  1210 		{
       
  1211 		iText.Append(aChar);
       
  1212 		}
       
  1213 	else
       
  1214 		{
       
  1215 		iText[aIndex] = aChar;
       
  1216 		}
       
  1217 	}
       
  1218 	
       
  1219 void CConsoleLine::Clear()
       
  1220 	{
       
  1221 	iAttributeMap.Reset();
       
  1222 	iText.Zero();
       
  1223 	}
       
  1224 	
       
  1225 void CConsoleLine::ClearFrom(TBufferPosition aPos)
       
  1226 	{
       
  1227 	TInt pos = Min(aPos.iPoint.iX, iText.Length());
       
  1228 	iText.SetLength(pos);
       
  1229 	iAttributeMap.RemoveFrom(pos);
       
  1230 	}
       
  1231 
       
  1232 void CConsoleLine::Draw(CBitmapContext& aDrawTo, TViewPosition aViewPosition) const
       
  1233 	{
       
  1234 	const TSize glyphSize(iFont.GlyphSize());
       
  1235 
       
  1236 	TScreenPosition screenPos(aViewPosition);
       
  1237 	TRect rectToClear(screenPos.iPoint, TScreenPosition(aViewPosition.iConsole, 0, (aViewPosition.iPoint.iY + 1) * glyphSize.iHeight).iPoint);
       
  1238 
       
  1239 	const TInt numAttributeBlocks = iAttributeMap.NumberOfBlocks();
       
  1240 	for (TInt i = 0; i < numAttributeBlocks; ++i)
       
  1241 		{
       
  1242 		TInt startXPos = 0;
       
  1243 		TInt endXPos = 0;
       
  1244 		ConsoleAttributes::TAttributes attributes(ConsoleAttributes::ENone);
       
  1245 		iAttributeMap.GetBlock(i, iWidth, startXPos, endXPos, attributes);
       
  1246 
       
  1247 		// Draw the background in the appropriate color in one hit.
       
  1248 		rectToClear.iTl.iX = screenPos.iPoint.iX + (startXPos * glyphSize.iWidth);
       
  1249 		rectToClear.iBr.iX = screenPos.iPoint.iX + (endXPos * glyphSize.iWidth);
       
  1250 		TRgb backgroundColor = MapColor(attributes.iAttributes, attributes.iBackgroundColor);
       
  1251 		aDrawTo.SetBrushColor(backgroundColor);
       
  1252 		aDrawTo.Clear(rectToClear);
       
  1253 
       
  1254 		// Check if we're blinking.
       
  1255 		TRgb foregroundColor = MapColor(attributes.iAttributes, attributes.iForegroundColor);
       
  1256 		if ((attributes.iAttributes & ConsoleAttributes::EBlink) && iBlinkOn)
       
  1257 			{
       
  1258 			foregroundColor = backgroundColor;
       
  1259 			}
       
  1260 
       
  1261 		// Draw any non-white-space characters in the appropriate foreground color.
       
  1262 		for (TInt i = startXPos; i < endXPos; ++i)
       
  1263 			{
       
  1264 			TUint16 c = At(i);
       
  1265 			if (c != ' ')
       
  1266 				{
       
  1267 				const_cast<CConsoleFont&>(iFont).DrawChar(c, aDrawTo, TPoint(screenPos.iPoint.iX + (i * glyphSize.iWidth), screenPos.iPoint.iY), foregroundColor);
       
  1268 				}
       
  1269 			if (attributes.iAttributes & ConsoleAttributes::EUnderscore)
       
  1270 				{
       
  1271 				const_cast<CConsoleFont&>(iFont).DrawChar('_', aDrawTo, TPoint(screenPos.iPoint.iX + (i * glyphSize.iWidth), screenPos.iPoint.iY), foregroundColor);
       
  1272 				}
       
  1273 			}
       
  1274 
       
  1275 		if (attributes.iAttributes & ConsoleAttributes::EBlink)
       
  1276 			{
       
  1277 			iControl.StartBlinking();
       
  1278 			}
       
  1279 		}
       
  1280 	}
       
  1281 
       
  1282 TBool CConsoleLine::NeedToBlink(TBool aBlinkOn)
       
  1283 	{
       
  1284 	TBool needToBlink(EFalse);
       
  1285 	const TInt numAttributeBlocks = iAttributeMap.NumberOfBlocks();
       
  1286 	for (TInt i = 0; i < numAttributeBlocks; ++i)
       
  1287 		{
       
  1288 		TInt startXPos = 0;
       
  1289 		TInt endXPos = 0;
       
  1290 		ConsoleAttributes::TAttributes attributes(ConsoleAttributes::ENone);
       
  1291 		iAttributeMap.GetBlock(i, iWidth, startXPos, endXPos, attributes);
       
  1292 		if (attributes.iAttributes & ConsoleAttributes::EBlink)
       
  1293 			{
       
  1294 			needToBlink = ETrue;
       
  1295 			iBlinkOn = aBlinkOn;
       
  1296 			break;
       
  1297 			}
       
  1298 		}
       
  1299 	return needToBlink;
       
  1300 	}
       
  1301 	
       
  1302 TUint16 CConsoleLine::At(TInt aPos) const
       
  1303 	{
       
  1304 	__ASSERT_ALWAYS((aPos < iWidth)&&(aPos>=0), User::Invariant());
       
  1305 	if (aPos < iText.Length())
       
  1306 		{
       
  1307 		return iText[aPos];
       
  1308 		}
       
  1309 	else
       
  1310 		{
       
  1311 		return ' ';
       
  1312 		}
       
  1313 	}
       
  1314 	
       
  1315 CConsoleLine::CConsoleLine(CConsoleControl& aControl, const CConsoleFont& aFont)
       
  1316 	: iControl(aControl), iFont(aFont)
       
  1317 	{
       
  1318 	}
       
  1319 	
       
  1320 void CConsoleLine::ConstructL(TInt aWidth)
       
  1321 	{
       
  1322 	iText.CreateL(aWidth);
       
  1323 	iWidth = aWidth;
       
  1324 	}
       
  1325 
       
  1326 //______________________________________________________________________________
       
  1327 //						TConsoleCursor
       
  1328 TConsoleCursor::TConsoleCursor(CConsoleControl& aOwner)
       
  1329 	: iOwner(aOwner)
       
  1330 	{
       
  1331 	iTextCursor.iType = TTextCursor::ETypeRectangle;
       
  1332 	iTextCursor.iAscent = 0;
       
  1333 	iTextCursor.iColor = KRgbWhite;
       
  1334 	}
       
  1335 
       
  1336 void TConsoleCursor::SetFont(const CConsoleFont& aFont)
       
  1337 	{
       
  1338 	iGlyphSize = aFont.GlyphSize();
       
  1339 	iTextCursor.iWidth = iGlyphSize.iWidth;
       
  1340 	}
       
  1341 
       
  1342 TConsCursorPosition TConsoleCursor::Position() const
       
  1343 	{
       
  1344 	return TConsCursorPosition(iOwner, iPosition);
       
  1345 	}
       
  1346 
       
  1347 void TConsoleCursor::SetPosAbs(TConsCursorPosition aPos)
       
  1348 	{
       
  1349 	iPosition = aPos.iPoint;
       
  1350 	BoundsCheck();
       
  1351 	}
       
  1352 
       
  1353 void TConsoleCursor::SetPosRel(TConsCursorPosition aPos)
       
  1354 	{
       
  1355 	iPosition += aPos.iPoint;
       
  1356 	BoundsCheck();
       
  1357 	}
       
  1358 
       
  1359 void TConsoleCursor::SetHeight(TInt aPercentage)
       
  1360 	{
       
  1361 	aPercentage = Max(0, Min(100, aPercentage));
       
  1362 	TReal height = ((TReal)iGlyphSize.iHeight * (TReal)aPercentage) / 100.0;
       
  1363 	TReal roundedHeight;
       
  1364 	Math::Round(roundedHeight, height, 0);
       
  1365 	iTextCursor.iHeight = (TInt)roundedHeight;
       
  1366 	// make sure the cursor is always visible if the percentage is non-zero.
       
  1367 	if ((iTextCursor.iHeight==0) && (aPercentage!=0)) iTextCursor.iHeight = 1;
       
  1368 	iTextCursor.iAscent = 0;
       
  1369 	iTextCursorOffset = iGlyphSize.iHeight - iTextCursor.iHeight;
       
  1370 	}
       
  1371 
       
  1372 void TConsoleCursor::Update()
       
  1373 	{
       
  1374 	if (iOwner.IsFocused() && !iOwner.IsNonFocusing())
       
  1375 		{
       
  1376 		TViewPosition viewPos = Position();
       
  1377 		TPoint cursorPosPixels;
       
  1378 		cursorPosPixels.iX = viewPos.iPoint.iX * iGlyphSize.iWidth;
       
  1379 		cursorPosPixels.iY = ((viewPos.iPoint.iY) * iGlyphSize.iHeight) + iTextCursorOffset;
       
  1380 		/*if (iOwner.Rect().Contains(cursorPosPixels))
       
  1381 			{*/
       
  1382 			if (iOwner.DrawableWindow())
       
  1383 				{
       
  1384 				CCoeEnv::Static()->RootWin().SetTextCursor(*iOwner.DrawableWindow(), cursorPosPixels, iTextCursor);
       
  1385 				}
       
  1386 		/*	}
       
  1387 		else
       
  1388 			{
       
  1389 			Hide();
       
  1390 			}*/
       
  1391 		}
       
  1392 	}
       
  1393 	
       
  1394 void TConsoleCursor::Hide()
       
  1395 	{
       
  1396 	CCoeEnv::Static()->RootWin().CancelTextCursor();
       
  1397 	}
       
  1398 
       
  1399 void TConsoleCursor::BoundsCheck()
       
  1400 	{
       
  1401 	iPosition.iX = Max(0, iPosition.iX);
       
  1402 	iPosition.iY = Max(0, iPosition.iY);
       
  1403 	iPosition.iX = Min(iOwner.ScreenSize().iWidth-1, iPosition.iX);
       
  1404 	iPosition.iY = Min(iOwner.ScreenSize().iHeight-1, iPosition.iY);
       
  1405 	}
       
  1406 
       
  1407 void TConsoleCursor::operator++(int)
       
  1408 	{
       
  1409 	(*this)+=1;
       
  1410 	}
       
  1411 	
       
  1412 void TConsoleCursor::operator--(int)
       
  1413 	{
       
  1414 	(*this)-=1;
       
  1415 	}
       
  1416 	
       
  1417 void TConsoleCursor::operator+=(TUint aHowMuch)
       
  1418 	{
       
  1419 	TSize consSize(iOwner.ScreenSize());
       
  1420 	while (aHowMuch)
       
  1421 		{
       
  1422 		TInt len = Min(consSize.iWidth - iPosition.iX, aHowMuch);
       
  1423 		iPosition.iX += len;
       
  1424 		aHowMuch -= len;
       
  1425 
       
  1426 		if (iPosition.iX == consSize.iWidth)
       
  1427 			{
       
  1428 			Down();
       
  1429 			iPosition.iX = 0;
       
  1430 			}
       
  1431 		}
       
  1432 	}
       
  1433 	
       
  1434 void TConsoleCursor::operator-=(TUint aHowMuch)
       
  1435 	{
       
  1436 	TSize consSize(iOwner.ScreenSize());
       
  1437 	while (aHowMuch)
       
  1438 		{
       
  1439 		if (iPosition.iX == 0)
       
  1440 			{
       
  1441 			Up();
       
  1442 			iPosition.iX = consSize.iWidth;
       
  1443 			}
       
  1444 
       
  1445 		TInt len = Min(iPosition.iX, aHowMuch);
       
  1446 		iPosition.iX -= len;
       
  1447 		aHowMuch -= len;
       
  1448 		}
       
  1449 	
       
  1450 	}
       
  1451 	
       
  1452 void TConsoleCursor::Down()
       
  1453 	{
       
  1454 	iPosition.iY++;
       
  1455 	if (iPosition.iY >= iOwner.ScreenSize().iHeight)
       
  1456 		{
       
  1457 		iPosition.iY--;
       
  1458 		iOwner.CursorWindowScrollDown();
       
  1459 		}
       
  1460 	}
       
  1461 
       
  1462 void TConsoleCursor::Up()
       
  1463 	{
       
  1464 	iPosition.iY--;
       
  1465 	BoundsCheck();
       
  1466 	}
       
  1467 
       
  1468 //______________________________________________________________________________
       
  1469 //						CGuiConsole
       
  1470 EXPORT_C CGuiConsole::CGuiConsole(CConsoleControl& aControl)
       
  1471 	: iControl(aControl), iRefCount(1)
       
  1472 	{
       
  1473 	}
       
  1474 	
       
  1475 EXPORT_C CConsoleControl& CGuiConsole::Control()
       
  1476 	{
       
  1477 	return iControl;
       
  1478 	}
       
  1479 
       
  1480 EXPORT_C TInt CGuiConsole::Create(const TDesC &aTitle, TSize)
       
  1481 	{
       
  1482 	iControl.SetTitle(aTitle);
       
  1483 	return KErrNone;
       
  1484 	}
       
  1485 
       
  1486 EXPORT_C void CGuiConsole::Read(TRequestStatus &aStatus)
       
  1487 	{
       
  1488 	if (iReadStatus || iReader)
       
  1489 		{
       
  1490 		TRequestStatus* stat = &aStatus;
       
  1491 		User::RequestComplete(stat, KErrInUse);
       
  1492 		}
       
  1493 	else
       
  1494 		{
       
  1495 		iReadStatus = &aStatus;
       
  1496 		iControl.Read(*this);
       
  1497 		}
       
  1498 	}
       
  1499 
       
  1500 EXPORT_C void CGuiConsole::ReadCancel()
       
  1501 	{
       
  1502 	if (iReadStatus)
       
  1503 		{
       
  1504 		User::RequestComplete(iReadStatus, KErrCancel);
       
  1505 		iControl.ReadCancel();
       
  1506 		}
       
  1507 	else if (iReader)
       
  1508 		{
       
  1509 		iReader->ReadComplete(KErrCancel);
       
  1510 		iReader = NULL;
       
  1511 		iControl.ReadCancel();
       
  1512 		}
       
  1513 	}
       
  1514 
       
  1515 EXPORT_C void CGuiConsole::Write(const TDesC &aDes)
       
  1516 	{
       
  1517 	iControl.Write(aDes);
       
  1518 	}
       
  1519 
       
  1520 EXPORT_C TPoint CGuiConsole::CursorPos() const
       
  1521 	{
       
  1522 	return iControl.CursorPos();
       
  1523 	}
       
  1524 
       
  1525 EXPORT_C void CGuiConsole::SetCursorPosAbs(const TPoint &aPoint)
       
  1526 	{
       
  1527 	iControl.SetCursorPosAbs(aPoint);
       
  1528 	}
       
  1529 
       
  1530 EXPORT_C void CGuiConsole::SetCursorPosRel(const TPoint &aPoint)
       
  1531 	{
       
  1532 	iControl.SetCursorPosRel(aPoint);
       
  1533 	}
       
  1534 
       
  1535 EXPORT_C void CGuiConsole::SetCursorHeight(TInt aPercentage)
       
  1536 	{
       
  1537 	iControl.SetCursorHeight(aPercentage);
       
  1538 	}
       
  1539 
       
  1540 EXPORT_C void CGuiConsole::SetTitle(const TDesC &aTitle)
       
  1541 	{
       
  1542 	iControl.SetTitle(aTitle);
       
  1543 	}
       
  1544 
       
  1545 EXPORT_C void CGuiConsole::ClearScreen()
       
  1546 	{
       
  1547 	iControl.ClearScreen();
       
  1548 	}
       
  1549 
       
  1550 EXPORT_C void CGuiConsole::ClearToEndOfLine()
       
  1551 	{
       
  1552 	iControl.ClearToEndOfLine();
       
  1553 	}
       
  1554 
       
  1555 EXPORT_C TSize CGuiConsole::ScreenSize() const
       
  1556 	{
       
  1557 	return iControl.ScreenSize();
       
  1558 	}
       
  1559 
       
  1560 
       
  1561 EXPORT_C TKeyCode CGuiConsole::KeyCode() const
       
  1562 	{
       
  1563 	return iControl.KeyCode();
       
  1564 	}
       
  1565 
       
  1566 
       
  1567 EXPORT_C TUint CGuiConsole::KeyModifiers() const
       
  1568 	{
       
  1569 	return iControl.KeyModifiers();
       
  1570 	}
       
  1571 
       
  1572 EXPORT_C TInt CGuiConsole::Extension_(TUint aExtensionId, TAny*&, TAny* a1)
       
  1573 	{
       
  1574 	if (aExtensionId == ConsoleAttributes::KSetConsoleAttributesExtension)
       
  1575 		{
       
  1576 		ConsoleAttributes::TAttributes* attributes = (ConsoleAttributes::TAttributes*)a1;
       
  1577 		return iControl.SetAttributes(attributes->iAttributes, attributes->iForegroundColor, attributes->iBackgroundColor);
       
  1578 		}
       
  1579 	return KErrNotSupported;
       
  1580 	}
       
  1581 
       
  1582 void CGuiConsole::ReadComplete(TInt aStatus)
       
  1583 	{
       
  1584 	if (iReadStatus)
       
  1585 		{
       
  1586 		User::RequestComplete(iReadStatus, aStatus);
       
  1587 		}
       
  1588 	if (iReader)
       
  1589 		{
       
  1590 		CConsoleProxySession* reader = iReader;
       
  1591 		iReader = NULL;
       
  1592 		reader->ReadComplete(aStatus);
       
  1593 		}
       
  1594 	}
       
  1595 	
       
  1596 void CGuiConsole::Open()
       
  1597 	{
       
  1598 	++iRefCount;
       
  1599 	}
       
  1600 
       
  1601 void CGuiConsole::Close()
       
  1602 	{
       
  1603 	--iRefCount;
       
  1604 	if (iRefCount==0)
       
  1605 		{
       
  1606 		delete this;
       
  1607 		}
       
  1608 	}
       
  1609 
       
  1610 CConsoleBase* CGuiConsole::Console()
       
  1611 	{
       
  1612 	return this;
       
  1613 	}
       
  1614 
       
  1615 void CGuiConsole::Read(CConsoleProxySession& aSession)
       
  1616 	{
       
  1617 	if (iReader || iReadStatus)
       
  1618 		{
       
  1619 		aSession.ReadComplete(KErrInUse);
       
  1620 		}
       
  1621 	else
       
  1622 		{
       
  1623 		iReader = &aSession;
       
  1624 		iControl.Read(*this);
       
  1625 		}
       
  1626 	}
       
  1627 
       
  1628 CGuiConsole::~CGuiConsole()
       
  1629 	{
       
  1630 	iControl.Closed();
       
  1631 	}
       
  1632 
       
  1633 //______________________________________________________________________________
       
  1634 //						TBufferPosition
       
  1635 TBufferPosition::TBufferPosition(const CConsoleControl& aConsole, TPoint aPosition)
       
  1636 	: iConsole(aConsole), iPoint(aPosition)
       
  1637 	{
       
  1638 	}
       
  1639 
       
  1640 TBufferPosition::TBufferPosition(const CConsoleControl& aConsole, TInt aX, TInt aY)
       
  1641 	: iConsole(aConsole), iPoint(aX, aY)
       
  1642 	{
       
  1643 	}
       
  1644 
       
  1645 TBufferPosition::TBufferPosition(const TConsCursorPosition& aCursorPosition)
       
  1646 	: iConsole(aCursorPosition.iConsole)
       
  1647 	, iPoint(aCursorPosition.iPoint + aCursorPosition.iConsole.CursorWindowPosition())
       
  1648 	{
       
  1649 	}
       
  1650 
       
  1651 TBufferPosition::TBufferPosition(const TViewPosition& aViewPosition)
       
  1652 	: iConsole(aViewPosition.iConsole)
       
  1653 	, iPoint(aViewPosition.iPoint + aViewPosition.iConsole.ViewPosition())
       
  1654 	{
       
  1655 	}
       
  1656 
       
  1657 	
       
  1658 
       
  1659 //______________________________________________________________________________
       
  1660 //						TConsCursorPosition
       
  1661 TConsCursorPosition::TConsCursorPosition(const CConsoleControl& aConsole, TPoint aPosition)
       
  1662 	: iConsole(aConsole), iPoint(aPosition)
       
  1663 	{
       
  1664 	}
       
  1665 
       
  1666 TConsCursorPosition::TConsCursorPosition(const CConsoleControl& aConsole, TInt aX, TInt aY)
       
  1667 	: iConsole(aConsole), iPoint(aX, aY)
       
  1668 	{
       
  1669 	}
       
  1670 
       
  1671 TConsCursorPosition::TConsCursorPosition(const TBufferPosition& aBufferPosition)
       
  1672 	: iConsole(aBufferPosition.iConsole)
       
  1673 	, iPoint(aBufferPosition.iPoint - aBufferPosition.iConsole.CursorWindowPosition())
       
  1674 	{
       
  1675 	}
       
  1676 
       
  1677 TConsCursorPosition::TConsCursorPosition(const TViewPosition& aViewPosition)
       
  1678 	: iConsole(aViewPosition.iConsole)
       
  1679 	, iPoint(aViewPosition.iPoint + aViewPosition.iConsole.ViewPosition() - aViewPosition.iConsole.CursorWindowPosition())
       
  1680 	{
       
  1681 	}
       
  1682 
       
  1683 	
       
  1684 
       
  1685 //______________________________________________________________________________
       
  1686 //						TViewPosition
       
  1687 TViewPosition::TViewPosition(const CConsoleControl& aConsole, TPoint aPosition)
       
  1688 	: iConsole(aConsole), iPoint(aPosition)
       
  1689 	{
       
  1690 	}
       
  1691 
       
  1692 TViewPosition::TViewPosition(const CConsoleControl& aConsole, TInt aX, TInt aY)
       
  1693 	: iConsole(aConsole), iPoint(aX, aY)
       
  1694 	{
       
  1695 	}
       
  1696 
       
  1697 TViewPosition::TViewPosition(const TConsCursorPosition& aCursorPosition)
       
  1698 	: iConsole(aCursorPosition.iConsole)
       
  1699 	, iPoint(aCursorPosition.iPoint + aCursorPosition.iConsole.CursorWindowPosition() - aCursorPosition.iConsole.ViewPosition())
       
  1700 	{
       
  1701 	}
       
  1702 
       
  1703 TViewPosition::TViewPosition(const TBufferPosition& aBufferPosition)
       
  1704 	: iConsole(aBufferPosition.iConsole)
       
  1705 	, iPoint(aBufferPosition.iPoint - aBufferPosition.iConsole.ViewPosition())
       
  1706 	{
       
  1707 	}
       
  1708 
       
  1709 //______________________________________________________________________________
       
  1710 //						TScreenPosition
       
  1711 TScreenPosition::TScreenPosition(const CConsoleControl& aConsole, TPoint aPosition)
       
  1712 	: iConsole(aConsole), iPoint(aPosition)
       
  1713 	{
       
  1714 	}
       
  1715 
       
  1716 TScreenPosition::TScreenPosition(const CConsoleControl& aConsole, TInt aX, TInt aY)
       
  1717 	: iConsole(aConsole), iPoint(aX, aY)
       
  1718 	{
       
  1719 	}
       
  1720 
       
  1721 TScreenPosition::TScreenPosition(const TViewPosition& aViewPosition)
       
  1722 	: iConsole(aViewPosition.iConsole)
       
  1723 	, iPoint(aViewPosition.iPoint.iX * aViewPosition.iConsole.GlyphSize().iWidth, aViewPosition.iPoint.iY * aViewPosition.iConsole.GlyphSize().iHeight)
       
  1724 	{
       
  1725 	}
       
  1726 
       
  1727 //______________________________________________________________________________
       
  1728 //						RAttributeMap
       
  1729 
       
  1730 RAttributeMap::RAttributeMap()
       
  1731 	: iAttributes(KAttributeMapGranularity, _FOFF(TAttributes, iPosition))
       
  1732 	{
       
  1733 	}
       
  1734 
       
  1735 void RAttributeMap::Close()
       
  1736 	{
       
  1737 	iAttributes.Close();
       
  1738 	}
       
  1739 
       
  1740 void RAttributeMap::Reset()
       
  1741 	{
       
  1742 	iAttributes.Reset();
       
  1743 	}
       
  1744 
       
  1745 void RAttributeMap::AddL(TInt aPosition, TInt aLineWidth, const ConsoleAttributes::TAttributes& aAttributes)
       
  1746 	{
       
  1747 	// Take a copy of the attributes array to make cleanup easier.
       
  1748 	RArray<TAttributes> attributes;
       
  1749 	CleanupClosePushL(attributes);
       
  1750 	const TInt numAttributes = iAttributes.Count();
       
  1751 	for (TInt i = 0; i < numAttributes; ++i)
       
  1752 		{
       
  1753 		attributes.AppendL(iAttributes[i]);
       
  1754 		}
       
  1755 
       
  1756 	if (attributes.Count() == 0)
       
  1757 		{
       
  1758 		// This is the first set of attributes to be added. Add a default set before them.
       
  1759 		attributes.AppendL(TAttributes(0, DefaultAttributes()));
       
  1760 		}
       
  1761 
       
  1762 	TAttributes attr(aPosition, aAttributes);
       
  1763 	TInt pos;
       
  1764 	TInt err = attributes.FindInSignedKeyOrder(attr, pos);
       
  1765 	if (err == KErrNone)
       
  1766 		{
       
  1767 		// Attribute already exists at this position - replace.
       
  1768 		attributes[pos] = attr;
       
  1769 		}
       
  1770 	else
       
  1771 		{
       
  1772 		// No attribute found at aPosition.
       
  1773 		// pos is set to the index _after_ aPosition. This must be at least 1 because the first slot in the array is always taken with defaults or something else.
       
  1774 		// Set pos to the index _before_ aPosition.
       
  1775 		--pos;
       
  1776 
       
  1777 		// Check earlier attributes to see if they match.
       
  1778 		if (!(attributes[pos] == attr))
       
  1779 			{
       
  1780 			// No match - insert new attributes.
       
  1781 			attributes.InsertInSignedKeyOrderL(attr);
       
  1782 
       
  1783 			// Get the position of the newly inserted attributes.
       
  1784 			attributes.FindInSignedKeyOrder(attr, pos);
       
  1785 			}
       
  1786 		}
       
  1787 
       
  1788 	const TAttributes& newAttributes = attributes[pos];
       
  1789 	if ((pos == (attributes.Count() - 1)) && (newAttributes.iPosition < (aLineWidth - 1)) && !(newAttributes == TAttributes(0, DefaultAttributes())))
       
  1790 		{
       
  1791 		// New attributes are the last in the list, and not at the end of the line and not defaults.
       
  1792 		// Add another set of defaults after them.
       
  1793 		attributes.AppendL(TAttributes(newAttributes.iPosition + 1, DefaultAttributes()));
       
  1794 		}
       
  1795 
       
  1796 	iAttributes.Close();
       
  1797 	iAttributes = attributes;
       
  1798 	CleanupStack::Pop(&attributes);
       
  1799 	}
       
  1800 
       
  1801 void RAttributeMap::RemoveFrom(TInt aPosition)
       
  1802 	{
       
  1803 	for (TInt i = (iAttributes.Count() - 1); i >= 0; --i)
       
  1804 		{
       
  1805 		if (iAttributes[i].iPosition >= aPosition)
       
  1806 			{
       
  1807 			iAttributes.Remove(i);
       
  1808 			}
       
  1809 		}
       
  1810 	}
       
  1811 
       
  1812 TInt RAttributeMap::NumberOfBlocks() const
       
  1813 	{
       
  1814 	if (iAttributes.Count() == 0)
       
  1815 		{
       
  1816 		return 1; // If no attributes have been added, give the entire line an implict default set of attributes.
       
  1817 		}
       
  1818 	return iAttributes.Count();
       
  1819 	}
       
  1820 
       
  1821 void RAttributeMap::GetBlock(TInt aIndex, TInt aLineWidth, TInt& aStartPosition, TInt& aEndPosition, ConsoleAttributes::TAttributes& aAttributes) const
       
  1822 	{
       
  1823 	if (iAttributes.Count() == 0)
       
  1824 		{
       
  1825 		ASSERT(aIndex == 0);
       
  1826 		aStartPosition = 0;
       
  1827 		aEndPosition = aLineWidth;
       
  1828 		aAttributes = DefaultAttributes();
       
  1829 		}
       
  1830 	else
       
  1831 		{
       
  1832 		const TAttributes& attributes = iAttributes[aIndex];
       
  1833 		aAttributes = attributes.iAttributes;
       
  1834 		aStartPosition = attributes.iPosition;
       
  1835 
       
  1836 		if ((iAttributes.Count() == 1) || (aIndex == (iAttributes.Count() - 1)))
       
  1837 			{
       
  1838 			aEndPosition = aLineWidth;
       
  1839 			}
       
  1840 		else
       
  1841 			{
       
  1842 			aEndPosition = iAttributes[aIndex + 1].iPosition;
       
  1843 			}
       
  1844 		}
       
  1845 	}
       
  1846 
       
  1847 RAttributeMap::TAttributes::TAttributes(TInt aPosition, const ConsoleAttributes::TAttributes& aAttributes)
       
  1848 	: iPosition(aPosition), iAttributes(aAttributes)
       
  1849 	{
       
  1850 	}
       
  1851 
       
  1852 TBool RAttributeMap::TAttributes::operator==(const TAttributes& aAttributes) const
       
  1853 	{
       
  1854 	// Note, intentionally ignoring iPosition so ensure that existing attribute block are extended where possible.
       
  1855 	return ((iAttributes.iAttributes == aAttributes.iAttributes.iAttributes) && 
       
  1856 			(iAttributes.iForegroundColor == aAttributes.iAttributes.iForegroundColor) &&
       
  1857 			(iAttributes.iBackgroundColor == aAttributes.iAttributes.iBackgroundColor));
       
  1858 	}