diff -r a6fec624de6c -r 706c7a69e448 libraries/iosrv/server/console.cpp --- a/libraries/iosrv/server/console.cpp Thu Nov 04 20:51:05 2010 +0000 +++ b/libraries/iosrv/server/console.cpp Thu Nov 04 23:22:39 2010 +0000 @@ -52,8 +52,9 @@ iRequestQueue.Close(); delete iImplementation; delete iReader; + delete iConsoleSizeChangedNotifier; iConsole.Close(); - delete iCreationTitle ; + delete iCreationTitle; iServerThread.Close(); } @@ -99,10 +100,7 @@ void CIoConsole::IorepReadL(MIoReader&) { - if (!iReader->IsActive()) - { - iReader->QueueRead(); - } + QueueReaderIfRequired(); } void CIoConsole::IorepReadKeyL(MIoReader& aReader) @@ -197,10 +195,6 @@ { User::LeaveIfError(iConsole.SetLazyConstruct()); } - if (iConfig.ConsoleSizeDetect()) - { - User::LeaveIfError(iConsole.SetConsoleSizeDetect()); - } if (aUnderlying) { User::LeaveIfError(aUnderlying->Open()); @@ -211,6 +205,7 @@ NewRequest(new(ELeave)TConsoleCreateRequest(*this)); iReader = CConsoleReader::NewL(*this); + iConsoleSizeChangedNotifier = new(ELeave) CConsoleSizeChangedNotifier(*this); } void CIoConsole::CreateComplete(TInt aError) @@ -276,16 +271,7 @@ { if (reader->IorIsKeyCaptured(aKeyCode, aModifiers)) { - if (reader->IorReadPending()) - { - TPtrC keyCodePtr((TUint16*)&aKeyCode, 1); - reader->IorReadBuf().Append(keyCodePtr); - reader->IorDataBuffered(1); - } - else - { - reader->IorReadKeyComplete(KErrNone, aKeyCode, aModifiers); - } + reader->IorReadKeyComplete(KErrNone, aKeyCode, aModifiers); keyHandled = ETrue; break; } @@ -306,6 +292,7 @@ TBool pendingReader(EFalse); TInt index = 0; MIoReader* reader = AttachedReader(index++); + TBool foregroundReader(ETrue); while (reader) { if (reader->IorReadPending() || reader->IorReadKeyPending()) @@ -313,7 +300,13 @@ pendingReader = ETrue; break; } + if (foregroundReader && reader->IorAllKeysCaptured()) + { + // If the foreground reader has captured all keys, we don't care about the background readers. + break; + } reader = AttachedReader(index++); + foregroundReader = EFalse; } if (pendingReader && !iReader->IsActive()) @@ -841,11 +834,6 @@ //______________________________________________________________________________ // RIoConsoleProxy -TInt RIoConsoleProxy::SetConsoleSizeDetect() - { - return SendReceive(ESetConsoleSizeDetect); - } - TInt RIoConsoleProxy::SetLazyConstruct() { return SendReceive(ESetLazyConstruct); @@ -871,6 +859,16 @@ SendReceive(EWriteStdErr, TIpcArgs(&aDescriptor), aStatus); } +void RIoConsoleProxy::NotifySizeChanged(TRequestStatus& aStatus) + { + SendReceive(ENotifySizeChange, TIpcArgs(), aStatus); + } + +void RIoConsoleProxy::CancelNotifySizeChanged() + { + SendReceive(ECancelNotifySizeChange, TIpcArgs()); + } + //______________________________________________________________________________ // CIoConsoleProxyServer CConsoleProxyServer* CIoConsoleProxyServerNewL(TAny* aParams) @@ -983,6 +981,7 @@ CIoConsoleProxySession::~CIoConsoleProxySession() { + delete iSizeChangedMessageCompleter; delete iUnderlyingConsole; } @@ -990,11 +989,6 @@ { switch (aMessage.Function()) { - case RIoConsoleProxy::ESetConsoleSizeDetect: - if (iConsole) User::Leave(KErrNotReady); // too late! - SetFlag(EAutoDetectSize, ETrue); - aMessage.Complete(KErrNone); - return; case RIoConsoleProxy::ESetLazyConstruct: if (iConsole) User::Leave(KErrNotReady); // too late! SetFlag(ELazy, ETrue); @@ -1010,11 +1004,12 @@ OpenExistingL(aMessage); return; case RConsoleProxy::EGetScreenSize: - if (GetFlag(EAutoDetectSize) && !GetFlag(ELazy)) + if (GetFlag(EHaveDetectedSize)) { DetectSizeL(aMessage); return; } + // Otherwise drop through to CConsoleProxySession's implementation break; case RIoConsoleProxy::EWriteStdErr: { @@ -1040,6 +1035,26 @@ aMessage.Complete(KErrNone); return; } + case RIoConsoleProxy::ENotifySizeChange: + { + if (iSizeChangedMessageCompleter == NULL) + { + iSizeChangedMessageCompleter = new(ELeave) CSizeChangeMessageCompleter; + if (iConsole) iSizeChangedMessageCompleter->SetConsole(iConsole->Console()); + } + iSizeChangedMessageCompleter->NotifySizeChange(const_cast(aMessage)); + return; + } + case RIoConsoleProxy::ECancelNotifySizeChange: + { + //RDebug::Printf("case RIoConsoleProxy::ECancelNotifySizeChange "); + if (iSizeChangedMessageCompleter) + { + iSizeChangedMessageCompleter->CancelNotify(); + } + aMessage.Complete(KErrNone); + return; + } default: break; } @@ -1057,7 +1072,7 @@ MProxiedConsole* cons; if (GetFlag(ELazy)) { - CLazyConsole* lazy = new(ELeave)CLazyConsole(iConsoleCreate, GetFlag(EAutoDetectSize)); + CLazyConsole* lazy = new(ELeave) CLazyConsole(iConsoleCreate); CleanupStack::PushL(lazy); cons = MProxiedConsole::DefaultL(lazy); CleanupStack::Pop(); @@ -1086,10 +1101,18 @@ void CIoConsoleProxySession::ConsoleCreatedL(MProxiedConsole* aConsole) { - if (GetFlag(EAutoDetectSize) && !(GetFlag(ELazy))) + if (!GetFlag(ELazy)) { - iDetectedSize = DetectConsoleSize(aConsole->Console()); + // If it's lazy, we can't check ReportedCorrectly until it's been instantiated + CConsoleBase* console = aConsole->Console(); + if (!ConsoleSize::ReportedCorrectly(console)) + { + iDetectedSize = DetectConsoleSize(console); + SetFlag(EHaveDetectedSize, ETrue); + } } + + if (iSizeChangedMessageCompleter) iSizeChangedMessageCompleter->SetConsole(aConsole->Console()); } void CIoConsoleProxySession::DetectSizeL(const RMessage2& aMessage) @@ -1207,8 +1230,8 @@ //______________________________________________________________________________ // CLazyConsole -CLazyConsole::CLazyConsole(TConsoleCreateFunction aConsoleCreate, TBool aAutoDetectSize) - : iConsoleCreate(aConsoleCreate), iSizeAutoDetect(aAutoDetectSize) +CLazyConsole::CLazyConsole(TConsoleCreateFunction aConsoleCreate) + : iConsoleCreate(aConsoleCreate) { } @@ -1240,10 +1263,17 @@ iCreateError = iConsole->Create(iTitle, iSize); User::RenameProcess(procName.Left(procName.Locate('['))); // ...so restore it just in case } - if ((iCreateError == KErrNone) && iSizeAutoDetect) + if ((iCreateError == KErrNone) && !ConsoleSize::ReportedCorrectly(iConsole)) { iDetectedSize = DetectConsoleSize(iConsole); + iHaveDetectedSize = ETrue; } + if (iCreateError == KErrNone && iStatusForNotifySizeRequest != NULL) + { + ConsoleSize::NotifySizeChanged(iConsole, *iStatusForNotifySizeRequest); + iStatusForNotifySizeRequest = NULL; + } + if (iCreateError != KErrNone) { delete iConsole; @@ -1341,7 +1371,7 @@ { if (CheckCreated() == KErrNone) { - if (iSizeAutoDetect) + if (iHaveDetectedSize) { return iDetectedSize; } @@ -1382,6 +1412,23 @@ *constructed = (iConsole != NULL); return KErrNone; } + else if (iConsole == NULL && aExtensionId == ConsoleMode::KSetConsoleModeExtension && (ConsoleMode::TMode)(TUint)a1 == ConsoleMode::EText) + { + // A console that isn't created yet will default to text mode anyway so we don't need to force instantiation. This works around an issue with iosrv calling ConsoleMode::Set even on the underlying console + return KErrNone; + } + else if (iConsole == NULL && aExtensionId == ConsoleSize::KConsoleSizeNotifyChangedExtension) + { + // Remember this notify for later + TRequestStatus* stat = (TRequestStatus*)a1; + //RDebug::Printf("Lazycons KConsoleSizeNotifyChangedExtension a1=%x iStatusForNotifySizeRequest=%x", a1, iStatusForNotifySizeRequest); + if (stat == NULL && iStatusForNotifySizeRequest != NULL) + { + User::RequestComplete(iStatusForNotifySizeRequest, KErrCancel); + } + iStatusForNotifySizeRequest = stat; + return KErrNone; // It's ok to say KErrNone now but complete the TRequestStatus with KErrExtensionNotSupported later + } else { TInt err = CheckCreated(); @@ -1392,3 +1439,100 @@ return err; } } + +// + +CIoConsole::CConsoleSizeChangedNotifier::CConsoleSizeChangedNotifier(CIoConsole& aConsole) + : CActive(CActive::EPriorityStandard), iConsole(aConsole) + { + CActiveScheduler::Add(this); + iConsole.iConsole.NotifySizeChanged(iStatus); + SetActive(); + } + +CIoConsole::CConsoleSizeChangedNotifier::~CConsoleSizeChangedNotifier() + { + Cancel(); + } + +void CIoConsole::CConsoleSizeChangedNotifier::RunL() + { + if (iStatus.Int() != KErrNone) // eg KErrExtensionNotSupported + { + return; + } + + iConsole.iConsole.NotifySizeChanged(iStatus); + SetActive(); + + MIoReader* fg = iConsole.AttachedReader(); + if (fg) + { + fg->IorReaderChange(RIoReadHandle::EConsoleSizeChanged); + } + } + +void CIoConsole::CConsoleSizeChangedNotifier::DoCancel() + { + //RDebug::Printf("Calling RIoConsoleProxt::CancelNotifySizeChanged"); + iConsole.iConsole.CancelNotifySizeChanged(); + } + +// + +CSizeChangeMessageCompleter::CSizeChangeMessageCompleter() + : CActive(CActive::EPriorityStandard) + { + CActiveScheduler::Add(this); + } + +CSizeChangeMessageCompleter::~CSizeChangeMessageCompleter() + { + Cancel(); + } + +void CSizeChangeMessageCompleter::NotifySizeChange(RMessagePtr2& aMessage) + { + iMessage = aMessage; + if (iActualConsole) + { + ConsoleSize::NotifySizeChanged(iActualConsole, iStatus); + SetActive(); + } + } + +void CSizeChangeMessageCompleter::RunL() + { + iMessage.Complete(iStatus.Int()); + } + +void CSizeChangeMessageCompleter::DoCancel() + { + ASSERT(iActualConsole); + ConsoleSize::CancelNotifySizeChanged(iActualConsole); + } + +void CSizeChangeMessageCompleter::SetConsole(CConsoleBase* aConsole) + { + ASSERT(iActualConsole == NULL); + iActualConsole = aConsole; + if (!iMessage.IsNull()) + { + ConsoleSize::NotifySizeChanged(iActualConsole, iStatus); + SetActive(); + } + } + +void CSizeChangeMessageCompleter::CancelNotify() + { + //RDebug::Printf("CSizeChangeMessageCompleter::CancelNotify"); + if (IsActive()) + { + Cancel(); + } + + if (!iMessage.IsNull()) + { + iMessage.Complete(KErrCancel); + } + }