libraries/iosrv/server/console.cpp
changeset 0 7f656887cf89
child 66 2a78c4ff2eab
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // console.cpp
       
     2 // 
       
     3 // Copyright (c) 2006 - 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 <e32cons.h>
       
    14 #include <e32uid.h>
       
    15 #include "server.h"
       
    16 #include "console.h"
       
    17 #include "log.h"
       
    18 
       
    19 
       
    20 #ifdef IOSRV_LOGGING
       
    21 #define CONSOLE_NAME TName consoleName(Name())
       
    22 #define READER_NAME(x) TName readerName((x).IorName())
       
    23 #define WRITER_NAME(x) TName writerName((x).IowName())
       
    24 #else
       
    25 #define CONSOLE_NAME
       
    26 #define READER_NAME(x)
       
    27 #define WRITER_NAME(x)
       
    28 #endif
       
    29 
       
    30 const TInt KConsoleThreadMinHeapSize = 0x1000;
       
    31 const TInt KConsoleThreadMaxHeapSize = 0x1000000;
       
    32 
       
    33 CIoConsole* CIoConsole::NewLC(const TDesC& aImplementation, const TDesC& aTitle, const TSize& aSize, const TIoConfig& aConfig, CIoConsole* aUnderlying, TUint aOptions)
       
    34 	{
       
    35 	CIoConsole* self = new(ELeave) CIoConsole(aConfig);
       
    36 	CleanupClosePushL(*self);
       
    37 	self->ConstructL(aImplementation, aTitle, aSize, aUnderlying, aOptions);
       
    38 	return self;
       
    39 	}
       
    40 
       
    41 CIoConsole::~CIoConsole()
       
    42 	{
       
    43 	// if the sub-thread is servicing a request of ours now, we have to kill it. Otherwise, we might hang
       
    44 	// when we try and cancel the request AO, if (for example) it's servicing a long-standing Create request.
       
    45 	if (iRequestAo && (iRequestAo->IsActive()) && (iServerThread.Handle()!=KNullHandle))
       
    46 		{
       
    47 		iServerThread.Kill(KErrCancel);
       
    48 		iThreadServer.Close(); // this won't be closed by the sub-thread, as we just killed it.
       
    49 		}
       
    50 	delete iThreadWatcher;
       
    51 	delete iRequestAo;
       
    52 	iRequestQueue.Close();
       
    53 	delete iImplementation;
       
    54 	delete iReader;
       
    55 	iConsole.Close();
       
    56 	delete iCreationTitle ;
       
    57 	iServerThread.Close();
       
    58 	}
       
    59 
       
    60 const TDesC& CIoConsole::Implementation() const
       
    61 	{
       
    62 	return *iImplementation;
       
    63 	}
       
    64 
       
    65 TBool CIoConsole::IsType(RIoHandle::TType aType) const
       
    66 	{
       
    67 	return ((aType == RIoHandle::EEndPoint) || (aType == RIoHandle::EConsole));
       
    68 	}
       
    69 
       
    70 void CIoConsole::HandleReaderDetached(MIoReader& aReader)
       
    71 	{
       
    72 	HandleReadWriterDetached(aReader);
       
    73 	}
       
    74 
       
    75 void CIoConsole::HandleWriterDetached(MIoWriter& aWriter)
       
    76 	{
       
    77 	HandleReadWriterDetached(aWriter);
       
    78 	}
       
    79 
       
    80 template <class T> void CIoConsole::HandleReadWriterDetached(T& aReadWriter)
       
    81 	{
       
    82 	// Remove pending requests originated from this reader / writer.
       
    83 	for (TInt i = (iRequestQueue.Count() - 1); i >= 0; --i)
       
    84 		{
       
    85 		TConsoleRequest* request = iRequestQueue[i];
       
    86 		if (request->OriginatedFrom(aReadWriter))
       
    87 			{
       
    88 			delete request;
       
    89 			iRequestQueue.Remove(i);
       
    90 			}
       
    91 		}
       
    92 
       
    93 	// If this reader / writer originated the request that's currently being process, abort it.
       
    94 	if (iRequestAo->CurrentRequest() && iRequestAo->CurrentRequest()->OriginatedFrom(aReadWriter))
       
    95 		{
       
    96 		iRequestAo->Abort();
       
    97 		}
       
    98 	}
       
    99 
       
   100 void CIoConsole::IorepReadL(MIoReader&)
       
   101 	{
       
   102 	if (!iReader->IsActive())
       
   103 		{
       
   104 		iReader->QueueRead();
       
   105 		}
       
   106 	}
       
   107 
       
   108 void CIoConsole::IorepReadKeyL(MIoReader& aReader)
       
   109 	{
       
   110 	IorepReadL(aReader);
       
   111 	}
       
   112 
       
   113 void CIoConsole::IorepSetConsoleModeL(RIoReadWriteHandle::TMode aMode, MIoReader& aReader)
       
   114 	{
       
   115 	NewRequest(new(ELeave)TConsoleSetModeRequest(aReader, *this, aMode));
       
   116 	}
       
   117 
       
   118 void CIoConsole::IowepWriteL(MIoWriter& aWriter)
       
   119 	{
       
   120 	NewRequest(new(ELeave)TConsoleWriteRequest(aWriter));
       
   121 	}
       
   122 
       
   123 void CIoConsole::IowepWriteCancel(MIoWriter&)
       
   124 	{
       
   125 	}
       
   126 
       
   127 void CIoConsole::IowepCursorPosL(MIoWriter& aWriter) const
       
   128 	{
       
   129 	NewRequest(new(ELeave)TConsoleCursorPosRequest(aWriter));
       
   130 	}
       
   131 
       
   132 void CIoConsole::IowepSetCursorPosAbsL(const TPoint& aPoint, MIoWriter& aWriter)
       
   133 	{
       
   134 	NewRequest(new(ELeave)TConsoleSetCursorPosAbsRequest(aWriter, aPoint));
       
   135 	}
       
   136 
       
   137 void CIoConsole::IowepSetCursorPosRelL(const TPoint& aPoint, MIoWriter& aWriter)
       
   138 	{
       
   139 	NewRequest(new(ELeave)TConsoleSetCursorPosRelRequest(aWriter, aPoint));
       
   140 	}
       
   141 
       
   142 void CIoConsole::IowepSetCursorHeightL(TInt aPercentage, MIoWriter& aWriter)
       
   143 	{
       
   144 	NewRequest(new(ELeave)TConsoleSetCursorHeightRequest(aWriter, aPercentage));
       
   145 	}
       
   146 
       
   147 void CIoConsole::IowepSetTitleL(MIoWriter& aWriter)
       
   148 	{
       
   149 	NewRequest(new(ELeave)TConsoleSetTitleRequest(aWriter));
       
   150 	}
       
   151 
       
   152 void CIoConsole::IowepClearScreenL(MIoWriter& aWriter)
       
   153 	{
       
   154 	NewRequest(new(ELeave)TConsoleClearScreenRequest(aWriter));
       
   155 	}
       
   156 
       
   157 void CIoConsole::IowepClearToEndOfLineL(MIoWriter& aWriter)
       
   158 	{
       
   159 	NewRequest(new(ELeave)TConsoleClearToEndOfLineRequest(aWriter));
       
   160 	}
       
   161 
       
   162 void CIoConsole::IowepSetAttributesL(TUint aAttributes, ConsoleAttributes::TColor aForegroundColor, ConsoleAttributes::TColor aBackgroundColor, MIoWriter& aWriter)
       
   163 	{
       
   164 	NewRequest(new(ELeave)TConsoleSetAttributesRequest(aWriter, aAttributes, aForegroundColor, aBackgroundColor));
       
   165 	}
       
   166 
       
   167 void CIoConsole::IowepScreenSizeL(MIoWriter& aWriter) const
       
   168 	{
       
   169 	NewRequest(new(ELeave)TConsoleScreenSizeRequest(aWriter, iConfig));
       
   170 	}
       
   171 
       
   172 CIoConsole::CIoConsole(const TIoConfig& aConfig)
       
   173 	: iConfig(aConfig), iDetectedSize(-1, -1)
       
   174 	{
       
   175 	}
       
   176 
       
   177 void CIoConsole::ConstructL(const TDesC& aImplementation, const TDesC& aTitle, const TSize& aSize, CIoConsole* aUnderlying, TUint aOptions)
       
   178 	{
       
   179 	LOG(CIoLog::Printf(_L("Console 0x%08x created"), this));
       
   180 	iCreationTitle = aTitle.AllocL();
       
   181 	iCreationSize = aSize;
       
   182 	
       
   183 	iRequestAo = new(ELeave)CConsoleRequest(*this);
       
   184 	
       
   185 	if (aImplementation.Length())
       
   186 		{
       
   187 		iImplementation = aImplementation.AllocL();
       
   188 		}
       
   189 	else
       
   190 		{
       
   191 		iImplementation = iConfig.ConsoleImplementation().AllocL();
       
   192 		}
       
   193 		
       
   194 	User::LeaveIfError(iConsole.Connect(CIoConsoleProxyServerNewL, iImplementation, *iImplementation, KDefaultStackSize, KConsoleThreadMinHeapSize, KConsoleThreadMaxHeapSize, iThreadServer, iServerThread));
       
   195 	iThreadWatcher = new(ELeave)CServerDeathWatcher(iThreadServer, iServerThread);
       
   196 	if (aOptions & RIoConsole::ELazyCreate)
       
   197 		{
       
   198 		User::LeaveIfError(iConsole.SetLazyConstruct());
       
   199 		}
       
   200 	if (iConfig.ConsoleSizeDetect())
       
   201 		{
       
   202 		User::LeaveIfError(iConsole.SetConsoleSizeDetect());
       
   203 		}
       
   204 	if (aUnderlying)
       
   205 		{
       
   206 		User::LeaveIfError(aUnderlying->Open());
       
   207 		CleanupClosePushL(*aUnderlying);
       
   208 		NewRequest(new(ELeave)TConsoleSetUnderlyingRequest(*aUnderlying));
       
   209 		CleanupStack::Pop();
       
   210 		}
       
   211 	NewRequest(new(ELeave)TConsoleCreateRequest(*this));
       
   212 		
       
   213 	iReader = CConsoleReader::NewL(*this);
       
   214 	}
       
   215 	
       
   216 void CIoConsole::CreateComplete(TInt aError)
       
   217 	{
       
   218 	iCreateStatus = aError;
       
   219 	}
       
   220 	
       
   221 void CIoConsole::NewRequest(TConsoleRequest* aRequest) const
       
   222 	{
       
   223 	ASSERT(aRequest);
       
   224 	TInt err = iRequestQueue.Append(aRequest);
       
   225 	if (err!=KErrNone)
       
   226 		{
       
   227 		aRequest->CompleteD(err);
       
   228 		return;
       
   229 		}
       
   230 
       
   231 	CheckQueue();
       
   232 	}
       
   233 	
       
   234 void CIoConsole::CheckQueue() const
       
   235 	{
       
   236 	if (iCreateStatus != KErrNone)
       
   237 		{
       
   238 		while (iRequestQueue.Count())
       
   239 			{
       
   240 			TConsoleRequest* req = iRequestQueue[0];
       
   241 			iRequestQueue.Remove(0);
       
   242 			req->CompleteD(iCreateStatus);
       
   243 			}
       
   244 		return;
       
   245 		}
       
   246 	if ((!iRequestAo->IsActive()) && (iRequestQueue.Count()))
       
   247 		{
       
   248 		iRequestAo->Service(iRequestQueue[0]);
       
   249 		iRequestQueue.Remove(0);
       
   250 		}
       
   251 	}
       
   252 	
       
   253 void CIoConsole::ConsoleDied()
       
   254 	{
       
   255 	iCreateStatus = KErrGeneral;
       
   256 
       
   257 	iReader = CConsoleReader::NewL(*this);
       
   258 	}
       
   259 
       
   260 void CIoConsole::ReadComplete(TInt aError)
       
   261 	{
       
   262 	MIoReader* foregroundReader = AttachedReader(0);
       
   263 	if (foregroundReader)
       
   264 		{
       
   265 		foregroundReader->IorReadKeyComplete(aError, 0, 0);
       
   266 		}
       
   267 	}
       
   268 
       
   269 void CIoConsole::ReadComplete(TUint aKeyCode, TUint aModifiers)
       
   270 	{
       
   271 	TInt index = 0;
       
   272 	MIoReader* foregroundReader = AttachedReader(index++);
       
   273 	MIoReader* reader = foregroundReader;
       
   274 	TBool keyHandled(EFalse);
       
   275 	while (reader)
       
   276 		{
       
   277 		if (reader->IorIsKeyCaptured(aKeyCode, aModifiers))
       
   278 			{
       
   279 			if (reader->IorReadPending())
       
   280 				{
       
   281 				TPtrC keyCodePtr((TUint16*)&aKeyCode, 1);
       
   282 				reader->IorReadBuf().Append(keyCodePtr);
       
   283 				reader->IorDataBuffered(1);
       
   284 				}
       
   285 			else
       
   286 				{
       
   287 				reader->IorReadKeyComplete(KErrNone, aKeyCode, aModifiers);
       
   288 				}
       
   289 			keyHandled = ETrue;
       
   290 			break;
       
   291 			}
       
   292 		reader = AttachedReader(index++);;
       
   293 		}
       
   294 
       
   295 	// Key not captured, so send to foreground (i.e. the first) reader.
       
   296 	if (!keyHandled && foregroundReader)
       
   297 		{
       
   298 		foregroundReader->IorReadKeyComplete(KErrNone, aKeyCode, aModifiers);
       
   299 		}
       
   300 
       
   301 	QueueReaderIfRequired();
       
   302 	}
       
   303 
       
   304 void CIoConsole::QueueReaderIfRequired()
       
   305 	{
       
   306 	TBool pendingReader(EFalse);
       
   307 	TInt index = 0;
       
   308 	MIoReader* reader = AttachedReader(index++);
       
   309 	while (reader)
       
   310 		{
       
   311 		if (reader->IorReadPending() || reader->IorReadKeyPending())
       
   312 			{
       
   313 			pendingReader = ETrue;
       
   314 			break;
       
   315 			}
       
   316 		reader = AttachedReader(index++);
       
   317 		}
       
   318 
       
   319 	if (pendingReader && !iReader->IsActive())
       
   320 		{
       
   321 		iReader->QueueRead();
       
   322 		}
       
   323 	else if (!pendingReader && iReader->IsActive())
       
   324 		{
       
   325 		iReader->Cancel();
       
   326 		}
       
   327 	}
       
   328 
       
   329 CIoConsole::CConsoleReader* CIoConsole::CConsoleReader::NewL(CIoConsole& aConsole)
       
   330 	{
       
   331 	return new(ELeave) CConsoleReader(aConsole);
       
   332 	}
       
   333 
       
   334 CIoConsole::CConsoleReader::~CConsoleReader()
       
   335 	{
       
   336 	Cancel();
       
   337 	}
       
   338 
       
   339 void CIoConsole::CConsoleReader::QueueRead()
       
   340 	{
       
   341 	iConsole.iConsole.Read(iKeyCodePckg, iKeyModifiersPckg, iStatus);
       
   342 	SetActive();
       
   343 	}
       
   344 
       
   345 CIoConsole::CConsoleReader::CConsoleReader(CIoConsole& aConsole)
       
   346 	: CActive(CActive::EPriorityStandard), iConsole(aConsole)
       
   347 	, iKeyCodePckg(iKeyCode), iKeyModifiersPckg(iKeyModifiers)
       
   348 	{
       
   349 	CActiveScheduler::Add(this);
       
   350 	}
       
   351 
       
   352 void CIoConsole::CConsoleReader::RunL()
       
   353 	{
       
   354 	TInt err = iStatus.Int();
       
   355 	if (err==KErrServerTerminated)
       
   356 		{
       
   357 		iConsole.ConsoleDied();
       
   358 		err = KErrGeneral;
       
   359 		}
       
   360 	if (err)
       
   361 		{
       
   362 		iConsole.ReadComplete(err);
       
   363 		}
       
   364 	else
       
   365 		{
       
   366 		iConsole.ReadComplete(iKeyCode, iKeyModifiers);
       
   367 		}
       
   368 	}
       
   369 
       
   370 void CIoConsole::CConsoleReader::DoCancel()
       
   371 	{
       
   372 	iConsole.iConsole.ReadCancel();
       
   373 	}
       
   374 
       
   375 //______________________________________________________________________________
       
   376 //						TConsoleRequest
       
   377 void CIoConsole::TConsoleRequest::PrepareL()
       
   378 	{
       
   379 	}
       
   380 
       
   381 TBool CIoConsole::TConsoleRequest::OriginatedFrom(MIoReader&) const
       
   382 	{ 
       
   383 	return EFalse; 
       
   384 	}
       
   385 
       
   386 TBool CIoConsole::TConsoleRequest::OriginatedFrom(MIoWriter&) const
       
   387 	{
       
   388 	return EFalse;
       
   389 	}
       
   390 
       
   391 //______________________________________________________________________________
       
   392 //						TConsoleWriterRequest
       
   393 CIoConsole::TConsoleWriterRequest::TConsoleWriterRequest(MIoWriter& aWriter)
       
   394 	: iWriter(aWriter)
       
   395 	{
       
   396 	}
       
   397 
       
   398 TBool CIoConsole::TConsoleWriterRequest::OriginatedFrom(MIoWriter& aWriter) const
       
   399 	{
       
   400 	return (&iWriter == &aWriter);
       
   401 	}
       
   402 
       
   403 //______________________________________________________________________________
       
   404 //						TConsoleReaderRequest
       
   405 CIoConsole::TConsoleReaderRequest::TConsoleReaderRequest(MIoReader& aReader)
       
   406 	: iReader(aReader)
       
   407 	{
       
   408 	}
       
   409 
       
   410 TBool CIoConsole::TConsoleReaderRequest::OriginatedFrom(MIoReader& aReader) const
       
   411 	{
       
   412 	return (&iReader == &aReader);
       
   413 	}
       
   414 
       
   415 //______________________________________________________________________________
       
   416 //						TConsoleCreateRequest
       
   417 CIoConsole::TConsoleCreateRequest::TConsoleCreateRequest(CIoConsole& aOwner)
       
   418 	: iOwner(aOwner)
       
   419 	{
       
   420 	}
       
   421 
       
   422 void CIoConsole::TConsoleCreateRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   423 	{
       
   424 	aProxy.Create(*iOwner.iCreationTitle, iOwner.iCreationSize, aStatus);
       
   425 	}
       
   426 
       
   427 void CIoConsole::TConsoleCreateRequest::CompleteD(TInt aError)
       
   428 	{
       
   429 	iOwner.CreateComplete(aError);
       
   430 	delete this;
       
   431 	}
       
   432 
       
   433 //______________________________________________________________________________
       
   434 //						TConsoleWriteRequest
       
   435 CIoConsole::TConsoleWriteRequest::TConsoleWriteRequest(MIoWriter& aWriter)
       
   436 	: TConsoleWriterRequest(aWriter), iBuf(NULL)
       
   437 	{
       
   438 	}
       
   439 
       
   440 void CIoConsole::TConsoleWriteRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   441 	{
       
   442 	if (iWriter.IowIsStdErr())
       
   443 		{
       
   444 		aProxy.WriteStdErr(*iBuf, aStatus);
       
   445 		}
       
   446 	else
       
   447 		{
       
   448 		aProxy.Write(*iBuf, aStatus);
       
   449 		}
       
   450 	}
       
   451 
       
   452 void CIoConsole::TConsoleWriteRequest::PrepareL()
       
   453 	{
       
   454 	const TInt length = iWriter.IowWriteLength();
       
   455 	if (iBuf == NULL)
       
   456 		{
       
   457 		iBuf = HBufC::NewL(length);
       
   458 		}
       
   459 	else if (iBuf->Des().MaxLength() < length)
       
   460 		{
       
   461 		iBuf = iBuf->ReAllocL(length);
       
   462 		}
       
   463 
       
   464 	TPtr bufPtr(iBuf->Des());
       
   465 	bufPtr.Zero();
       
   466 	iWriter.IowWrite(bufPtr);
       
   467 
       
   468 	if (iWriter.IorwMode() == RIoReadWriteHandle::EText)
       
   469 		{
       
   470 		// Fix line endings (change LF to CRLF).
       
   471 		RArray<TInt> indicies(5);
       
   472 		CleanupClosePushL(indicies);
       
   473 		_LIT(KCarriageReturn, "\r");
       
   474 		for (TInt i = 0; i < length; ++i)
       
   475 			{
       
   476 			if ((*iBuf)[i] == '\n')
       
   477 				{
       
   478 				if ((i == 0) || ((*iBuf)[i - 1] != '\r'))
       
   479 					{
       
   480 					User::LeaveIfError(indicies.Append(i));
       
   481 					}
       
   482 				}
       
   483 			}
       
   484 		const TInt count = indicies.Count();
       
   485 		if (count > 0)
       
   486 			{
       
   487 			if (bufPtr.MaxLength() < (length + count))
       
   488 				{
       
   489 				iBuf = iBuf->ReAllocL(length + count);
       
   490 				bufPtr.Set(iBuf->Des());
       
   491 				}
       
   492 			for (TInt i = (count - 1); i >= 0; --i)
       
   493 				{
       
   494 				bufPtr.Insert(indicies[i], KCarriageReturn);
       
   495 				}
       
   496 			}
       
   497 		CleanupStack::PopAndDestroy(&indicies);
       
   498 		}
       
   499 	
       
   500 	}
       
   501 
       
   502 void CIoConsole::TConsoleWriteRequest::CompleteD(TInt aError)
       
   503 	{
       
   504 	delete iBuf;
       
   505 	iWriter.IowComplete(aError);
       
   506 	delete this;
       
   507 	}
       
   508 
       
   509 //______________________________________________________________________________
       
   510 //						TConsoleCursorPosRequest
       
   511 CIoConsole::TConsoleCursorPosRequest::TConsoleCursorPosRequest(MIoWriter& aWriter)
       
   512 	: TConsoleWriterRequest(aWriter), iPosPckg(iPos)
       
   513 	{
       
   514 	}
       
   515 
       
   516 void CIoConsole::TConsoleCursorPosRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   517 	{
       
   518 	aProxy.CursorPos(iPosPckg, aStatus);
       
   519 	}
       
   520 
       
   521 void CIoConsole::TConsoleCursorPosRequest::CompleteD(TInt aError)
       
   522 	{
       
   523 	iWriter.IowCursorPos(aError, iPos);
       
   524 	delete this;
       
   525 	}
       
   526 
       
   527 //______________________________________________________________________________
       
   528 //						TConsoleSetCursorPosAbsRequest
       
   529 CIoConsole::TConsoleSetCursorPosAbsRequest::TConsoleSetCursorPosAbsRequest(MIoWriter& aWriter, const TPoint& aPoint)
       
   530 	: TConsoleWriterRequest(aWriter), iPoint(aPoint)
       
   531 	{
       
   532 	}
       
   533 
       
   534 void CIoConsole::TConsoleSetCursorPosAbsRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   535 	{
       
   536 	aProxy.SetCursorPosAbs(iPoint, aStatus);	
       
   537 	}
       
   538 
       
   539 void CIoConsole::TConsoleSetCursorPosAbsRequest::CompleteD(TInt aError)
       
   540 	{
       
   541 	iWriter.IowSetCursorPosAbsComplete(aError);
       
   542 	delete this;
       
   543 	}
       
   544 
       
   545 //______________________________________________________________________________
       
   546 //						TConsoleSetCursorPosRelRequest
       
   547 CIoConsole::TConsoleSetCursorPosRelRequest::TConsoleSetCursorPosRelRequest(MIoWriter& aWriter, const TPoint& aPoint)
       
   548 	: TConsoleWriterRequest(aWriter), iPoint(aPoint)
       
   549 	{
       
   550 	}
       
   551 
       
   552 void CIoConsole::TConsoleSetCursorPosRelRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   553 	{
       
   554 	aProxy.SetCursorPosRel(iPoint, aStatus);
       
   555 	}
       
   556 
       
   557 void CIoConsole::TConsoleSetCursorPosRelRequest::CompleteD(TInt aError)
       
   558 	{
       
   559 	iWriter.IowSetCursorPosRelComplete(aError);
       
   560 	delete this;
       
   561 	}
       
   562 
       
   563 //______________________________________________________________________________
       
   564 //						TConsoleSetCursorHeightRequest
       
   565 CIoConsole::TConsoleSetCursorHeightRequest::TConsoleSetCursorHeightRequest(MIoWriter& aWriter, TInt aHeight)
       
   566 	: TConsoleWriterRequest(aWriter), iHeight(aHeight)
       
   567 	{
       
   568 	}	
       
   569 
       
   570 void CIoConsole::TConsoleSetCursorHeightRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   571 	{
       
   572 	aProxy.SetCursorHeight(iHeight, aStatus);
       
   573 	}
       
   574 
       
   575 void CIoConsole::TConsoleSetCursorHeightRequest::CompleteD(TInt aError)
       
   576 	{
       
   577 	iWriter.IowSetCursorHeightComplete(aError);
       
   578 	delete this;
       
   579 	}
       
   580 
       
   581 //______________________________________________________________________________
       
   582 //						TConsoleSetTitleRequest
       
   583 CIoConsole::TConsoleSetTitleRequest::TConsoleSetTitleRequest(MIoWriter& aWriter)
       
   584 	: TConsoleWriterRequest(aWriter)
       
   585 	{
       
   586 	}
       
   587 
       
   588 void CIoConsole::TConsoleSetTitleRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   589 	{
       
   590 	aProxy.SetTitle(*iTitle, aStatus);
       
   591 	}
       
   592 
       
   593 void CIoConsole::TConsoleSetTitleRequest::PrepareL()
       
   594 	{
       
   595 	iTitle = iWriter.IowTitleLC();
       
   596 	CleanupStack::Pop(iTitle);
       
   597 	}
       
   598 
       
   599 void CIoConsole::TConsoleSetTitleRequest::CompleteD(TInt aError)
       
   600 	{
       
   601 	delete iTitle;
       
   602 	iWriter.IowSetTitleComplete(aError);
       
   603 	delete this;
       
   604 	}
       
   605 
       
   606 //______________________________________________________________________________
       
   607 //						TConsoleClearScreenRequest
       
   608 CIoConsole::TConsoleClearScreenRequest::TConsoleClearScreenRequest(MIoWriter& aWriter)
       
   609 	: TConsoleWriterRequest(aWriter)
       
   610 	{
       
   611 	}
       
   612 
       
   613 void CIoConsole::TConsoleClearScreenRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   614 	{
       
   615 	aProxy.ClearScreen(aStatus);
       
   616 	}
       
   617 
       
   618 void CIoConsole::TConsoleClearScreenRequest::CompleteD(TInt aError)
       
   619 	{
       
   620 	iWriter.IowClearScreenComplete(aError);
       
   621 	delete this;
       
   622 	}
       
   623 
       
   624 		
       
   625 	
       
   626 
       
   627 //______________________________________________________________________________
       
   628 //						TConsoleClearToEndOfLineRequest
       
   629 CIoConsole::TConsoleClearToEndOfLineRequest::TConsoleClearToEndOfLineRequest(MIoWriter& aWriter)
       
   630 	: TConsoleWriterRequest(aWriter)
       
   631 	{
       
   632 	}
       
   633 
       
   634 void CIoConsole::TConsoleClearToEndOfLineRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   635 	{
       
   636 	aProxy.ClearToEndOfLine(aStatus);
       
   637 	}
       
   638 
       
   639 void CIoConsole::TConsoleClearToEndOfLineRequest::CompleteD(TInt aError)
       
   640 	{
       
   641 	iWriter.IowClearToEndOfLineComplete(aError);
       
   642 	delete this;
       
   643 	}
       
   644 
       
   645 		
       
   646 	
       
   647 
       
   648 //______________________________________________________________________________
       
   649 //						TConsoleScreenSizeRequest
       
   650 CIoConsole::TConsoleScreenSizeRequest::TConsoleScreenSizeRequest(MIoWriter& aWriter, const TIoConfig& aConfig)
       
   651 	: TConsoleWriterRequest(aWriter), iConfig(aConfig), iSizeBuf(iSize)
       
   652 	{
       
   653 	}
       
   654 
       
   655 void CIoConsole::TConsoleScreenSizeRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   656 	{
       
   657 	aProxy.GetScreenSize(iSizeBuf, aStatus);
       
   658 	}
       
   659 
       
   660 void CIoConsole::TConsoleScreenSizeRequest::CompleteD(TInt aError)
       
   661 	{
       
   662 	if (aError==KErrNone)
       
   663 		{
       
   664 		iSize.iWidth += iConfig.ConsoleSizeAdjustment().iWidth;
       
   665 		iSize.iHeight += iConfig.ConsoleSizeAdjustment().iHeight;
       
   666 		}
       
   667 	iWriter.IowScreenSize(aError, iSize);
       
   668 	delete this;
       
   669 	}
       
   670 
       
   671 //______________________________________________________________________________
       
   672 //						TConsoleSetAttributesRequest
       
   673 CIoConsole::TConsoleSetAttributesRequest::TConsoleSetAttributesRequest(MIoWriter& aWriter, TUint aAttributes, ConsoleAttributes::TColor aForegroundColor, ConsoleAttributes::TColor aBackgroundColor)
       
   674 	: TConsoleWriterRequest(aWriter), iAttributes(aAttributes), iForegroundColor(aForegroundColor), iBackgroundColor(aBackgroundColor)
       
   675 	{
       
   676 	}
       
   677 
       
   678 void CIoConsole::TConsoleSetAttributesRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   679 	{
       
   680 	aProxy.SetAttributes(iAttributes, iForegroundColor, iBackgroundColor, aStatus);
       
   681 	}
       
   682 
       
   683 void CIoConsole::TConsoleSetAttributesRequest::CompleteD(TInt aError)
       
   684 	{
       
   685 	iWriter.IowSetAttributesComplete(aError);
       
   686 	delete this;
       
   687 	}
       
   688 
       
   689 		
       
   690 //______________________________________________________________________________
       
   691 //						TConsoleSetUnderlyingRequest
       
   692 CIoConsole::TConsoleSetUnderlyingRequest::TConsoleSetUnderlyingRequest(CIoConsole& aUnderlyingConsole)
       
   693 	: iConsole(aUnderlyingConsole)
       
   694 	{
       
   695 	}
       
   696 
       
   697 void CIoConsole::TConsoleSetUnderlyingRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   698 	{
       
   699 	aProxy.SetUnderlyingConsole(iSession, aStatus);
       
   700 	}
       
   701 
       
   702 void CIoConsole::TConsoleSetUnderlyingRequest::PrepareL()
       
   703 	{
       
   704 	if (iConsole.iThreadServer.Handle())
       
   705 		{
       
   706 		User::LeaveIfError(iSession.Connect(iConsole.iThreadServer));
       
   707 		}
       
   708 	else
       
   709 		{
       
   710 		User::Leave(KErrBadHandle);
       
   711 		}	
       
   712 	}
       
   713 
       
   714 void CIoConsole::TConsoleSetUnderlyingRequest::CompleteD(TInt)
       
   715 	{
       
   716 	iSession.Close();
       
   717 	iConsole.Close();
       
   718 	delete this;
       
   719 	}
       
   720 
       
   721 //______________________________________________________________________________
       
   722 //						TConsoleSetModeRequest
       
   723 CIoConsole::TConsoleSetModeRequest::TConsoleSetModeRequest(MIoReader& aReader,CIoConsole& aConsole, RIoReadWriteHandle::TMode aMode)
       
   724 	: TConsoleReaderRequest(aReader), iConsole(aConsole), iMode(aMode)
       
   725 	{
       
   726 	}
       
   727 
       
   728 void CIoConsole::TConsoleSetModeRequest::Request(RIoConsoleProxy aProxy, TRequestStatus& aStatus)
       
   729 	{
       
   730 	iConsole.iReader->Cancel();
       
   731 	aProxy.SetConsoleMode(iMode, aStatus);
       
   732 	}
       
   733 
       
   734 void CIoConsole::TConsoleSetModeRequest::CompleteD(TInt aError)
       
   735 	{
       
   736 	iConsole.QueueReaderIfRequired();
       
   737 	iReader.IorSetConsoleModeComplete(aError);
       
   738 	delete this;
       
   739 	}
       
   740 
       
   741 //______________________________________________________________________________
       
   742 //						CConsoleRequest
       
   743 CIoConsole::CConsoleRequest::CConsoleRequest(CIoConsole& aConsole)
       
   744 	: CActive(EPriorityStandard), iConsole(aConsole)
       
   745 	{
       
   746 	CActiveScheduler::Add(this);
       
   747 	}
       
   748 		
       
   749 void CIoConsole::CConsoleRequest::Service(TConsoleRequest* aRequest)
       
   750 	{
       
   751 	ASSERT(!IsActive());
       
   752 	ASSERT(!iCurrentRequest);
       
   753 	TRAPD(err, aRequest->PrepareL());
       
   754 	if (err!=KErrNone)
       
   755 		{
       
   756 		Complete(aRequest, err);
       
   757 		return;
       
   758 		}
       
   759 	aRequest->Request(iConsole.iConsole, iStatus);
       
   760 	SetActive();
       
   761 	iCurrentRequest = aRequest;
       
   762 	}
       
   763 	
       
   764 void CIoConsole::CConsoleRequest::Complete(TConsoleRequest* aRequest, TInt aError)
       
   765 	{
       
   766 	if (aError == KErrServerTerminated)
       
   767 		{
       
   768 		// console has panicked.
       
   769 		iConsole.ConsoleDied();
       
   770 		// don't want to send KErrServerTerminated up to our (iosrv) clients, as it will
       
   771 		// make them think the iosrv has died.
       
   772 		aError = KErrGeneral;
       
   773 		}
       
   774 	if (aRequest)
       
   775 		{
       
   776 		aRequest->CompleteD(aError);
       
   777 		}
       
   778 	iConsole.CheckQueue();
       
   779 	}
       
   780 
       
   781 
       
   782 CIoConsole::CConsoleRequest::~CConsoleRequest()
       
   783 	{
       
   784 	Cancel();
       
   785 	}
       
   786 	
       
   787 void CIoConsole::CConsoleRequest::RunL()
       
   788 	{
       
   789 	TConsoleRequest* req = iCurrentRequest;
       
   790 	iCurrentRequest = NULL;
       
   791 	Complete(req, iStatus.Int());
       
   792 	}
       
   793 
       
   794 void CIoConsole::CConsoleRequest::DoCancel()
       
   795 	{
       
   796 	// request are handled synchronously on the server side, no cancelling is possible.
       
   797 	}
       
   798 
       
   799 const CIoConsole::TConsoleRequest* CIoConsole::CConsoleRequest::CurrentRequest() const
       
   800 	{
       
   801 	return iCurrentRequest;
       
   802 	}
       
   803 
       
   804 void CIoConsole::CConsoleRequest::Abort()
       
   805 	{
       
   806 	// We can't cancel a pending request (because they are handled synchronously on the server side),
       
   807 	// so instead we delete and NULL the associated request object. This active object will then
       
   808 	// continue to wait for the server to complete the request (as normal), but will take no further
       
   809 	// action. This is used when the originating MIoReader or MIoWriter object has been detached from
       
   810 	// the console and no longer exists.
       
   811 	ASSERT(IsActive());
       
   812 	ASSERT(iCurrentRequest);
       
   813 	delete iCurrentRequest;
       
   814 	iCurrentRequest = NULL;
       
   815 	}
       
   816 
       
   817 
       
   818 //______________________________________________________________________________
       
   819 //						CServerDeathWatcher
       
   820 CIoConsole::CServerDeathWatcher::CServerDeathWatcher(RServer2& aServer, RThread& aThread)
       
   821 	: CActive(CActive::EPriorityStandard), iServer(aServer), iThread(aThread)
       
   822 	{
       
   823 	CActiveScheduler::Add(this);
       
   824 	aThread.Logon(iStatus);
       
   825 	SetActive();
       
   826 	}
       
   827 	
       
   828 CIoConsole::CServerDeathWatcher::~CServerDeathWatcher()
       
   829 	{
       
   830 	Cancel();
       
   831 	}
       
   832 
       
   833 void CIoConsole::CServerDeathWatcher::RunL()
       
   834 	{
       
   835 	}
       
   836 
       
   837 void CIoConsole::CServerDeathWatcher::DoCancel()
       
   838 	{
       
   839 	iThread.LogonCancel(iStatus);
       
   840 	}
       
   841 
       
   842 //______________________________________________________________________________
       
   843 //						RIoConsoleProxy
       
   844 TInt RIoConsoleProxy::SetConsoleSizeDetect()
       
   845 	{
       
   846 	return SendReceive(ESetConsoleSizeDetect);
       
   847 	}
       
   848 	
       
   849 TInt RIoConsoleProxy::SetLazyConstruct()
       
   850 	{
       
   851 	return SendReceive(ESetLazyConstruct);
       
   852 	}
       
   853 	
       
   854 void RIoConsoleProxy::SetConsoleMode(RIoReadWriteHandle::TMode aMode, TRequestStatus& aStatus)
       
   855 	{
       
   856 	SendReceive(ESetConsoleMode, TIpcArgs(aMode), aStatus);
       
   857 	}
       
   858 	
       
   859 void RIoConsoleProxy::SetUnderlyingConsole(const RIoConsoleProxy& aUnderlyingSession, TRequestStatus& aStatus)
       
   860 	{
       
   861 	SendReceive(ESetUnderlyingConsole, TIpcArgs(aUnderlyingSession), aStatus);
       
   862 	}
       
   863 	
       
   864 TInt RIoConsoleProxy::OpenExisting()
       
   865 	{
       
   866 	return SendReceive(EOpenExistingConsole);
       
   867 	}
       
   868 
       
   869 void RIoConsoleProxy::WriteStdErr(const TDesC& aDescriptor, TRequestStatus& aStatus)
       
   870 	{
       
   871 	SendReceive(EWriteStdErr, TIpcArgs(&aDescriptor), aStatus);
       
   872 	}
       
   873 
       
   874 //______________________________________________________________________________
       
   875 //						CIoConsoleProxyServer
       
   876 CConsoleProxyServer* CIoConsoleProxyServerNewL(TAny* aParams)
       
   877 	{
       
   878 	const TDesC* dllName = (const TDesC*)aParams;
       
   879 	RLibrary lib;
       
   880 
       
   881 	User::LeaveIfError(lib.Load(*dllName));
       
   882 	CleanupClosePushL(lib);
       
   883 	if ((lib.Type()[1] == KSharedLibraryUid) && (lib.Type()[2] == KConsoleDllUid))
       
   884 		{
       
   885 		TConsoleCreateFunction entry = (TConsoleCreateFunction)lib.Lookup(1);
       
   886 		if (!entry) User::Leave(KErrNotSupported);
       
   887 		CleanupStack::Pop(&lib);
       
   888 		return CIoConsoleProxyServer::NewL(entry, lib);
       
   889 		}
       
   890 	else
       
   891 		{
       
   892 		User::Leave(KErrNotSupported);
       
   893 		return NULL; // ASSERT(Happy(compiler))
       
   894 		}
       
   895 	}
       
   896 	
       
   897 CIoConsoleProxyServer* CIoConsoleProxyServer::NewL(TConsoleCreateFunction aConsoleCreate, RLibrary& aConsoleLibrary)
       
   898 	{
       
   899 	CIoConsoleProxyServer* self = new CIoConsoleProxyServer(aConsoleCreate, aConsoleLibrary);
       
   900 	if (!self)
       
   901 		{
       
   902 		aConsoleLibrary.Close();
       
   903 		User::Leave(KErrNoMemory);
       
   904 		}
       
   905 	CleanupStack::PushL(self);
       
   906 	self->ConstructL(KNullDesC);
       
   907 	CleanupStack::Pop(self);
       
   908 	return self;
       
   909 	}
       
   910 	
       
   911 CIoConsoleProxyServer::CIoConsoleProxyServer(TConsoleCreateFunction aConsoleCreate, const RLibrary& aConsoleLibrary)
       
   912 	: CConsoleProxyServer(aConsoleCreate, CActive::EPriorityStandard)
       
   913 	, iConsoleLibrary(aConsoleLibrary)
       
   914 	{
       
   915 	}
       
   916 
       
   917 CSession2* CIoConsoleProxyServer::NewSessionL(const TVersion&,const RMessage2&) const
       
   918 	{
       
   919 	return new(ELeave)CIoConsoleProxySession(iConsoleCreate);
       
   920 	}
       
   921 	
       
   922 CIoConsoleProxyServer::~CIoConsoleProxyServer()
       
   923 	{
       
   924 	iConsoleLibrary.Close();
       
   925 	}
       
   926 	
       
   927 MProxiedConsole* CIoConsoleProxyServer::TheConsole() const
       
   928 	{
       
   929 	return iTheConsole;
       
   930 	}
       
   931 	
       
   932 void CIoConsoleProxyServer::SetTheConsole(MProxiedConsole* aConsole)
       
   933 	{
       
   934 	ASSERT(!iTheConsole);
       
   935 	iTheConsole = aConsole;
       
   936 	}
       
   937 
       
   938 //______________________________________________________________________________
       
   939 TSize DetectConsoleSize(CConsoleBase* aConsole)
       
   940 	{
       
   941 	TSize detectedSize;
       
   942 	aConsole->SetCursorHeight(0);
       
   943 	aConsole->ScreenSize(); // This used to be assigned to a variable, which was never used, but I'm not sure if calling ScreenSize() has side-effects so I'm leaving the call in
       
   944 	aConsole->SetCursorPosAbs(TPoint(0, 0));
       
   945 	_LIT(KSpace, " ");
       
   946 	for (TInt x = 0; ; ++x)
       
   947 		{
       
   948 		aConsole->Write(KSpace);
       
   949 		if (aConsole->CursorPos().iX == 0)
       
   950 			{
       
   951 			detectedSize.iWidth = x + 1;
       
   952 			break;
       
   953 			}
       
   954 		}
       
   955 	aConsole->SetCursorPosAbs(TPoint(0, 0));
       
   956 	TInt prevYPos = 0;
       
   957 	_LIT(KNewLine, "\r\n");
       
   958 	for (TInt y = 0; ; ++y)
       
   959 		{
       
   960 		aConsole->Write(KNewLine);
       
   961 		if (aConsole->CursorPos().iY == prevYPos)
       
   962 			{
       
   963 			detectedSize.iHeight = y;
       
   964 			break;
       
   965 			}
       
   966 		else
       
   967 			{
       
   968 			prevYPos = y;
       
   969 			}
       
   970 		}
       
   971 	aConsole->ClearScreen();
       
   972 	aConsole->SetCursorHeight(20);
       
   973 	return detectedSize;
       
   974 	}
       
   975 
       
   976 //______________________________________________________________________________
       
   977 //						CIoConsoleProxySession
       
   978 CIoConsoleProxySession::CIoConsoleProxySession(TConsoleCreateFunction aConsoleCreate)
       
   979 	: CConsoleProxySession(aConsoleCreate), iFlags(ESupportsStdErr)
       
   980 	{
       
   981 	// Assume ESupportsStdErr until proven otherwise
       
   982 	}
       
   983 
       
   984 CIoConsoleProxySession::~CIoConsoleProxySession()
       
   985 	{
       
   986 	delete iUnderlyingConsole;
       
   987 	}
       
   988 
       
   989 void CIoConsoleProxySession::ServiceL(const RMessage2& aMessage)
       
   990 	{
       
   991 	switch (aMessage.Function())
       
   992 		{
       
   993 	case RIoConsoleProxy::ESetConsoleSizeDetect:
       
   994 		if (iConsole) User::Leave(KErrNotReady); // too late!
       
   995 		SetFlag(EAutoDetectSize, ETrue);
       
   996 		aMessage.Complete(KErrNone);
       
   997 		return;
       
   998 	case RIoConsoleProxy::ESetLazyConstruct:
       
   999 		if (iConsole) User::Leave(KErrNotReady); // too late!
       
  1000 		SetFlag(ELazy, ETrue);
       
  1001 		aMessage.Complete(KErrNone);
       
  1002 		return;
       
  1003 	case RIoConsoleProxy::ESetConsoleMode:
       
  1004 		SetModeL(aMessage);
       
  1005 		return;
       
  1006 	case RIoConsoleProxy::ESetUnderlyingConsole:
       
  1007 		SetUnderlyingConsoleL(aMessage);
       
  1008 		return;
       
  1009 	case RIoConsoleProxy::EOpenExistingConsole:
       
  1010 		OpenExistingL(aMessage);
       
  1011 		return;	
       
  1012 	case RConsoleProxy::EGetScreenSize:
       
  1013 		if (GetFlag(EAutoDetectSize) && !GetFlag(ELazy))
       
  1014 			{
       
  1015 			DetectSizeL(aMessage);
       
  1016 			return;
       
  1017 			}
       
  1018 		break;
       
  1019 	case RIoConsoleProxy::EWriteStdErr:
       
  1020 		{
       
  1021 		RBuf buf;
       
  1022 		CleanupClosePushL(buf);
       
  1023 		buf.CreateL(aMessage.GetDesLengthL(0));
       
  1024 		aMessage.ReadL(0, buf);
       
  1025 		if (iFlags & ESupportsStdErr)
       
  1026 			{
       
  1027 			TInt err = ConsoleStdErr::Write(iConsole->Console(), buf);
       
  1028 			if (err != KErrNone)
       
  1029 				{
       
  1030 				// Clearly it doesn't support it, clear the flag so we fall back to normal write and don't bother trying again
       
  1031 				iFlags &= ~ESupportsStdErr;
       
  1032 				}
       
  1033 			}
       
  1034 
       
  1035 		if (!(iFlags & ESupportsStdErr))
       
  1036 			{
       
  1037 			iConsole->Console()->Write(buf);
       
  1038 			}
       
  1039 		CleanupStack::PopAndDestroy(&buf);
       
  1040 		aMessage.Complete(KErrNone);
       
  1041 		return;
       
  1042 		}
       
  1043 	default:
       
  1044 		break;
       
  1045 		}
       
  1046 
       
  1047 	CConsoleProxySession::ServiceL(aMessage);
       
  1048 	}
       
  1049 	
       
  1050 MProxiedConsole* CIoConsoleProxySession::InstantiateConsoleL()
       
  1051 	{
       
  1052 	if (Server()->TheConsole()!=NULL)
       
  1053 		{
       
  1054 		// make sure that only 1 console is ever created in this server
       
  1055 		User::Leave(KErrAlreadyExists);
       
  1056 		}
       
  1057 	MProxiedConsole* cons;
       
  1058 	if (GetFlag(ELazy))
       
  1059 		{
       
  1060 		CLazyConsole* lazy = new(ELeave)CLazyConsole(iConsoleCreate, GetFlag(EAutoDetectSize));
       
  1061 		CleanupStack::PushL(lazy);
       
  1062 		cons = MProxiedConsole::DefaultL(lazy);
       
  1063 		CleanupStack::Pop();
       
  1064 		}
       
  1065 	else
       
  1066 		{
       
  1067 		cons = CConsoleProxySession::InstantiateConsoleL();
       
  1068 		}
       
  1069 	
       
  1070 	Server()->SetTheConsole(cons);
       
  1071 	
       
  1072 	if (iUnderlyingConsole)
       
  1073 		{
       
  1074 		TInt err = UnderlyingConsole::Set(cons->Console(), iUnderlyingConsole);
       
  1075 		// if this succeeds, ownership of the underlying console has been taken
       
  1076 		// if it didn't, we should delete it as it's not needed.
       
  1077 		if (err!=KErrNone)
       
  1078 			{
       
  1079 			delete iUnderlyingConsole;
       
  1080 			}
       
  1081 		iUnderlyingConsole = NULL;
       
  1082 		}
       
  1083 	
       
  1084 	return cons;	
       
  1085 	}
       
  1086 	
       
  1087 void CIoConsoleProxySession::ConsoleCreatedL(MProxiedConsole* aConsole)
       
  1088 	{
       
  1089 	if (GetFlag(EAutoDetectSize) && !(GetFlag(ELazy)))
       
  1090 		{
       
  1091 		iDetectedSize = DetectConsoleSize(aConsole->Console());
       
  1092 		}
       
  1093 	}
       
  1094 
       
  1095 void CIoConsoleProxySession::DetectSizeL(const RMessage2& aMessage)
       
  1096 	{
       
  1097 	if (!iConsole) User::Leave(KErrNotReady);
       
  1098 	
       
  1099 	aMessage.WriteL(0, TPckg<TSize>(iDetectedSize));
       
  1100 	aMessage.Complete(KErrNone);	
       
  1101 	}
       
  1102 
       
  1103 void CIoConsoleProxySession::SetModeL(const RMessage2& aMessage)
       
  1104 	{
       
  1105 	if (!iConsole) User::Leave(KErrNotReady);
       
  1106 	RIoReadWriteHandle::TMode mode = (RIoReadWriteHandle::TMode)aMessage.Int0();
       
  1107 	TInt err = ConsoleMode::Set(iConsole->Console(), (mode == RIoReadWriteHandle::EBinary) ? ConsoleMode::EBinary : ConsoleMode::EText);
       
  1108 	aMessage.Complete(err);
       
  1109 	}
       
  1110 
       
  1111 void CIoConsoleProxySession::SetUnderlyingConsoleL(const RMessage2& aMessage)
       
  1112 	{
       
  1113 	if (iUnderlyingConsole) User::Leave(KErrAlreadyExists);
       
  1114 	
       
  1115 	RIoConsoleProxy underlyingSession;
       
  1116 	RThread client;
       
  1117 	aMessage.ClientL(client, EOwnerThread);
       
  1118 	CleanupClosePushL(client);
       
  1119 
       
  1120 	underlyingSession.SetHandle(aMessage.Int0());
       
  1121 	User::LeaveIfError(underlyingSession.Duplicate(client, EOwnerThread));
       
  1122 	
       
  1123 	CleanupClosePushL(underlyingSession);
       
  1124 	User::LeaveIfError(underlyingSession.OpenExisting());
       
  1125 	
       
  1126 	CConsoleProxy* underlying = CWriteOnlyConsoleProxy::NewL(underlyingSession);
       
  1127 	
       
  1128 	CleanupStack::PopAndDestroy(2, &client); // we can close underlyingSession as it's been duplicated by CConsoleProxy::NewL
       
  1129 	
       
  1130 	if (iConsole && iConsole->Console())
       
  1131 		{
       
  1132 		CleanupStack::PushL(underlying);
       
  1133 		User::LeaveIfError(UnderlyingConsole::Set(iConsole->Console(), underlying));
       
  1134 		// ownership of underlying now taken.
       
  1135 		CleanupStack::Pop();
       
  1136 		}
       
  1137 	else
       
  1138 		{
       
  1139 		// save it for when the console is instantiated
       
  1140 		iUnderlyingConsole = underlying;
       
  1141 		}
       
  1142 	
       
  1143 	aMessage.Complete(KErrNone);
       
  1144 	}
       
  1145 
       
  1146 void CIoConsoleProxySession::OpenExistingL(const RMessage2& aMessage)
       
  1147 	{
       
  1148 	if (Server()->TheConsole()==NULL) User::Leave(KErrNotReady); // no console to connect to
       
  1149 	
       
  1150 	iConsole = Server()->TheConsole();
       
  1151 	iConsole->Open();
       
  1152 	aMessage.Complete(KErrNone);
       
  1153 	}
       
  1154 
       
  1155 TBool CIoConsoleProxySession::GetFlag(TFlag aFlag)
       
  1156 	{
       
  1157 	return iFlags & aFlag ? (TBool)ETrue : EFalse;
       
  1158 	}
       
  1159 	
       
  1160 void CIoConsoleProxySession::SetFlag(TFlag aFlag, TBool aSet)
       
  1161 	{
       
  1162 	if (aSet)
       
  1163 		{
       
  1164 		iFlags |= aFlag;
       
  1165 		}
       
  1166 	else
       
  1167 		{
       
  1168 		iFlags &= (~(TUint)aFlag);
       
  1169 		}
       
  1170 	}
       
  1171 
       
  1172 
       
  1173 //______________________________________________________________________________
       
  1174 //						CWriteOnlyConsoleProxy
       
  1175 CConsoleProxy* CWriteOnlyConsoleProxy::NewL(const RConsoleProxy& aProxySession)
       
  1176 	{
       
  1177 	CWriteOnlyConsoleProxy* self = new(ELeave)CWriteOnlyConsoleProxy();
       
  1178 	CleanupStack::PushL(self);
       
  1179 	self->ConstructL(aProxySession);
       
  1180 	CleanupStack::Pop(self);
       
  1181 	return self;
       
  1182 	}
       
  1183 	
       
  1184 CWriteOnlyConsoleProxy::CWriteOnlyConsoleProxy()
       
  1185 	{
       
  1186 	}
       
  1187 
       
  1188 void CWriteOnlyConsoleProxy::Read(TRequestStatus&)
       
  1189 	{
       
  1190 	User::Panic(KIoServerName, EPanicCannotReadFromUnderlyingConsole);
       
  1191 	}
       
  1192 
       
  1193 void CWriteOnlyConsoleProxy::ReadCancel()
       
  1194 	{
       
  1195 	}
       
  1196 
       
  1197 TKeyCode CWriteOnlyConsoleProxy::KeyCode() const
       
  1198 	{
       
  1199 	return EKeyNull;
       
  1200 	}
       
  1201 
       
  1202 
       
  1203 TUint CWriteOnlyConsoleProxy::KeyModifiers() const
       
  1204 	{
       
  1205 	return 0;
       
  1206 	}
       
  1207 
       
  1208 //______________________________________________________________________________
       
  1209 //						CLazyConsole
       
  1210 CLazyConsole::CLazyConsole(TConsoleCreateFunction aConsoleCreate, TBool aAutoDetectSize)
       
  1211 	: iConsoleCreate(aConsoleCreate), iSizeAutoDetect(aAutoDetectSize)
       
  1212 	{
       
  1213 	}
       
  1214 
       
  1215 CLazyConsole::~CLazyConsole()
       
  1216 	{
       
  1217 	iTitle.Close();
       
  1218 	delete iConsole;
       
  1219 	}
       
  1220 
       
  1221 TInt CLazyConsole::Create(const TDesC &aTitle,TSize aSize)
       
  1222 	{
       
  1223 	iSize = aSize;
       
  1224 	return iTitle.Create(aTitle);
       
  1225 	}
       
  1226 	
       
  1227 TInt CLazyConsole::CheckCreated() const
       
  1228 	{
       
  1229 	if (iCreateError) return iCreateError;
       
  1230 	if (iConsole) return KErrNone;
       
  1231 	
       
  1232 	TRAP(iCreateError, iConsole = iConsoleCreate());
       
  1233 	if ((iCreateError==KErrNone) && (!iConsole))
       
  1234 		{
       
  1235 		iCreateError = KErrNoMemory;
       
  1236 		}
       
  1237 	if (iCreateError == KErrNone)
       
  1238 		{
       
  1239 		TName procName = RProcess().Name(); // econseik sets the process name to the console title...
       
  1240 		iCreateError = iConsole->Create(iTitle, iSize);
       
  1241 		User::RenameProcess(procName.Left(procName.Locate('['))); // ...so restore it just in case
       
  1242 		}
       
  1243 	if ((iCreateError == KErrNone) && iSizeAutoDetect)
       
  1244 		{
       
  1245 		iDetectedSize = DetectConsoleSize(iConsole);
       
  1246 		}
       
  1247 	if (iCreateError != KErrNone)
       
  1248 		{
       
  1249 		delete iConsole;
       
  1250 		iConsole = NULL;
       
  1251 		}
       
  1252 	return iCreateError;
       
  1253 	}
       
  1254 
       
  1255 void CLazyConsole::Read(TRequestStatus &aStatus)
       
  1256 	{
       
  1257 	TInt err = CheckCreated();
       
  1258 	if (err)
       
  1259 		{
       
  1260 		TRequestStatus* stat = &aStatus;
       
  1261 		User::RequestComplete(stat, err);
       
  1262 		return;
       
  1263 		}
       
  1264 	iConsole->Read(aStatus);
       
  1265 	}
       
  1266 
       
  1267 void CLazyConsole::ReadCancel()
       
  1268 	{
       
  1269 	if (iConsole)
       
  1270 		{
       
  1271 		iConsole->ReadCancel();
       
  1272 		}
       
  1273 	}
       
  1274 
       
  1275 void CLazyConsole::Write(const TDesC &aDes)
       
  1276 	{
       
  1277 	if (CheckCreated() == KErrNone)
       
  1278 		{
       
  1279 		iConsole->Write(aDes);
       
  1280 		}
       
  1281 	}
       
  1282 
       
  1283 TPoint CLazyConsole::CursorPos() const
       
  1284 	{
       
  1285 	if (CheckCreated() == KErrNone)
       
  1286 		{
       
  1287 		return iConsole->CursorPos();
       
  1288 		}
       
  1289 	return TPoint(0,0);
       
  1290 	}
       
  1291 
       
  1292 void CLazyConsole::SetCursorPosAbs(const TPoint &aPoint)
       
  1293 	{
       
  1294 	if (CheckCreated() == KErrNone)
       
  1295 		{
       
  1296 		return iConsole->SetCursorPosAbs(aPoint);
       
  1297 		}
       
  1298 	}
       
  1299 
       
  1300 void CLazyConsole::SetCursorPosRel(const TPoint &aPoint)
       
  1301 	{
       
  1302 	if (CheckCreated() == KErrNone)
       
  1303 		{
       
  1304 		return iConsole->SetCursorPosRel(aPoint);
       
  1305 		}
       
  1306 	}
       
  1307 
       
  1308 void CLazyConsole::SetCursorHeight(TInt aPercentage)
       
  1309 	{
       
  1310 	if (CheckCreated() == KErrNone)
       
  1311 		{
       
  1312 		return iConsole->SetCursorHeight(aPercentage);
       
  1313 		}
       
  1314 	}
       
  1315 
       
  1316 void CLazyConsole::SetTitle(const TDesC &aTitle)
       
  1317 	{
       
  1318 	if (CheckCreated() == KErrNone)
       
  1319 		{
       
  1320 		return iConsole->SetTitle(aTitle);
       
  1321 		}
       
  1322 	}
       
  1323 
       
  1324 void CLazyConsole::ClearScreen()
       
  1325 	{
       
  1326 	if (CheckCreated() == KErrNone)
       
  1327 		{
       
  1328 		return iConsole->ClearScreen();
       
  1329 		}
       
  1330 	}
       
  1331 
       
  1332 void CLazyConsole::ClearToEndOfLine()
       
  1333 	{
       
  1334 	if (CheckCreated() == KErrNone)
       
  1335 		{
       
  1336 		return iConsole->ClearToEndOfLine();
       
  1337 		}
       
  1338 	}
       
  1339 
       
  1340 TSize CLazyConsole::ScreenSize() const
       
  1341 	{
       
  1342 	if (CheckCreated() == KErrNone)
       
  1343 		{
       
  1344 		if (iSizeAutoDetect)
       
  1345 			{
       
  1346 			return iDetectedSize;
       
  1347 			}
       
  1348 		else
       
  1349 			{
       
  1350 			return iConsole->ScreenSize();
       
  1351 			}
       
  1352 		}
       
  1353 	else
       
  1354 		{
       
  1355 		return TSize(0,0);
       
  1356 		}
       
  1357 	}
       
  1358 
       
  1359 TKeyCode CLazyConsole::KeyCode() const
       
  1360 	{
       
  1361 	if (CheckCreated() == KErrNone)
       
  1362 		{
       
  1363 		return iConsole->KeyCode();
       
  1364 		}
       
  1365 	return EKeyNull;
       
  1366 	}
       
  1367 
       
  1368 TUint CLazyConsole::KeyModifiers() const
       
  1369 	{
       
  1370 	if (CheckCreated() == KErrNone)
       
  1371 		{
       
  1372 		return iConsole->KeyModifiers();
       
  1373 		}
       
  1374 	return 0;
       
  1375 	}
       
  1376 
       
  1377 TInt CLazyConsole::Extension_(TUint aExtensionId, TAny*& a0, TAny* a1)
       
  1378 	{
       
  1379 	if (aExtensionId == LazyConsole::KLazyConsoleExtension)
       
  1380 		{
       
  1381 		TBool* constructed = (TBool*)a1;
       
  1382 		*constructed = (iConsole != NULL);
       
  1383 		return KErrNone;
       
  1384 		}
       
  1385 	else 
       
  1386 		{
       
  1387 		TInt err = CheckCreated();
       
  1388 		if (err == KErrNone)
       
  1389 			{
       
  1390 			return ((CLazyConsole*)iConsole)->Extension_(aExtensionId, a0, a1);
       
  1391 			}
       
  1392 		return err;
       
  1393 		}
       
  1394 	}