50 delete iThreadWatcher; |
50 delete iThreadWatcher; |
51 delete iRequestAo; |
51 delete iRequestAo; |
52 iRequestQueue.Close(); |
52 iRequestQueue.Close(); |
53 delete iImplementation; |
53 delete iImplementation; |
54 delete iReader; |
54 delete iReader; |
|
55 delete iConsoleSizeChangedNotifier; |
55 iConsole.Close(); |
56 iConsole.Close(); |
56 delete iCreationTitle ; |
57 delete iCreationTitle; |
57 iServerThread.Close(); |
58 iServerThread.Close(); |
58 } |
59 } |
59 |
60 |
60 const TDesC& CIoConsole::Implementation() const |
61 const TDesC& CIoConsole::Implementation() const |
61 { |
62 { |
195 iThreadWatcher = new(ELeave)CServerDeathWatcher(iThreadServer, iServerThread); |
193 iThreadWatcher = new(ELeave)CServerDeathWatcher(iThreadServer, iServerThread); |
196 if (aOptions & RIoConsole::ELazyCreate) |
194 if (aOptions & RIoConsole::ELazyCreate) |
197 { |
195 { |
198 User::LeaveIfError(iConsole.SetLazyConstruct()); |
196 User::LeaveIfError(iConsole.SetLazyConstruct()); |
199 } |
197 } |
200 if (iConfig.ConsoleSizeDetect()) |
|
201 { |
|
202 User::LeaveIfError(iConsole.SetConsoleSizeDetect()); |
|
203 } |
|
204 if (aUnderlying) |
198 if (aUnderlying) |
205 { |
199 { |
206 User::LeaveIfError(aUnderlying->Open()); |
200 User::LeaveIfError(aUnderlying->Open()); |
207 CleanupClosePushL(*aUnderlying); |
201 CleanupClosePushL(*aUnderlying); |
208 NewRequest(new(ELeave)TConsoleSetUnderlyingRequest(*aUnderlying)); |
202 NewRequest(new(ELeave)TConsoleSetUnderlyingRequest(*aUnderlying)); |
209 CleanupStack::Pop(); |
203 CleanupStack::Pop(); |
210 } |
204 } |
211 NewRequest(new(ELeave)TConsoleCreateRequest(*this)); |
205 NewRequest(new(ELeave)TConsoleCreateRequest(*this)); |
212 |
206 |
213 iReader = CConsoleReader::NewL(*this); |
207 iReader = CConsoleReader::NewL(*this); |
|
208 iConsoleSizeChangedNotifier = new(ELeave) CConsoleSizeChangedNotifier(*this); |
214 } |
209 } |
215 |
210 |
216 void CIoConsole::CreateComplete(TInt aError) |
211 void CIoConsole::CreateComplete(TInt aError) |
217 { |
212 { |
218 iCreateStatus = aError; |
213 iCreateStatus = aError; |
274 TBool keyHandled(EFalse); |
269 TBool keyHandled(EFalse); |
275 while (reader) |
270 while (reader) |
276 { |
271 { |
277 if (reader->IorIsKeyCaptured(aKeyCode, aModifiers)) |
272 if (reader->IorIsKeyCaptured(aKeyCode, aModifiers)) |
278 { |
273 { |
279 if (reader->IorReadPending()) |
274 reader->IorReadKeyComplete(KErrNone, aKeyCode, aModifiers); |
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; |
275 keyHandled = ETrue; |
290 break; |
276 break; |
291 } |
277 } |
292 reader = AttachedReader(index++);; |
278 reader = AttachedReader(index++);; |
293 } |
279 } |
304 void CIoConsole::QueueReaderIfRequired() |
290 void CIoConsole::QueueReaderIfRequired() |
305 { |
291 { |
306 TBool pendingReader(EFalse); |
292 TBool pendingReader(EFalse); |
307 TInt index = 0; |
293 TInt index = 0; |
308 MIoReader* reader = AttachedReader(index++); |
294 MIoReader* reader = AttachedReader(index++); |
|
295 TBool foregroundReader(ETrue); |
309 while (reader) |
296 while (reader) |
310 { |
297 { |
311 if (reader->IorReadPending() || reader->IorReadKeyPending()) |
298 if (reader->IorReadPending() || reader->IorReadKeyPending()) |
312 { |
299 { |
313 pendingReader = ETrue; |
300 pendingReader = ETrue; |
314 break; |
301 break; |
315 } |
302 } |
|
303 if (foregroundReader && reader->IorAllKeysCaptured()) |
|
304 { |
|
305 // If the foreground reader has captured all keys, we don't care about the background readers. |
|
306 break; |
|
307 } |
316 reader = AttachedReader(index++); |
308 reader = AttachedReader(index++); |
|
309 foregroundReader = EFalse; |
317 } |
310 } |
318 |
311 |
319 if (pendingReader && !iReader->IsActive()) |
312 if (pendingReader && !iReader->IsActive()) |
320 { |
313 { |
321 iReader->QueueRead(); |
314 iReader->QueueRead(); |
867 } |
855 } |
868 |
856 |
869 void RIoConsoleProxy::WriteStdErr(const TDesC& aDescriptor, TRequestStatus& aStatus) |
857 void RIoConsoleProxy::WriteStdErr(const TDesC& aDescriptor, TRequestStatus& aStatus) |
870 { |
858 { |
871 SendReceive(EWriteStdErr, TIpcArgs(&aDescriptor), aStatus); |
859 SendReceive(EWriteStdErr, TIpcArgs(&aDescriptor), aStatus); |
|
860 } |
|
861 |
|
862 void RIoConsoleProxy::NotifySizeChanged(TRequestStatus& aStatus) |
|
863 { |
|
864 SendReceive(ENotifySizeChange, TIpcArgs(), aStatus); |
|
865 } |
|
866 |
|
867 void RIoConsoleProxy::CancelNotifySizeChanged() |
|
868 { |
|
869 SendReceive(ECancelNotifySizeChange, TIpcArgs()); |
872 } |
870 } |
873 |
871 |
874 //______________________________________________________________________________ |
872 //______________________________________________________________________________ |
875 // CIoConsoleProxyServer |
873 // CIoConsoleProxyServer |
876 CConsoleProxyServer* CIoConsoleProxyServerNewL(TAny* aParams) |
874 CConsoleProxyServer* CIoConsoleProxyServerNewL(TAny* aParams) |
981 // Assume ESupportsStdErr until proven otherwise |
979 // Assume ESupportsStdErr until proven otherwise |
982 } |
980 } |
983 |
981 |
984 CIoConsoleProxySession::~CIoConsoleProxySession() |
982 CIoConsoleProxySession::~CIoConsoleProxySession() |
985 { |
983 { |
|
984 delete iSizeChangedMessageCompleter; |
986 delete iUnderlyingConsole; |
985 delete iUnderlyingConsole; |
987 } |
986 } |
988 |
987 |
989 void CIoConsoleProxySession::ServiceL(const RMessage2& aMessage) |
988 void CIoConsoleProxySession::ServiceL(const RMessage2& aMessage) |
990 { |
989 { |
991 switch (aMessage.Function()) |
990 switch (aMessage.Function()) |
992 { |
991 { |
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: |
992 case RIoConsoleProxy::ESetLazyConstruct: |
999 if (iConsole) User::Leave(KErrNotReady); // too late! |
993 if (iConsole) User::Leave(KErrNotReady); // too late! |
1000 SetFlag(ELazy, ETrue); |
994 SetFlag(ELazy, ETrue); |
1001 aMessage.Complete(KErrNone); |
995 aMessage.Complete(KErrNone); |
1002 return; |
996 return; |
1008 return; |
1002 return; |
1009 case RIoConsoleProxy::EOpenExistingConsole: |
1003 case RIoConsoleProxy::EOpenExistingConsole: |
1010 OpenExistingL(aMessage); |
1004 OpenExistingL(aMessage); |
1011 return; |
1005 return; |
1012 case RConsoleProxy::EGetScreenSize: |
1006 case RConsoleProxy::EGetScreenSize: |
1013 if (GetFlag(EAutoDetectSize) && !GetFlag(ELazy)) |
1007 if (GetFlag(EHaveDetectedSize)) |
1014 { |
1008 { |
1015 DetectSizeL(aMessage); |
1009 DetectSizeL(aMessage); |
1016 return; |
1010 return; |
1017 } |
1011 } |
|
1012 // Otherwise drop through to CConsoleProxySession's implementation |
1018 break; |
1013 break; |
1019 case RIoConsoleProxy::EWriteStdErr: |
1014 case RIoConsoleProxy::EWriteStdErr: |
1020 { |
1015 { |
1021 RBuf buf; |
1016 RBuf buf; |
1022 CleanupClosePushL(buf); |
1017 CleanupClosePushL(buf); |
1038 } |
1033 } |
1039 CleanupStack::PopAndDestroy(&buf); |
1034 CleanupStack::PopAndDestroy(&buf); |
1040 aMessage.Complete(KErrNone); |
1035 aMessage.Complete(KErrNone); |
1041 return; |
1036 return; |
1042 } |
1037 } |
|
1038 case RIoConsoleProxy::ENotifySizeChange: |
|
1039 { |
|
1040 if (iSizeChangedMessageCompleter == NULL) |
|
1041 { |
|
1042 iSizeChangedMessageCompleter = new(ELeave) CSizeChangeMessageCompleter; |
|
1043 if (iConsole) iSizeChangedMessageCompleter->SetConsole(iConsole->Console()); |
|
1044 } |
|
1045 iSizeChangedMessageCompleter->NotifySizeChange(const_cast<RMessage2&>(aMessage)); |
|
1046 return; |
|
1047 } |
|
1048 case RIoConsoleProxy::ECancelNotifySizeChange: |
|
1049 { |
|
1050 //RDebug::Printf("case RIoConsoleProxy::ECancelNotifySizeChange "); |
|
1051 if (iSizeChangedMessageCompleter) |
|
1052 { |
|
1053 iSizeChangedMessageCompleter->CancelNotify(); |
|
1054 } |
|
1055 aMessage.Complete(KErrNone); |
|
1056 return; |
|
1057 } |
1043 default: |
1058 default: |
1044 break; |
1059 break; |
1045 } |
1060 } |
1046 |
1061 |
1047 CConsoleProxySession::ServiceL(aMessage); |
1062 CConsoleProxySession::ServiceL(aMessage); |
1084 return cons; |
1099 return cons; |
1085 } |
1100 } |
1086 |
1101 |
1087 void CIoConsoleProxySession::ConsoleCreatedL(MProxiedConsole* aConsole) |
1102 void CIoConsoleProxySession::ConsoleCreatedL(MProxiedConsole* aConsole) |
1088 { |
1103 { |
1089 if (GetFlag(EAutoDetectSize) && !(GetFlag(ELazy))) |
1104 if (!GetFlag(ELazy)) |
1090 { |
1105 { |
1091 iDetectedSize = DetectConsoleSize(aConsole->Console()); |
1106 // If it's lazy, we can't check ReportedCorrectly until it's been instantiated |
1092 } |
1107 CConsoleBase* console = aConsole->Console(); |
|
1108 if (!ConsoleSize::ReportedCorrectly(console)) |
|
1109 { |
|
1110 iDetectedSize = DetectConsoleSize(console); |
|
1111 SetFlag(EHaveDetectedSize, ETrue); |
|
1112 } |
|
1113 } |
|
1114 |
|
1115 if (iSizeChangedMessageCompleter) iSizeChangedMessageCompleter->SetConsole(aConsole->Console()); |
1093 } |
1116 } |
1094 |
1117 |
1095 void CIoConsoleProxySession::DetectSizeL(const RMessage2& aMessage) |
1118 void CIoConsoleProxySession::DetectSizeL(const RMessage2& aMessage) |
1096 { |
1119 { |
1097 if (!iConsole) User::Leave(KErrNotReady); |
1120 if (!iConsole) User::Leave(KErrNotReady); |
1238 { |
1261 { |
1239 TName procName = RProcess().Name(); // econseik sets the process name to the console title... |
1262 TName procName = RProcess().Name(); // econseik sets the process name to the console title... |
1240 iCreateError = iConsole->Create(iTitle, iSize); |
1263 iCreateError = iConsole->Create(iTitle, iSize); |
1241 User::RenameProcess(procName.Left(procName.Locate('['))); // ...so restore it just in case |
1264 User::RenameProcess(procName.Left(procName.Locate('['))); // ...so restore it just in case |
1242 } |
1265 } |
1243 if ((iCreateError == KErrNone) && iSizeAutoDetect) |
1266 if ((iCreateError == KErrNone) && !ConsoleSize::ReportedCorrectly(iConsole)) |
1244 { |
1267 { |
1245 iDetectedSize = DetectConsoleSize(iConsole); |
1268 iDetectedSize = DetectConsoleSize(iConsole); |
1246 } |
1269 iHaveDetectedSize = ETrue; |
|
1270 } |
|
1271 if (iCreateError == KErrNone && iStatusForNotifySizeRequest != NULL) |
|
1272 { |
|
1273 ConsoleSize::NotifySizeChanged(iConsole, *iStatusForNotifySizeRequest); |
|
1274 iStatusForNotifySizeRequest = NULL; |
|
1275 } |
|
1276 |
1247 if (iCreateError != KErrNone) |
1277 if (iCreateError != KErrNone) |
1248 { |
1278 { |
1249 delete iConsole; |
1279 delete iConsole; |
1250 iConsole = NULL; |
1280 iConsole = NULL; |
1251 } |
1281 } |
1380 { |
1410 { |
1381 TBool* constructed = (TBool*)a1; |
1411 TBool* constructed = (TBool*)a1; |
1382 *constructed = (iConsole != NULL); |
1412 *constructed = (iConsole != NULL); |
1383 return KErrNone; |
1413 return KErrNone; |
1384 } |
1414 } |
|
1415 else if (iConsole == NULL && aExtensionId == ConsoleMode::KSetConsoleModeExtension && (ConsoleMode::TMode)(TUint)a1 == ConsoleMode::EText) |
|
1416 { |
|
1417 // 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 |
|
1418 return KErrNone; |
|
1419 } |
|
1420 else if (iConsole == NULL && aExtensionId == ConsoleSize::KConsoleSizeNotifyChangedExtension) |
|
1421 { |
|
1422 // Remember this notify for later |
|
1423 TRequestStatus* stat = (TRequestStatus*)a1; |
|
1424 //RDebug::Printf("Lazycons KConsoleSizeNotifyChangedExtension a1=%x iStatusForNotifySizeRequest=%x", a1, iStatusForNotifySizeRequest); |
|
1425 if (stat == NULL && iStatusForNotifySizeRequest != NULL) |
|
1426 { |
|
1427 User::RequestComplete(iStatusForNotifySizeRequest, KErrCancel); |
|
1428 } |
|
1429 iStatusForNotifySizeRequest = stat; |
|
1430 return KErrNone; // It's ok to say KErrNone now but complete the TRequestStatus with KErrExtensionNotSupported later |
|
1431 } |
1385 else |
1432 else |
1386 { |
1433 { |
1387 TInt err = CheckCreated(); |
1434 TInt err = CheckCreated(); |
1388 if (err == KErrNone) |
1435 if (err == KErrNone) |
1389 { |
1436 { |
1390 return ((CLazyConsole*)iConsole)->Extension_(aExtensionId, a0, a1); |
1437 return ((CLazyConsole*)iConsole)->Extension_(aExtensionId, a0, a1); |
1391 } |
1438 } |
1392 return err; |
1439 return err; |
1393 } |
1440 } |
1394 } |
1441 } |
|
1442 |
|
1443 // |
|
1444 |
|
1445 CIoConsole::CConsoleSizeChangedNotifier::CConsoleSizeChangedNotifier(CIoConsole& aConsole) |
|
1446 : CActive(CActive::EPriorityStandard), iConsole(aConsole) |
|
1447 { |
|
1448 CActiveScheduler::Add(this); |
|
1449 iConsole.iConsole.NotifySizeChanged(iStatus); |
|
1450 SetActive(); |
|
1451 } |
|
1452 |
|
1453 CIoConsole::CConsoleSizeChangedNotifier::~CConsoleSizeChangedNotifier() |
|
1454 { |
|
1455 Cancel(); |
|
1456 } |
|
1457 |
|
1458 void CIoConsole::CConsoleSizeChangedNotifier::RunL() |
|
1459 { |
|
1460 if (iStatus.Int() != KErrNone) // eg KErrExtensionNotSupported |
|
1461 { |
|
1462 return; |
|
1463 } |
|
1464 |
|
1465 iConsole.iConsole.NotifySizeChanged(iStatus); |
|
1466 SetActive(); |
|
1467 |
|
1468 MIoReader* fg = iConsole.AttachedReader(); |
|
1469 if (fg) |
|
1470 { |
|
1471 fg->IorReaderChange(RIoReadHandle::EConsoleSizeChanged); |
|
1472 } |
|
1473 } |
|
1474 |
|
1475 void CIoConsole::CConsoleSizeChangedNotifier::DoCancel() |
|
1476 { |
|
1477 //RDebug::Printf("Calling RIoConsoleProxt::CancelNotifySizeChanged"); |
|
1478 iConsole.iConsole.CancelNotifySizeChanged(); |
|
1479 } |
|
1480 |
|
1481 // |
|
1482 |
|
1483 CSizeChangeMessageCompleter::CSizeChangeMessageCompleter() |
|
1484 : CActive(CActive::EPriorityStandard) |
|
1485 { |
|
1486 CActiveScheduler::Add(this); |
|
1487 } |
|
1488 |
|
1489 CSizeChangeMessageCompleter::~CSizeChangeMessageCompleter() |
|
1490 { |
|
1491 Cancel(); |
|
1492 } |
|
1493 |
|
1494 void CSizeChangeMessageCompleter::NotifySizeChange(RMessagePtr2& aMessage) |
|
1495 { |
|
1496 iMessage = aMessage; |
|
1497 if (iActualConsole) |
|
1498 { |
|
1499 ConsoleSize::NotifySizeChanged(iActualConsole, iStatus); |
|
1500 SetActive(); |
|
1501 } |
|
1502 } |
|
1503 |
|
1504 void CSizeChangeMessageCompleter::RunL() |
|
1505 { |
|
1506 iMessage.Complete(iStatus.Int()); |
|
1507 } |
|
1508 |
|
1509 void CSizeChangeMessageCompleter::DoCancel() |
|
1510 { |
|
1511 ASSERT(iActualConsole); |
|
1512 ConsoleSize::CancelNotifySizeChanged(iActualConsole); |
|
1513 } |
|
1514 |
|
1515 void CSizeChangeMessageCompleter::SetConsole(CConsoleBase* aConsole) |
|
1516 { |
|
1517 ASSERT(iActualConsole == NULL); |
|
1518 iActualConsole = aConsole; |
|
1519 if (!iMessage.IsNull()) |
|
1520 { |
|
1521 ConsoleSize::NotifySizeChanged(iActualConsole, iStatus); |
|
1522 SetActive(); |
|
1523 } |
|
1524 } |
|
1525 |
|
1526 void CSizeChangeMessageCompleter::CancelNotify() |
|
1527 { |
|
1528 //RDebug::Printf("CSizeChangeMessageCompleter::CancelNotify"); |
|
1529 if (IsActive()) |
|
1530 { |
|
1531 Cancel(); |
|
1532 } |
|
1533 |
|
1534 if (!iMessage.IsNull()) |
|
1535 { |
|
1536 iMessage.Complete(KErrCancel); |
|
1537 } |
|
1538 } |